Skip to content

Commit b741c19

Browse files
authored
vms/platformvm: Move VerifyUniqueInputs from verifier to backend (#2410)
1 parent 6aa20fc commit b741c19

File tree

3 files changed

+33
-31
lines changed

3 files changed

+33
-31
lines changed

vms/avm/block/executor/manager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ type Manager interface {
4343
// preferred state. This should *not* be used to verify transactions in a block.
4444
VerifyTx(tx *txs.Tx) error
4545

46-
// VerifyUniqueInputs verifies that the inputs are not duplicated in the
47-
// provided blk or any of its ancestors pinned in memory.
46+
// VerifyUniqueInputs returns nil iff no blocks in the inclusive
47+
// ancestry of [blkID] consume an input in [inputs].
4848
VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error
4949
}
5050

vms/platformvm/block/executor/backend.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@
44
package executor
55

66
import (
7+
"errors"
78
"time"
89

910
"github.com/ava-labs/avalanchego/ids"
1011
"github.com/ava-labs/avalanchego/snow"
12+
"github.com/ava-labs/avalanchego/utils/set"
1113
"github.com/ava-labs/avalanchego/vms/platformvm/block"
1214
"github.com/ava-labs/avalanchego/vms/platformvm/state"
1315
"github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool"
1416
)
1517

18+
var errConflictingParentTxs = errors.New("block contains a transaction that conflicts with a transaction in a parent block")
19+
1620
// Shared fields used by visitors.
1721
type backend struct {
1822
mempool.Mempool
@@ -95,3 +99,28 @@ func (b *backend) getTimestamp(blkID ids.ID) time.Time {
9599
// so we just return the chain time.
96100
return b.state.GetTimestamp()
97101
}
102+
103+
// verifyUniqueInputs returns nil iff no blocks in the inclusive
104+
// ancestry of [blkID] consume an input in [inputs].
105+
func (b *backend) verifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error {
106+
if inputs.Len() == 0 {
107+
return nil
108+
}
109+
110+
// Check for conflicts in ancestors.
111+
for {
112+
state, ok := b.blkIDToState[blkID]
113+
if !ok {
114+
// The parent state isn't pinned in memory.
115+
// This means the parent must be accepted already.
116+
return nil
117+
}
118+
119+
if state.inputs.Overlaps(inputs) {
120+
return errConflictingParentTxs
121+
}
122+
123+
blk := state.statelessBlock
124+
blkID = blk.Parent()
125+
}
126+
}

vms/platformvm/block/executor/verifier.go

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"github.com/ava-labs/avalanchego/chains/atomic"
1111
"github.com/ava-labs/avalanchego/ids"
12-
"github.com/ava-labs/avalanchego/utils/set"
1312
"github.com/ava-labs/avalanchego/vms/platformvm/block"
1413
"github.com/ava-labs/avalanchego/vms/platformvm/state"
1514
"github.com/ava-labs/avalanchego/vms/platformvm/status"
@@ -26,7 +25,6 @@ var (
2625
errIncorrectBlockHeight = errors.New("incorrect block height")
2726
errChildBlockEarlierThanParent = errors.New("proposed timestamp before current chain time")
2827
errConflictingBatchTxs = errors.New("block contains conflicting transactions")
29-
errConflictingParentTxs = errors.New("block contains a transaction that conflicts with a transaction in a parent block")
3028
errOptionBlockTimestampNotMatchingParent = errors.New("option block proposed timestamp not matching parent block one")
3129
)
3230

@@ -203,7 +201,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error {
203201

204202
atomicExecutor.OnAccept.AddTx(b.Tx, status.Committed)
205203

206-
if err := v.verifyUniqueInputs(b, atomicExecutor.Inputs); err != nil {
204+
if err := v.verifyUniqueInputs(b.Parent(), atomicExecutor.Inputs); err != nil {
207205
return err
208206
}
209207

@@ -441,7 +439,7 @@ func (v *verifier) standardBlock(
441439
}
442440
}
443441

444-
if err := v.verifyUniqueInputs(b, blkState.inputs); err != nil {
442+
if err := v.verifyUniqueInputs(b.Parent(), blkState.inputs); err != nil {
445443
return err
446444
}
447445

@@ -461,28 +459,3 @@ func (v *verifier) standardBlock(
461459
v.Mempool.Remove(b.Transactions)
462460
return nil
463461
}
464-
465-
// verifyUniqueInputs verifies that the inputs of the given block are not
466-
// duplicated in any of the parent blocks pinned in memory.
467-
func (v *verifier) verifyUniqueInputs(block block.Block, inputs set.Set[ids.ID]) error {
468-
if inputs.Len() == 0 {
469-
return nil
470-
}
471-
472-
// Check for conflicts in ancestors.
473-
for {
474-
parentID := block.Parent()
475-
parentState, ok := v.blkIDToState[parentID]
476-
if !ok {
477-
// The parent state isn't pinned in memory.
478-
// This means the parent must be accepted already.
479-
return nil
480-
}
481-
482-
if parentState.inputs.Overlaps(inputs) {
483-
return errConflictingParentTxs
484-
}
485-
486-
block = parentState.statelessBlock
487-
}
488-
}

0 commit comments

Comments
 (0)