From 60e1a9f4b5c4fe40c4435350ace0d2b98a93259e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 7 Nov 2024 14:33:15 -0500 Subject: [PATCH] Remove P-chain txsmock package (#3528) --- scripts/mocks.mockgen.source.txt | 1 - .../block/executor/verifier_test.go | 637 +++++++++--------- vms/platformvm/txs/txsmock/unsigned_tx.go | 138 ---- 3 files changed, 301 insertions(+), 475 deletions(-) delete mode 100644 vms/platformvm/txs/txsmock/unsigned_tx.go diff --git a/scripts/mocks.mockgen.source.txt b/scripts/mocks.mockgen.source.txt index 93f4c2fb5127..10cc5a678ebf 100644 --- a/scripts/mocks.mockgen.source.txt +++ b/scripts/mocks.mockgen.source.txt @@ -10,5 +10,4 @@ vms/platformvm/signer/signer.go==Signer=vms/platformvm/signer/signermock/signer. vms/platformvm/state/diff.go==MockDiff=vms/platformvm/state/mock_diff.go vms/platformvm/state/state.go=Chain=MockState=vms/platformvm/state/mock_state.go vms/platformvm/state/state.go=State=MockChain=vms/platformvm/state/mock_chain.go -vms/platformvm/txs/unsigned_tx.go==UnsignedTx=vms/platformvm/txs/txsmock/unsigned_tx.go vms/proposervm/block.go=Block=MockPostForkBlock=vms/proposervm/mock_post_fork_block.go diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 0a5d9e3c662f..4de3a6c8b2dd 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -14,10 +14,13 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/database/memdb" + "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/snowtest" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/upgrade/upgradetest" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" @@ -40,7 +43,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool/mempoolmock" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/txsmock" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -49,17 +51,36 @@ import ( validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) -func newTestVerifier(t testing.TB, s state.State) *verifier { +type testVerifierConfig struct { + DB database.Database + Upgrades upgrade.Config + Context *snow.Context +} + +func newTestVerifier(t testing.TB, c testVerifierConfig) *verifier { require := require.New(t) + if c.DB == nil { + c.DB = memdb.New() + } + if c.Upgrades == (upgrade.Config{}) { + c.Upgrades = upgradetest.GetConfig(upgradetest.Latest) + } + if c.Context == nil { + c.Context = snowtest.Context(t, constants.PlatformChainID) + } + mempool, err := mempool.New("", prometheus.NewRegistry(), nil) require.NoError(err) var ( - upgrades = upgradetest.GetConfig(upgradetest.Latest) - ctx = snowtest.Context(t, constants.PlatformChainID) - clock = &mockable.Clock{} - fx = &secp256k1fx.Fx{} + state = statetest.New(t, statetest.Config{ + DB: c.DB, + Upgrades: c.Upgrades, + Context: c.Context, + }) + clock = &mockable.Clock{} + fx = &secp256k1fx.Fx{} ) require.NoError(fx.InitializeVM(&secp256k1fx.TestVM{ Clk: *clock, @@ -69,10 +90,10 @@ func newTestVerifier(t testing.TB, s state.State) *verifier { return &verifier{ backend: &backend{ Mempool: mempool, - lastAccepted: s.GetLastAccepted(), + lastAccepted: state.GetLastAccepted(), blkIDToState: make(map[ids.ID]*blockState), - state: s, - ctx: ctx, + state: state, + ctx: c.Context, }, txExecutorBackend: &executor.Backend{ Config: &config.Config{ @@ -81,13 +102,13 @@ func newTestVerifier(t testing.TB, s state.State) *verifier { DynamicFeeConfig: genesis.LocalParams.DynamicFeeConfig, ValidatorFeeConfig: genesis.LocalParams.ValidatorFeeConfig, SybilProtectionEnabled: true, - UpgradeConfig: upgrades, + UpgradeConfig: c.Upgrades, }, - Ctx: ctx, + Ctx: c.Context, Clk: clock, Fx: fx, FlowChecker: utxo.NewVerifier( - ctx, + c.Context, clock, fx, ), @@ -97,271 +118,314 @@ func newTestVerifier(t testing.TB, s state.State) *verifier { } func TestVerifierVisitProposalBlock(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - s := state.NewMockState(ctrl) - mempool := mempoolmock.NewMempool(ctrl) - parentID := ids.GenerateTestID() - parentStatelessBlk := block.NewMockBlock(ctrl) - parentOnAcceptState := state.NewMockDiff(ctrl) - timestamp := time.Now() - // One call for each of onCommitState and onAbortState. - parentOnAcceptState.EXPECT().GetTimestamp().Return(timestamp).Times(2) - parentOnAcceptState.EXPECT().GetFeeState().Return(gas.State{}).Times(2) - parentOnAcceptState.EXPECT().GetSoVExcess().Return(gas.Gas(0)).Times(2) - parentOnAcceptState.EXPECT().GetAccruedFees().Return(uint64(0)).Times(2) - parentOnAcceptState.EXPECT().NumActiveSubnetOnlyValidators().Return(0).Times(2) - - backend := &backend{ - lastAccepted: parentID, - blkIDToState: map[ids.ID]*blockState{ - parentID: { - statelessBlock: parentStatelessBlk, - onAcceptState: parentOnAcceptState, - }, - }, - Mempool: mempool, - state: s, - ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - } - manager := &manager{ - txExecutorBackend: &executor.Backend{ - Config: &config.Config{ - UpgradeConfig: upgradetest.GetConfig(upgradetest.ApricotPhasePost6), + var ( + require = require.New(t) + verifier = newTestVerifier(t, testVerifierConfig{ + Upgrades: upgradetest.GetConfig(upgradetest.ApricotPhasePost6), + }) + initialTimestamp = verifier.state.GetTimestamp() + newTimestamp = initialTimestamp.Add(time.Second) + proposalTx = &txs.Tx{ + Unsigned: &txs.AdvanceTimeTx{ + Time: uint64(newTimestamp.Unix()), }, - Clk: &mockable.Clock{}, - }, - backend: backend, - } + } + ) + require.NoError(proposalTx.Initialize(txs.Codec)) - blkTx := txsmock.NewUnsignedTx(ctrl) - blkTx.EXPECT().Visit(gomock.AssignableToTypeOf(&executor.ProposalTxExecutor{})).Return(nil).Times(1) + // Build the block that will be executed on top of the last accepted block. + lastAcceptedID := verifier.state.GetLastAccepted() + lastAccepted, err := verifier.state.GetStatelessBlock(lastAcceptedID) + require.NoError(err) - // We can't serialize [blkTx] because it isn't - // registered with the blocks.Codec. - // Serialize this block with a dummy tx - // and replace it after creation with the mock tx. - // TODO allow serialization of mock txs. - apricotBlk, err := block.NewApricotProposalBlock( - parentID, - 2, - &txs.Tx{ - Unsigned: &txs.AdvanceTimeTx{}, - Creds: []verify.Verifiable{}, - }, + proposalBlock, err := block.NewApricotProposalBlock( + lastAcceptedID, + lastAccepted.Height()+1, + proposalTx, ) require.NoError(err) - apricotBlk.Tx.Unsigned = blkTx - // Set expectations for dependencies. - tx := apricotBlk.Txs()[0] - parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1) - mempool.EXPECT().Remove([]*txs.Tx{tx}).Times(1) + // Execute the block. + require.NoError(proposalBlock.Visit(verifier)) - // Visit the block - blk := manager.NewBlock(apricotBlk) - require.NoError(blk.Verify(context.Background())) - require.Contains(manager.backend.blkIDToState, apricotBlk.ID()) - gotBlkState := manager.backend.blkIDToState[apricotBlk.ID()] - require.Equal(apricotBlk, gotBlkState.statelessBlock) - require.Equal(timestamp, gotBlkState.timestamp) + // Verify that the block's execution was recorded as expected. + blkID := proposalBlock.ID() + require.Contains(verifier.blkIDToState, blkID) + executedBlockState := verifier.blkIDToState[blkID] + + txID := proposalTx.ID() - // Assert that the expected tx statuses are set. - _, gotStatus, err := gotBlkState.onCommitState.GetTx(tx.ID()) + onCommit := executedBlockState.onCommitState + require.NotNil(onCommit) + acceptedTx, acceptedStatus, err := onCommit.GetTx(txID) require.NoError(err) - require.Equal(status.Committed, gotStatus) + require.Equal(proposalTx, acceptedTx) + require.Equal(status.Committed, acceptedStatus) - _, gotStatus, err = gotBlkState.onAbortState.GetTx(tx.ID()) + onAbort := executedBlockState.onAbortState + require.NotNil(onAbort) + acceptedTx, acceptedStatus, err = onAbort.GetTx(txID) require.NoError(err) - require.Equal(status.Aborted, gotStatus) + require.Equal(proposalTx, acceptedTx) + require.Equal(status.Aborted, acceptedStatus) + + require.Equal( + &blockState{ + proposalBlockState: proposalBlockState{ + onCommitState: onCommit, + onAbortState: onAbort, + }, + statelessBlock: proposalBlock, - // Visiting again should return nil without using dependencies. - require.NoError(blk.Verify(context.Background())) + timestamp: initialTimestamp, + verifiedHeights: set.Of[uint64](0), + }, + executedBlockState, + ) } func TestVerifierVisitAtomicBlock(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - // Create mocked dependencies. - s := state.NewMockState(ctrl) - mempool := mempoolmock.NewMempool(ctrl) - parentID := ids.GenerateTestID() - parentStatelessBlk := block.NewMockBlock(ctrl) - grandparentID := ids.GenerateTestID() - parentState := state.NewMockDiff(ctrl) - - backend := &backend{ - blkIDToState: map[ids.ID]*blockState{ - parentID: { - statelessBlock: parentStatelessBlk, - onAcceptState: parentState, - }, - }, - Mempool: mempool, - state: s, - ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - } - manager := &manager{ - txExecutorBackend: &executor.Backend{ - Config: &config.Config{ - UpgradeConfig: upgradetest.GetConfig(upgradetest.ApricotPhasePost6), + var ( + require = require.New(t) + verifier = newTestVerifier(t, testVerifierConfig{ + Upgrades: upgradetest.GetConfig(upgradetest.ApricotPhase4), + }) + wallet = txstest.NewWallet( + t, + verifier.ctx, + verifier.txExecutorBackend.Config, + verifier.state, + secp256k1fx.NewKeychain(genesis.EWOQKey), + nil, // subnetIDs + nil, // chainIDs + ) + exportedOutput = &avax.TransferableOutput{ + Asset: avax.Asset{ID: verifier.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.NanoAvax, + OutputOwners: secp256k1fx.OutputOwners{}, }, - Clk: &mockable.Clock{}, - }, - backend: backend, - } + } + initialTimestamp = verifier.state.GetTimestamp() + ) - onAccept := state.NewMockDiff(ctrl) - blkTx := txsmock.NewUnsignedTx(ctrl) - inputs := set.Of(ids.GenerateTestID()) - blkTx.EXPECT().Visit(gomock.AssignableToTypeOf(&executor.AtomicTxExecutor{})).DoAndReturn( - func(e *executor.AtomicTxExecutor) error { - e.OnAccept = onAccept - e.Inputs = inputs - return nil + // Build the transaction that will be executed. + atomicTx, err := wallet.IssueExportTx( + verifier.ctx.XChainID, + []*avax.TransferableOutput{ + exportedOutput, }, - ).Times(1) + ) + require.NoError(err) - // We can't serialize [blkTx] because it isn't registered with blocks.Codec. - // Serialize this block with a dummy tx and replace it after creation with - // the mock tx. - // TODO allow serialization of mock txs. - apricotBlk, err := block.NewApricotAtomicBlock( - parentID, - 2, - &txs.Tx{ - Unsigned: &txs.AdvanceTimeTx{}, - Creds: []verify.Verifiable{}, - }, + // Build the block that will be executed on top of the last accepted block. + lastAcceptedID := verifier.state.GetLastAccepted() + lastAccepted, err := verifier.state.GetStatelessBlock(lastAcceptedID) + require.NoError(err) + + atomicBlock, err := block.NewApricotAtomicBlock( + lastAcceptedID, + lastAccepted.Height()+1, + atomicTx, ) require.NoError(err) - apricotBlk.Tx.Unsigned = blkTx - // Set expectations for dependencies. - timestamp := time.Now() - parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1) - parentStatelessBlk.EXPECT().Parent().Return(grandparentID).Times(1) - mempool.EXPECT().Remove([]*txs.Tx{apricotBlk.Tx}).Times(1) - onAccept.EXPECT().AddTx(apricotBlk.Tx, status.Committed).Times(1) - onAccept.EXPECT().GetTimestamp().Return(timestamp).Times(1) + // Execute the block. + require.NoError(atomicBlock.Visit(verifier)) - blk := manager.NewBlock(apricotBlk) - require.NoError(blk.Verify(context.Background())) + // Verify that the block's execution was recorded as expected. + blkID := atomicBlock.ID() + require.Contains(verifier.blkIDToState, blkID) + atomicBlockState := verifier.blkIDToState[blkID] + onAccept := atomicBlockState.onAcceptState + require.NotNil(onAccept) - require.Contains(manager.backend.blkIDToState, apricotBlk.ID()) - gotBlkState := manager.backend.blkIDToState[apricotBlk.ID()] - require.Equal(apricotBlk, gotBlkState.statelessBlock) - require.Equal(onAccept, gotBlkState.onAcceptState) - require.Equal(inputs, gotBlkState.inputs) - require.Equal(timestamp, gotBlkState.timestamp) + txID := atomicTx.ID() + acceptedTx, acceptedStatus, err := onAccept.GetTx(txID) + require.NoError(err) + require.Equal(atomicTx, acceptedTx) + require.Equal(status.Committed, acceptedStatus) - // Visiting again should return nil without using dependencies. - require.NoError(blk.Verify(context.Background())) + exportedUTXO := &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: txID, + OutputIndex: uint32(len(atomicTx.UTXOs())), + }, + Asset: exportedOutput.Asset, + Out: exportedOutput.Out, + } + exportedUTXOID := exportedUTXO.InputID() + exportedUTXOBytes, err := txs.Codec.Marshal(txs.CodecVersion, exportedUTXO) + require.NoError(err) + + require.Equal( + &blockState{ + statelessBlock: atomicBlock, + + onAcceptState: onAccept, + + timestamp: initialTimestamp, + atomicRequests: map[ids.ID]*atomic.Requests{ + verifier.ctx.XChainID: { + PutRequests: []*atomic.Element{ + { + Key: exportedUTXOID[:], + Value: exportedUTXOBytes, + Traits: [][]byte{}, + }, + }, + }, + }, + verifiedHeights: set.Of[uint64](0), + }, + atomicBlockState, + ) } func TestVerifierVisitStandardBlock(t *testing.T) { require := require.New(t) - ctrl := gomock.NewController(t) - // Create mocked dependencies. - s := state.NewMockState(ctrl) - mempool := mempoolmock.NewMempool(ctrl) - parentID := ids.GenerateTestID() - parentStatelessBlk := block.NewMockBlock(ctrl) - parentState := state.NewMockDiff(ctrl) + var ( + ctx = snowtest.Context(t, constants.PlatformChainID) - backend := &backend{ - blkIDToState: map[ids.ID]*blockState{ - parentID: { - statelessBlock: parentStatelessBlk, - onAcceptState: parentState, + baseDB = memdb.New() + stateDB = prefixdb.New([]byte{0}, baseDB) + amDB = prefixdb.New([]byte{1}, baseDB) + + am = atomic.NewMemory(amDB) + sm = am.NewSharedMemory(ctx.ChainID) + xChainSM = am.NewSharedMemory(ctx.XChainID) + + owner = secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{genesis.EWOQKey.Address()}, + } + utxo = &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: ids.GenerateTestID(), + OutputIndex: 1, }, - }, - Mempool: mempool, - state: s, - ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - } - manager := &manager{ - txExecutorBackend: &executor.Backend{ - Config: &config.Config{ - UpgradeConfig: upgradetest.GetConfig(upgradetest.ApricotPhasePost6), + Asset: avax.Asset{ID: ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.Avax, + OutputOwners: owner, }, - Clk: &mockable.Clock{}, - }, - backend: backend, - } + } + ) - blkTx := txsmock.NewUnsignedTx(ctrl) - atomicRequests := map[ids.ID]*atomic.Requests{ - ids.GenerateTestID(): { - RemoveRequests: [][]byte{{1}, {2}}, + inputID := utxo.InputID() + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) + require.NoError(err) + + require.NoError(xChainSM.Apply(map[ids.ID]*atomic.Requests{ + ctx.ChainID: { PutRequests: []*atomic.Element{ { - Key: []byte{3}, - Value: []byte{4}, - Traits: [][]byte{{5}, {6}}, + Key: inputID[:], + Value: utxoBytes, + Traits: [][]byte{ + genesis.EWOQKey.Address().Bytes(), + }, }, }, }, - } - blkTx.EXPECT().Visit(gomock.AssignableToTypeOf(&executor.StandardTxExecutor{})).DoAndReturn( - func(e *executor.StandardTxExecutor) error { - e.OnAccept = func() {} - e.Inputs = set.Set[ids.ID]{} - e.AtomicRequests = atomicRequests - return nil - }, - ).Times(1) - - // We can't serialize [blkTx] because it isn't - // registered with the blocks.Codec. - // Serialize this block with a dummy tx - // and replace it after creation with the mock tx. - // TODO allow serialization of mock txs. - apricotBlk, err := block.NewApricotStandardBlock( - parentID, - 2, /*height*/ - []*txs.Tx{ - { - Unsigned: &txs.AdvanceTimeTx{}, - Creds: []verify.Verifiable{}, - }, - }, + })) + + ctx.SharedMemory = sm + + var ( + verifier = newTestVerifier(t, testVerifierConfig{ + DB: stateDB, + Upgrades: upgradetest.GetConfig(upgradetest.ApricotPhase5), + Context: ctx, + }) + wallet = txstest.NewWallet( + t, + verifier.ctx, + verifier.txExecutorBackend.Config, + verifier.state, + secp256k1fx.NewKeychain(genesis.EWOQKey), + nil, // subnetIDs + []ids.ID{ctx.XChainID}, // Read the UTXO to import + ) + initialTimestamp = verifier.state.GetTimestamp() + ) + + // Build the transaction that will be executed. + tx, err := wallet.IssueImportTx( + verifier.ctx.XChainID, + &owner, ) require.NoError(err) - apricotBlk.Transactions[0].Unsigned = blkTx - // Set expectations for dependencies. - timestamp := time.Now() - parentState.EXPECT().GetTimestamp().Return(timestamp).Times(1) - parentState.EXPECT().GetFeeState().Return(gas.State{}).Times(1) - parentState.EXPECT().GetSoVExcess().Return(gas.Gas(0)).Times(1) - parentState.EXPECT().GetAccruedFees().Return(uint64(0)).Times(1) - parentState.EXPECT().NumActiveSubnetOnlyValidators().Return(0).Times(1) - parentState.EXPECT().GetActiveSubnetOnlyValidatorsIterator().Return(&iterator.Empty[state.SubnetOnlyValidator]{}, nil).Times(1) - parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1) - mempool.EXPECT().Remove(apricotBlk.Txs()).Times(1) + // Verify that the transaction is only consuming the imported UTXO. + require.Len(tx.InputIDs(), 1) - blk := manager.NewBlock(apricotBlk) - require.NoError(blk.Verify(context.Background())) + // Build the block that will be executed on top of the last accepted block. + lastAcceptedID := verifier.state.GetLastAccepted() + lastAccepted, err := verifier.state.GetStatelessBlock(lastAcceptedID) + require.NoError(err) - // Assert expected state. - require.Contains(manager.backend.blkIDToState, apricotBlk.ID()) - gotBlkState := manager.backend.blkIDToState[apricotBlk.ID()] - require.Equal(apricotBlk, gotBlkState.statelessBlock) - require.Equal(set.Set[ids.ID]{}, gotBlkState.inputs) - require.Equal(timestamp, gotBlkState.timestamp) + firstBlock, err := block.NewApricotStandardBlock( + lastAcceptedID, + lastAccepted.Height()+1, + []*txs.Tx{tx}, + ) + require.NoError(err) - // Visiting again should return nil without using dependencies. - require.NoError(blk.Verify(context.Background())) + // Execute the block. + require.NoError(firstBlock.Visit(verifier)) + + // Verify that the block's execution was recorded as expected. + firstBlockID := firstBlock.ID() + { + require.Contains(verifier.blkIDToState, firstBlockID) + atomicBlockState := verifier.blkIDToState[firstBlockID] + onAccept := atomicBlockState.onAcceptState + require.NotNil(onAccept) + + txID := tx.ID() + acceptedTx, acceptedStatus, err := onAccept.GetTx(txID) + require.NoError(err) + require.Equal(tx, acceptedTx) + require.Equal(status.Committed, acceptedStatus) + + require.Equal( + &blockState{ + statelessBlock: firstBlock, + + onAcceptState: onAccept, + + inputs: tx.InputIDs(), + timestamp: initialTimestamp, + atomicRequests: map[ids.ID]*atomic.Requests{ + verifier.ctx.XChainID: { + RemoveRequests: [][]byte{ + inputID[:], + }, + }, + }, + verifiedHeights: set.Of[uint64](0), + }, + atomicBlockState, + ) + } + + // Verify that the import transaction can not be replayed. + { + secondBlock, err := block.NewApricotStandardBlock( + firstBlockID, + firstBlock.Height()+1, + []*txs.Tx{tx}, // Replay the prior transaction + ) + require.NoError(err) + + err = secondBlock.Visit(verifier) + require.ErrorIs(err, errConflictingParentTxs) + + // Verify that the block's execution was not recorded. + require.NotContains(verifier.blkIDToState, secondBlock.ID()) + } } func TestVerifierVisitCommitBlock(t *testing.T) { @@ -737,104 +801,6 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) { } } -func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - // Create mocked dependencies. - s := state.NewMockState(ctrl) - mempool := mempoolmock.NewMempool(ctrl) - - grandParentID := ids.GenerateTestID() - grandParentStatelessBlk := block.NewMockBlock(ctrl) - grandParentState := state.NewMockDiff(ctrl) - parentID := ids.GenerateTestID() - parentStatelessBlk := block.NewMockBlock(ctrl) - parentState := state.NewMockDiff(ctrl) - atomicInputs := set.Of(ids.GenerateTestID()) - - backend := &backend{ - blkIDToState: map[ids.ID]*blockState{ - grandParentID: { - statelessBlock: grandParentStatelessBlk, - onAcceptState: grandParentState, - inputs: atomicInputs, - }, - parentID: { - statelessBlock: parentStatelessBlk, - onAcceptState: parentState, - }, - }, - Mempool: mempool, - state: s, - ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - } - verifier := &verifier{ - txExecutorBackend: &executor.Backend{ - Config: &config.Config{ - UpgradeConfig: upgradetest.GetConfig(upgradetest.ApricotPhasePost6), - }, - Clk: &mockable.Clock{}, - }, - backend: backend, - } - - blkTx := txsmock.NewUnsignedTx(ctrl) - atomicRequests := map[ids.ID]*atomic.Requests{ - ids.GenerateTestID(): { - RemoveRequests: [][]byte{{1}, {2}}, - PutRequests: []*atomic.Element{ - { - Key: []byte{3}, - Value: []byte{4}, - Traits: [][]byte{{5}, {6}}, - }, - }, - }, - } - blkTx.EXPECT().Visit(gomock.AssignableToTypeOf(&executor.StandardTxExecutor{})).DoAndReturn( - func(e *executor.StandardTxExecutor) error { - e.OnAccept = func() {} - e.Inputs = atomicInputs - e.AtomicRequests = atomicRequests - return nil - }, - ).Times(1) - - // We can't serialize [blkTx] because it isn't - // registered with the blocks.Codec. - // Serialize this block with a dummy tx - // and replace it after creation with the mock tx. - // TODO allow serialization of mock txs. - blk, err := block.NewApricotStandardBlock( - parentID, - 2, - []*txs.Tx{ - { - Unsigned: &txs.AdvanceTimeTx{}, - Creds: []verify.Verifiable{}, - }, - }, - ) - require.NoError(err) - blk.Transactions[0].Unsigned = blkTx - - // Set expectations for dependencies. - timestamp := time.Now() - parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1) - parentState.EXPECT().GetTimestamp().Return(timestamp).Times(1) - parentState.EXPECT().GetFeeState().Return(gas.State{}).Times(1) - parentState.EXPECT().GetSoVExcess().Return(gas.Gas(0)).Times(1) - parentState.EXPECT().GetAccruedFees().Return(uint64(0)).Times(1) - parentState.EXPECT().NumActiveSubnetOnlyValidators().Return(0).Times(1) - parentStatelessBlk.EXPECT().Parent().Return(grandParentID).Times(1) - - err = verifier.ApricotStandardBlock(blk) - require.ErrorIs(err, errConflictingParentTxs) -} - func TestVerifierVisitApricotStandardBlockWithProposalBlockParent(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) @@ -1124,13 +1090,12 @@ func TestVerifierVisitBanffAbortBlockUnexpectedParentState(t *testing.T) { } func TestBlockExecutionWithComplexity(t *testing.T) { - s := statetest.New(t, statetest.Config{}) - verifier := newTestVerifier(t, s) + verifier := newTestVerifier(t, testVerifierConfig{}) wallet := txstest.NewWallet( t, verifier.ctx, verifier.txExecutorBackend.Config, - s, + verifier.state, secp256k1fx.NewKeychain(genesis.EWOQKey), nil, // subnetIDs nil, // chainIDs @@ -1185,13 +1150,13 @@ func TestBlockExecutionWithComplexity(t *testing.T) { verifier.txExecutorBackend.Clk.Set(test.timestamp) timestamp, _, err := state.NextBlockTime( verifier.txExecutorBackend.Config.ValidatorFeeConfig, - s, + verifier.state, verifier.txExecutorBackend.Clk, ) require.NoError(err) - lastAcceptedID := s.GetLastAccepted() - lastAccepted, err := s.GetStatelessBlock(lastAcceptedID) + lastAcceptedID := verifier.state.GetLastAccepted() + lastAccepted, err := verifier.state.GetStatelessBlock(lastAcceptedID) require.NoError(err) blk, err := block.NewBanffStandardBlock( diff --git a/vms/platformvm/txs/txsmock/unsigned_tx.go b/vms/platformvm/txs/txsmock/unsigned_tx.go deleted file mode 100644 index a7ba0daac896..000000000000 --- a/vms/platformvm/txs/txsmock/unsigned_tx.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: vms/platformvm/txs/unsigned_tx.go -// -// Generated by this command: -// -// mockgen -source=vms/platformvm/txs/unsigned_tx.go -destination=vms/platformvm/txs/txsmock/unsigned_tx.go -package=txsmock -exclude_interfaces= -mock_names=UnsignedTx=UnsignedTx -// - -// Package txsmock is a generated GoMock package. -package txsmock - -import ( - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - snow "github.com/ava-labs/avalanchego/snow" - set "github.com/ava-labs/avalanchego/utils/set" - avax "github.com/ava-labs/avalanchego/vms/components/avax" - txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" - gomock "go.uber.org/mock/gomock" -) - -// UnsignedTx is a mock of UnsignedTx interface. -type UnsignedTx struct { - ctrl *gomock.Controller - recorder *UnsignedTxMockRecorder -} - -// UnsignedTxMockRecorder is the mock recorder for UnsignedTx. -type UnsignedTxMockRecorder struct { - mock *UnsignedTx -} - -// NewUnsignedTx creates a new mock instance. -func NewUnsignedTx(ctrl *gomock.Controller) *UnsignedTx { - mock := &UnsignedTx{ctrl: ctrl} - mock.recorder = &UnsignedTxMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *UnsignedTx) EXPECT() *UnsignedTxMockRecorder { - return m.recorder -} - -// Bytes mocks base method. -func (m *UnsignedTx) Bytes() []byte { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Bytes") - ret0, _ := ret[0].([]byte) - return ret0 -} - -// Bytes indicates an expected call of Bytes. -func (mr *UnsignedTxMockRecorder) Bytes() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bytes", reflect.TypeOf((*UnsignedTx)(nil).Bytes)) -} - -// InitCtx mocks base method. -func (m *UnsignedTx) InitCtx(ctx *snow.Context) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "InitCtx", ctx) -} - -// InitCtx indicates an expected call of InitCtx. -func (mr *UnsignedTxMockRecorder) InitCtx(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*UnsignedTx)(nil).InitCtx), ctx) -} - -// InputIDs mocks base method. -func (m *UnsignedTx) InputIDs() set.Set[ids.ID] { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InputIDs") - ret0, _ := ret[0].(set.Set[ids.ID]) - return ret0 -} - -// InputIDs indicates an expected call of InputIDs. -func (mr *UnsignedTxMockRecorder) InputIDs() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InputIDs", reflect.TypeOf((*UnsignedTx)(nil).InputIDs)) -} - -// Outputs mocks base method. -func (m *UnsignedTx) Outputs() []*avax.TransferableOutput { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Outputs") - ret0, _ := ret[0].([]*avax.TransferableOutput) - return ret0 -} - -// Outputs indicates an expected call of Outputs. -func (mr *UnsignedTxMockRecorder) Outputs() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Outputs", reflect.TypeOf((*UnsignedTx)(nil).Outputs)) -} - -// SetBytes mocks base method. -func (m *UnsignedTx) SetBytes(unsignedBytes []byte) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetBytes", unsignedBytes) -} - -// SetBytes indicates an expected call of SetBytes. -func (mr *UnsignedTxMockRecorder) SetBytes(unsignedBytes any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBytes", reflect.TypeOf((*UnsignedTx)(nil).SetBytes), unsignedBytes) -} - -// SyntacticVerify mocks base method. -func (m *UnsignedTx) SyntacticVerify(ctx *snow.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SyntacticVerify", ctx) - ret0, _ := ret[0].(error) - return ret0 -} - -// SyntacticVerify indicates an expected call of SyntacticVerify. -func (mr *UnsignedTxMockRecorder) SyntacticVerify(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyntacticVerify", reflect.TypeOf((*UnsignedTx)(nil).SyntacticVerify), ctx) -} - -// Visit mocks base method. -func (m *UnsignedTx) Visit(visitor txs.Visitor) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Visit", visitor) - ret0, _ := ret[0].(error) - return ret0 -} - -// Visit indicates an expected call of Visit. -func (mr *UnsignedTxMockRecorder) Visit(visitor any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Visit", reflect.TypeOf((*UnsignedTx)(nil).Visit), visitor) -}