-
Notifications
You must be signed in to change notification settings - Fork 679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ACP-77: Implement Warp message verification #3423
Changes from 190 commits
845f1d2
91a7cd7
df02f3c
c848fee
79c9b40
d8819fc
667002e
31be1e2
fb7f564
cd317f5
9884275
ed2fcfd
c4f5652
eb52075
8f0a080
d482de8
fc27346
e8b21ec
7f517c7
7d0d7e5
08bd9e3
78c1c3d
6547c6d
38ee164
d2137ef
5845d11
6c3116a
d0d1602
d397375
5f8a09c
3e9dc01
da3a726
8483ced
0507ce7
0022a65
8bbeee6
08dd776
255b0bf
3bc547d
bff468d
99f3c97
7cf1668
41f78f0
29cd6ba
8dfcbb1
ef29548
a77fb3c
ce05dc8
3d04cef
dc35645
d472a9f
34ba29b
97029aa
dbeee70
729ded5
3621e53
de2be9f
92a2277
6375aa2
aedff15
1ac030a
9e0d7d5
9993b05
547d426
6bcc0ea
6065604
a7792c7
39b961b
4723c46
46c4889
a576cd1
f1ca6e6
71f88e8
c2ffd17
2b5d7c7
91a6465
07370a5
23aff43
66011f0
32bba0e
d183148
b1bb458
ad31107
cee236e
900eba3
fd48bde
7cbf31b
33d297d
486f732
b448a04
0685531
bb9f853
e6e3e76
3077356
69837c1
8611fe4
a5d3930
d74cdff
7cddfc0
afc9054
3c8246e
1268ed1
f7b75bc
82a249b
d37e9f3
9dc642a
22de2b1
cc0e0ee
33fea00
915eb71
3811423
b0c6f0b
74edd4f
7d31e7a
fca9460
158621c
4c6462c
a217d1b
3987922
56475cf
db85cf1
8a18b14
6dc3e84
f8552ba
7e1c545
88fe959
5b08c6a
54b24e5
9884a93
a7cd427
4c2605c
20bd155
acf026a
bb0a605
0bf397a
5591626
0093c70
a0e6bcd
5e46925
706c833
3a01924
d7e00dd
56b0049
3540203
1bf8709
018b0aa
bd6e10b
24c7d4b
833c04d
70a53b3
26c3549
877242f
5110cfa
e435ed7
3750b1c
687398e
5a08505
05d24ca
37bede4
3098c0b
240f1e8
e0ab968
efa35a4
031b989
a3f6186
f767800
0901618
aedd8da
e64ca23
4c86649
987c4e2
e10a311
f55e2c0
98ffb01
6b23e82
c8f5157
a741fe9
af6171a
e3f6ab3
fc9440c
f41cff6
e2b971e
38f63f9
aa4e859
a35c877
93ffbcd
28b478b
db37d00
3b1d5ca
9571693
30ac509
9769f21
f16cc58
2947902
6357f5a
eaa7ea3
e2451ab
6d04b1f
b71faf7
949da1d
fde96e7
c975b67
ddd97e3
d5148eb
6dc9f6d
5e49482
abae441
b3e1095
5f86e1a
4c9f376
b44a5eb
a4637e7
e055312
5797442
6756ea0
22e6b6b
d92a83d
024b042
33c2ac8
fa5f2cb
b413478
860fc32
02fa55a
e42e213
4b36d76
ee3f305
b49f7f8
cdabac6
a513cf1
0b529af
4935575
fd9e198
5953b6b
963b122
44d3bd5
79cd3be
c7842c0
f7c3e71
a245061
039d539
a14dc90
06ce053
c03ad3b
54f58a8
8806a57
d9b04ba
cfc0432
137ce85
2fc07b3
52e04ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ import ( | |
"github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" | ||
"github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" | ||
|
||
smblock "github.com/ava-labs/avalanchego/snow/engine/snowman/block" | ||
blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" | ||
txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" | ||
) | ||
|
@@ -51,6 +52,7 @@ var ( | |
) | ||
|
||
type Builder interface { | ||
smblock.BuildBlockWithContextChainVM | ||
mempool.Mempool | ||
|
||
// StartBlockTimer starts to issue block creation requests to advance the | ||
|
@@ -182,7 +184,11 @@ func (b *builder) durationToSleep() (time.Duration, error) { | |
|
||
now := b.txExecutorBackend.Clk.Time() | ||
maxTimeToAwake := now.Add(maxTimeToSleep) | ||
nextStakerChangeTime, err := state.GetNextStakerChangeTime(preferredState, maxTimeToAwake) | ||
nextStakerChangeTime, err := state.GetNextStakerChangeTime( | ||
b.txExecutorBackend.Config.ValidatorFeeConfig, | ||
preferredState, | ||
maxTimeToAwake, | ||
) | ||
if err != nil { | ||
return 0, fmt.Errorf("%w of %s: %w", errCalculatingNextStakerTime, preferredID, err) | ||
} | ||
|
@@ -204,10 +210,14 @@ func (b *builder) ShutdownBlockTimer() { | |
}) | ||
} | ||
|
||
// BuildBlock builds a block to be added to consensus. | ||
// This method removes the transactions from the returned | ||
// blocks from the mempool. | ||
func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { | ||
func (b *builder) BuildBlock(ctx context.Context) (snowman.Block, error) { | ||
return b.BuildBlockWithContext(ctx, nil) | ||
} | ||
|
||
func (b *builder) BuildBlockWithContext( | ||
ctx context.Context, | ||
blockContext *smblock.Context, | ||
) (snowman.Block, error) { | ||
// If there are still transactions in the mempool, then we need to | ||
// re-trigger block building. | ||
defer b.Mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) | ||
|
@@ -226,18 +236,29 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { | |
return nil, fmt.Errorf("%w: %s", state.ErrMissingParentState, preferredID) | ||
} | ||
|
||
timestamp, timeWasCapped, err := state.NextBlockTime(preferredState, b.txExecutorBackend.Clk) | ||
timestamp, timeWasCapped, err := state.NextBlockTime( | ||
b.txExecutorBackend.Config.ValidatorFeeConfig, | ||
preferredState, | ||
b.txExecutorBackend.Clk, | ||
) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not calculate next staker change time: %w", err) | ||
} | ||
|
||
var pChainHeight uint64 | ||
if blockContext != nil { | ||
pChainHeight = blockContext.PChainHeight | ||
} | ||
|
||
statelessBlk, err := buildBlock( | ||
ctx, | ||
b, | ||
preferredID, | ||
nextHeight, | ||
timestamp, | ||
timeWasCapped, | ||
preferredState, | ||
pChainHeight, | ||
) | ||
if err != nil { | ||
return nil, err | ||
|
@@ -253,64 +274,83 @@ func (b *builder) PackAllBlockTxs() ([]*txs.Tx, error) { | |
return nil, fmt.Errorf("%w: %s", errMissingPreferredState, preferredID) | ||
} | ||
|
||
timestamp, _, err := state.NextBlockTime(preferredState, b.txExecutorBackend.Clk) | ||
timestamp, _, err := state.NextBlockTime( | ||
b.txExecutorBackend.Config.ValidatorFeeConfig, | ||
preferredState, | ||
b.txExecutorBackend.Clk, | ||
) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not calculate next staker change time: %w", err) | ||
} | ||
|
||
recommendedPChainHeight, err := b.txExecutorBackend.Ctx.ValidatorState.GetMinimumHeight(context.TODO()) | ||
ceyonur marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if !b.txExecutorBackend.Config.UpgradeConfig.IsEtnaActivated(timestamp) { | ||
return packDurangoBlockTxs( | ||
context.TODO(), | ||
marun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
preferredID, | ||
preferredState, | ||
b.Mempool, | ||
b.txExecutorBackend, | ||
b.blkManager, | ||
timestamp, | ||
recommendedPChainHeight, | ||
math.MaxInt, | ||
) | ||
} | ||
return packEtnaBlockTxs( | ||
context.TODO(), | ||
preferredID, | ||
preferredState, | ||
b.Mempool, | ||
b.txExecutorBackend, | ||
b.blkManager, | ||
timestamp, | ||
recommendedPChainHeight, | ||
math.MaxUint64, | ||
) | ||
} | ||
|
||
// [timestamp] is min(max(now, parent timestamp), next staker change time) | ||
func buildBlock( | ||
ctx context.Context, | ||
builder *builder, | ||
parentID ids.ID, | ||
height uint64, | ||
timestamp time.Time, | ||
forceAdvanceTime bool, | ||
parentState state.Chain, | ||
pChainHeight uint64, | ||
) (block.Block, error) { | ||
var ( | ||
blockTxs []*txs.Tx | ||
err error | ||
) | ||
if builder.txExecutorBackend.Config.UpgradeConfig.IsEtnaActivated(timestamp) { | ||
blockTxs, err = packEtnaBlockTxs( | ||
ctx, | ||
parentID, | ||
parentState, | ||
builder.Mempool, | ||
builder.txExecutorBackend, | ||
builder.blkManager, | ||
timestamp, | ||
pChainHeight, | ||
0, // minCapacity is 0 as we want to honor the capacity in state. | ||
) | ||
} else { | ||
blockTxs, err = packDurangoBlockTxs( | ||
ctx, | ||
parentID, | ||
parentState, | ||
builder.Mempool, | ||
builder.txExecutorBackend, | ||
builder.blkManager, | ||
timestamp, | ||
pChainHeight, | ||
targetBlockSize, | ||
) | ||
} | ||
|
@@ -356,12 +396,14 @@ func buildBlock( | |
} | ||
|
||
func packDurangoBlockTxs( | ||
ctx context.Context, | ||
parentID ids.ID, | ||
parentState state.Chain, | ||
mempool mempool.Mempool, | ||
backend *txexecutor.Backend, | ||
manager blockexecutor.Manager, | ||
timestamp time.Time, | ||
pChainHeight uint64, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For my own understanding, why are we adding the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's just so that we can call the same |
||
remainingSize int, | ||
) ([]*txs.Tx, error) { | ||
stateDiff, err := state.NewDiffOn(parentState) | ||
|
@@ -389,11 +431,13 @@ func packDurangoBlockTxs( | |
} | ||
|
||
shouldAdd, err := executeTx( | ||
ctx, | ||
parentID, | ||
stateDiff, | ||
mempool, | ||
backend, | ||
manager, | ||
pChainHeight, | ||
&inputs, | ||
feeCalculator, | ||
tx, | ||
|
@@ -413,12 +457,14 @@ func packDurangoBlockTxs( | |
} | ||
|
||
func packEtnaBlockTxs( | ||
ctx context.Context, | ||
parentID ids.ID, | ||
parentState state.Chain, | ||
mempool mempool.Mempool, | ||
backend *txexecutor.Backend, | ||
manager blockexecutor.Manager, | ||
timestamp time.Time, | ||
pChainHeight uint64, | ||
minCapacity gas.Gas, | ||
) ([]*txs.Tx, error) { | ||
stateDiff, err := state.NewDiffOn(parentState) | ||
|
@@ -462,11 +508,13 @@ func packEtnaBlockTxs( | |
} | ||
|
||
shouldAdd, err := executeTx( | ||
ctx, | ||
parentID, | ||
stateDiff, | ||
mempool, | ||
backend, | ||
manager, | ||
pChainHeight, | ||
&inputs, | ||
feeCalculator, | ||
tx, | ||
|
@@ -486,11 +534,13 @@ func packEtnaBlockTxs( | |
} | ||
|
||
func executeTx( | ||
ctx context.Context, | ||
parentID ids.ID, | ||
stateDiff state.Diff, | ||
mempool mempool.Mempool, | ||
backend *txexecutor.Backend, | ||
manager blockexecutor.Manager, | ||
pChainHeight uint64, | ||
inputs *set.Set[ids.ID], | ||
feeCalculator fee.Calculator, | ||
tx *txs.Tx, | ||
|
@@ -499,6 +549,19 @@ func executeTx( | |
|
||
// Invariant: [tx] has already been syntactically verified. | ||
|
||
err := txexecutor.VerifyWarpMessages( | ||
ctx, | ||
backend.Ctx.NetworkID, | ||
backend.Ctx.ValidatorState, | ||
pChainHeight, | ||
tx.Unsigned, | ||
) | ||
if err != nil { | ||
txID := tx.ID() | ||
mempool.MarkDropped(txID, err) | ||
return false, nil | ||
} | ||
|
||
txDiff, err := state.NewDiffOn(stateDiff) | ||
if err != nil { | ||
return false, err | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming
pChainHeight=0
is a valid input tobuildBlock
and subsequent function calls? Is this documented anywhere? I traced the call as far as BitSetSignature.Verify and wasn't seeing where this case was handled.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing in
pChainHeight=0
just means that the warp messages (if any existed) would be verified against the genesis state of the chain.(Not that this particularly matters.. but) For Fuji and Mainnet, it is impossible to verify a warp message against block height = 0 because there are no validators with BLS keys in the genesis.