From 1595b77bd7e94c34258d2257c42b3ad4850748ad Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Thu, 9 Jan 2025 10:45:02 -0500 Subject: [PATCH 01/14] init --- chain/pre_executor_test.go | 259 +++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 chain/pre_executor_test.go diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go new file mode 100644 index 0000000000..521b440072 --- /dev/null +++ b/chain/pre_executor_test.go @@ -0,0 +1,259 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package chain_test + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/x/merkledb" + "github.com/stretchr/testify/require" + + "github.com/ava-labs/hypersdk/chain" + "github.com/ava-labs/hypersdk/codec" + "github.com/ava-labs/hypersdk/genesis" + "github.com/ava-labs/hypersdk/internal/validitywindow" + "github.com/ava-labs/hypersdk/state" +) + +var ( + _ state.View = (*abstractMockView)(nil) + _ chain.MetadataManager = (*mockMetadataManager)(nil) + _ validitywindow.ChainIndex[*chain.Transaction] = (*mockChainIndex1)(nil) + _ validitywindow.ChainIndex[*chain.Transaction] = (*mockChainIndex2)(nil) + _ chain.Action = (*mockAction1)(nil) + _ chain.Auth = (*mockAuth)(nil) + _ chain.BalanceHandler = (*mockBalanceHandler)(nil) +) + +var ( + errMockView = errors.New("mock view error") + errMockExecutionBlock = errors.New("mock execution block error") + errMockAuth = errors.New("mock auth error") +) + +type abstractMockView struct{} + +func (*abstractMockView) GetValue(context.Context, []byte) ([]byte, error) { + panic("unimplemented") +} + +func (*abstractMockView) GetMerkleRoot(context.Context) (ids.ID, error) { + panic("unimplemented") +} + +func (*abstractMockView) NewView(context.Context, merkledb.ViewChanges) (merkledb.View, error) { + panic("unimplemented") +} + +type mockView1 struct { + abstractMockView +} + +func (*mockView1) GetValue(context.Context, []byte) ([]byte, error) { + return nil, errMockView +} + +type mockView2 struct { + abstractMockView +} + +func (*mockView2) GetValue(context.Context, []byte) ([]byte, error) { + return []byte{}, nil +} + +type mockMetadataManager struct{} + +func (*mockMetadataManager) FeePrefix() []byte { + return []byte{} +} + +func (*mockMetadataManager) HeightPrefix() []byte { + return []byte{} +} + +func (*mockMetadataManager) TimestampPrefix() []byte { + return []byte{} +} + +type mockChainIndex1 struct{} + +func (*mockChainIndex1) GetExecutionBlock(context.Context, ids.ID) (validitywindow.ExecutionBlock[*chain.Transaction], error) { + return nil, errMockExecutionBlock +} + +type mockChainIndex2 struct{} + +func (*mockChainIndex2) GetExecutionBlock(context.Context, ids.ID) (validitywindow.ExecutionBlock[*chain.Transaction], error) { + return nil, nil +} + +type mockAction1 struct { + abstractMockAction + stateKeys state.Keys +} + +func (*mockAction1) GetTypeID() uint8 { + return 1 +} + +func (m *mockAction1) StateKeys(codec.Address, ids.ID) state.Keys { + return m.stateKeys +} + +type mockAuth struct{} + +func (*mockAuth) Actor() codec.Address { + return codec.Address{} +} + +func (*mockAuth) ComputeUnits(chain.Rules) uint64 { + panic("unimplemented") +} + +func (*mockAuth) GetTypeID() uint8 { + panic("unimplemented") +} + +func (*mockAuth) Marshal(*codec.Packer) { + panic("unimplemented") +} + +func (*mockAuth) Size() int { + panic("unimplemented") +} + +func (*mockAuth) Sponsor() codec.Address { + return codec.Address{} +} + +func (*mockAuth) ValidRange(chain.Rules) (int64, int64) { + panic("unimplemented") +} + +func (*mockAuth) Verify(context.Context, []byte) error { + return errMockAuth +} + +type mockBalanceHandler struct{} + +func (*mockBalanceHandler) AddBalance(context.Context, codec.Address, state.Mutable, uint64) error { + panic("unimplemented") +} + +func (*mockBalanceHandler) CanDeduct(context.Context, codec.Address, state.Immutable, uint64) error { + panic("unimplemented") +} + +func (*mockBalanceHandler) Deduct(context.Context, codec.Address, state.Mutable, uint64) error { + panic("unimplemented") +} + +func (*mockBalanceHandler) GetBalance(context.Context, codec.Address, state.Immutable) (uint64, error) { + panic("unimplemented") +} + +func (*mockBalanceHandler) SponsorStateKeys(codec.Address) state.Keys { + return state.Keys{} +} + +func TestPreExecutor(t *testing.T) { + // Test values + ruleFactory := genesis.ImmutableRuleFactory{Rules: genesis.NewDefaultRules()} + + tests := []struct { + name string + + view state.View + tx *chain.Transaction + chainIndex validitywindow.ChainIndex[*chain.Transaction] + height uint64 + verifyAuth bool + err error + }{ + { + name: "raw fee doesn't exist", + view: &mockView1{}, + err: errMockView, + }, + { + name: "repeat error", + view: &mockView2{}, + tx: &chain.Transaction{}, + chainIndex: &mockChainIndex1{}, + height: 1, + err: errMockExecutionBlock, + }, + { + name: "tx state keys are invalid", + view: &mockView2{}, + tx: &chain.Transaction{ + TransactionData: chain.TransactionData{ + Actions: []chain.Action{ + &mockAction1{ + stateKeys: state.Keys{ + "": state.None, + }, + }, + }, + }, + Auth: &mockAuth{}, + }, + chainIndex: &mockChainIndex2{}, + err: chain.ErrInvalidKeyValue, + }, + { + name: "verify auth error", + view: &mockView2{}, + tx: &chain.Transaction{ + TransactionData: chain.TransactionData{ + Base: &chain.Base{}, + Actions: []chain.Action{ + &mockAction1{}, + }, + }, + Auth: &mockAuth{}, + }, + chainIndex: &mockChainIndex2{}, + verifyAuth: true, + err: errMockAuth, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := require.New(t) + ctx := context.Background() + + parentBlock, err := chain.NewExecutionBlock( + &chain.StatelessBlock{ + Hght: tt.height, + Tmstmp: time.Now().UnixMilli(), + }, + ) + r.NoError(err) + + preExecutor := chain.NewPreExecutor( + &ruleFactory, + validitywindow.NewTimeValidityWindow(nil, trace.Noop, tt.chainIndex), + &mockMetadataManager{}, + &mockBalanceHandler{}, + ) + + r.ErrorIs( + preExecutor.PreExecute( + ctx, + parentBlock, + tt.view, + tt.tx, + tt.verifyAuth, + ), tt.err, + ) + }) + } +} From b324ada31b8b86cb55474cc576a2d18af839d3b9 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 10 Jan 2025 11:19:44 -0500 Subject: [PATCH 02/14] less abstract types --- chain/pre_executor_test.go | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 521b440072..fceb680de6 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -22,13 +22,12 @@ import ( ) var ( - _ state.View = (*abstractMockView)(nil) _ chain.MetadataManager = (*mockMetadataManager)(nil) - _ validitywindow.ChainIndex[*chain.Transaction] = (*mockChainIndex1)(nil) - _ validitywindow.ChainIndex[*chain.Transaction] = (*mockChainIndex2)(nil) _ chain.Action = (*mockAction1)(nil) _ chain.Auth = (*mockAuth)(nil) _ chain.BalanceHandler = (*mockBalanceHandler)(nil) + _ state.View = (*abstractMockView)(nil) + _ validitywindow.ChainIndex[*chain.Transaction] = (*mockChainIndex)(nil) ) var ( @@ -81,16 +80,12 @@ func (*mockMetadataManager) TimestampPrefix() []byte { return []byte{} } -type mockChainIndex1 struct{} - -func (*mockChainIndex1) GetExecutionBlock(context.Context, ids.ID) (validitywindow.ExecutionBlock[*chain.Transaction], error) { - return nil, errMockExecutionBlock +type mockChainIndex struct { + err error } -type mockChainIndex2 struct{} - -func (*mockChainIndex2) GetExecutionBlock(context.Context, ids.ID) (validitywindow.ExecutionBlock[*chain.Transaction], error) { - return nil, nil +func (m *mockChainIndex) GetExecutionBlock(context.Context, ids.ID) (validitywindow.ExecutionBlock[*chain.Transaction], error) { + return nil, m.err } type mockAction1 struct { @@ -182,12 +177,14 @@ func TestPreExecutor(t *testing.T) { err: errMockView, }, { - name: "repeat error", - view: &mockView2{}, - tx: &chain.Transaction{}, - chainIndex: &mockChainIndex1{}, - height: 1, - err: errMockExecutionBlock, + name: "repeat error", + view: &mockView2{}, + tx: &chain.Transaction{}, + chainIndex: &mockChainIndex{ + err: errMockExecutionBlock, + }, + height: 1, + err: errMockExecutionBlock, }, { name: "tx state keys are invalid", @@ -204,7 +201,7 @@ func TestPreExecutor(t *testing.T) { }, Auth: &mockAuth{}, }, - chainIndex: &mockChainIndex2{}, + chainIndex: &mockChainIndex{}, err: chain.ErrInvalidKeyValue, }, { @@ -219,7 +216,7 @@ func TestPreExecutor(t *testing.T) { }, Auth: &mockAuth{}, }, - chainIndex: &mockChainIndex2{}, + chainIndex: &mockChainIndex{}, verifyAuth: true, err: errMockAuth, }, From 656d3aca46417960a197b6a5858ad6af6f001b14 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 10 Jan 2025 11:24:42 -0500 Subject: [PATCH 03/14] nit --- chain/pre_executor_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index fceb680de6..fcf1be0c91 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -158,7 +158,6 @@ func (*mockBalanceHandler) SponsorStateKeys(codec.Address) state.Keys { } func TestPreExecutor(t *testing.T) { - // Test values ruleFactory := genesis.ImmutableRuleFactory{Rules: genesis.NewDefaultRules()} tests := []struct { From 2fc73de3d491e10d817d75598585e3d6fe6fcf8d Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Mon, 13 Jan 2025 15:14:40 -0500 Subject: [PATCH 04/14] fix merge conflicts --- chain/pre_executor_test.go | 82 ++++---------------------------------- chain/transaction_test.go | 10 +++-- 2 files changed, 14 insertions(+), 78 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index fcf1be0c91..4c894aac0e 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -15,7 +15,6 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/hypersdk/chain" - "github.com/ava-labs/hypersdk/codec" "github.com/ava-labs/hypersdk/genesis" "github.com/ava-labs/hypersdk/internal/validitywindow" "github.com/ava-labs/hypersdk/state" @@ -23,7 +22,6 @@ import ( var ( _ chain.MetadataManager = (*mockMetadataManager)(nil) - _ chain.Action = (*mockAction1)(nil) _ chain.Auth = (*mockAuth)(nil) _ chain.BalanceHandler = (*mockBalanceHandler)(nil) _ state.View = (*abstractMockView)(nil) @@ -88,75 +86,6 @@ func (m *mockChainIndex) GetExecutionBlock(context.Context, ids.ID) (validitywin return nil, m.err } -type mockAction1 struct { - abstractMockAction - stateKeys state.Keys -} - -func (*mockAction1) GetTypeID() uint8 { - return 1 -} - -func (m *mockAction1) StateKeys(codec.Address, ids.ID) state.Keys { - return m.stateKeys -} - -type mockAuth struct{} - -func (*mockAuth) Actor() codec.Address { - return codec.Address{} -} - -func (*mockAuth) ComputeUnits(chain.Rules) uint64 { - panic("unimplemented") -} - -func (*mockAuth) GetTypeID() uint8 { - panic("unimplemented") -} - -func (*mockAuth) Marshal(*codec.Packer) { - panic("unimplemented") -} - -func (*mockAuth) Size() int { - panic("unimplemented") -} - -func (*mockAuth) Sponsor() codec.Address { - return codec.Address{} -} - -func (*mockAuth) ValidRange(chain.Rules) (int64, int64) { - panic("unimplemented") -} - -func (*mockAuth) Verify(context.Context, []byte) error { - return errMockAuth -} - -type mockBalanceHandler struct{} - -func (*mockBalanceHandler) AddBalance(context.Context, codec.Address, state.Mutable, uint64) error { - panic("unimplemented") -} - -func (*mockBalanceHandler) CanDeduct(context.Context, codec.Address, state.Immutable, uint64) error { - panic("unimplemented") -} - -func (*mockBalanceHandler) Deduct(context.Context, codec.Address, state.Mutable, uint64) error { - panic("unimplemented") -} - -func (*mockBalanceHandler) GetBalance(context.Context, codec.Address, state.Immutable) (uint64, error) { - panic("unimplemented") -} - -func (*mockBalanceHandler) SponsorStateKeys(codec.Address) state.Keys { - return state.Keys{} -} - func TestPreExecutor(t *testing.T) { ruleFactory := genesis.ImmutableRuleFactory{Rules: genesis.NewDefaultRules()} @@ -191,10 +120,11 @@ func TestPreExecutor(t *testing.T) { tx: &chain.Transaction{ TransactionData: chain.TransactionData{ Actions: []chain.Action{ - &mockAction1{ + &mockAction{ stateKeys: state.Keys{ "": state.None, }, + typeID: 1, }, }, }, @@ -210,10 +140,14 @@ func TestPreExecutor(t *testing.T) { TransactionData: chain.TransactionData{ Base: &chain.Base{}, Actions: []chain.Action{ - &mockAction1{}, + &mockAction{ + typeID: 1, + }, }, }, - Auth: &mockAuth{}, + Auth: &mockAuth{ + verifyError: errMockAuth, + }, }, chainIndex: &mockChainIndex{}, verifyAuth: true, diff --git a/chain/transaction_test.go b/chain/transaction_test.go index 1da000ab52..45a45818e2 100644 --- a/chain/transaction_test.go +++ b/chain/transaction_test.go @@ -42,6 +42,7 @@ type mockAction struct { end int64 computeUnits uint64 typeID uint8 + stateKeys state.Keys } func (m *mockAction) ComputeUnits(chain.Rules) uint64 { @@ -56,8 +57,8 @@ func (m *mockAction) GetTypeID() uint8 { return m.typeID } -func (*mockAction) StateKeys(codec.Address, ids.ID) state.Keys { - return state.Keys{} +func (m *mockAction) StateKeys(codec.Address, ids.ID) state.Keys { + return m.stateKeys } func (m *mockAction) ValidRange(chain.Rules) (int64, int64) { @@ -127,6 +128,7 @@ type mockAuth struct { computeUnits uint64 actor codec.Address sponsor codec.Address + verifyError error } func (m *mockAuth) Actor() codec.Address { @@ -157,8 +159,8 @@ func (m *mockAuth) ValidRange(chain.Rules) (int64, int64) { return m.start, m.end } -func (*mockAuth) Verify(context.Context, []byte) error { - panic("unimplemented") +func (m *mockAuth) Verify(context.Context, []byte) error { + return m.verifyError } func TestJSONMarshalUnmarshal(t *testing.T) { From 91e0f9222e92dc7c270bd288d48689ba401734cb Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Mon, 13 Jan 2025 15:51:53 -0500 Subject: [PATCH 05/14] reduce mocks --- chain/pre_executor_test.go | 135 +++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 75 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 4c894aac0e..6dcadedb4d 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -9,8 +9,10 @@ import ( "testing" "time" - "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/x/merkledb" "github.com/stretchr/testify/require" @@ -18,105 +20,71 @@ import ( "github.com/ava-labs/hypersdk/genesis" "github.com/ava-labs/hypersdk/internal/validitywindow" "github.com/ava-labs/hypersdk/state" + "github.com/ava-labs/hypersdk/state/metadata" ) var ( - _ chain.MetadataManager = (*mockMetadataManager)(nil) - _ chain.Auth = (*mockAuth)(nil) - _ chain.BalanceHandler = (*mockBalanceHandler)(nil) - _ state.View = (*abstractMockView)(nil) - _ validitywindow.ChainIndex[*chain.Transaction] = (*mockChainIndex)(nil) + _ chain.Auth = (*mockAuth)(nil) + _ chain.BalanceHandler = (*mockBalanceHandler)(nil) + _ chain.ValidityWindow = (*mockValidityWindow)(nil) ) var ( - errMockView = errors.New("mock view error") - errMockExecutionBlock = errors.New("mock execution block error") errMockAuth = errors.New("mock auth error") + errMockValidityWindow = errors.New("mock validity window error") ) -type abstractMockView struct{} - -func (*abstractMockView) GetValue(context.Context, []byte) ([]byte, error) { - panic("unimplemented") -} - -func (*abstractMockView) GetMerkleRoot(context.Context) (ids.ID, error) { - panic("unimplemented") +type mockValidityWindow struct { + isRepeatError error } -func (*abstractMockView) NewView(context.Context, merkledb.ViewChanges) (merkledb.View, error) { +func (*mockValidityWindow) Accept(validitywindow.ExecutionBlock[*chain.Transaction]) { panic("unimplemented") } -type mockView1 struct { - abstractMockView -} - -func (*mockView1) GetValue(context.Context, []byte) ([]byte, error) { - return nil, errMockView +func (m *mockValidityWindow) IsRepeat(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], []*chain.Transaction, int64) (set.Bits, error) { + return set.NewBits(), m.isRepeatError } -type mockView2 struct { - abstractMockView -} - -func (*mockView2) GetValue(context.Context, []byte) ([]byte, error) { - return []byte{}, nil -} - -type mockMetadataManager struct{} - -func (*mockMetadataManager) FeePrefix() []byte { - return []byte{} -} - -func (*mockMetadataManager) HeightPrefix() []byte { - return []byte{} -} - -func (*mockMetadataManager) TimestampPrefix() []byte { - return []byte{} -} - -type mockChainIndex struct { - err error -} - -func (m *mockChainIndex) GetExecutionBlock(context.Context, ids.ID) (validitywindow.ExecutionBlock[*chain.Transaction], error) { - return nil, m.err +func (*mockValidityWindow) VerifyExpiryReplayProtection(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], int64) error { + panic("unimplemented") } func TestPreExecutor(t *testing.T) { ruleFactory := genesis.ImmutableRuleFactory{Rules: genesis.NewDefaultRules()} tests := []struct { - name string - - view state.View - tx *chain.Transaction - chainIndex validitywindow.ChainIndex[*chain.Transaction] - height uint64 - verifyAuth bool - err error + name string + state map[string][]byte + view state.View + tx *chain.Transaction + validityWindow chain.ValidityWindow + chainIndex validitywindow.ChainIndex[*chain.Transaction] + height uint64 + verifyAuth bool + err error }{ { name: "raw fee doesn't exist", - view: &mockView1{}, - err: errMockView, + err: database.ErrNotFound, }, { name: "repeat error", - view: &mockView2{}, tx: &chain.Transaction{}, - chainIndex: &mockChainIndex{ - err: errMockExecutionBlock, + state: map[string][]byte{ + string(chain.FeeKey([]byte{2})): {}, + }, + validityWindow: &mockValidityWindow{ + isRepeatError: errMockValidityWindow, }, height: 1, - err: errMockExecutionBlock, + err: errMockValidityWindow, }, { name: "tx state keys are invalid", - view: &mockView2{}, + state: map[string][]byte{ + string(chain.FeeKey([]byte{2})): {}, + }, tx: &chain.Transaction{ TransactionData: chain.TransactionData{ Actions: []chain.Action{ @@ -130,12 +98,14 @@ func TestPreExecutor(t *testing.T) { }, Auth: &mockAuth{}, }, - chainIndex: &mockChainIndex{}, - err: chain.ErrInvalidKeyValue, + validityWindow: &mockValidityWindow{}, + err: chain.ErrInvalidKeyValue, }, { name: "verify auth error", - view: &mockView2{}, + state: map[string][]byte{ + string(chain.FeeKey([]byte{2})): {}, + }, tx: &chain.Transaction{ TransactionData: chain.TransactionData{ Base: &chain.Base{}, @@ -149,9 +119,9 @@ func TestPreExecutor(t *testing.T) { verifyError: errMockAuth, }, }, - chainIndex: &mockChainIndex{}, - verifyAuth: true, - err: errMockAuth, + validityWindow: &mockValidityWindow{}, + verifyAuth: true, + err: errMockAuth, }, } @@ -168,10 +138,25 @@ func TestPreExecutor(t *testing.T) { ) r.NoError(err) + db, err := merkledb.New( + ctx, + memdb.New(), + merkledb.Config{ + BranchFactor: merkledb.BranchFactor16, + Tracer: trace.Noop, + }, + ) + r.NoError(err) + + for k, v := range tt.state { + r.NoError(db.Put([]byte(k), v)) + } + r.NoError(db.CommitToDB(ctx)) + preExecutor := chain.NewPreExecutor( &ruleFactory, - validitywindow.NewTimeValidityWindow(nil, trace.Noop, tt.chainIndex), - &mockMetadataManager{}, + tt.validityWindow, + metadata.NewDefaultManager(), &mockBalanceHandler{}, ) @@ -179,7 +164,7 @@ func TestPreExecutor(t *testing.T) { preExecutor.PreExecute( ctx, parentBlock, - tt.view, + db, tt.tx, tt.verifyAuth, ), tt.err, From 679a045c76b865842f93bbcad3878520792bce0e Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Mon, 13 Jan 2025 16:01:43 -0500 Subject: [PATCH 06/14] nits --- chain/pre_executor_test.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 6dcadedb4d..a30ea41bfd 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -24,14 +24,14 @@ import ( ) var ( - _ chain.Auth = (*mockAuth)(nil) - _ chain.BalanceHandler = (*mockBalanceHandler)(nil) - _ chain.ValidityWindow = (*mockValidityWindow)(nil) -) + feeKey = string(chain.FeeKey([]byte{2})) -var ( errMockAuth = errors.New("mock auth error") errMockValidityWindow = errors.New("mock validity window error") + + _ chain.Auth = (*mockAuth)(nil) + _ chain.BalanceHandler = (*mockBalanceHandler)(nil) + _ chain.ValidityWindow = (*mockValidityWindow)(nil) ) type mockValidityWindow struct { @@ -56,10 +56,8 @@ func TestPreExecutor(t *testing.T) { tests := []struct { name string state map[string][]byte - view state.View tx *chain.Transaction validityWindow chain.ValidityWindow - chainIndex validitywindow.ChainIndex[*chain.Transaction] height uint64 verifyAuth bool err error @@ -72,7 +70,7 @@ func TestPreExecutor(t *testing.T) { name: "repeat error", tx: &chain.Transaction{}, state: map[string][]byte{ - string(chain.FeeKey([]byte{2})): {}, + feeKey: {}, }, validityWindow: &mockValidityWindow{ isRepeatError: errMockValidityWindow, From 993ffc5dc374664d7d53001dc606218a22ad48e3 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Mon, 13 Jan 2025 16:10:53 -0500 Subject: [PATCH 07/14] remove height --- chain/pre_executor_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index a30ea41bfd..43d99ecfb9 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -58,7 +58,6 @@ func TestPreExecutor(t *testing.T) { state map[string][]byte tx *chain.Transaction validityWindow chain.ValidityWindow - height uint64 verifyAuth bool err error }{ @@ -75,8 +74,7 @@ func TestPreExecutor(t *testing.T) { validityWindow: &mockValidityWindow{ isRepeatError: errMockValidityWindow, }, - height: 1, - err: errMockValidityWindow, + err: errMockValidityWindow, }, { name: "tx state keys are invalid", @@ -130,7 +128,6 @@ func TestPreExecutor(t *testing.T) { parentBlock, err := chain.NewExecutionBlock( &chain.StatelessBlock{ - Hght: tt.height, Tmstmp: time.Now().UnixMilli(), }, ) From 7dfcebd24bdfb04de3c21216ddcbf5bc5de6dde6 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Tue, 14 Jan 2025 09:57:44 -0500 Subject: [PATCH 08/14] nits --- chain/pre_executor_test.go | 76 ++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 19 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 43d99ecfb9..8e7ed96e7b 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/hypersdk/internal/validitywindow" "github.com/ava-labs/hypersdk/state" "github.com/ava-labs/hypersdk/state/metadata" + "github.com/ava-labs/hypersdk/utils" ) var ( @@ -36,6 +37,7 @@ var ( type mockValidityWindow struct { isRepeatError error + setBits []int } func (*mockValidityWindow) Accept(validitywindow.ExecutionBlock[*chain.Transaction]) { @@ -43,7 +45,7 @@ func (*mockValidityWindow) Accept(validitywindow.ExecutionBlock[*chain.Transacti } func (m *mockValidityWindow) IsRepeat(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], []*chain.Transaction, int64) (set.Bits, error) { - return set.NewBits(), m.isRepeatError + return set.NewBits(m.setBits...), m.isRepeatError } func (*mockValidityWindow) VerifyExpiryReplayProtection(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], int64) error { @@ -51,7 +53,10 @@ func (*mockValidityWindow) VerifyExpiryReplayProtection(context.Context, validit } func TestPreExecutor(t *testing.T) { - ruleFactory := genesis.ImmutableRuleFactory{Rules: genesis.NewDefaultRules()} + testRules := genesis.NewDefaultRules() + ruleFactory := genesis.ImmutableRuleFactory{ + Rules: testRules, + } tests := []struct { name string @@ -61,12 +66,33 @@ func TestPreExecutor(t *testing.T) { verifyAuth bool err error }{ + { + name: "valid test case", + state: map[string][]byte{ + feeKey: {}, + }, + tx: &chain.Transaction{ + TransactionData: chain.TransactionData{ + Base: &chain.Base{ + Timestamp: utils.UnixRMilli( + time.Now().UnixMilli(), + testRules.GetValidityWindow(), + ), + }, + }, + Auth: &mockAuth{ + start: -1, + end: -1, + }, + }, + validityWindow: &mockValidityWindow{}, + }, { name: "raw fee doesn't exist", err: database.ErrNotFound, }, { - name: "repeat error", + name: "validity window error", tx: &chain.Transaction{}, state: map[string][]byte{ feeKey: {}, @@ -76,10 +102,21 @@ func TestPreExecutor(t *testing.T) { }, err: errMockValidityWindow, }, + { + name: "duplicate transaction", + tx: &chain.Transaction{}, + state: map[string][]byte{ + feeKey: {}, + }, + validityWindow: &mockValidityWindow{ + setBits: []int{0}, + }, + err: chain.ErrDuplicateTx, + }, { name: "tx state keys are invalid", state: map[string][]byte{ - string(chain.FeeKey([]byte{2})): {}, + feeKey: {}, }, tx: &chain.Transaction{ TransactionData: chain.TransactionData{ @@ -88,7 +125,6 @@ func TestPreExecutor(t *testing.T) { stateKeys: state.Keys{ "": state.None, }, - typeID: 1, }, }, }, @@ -100,16 +136,11 @@ func TestPreExecutor(t *testing.T) { { name: "verify auth error", state: map[string][]byte{ - string(chain.FeeKey([]byte{2})): {}, + feeKey: {}, }, tx: &chain.Transaction{ TransactionData: chain.TransactionData{ Base: &chain.Base{}, - Actions: []chain.Action{ - &mockAction{ - typeID: 1, - }, - }, }, Auth: &mockAuth{ verifyError: errMockAuth, @@ -119,6 +150,20 @@ func TestPreExecutor(t *testing.T) { verifyAuth: true, err: errMockAuth, }, + { + name: "transaction pre-execute error", + state: map[string][]byte{ + feeKey: {}, + }, + tx: &chain.Transaction{ + TransactionData: chain.TransactionData{ + Base: &chain.Base{}, + }, + Auth: &mockAuth{}, + }, + validityWindow: &mockValidityWindow{}, + err: chain.ErrTimestampTooLate, + }, } for _, tt := range tests { @@ -126,13 +171,6 @@ func TestPreExecutor(t *testing.T) { r := require.New(t) ctx := context.Background() - parentBlock, err := chain.NewExecutionBlock( - &chain.StatelessBlock{ - Tmstmp: time.Now().UnixMilli(), - }, - ) - r.NoError(err) - db, err := merkledb.New( ctx, memdb.New(), @@ -158,7 +196,7 @@ func TestPreExecutor(t *testing.T) { r.ErrorIs( preExecutor.PreExecute( ctx, - parentBlock, + nil, db, tt.tx, tt.verifyAuth, From de25e8c6497ad4cbf81e313169063c6cc3bc6905 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 17 Jan 2025 09:43:44 -0500 Subject: [PATCH 09/14] add valid tx and modify setbits --- chain/pre_executor_test.go | 63 ++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 8e7ed96e7b..5df57b0fbd 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -37,7 +37,7 @@ var ( type mockValidityWindow struct { isRepeatError error - setBits []int + setBits set.Bits } func (*mockValidityWindow) Accept(validitywindow.ExecutionBlock[*chain.Transaction]) { @@ -45,7 +45,7 @@ func (*mockValidityWindow) Accept(validitywindow.ExecutionBlock[*chain.Transacti } func (m *mockValidityWindow) IsRepeat(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], []*chain.Transaction, int64) (set.Bits, error) { - return set.NewBits(m.setBits...), m.isRepeatError + return m.setBits, m.isRepeatError } func (*mockValidityWindow) VerifyExpiryReplayProtection(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], int64) error { @@ -57,6 +57,20 @@ func TestPreExecutor(t *testing.T) { ruleFactory := genesis.ImmutableRuleFactory{ Rules: testRules, } + validTX := &chain.Transaction{ + TransactionData: chain.TransactionData{ + Base: &chain.Base{ + Timestamp: utils.UnixRMilli( + time.Now().UnixMilli(), + testRules.GetValidityWindow(), + ), + }, + }, + Auth: &mockAuth{ + start: -1, + end: -1, + }, + } tests := []struct { name string @@ -71,29 +85,19 @@ func TestPreExecutor(t *testing.T) { state: map[string][]byte{ feeKey: {}, }, - tx: &chain.Transaction{ - TransactionData: chain.TransactionData{ - Base: &chain.Base{ - Timestamp: utils.UnixRMilli( - time.Now().UnixMilli(), - testRules.GetValidityWindow(), - ), - }, - }, - Auth: &mockAuth{ - start: -1, - end: -1, - }, + tx: validTX, + validityWindow: &mockValidityWindow{ + setBits: set.NewBits(), }, - validityWindow: &mockValidityWindow{}, }, { name: "raw fee doesn't exist", + tx: validTX, err: database.ErrNotFound, }, { name: "validity window error", - tx: &chain.Transaction{}, + tx: validTX, state: map[string][]byte{ feeKey: {}, }, @@ -104,12 +108,12 @@ func TestPreExecutor(t *testing.T) { }, { name: "duplicate transaction", - tx: &chain.Transaction{}, + tx: validTX, state: map[string][]byte{ feeKey: {}, }, validityWindow: &mockValidityWindow{ - setBits: []int{0}, + setBits: set.NewBits(0), }, err: chain.ErrDuplicateTx, }, @@ -130,8 +134,10 @@ func TestPreExecutor(t *testing.T) { }, Auth: &mockAuth{}, }, - validityWindow: &mockValidityWindow{}, - err: chain.ErrInvalidKeyValue, + validityWindow: &mockValidityWindow{ + setBits: set.NewBits(), + }, + err: chain.ErrInvalidKeyValue, }, { name: "verify auth error", @@ -146,9 +152,11 @@ func TestPreExecutor(t *testing.T) { verifyError: errMockAuth, }, }, - validityWindow: &mockValidityWindow{}, - verifyAuth: true, - err: errMockAuth, + validityWindow: &mockValidityWindow{ + setBits: set.NewBits(), + }, + verifyAuth: true, + err: errMockAuth, }, { name: "transaction pre-execute error", @@ -161,8 +169,10 @@ func TestPreExecutor(t *testing.T) { }, Auth: &mockAuth{}, }, - validityWindow: &mockValidityWindow{}, - err: chain.ErrTimestampTooLate, + validityWindow: &mockValidityWindow{ + setBits: set.NewBits(), + }, + err: chain.ErrTimestampTooLate, }, } @@ -199,7 +209,6 @@ func TestPreExecutor(t *testing.T) { nil, db, tt.tx, - tt.verifyAuth, ), tt.err, ) }) From 553544b077a89f2d6760e8b7d73f2e119c950a48 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 17 Jan 2025 13:18:35 -0500 Subject: [PATCH 10/14] nits --- chain/errors.go | 3 +++ chain/pre_executor.go | 7 ++++++- chain/pre_executor_test.go | 3 +-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/chain/errors.go b/chain/errors.go index aea7f42a5f..988ff8344c 100644 --- a/chain/errors.go +++ b/chain/errors.go @@ -57,6 +57,9 @@ var ( ErrBlockTooBig = errors.New("block too big") ErrKeyNotSpecified = errors.New("key not specified") + // State Correctness + ErrFeeNotFound = errors.New("fee not found") + // Misc ErrNotImplemented = errors.New("not implemented") ErrBlockNotProcessed = errors.New("block is not processed") diff --git a/chain/pre_executor.go b/chain/pre_executor.go index 6038b28a2a..c015a30b77 100644 --- a/chain/pre_executor.go +++ b/chain/pre_executor.go @@ -7,6 +7,8 @@ import ( "context" "time" + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/hypersdk/state" internalfees "github.com/ava-labs/hypersdk/internal/fees" @@ -40,9 +42,12 @@ func (p *PreExecutor) PreExecute( tx *Transaction, ) error { feeRaw, err := view.GetValue(ctx, FeeKey(p.metadataManager.FeePrefix())) - if err != nil { + if err != nil && err != database.ErrNotFound { return err } + if err == database.ErrNotFound { + return ErrFeeNotFound + } feeManager := internalfees.NewManager(feeRaw) now := time.Now().UnixMilli() r := p.ruleFactory.GetRules(now) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 5df57b0fbd..de118a45ba 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/trace" "github.com/ava-labs/avalanchego/utils/set" @@ -93,7 +92,7 @@ func TestPreExecutor(t *testing.T) { { name: "raw fee doesn't exist", tx: validTX, - err: database.ErrNotFound, + err: chain.ErrFeeNotFound, }, { name: "validity window error", From c774d0d46f9bfebfffe21de710876acb761d0770 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 17 Jan 2025 15:29:04 -0500 Subject: [PATCH 11/14] camcelcase --- chain/pre_executor_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index de118a45ba..13bf814c03 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -56,7 +56,7 @@ func TestPreExecutor(t *testing.T) { ruleFactory := genesis.ImmutableRuleFactory{ Rules: testRules, } - validTX := &chain.Transaction{ + validTx := &chain.Transaction{ TransactionData: chain.TransactionData{ Base: &chain.Base{ Timestamp: utils.UnixRMilli( @@ -84,19 +84,19 @@ func TestPreExecutor(t *testing.T) { state: map[string][]byte{ feeKey: {}, }, - tx: validTX, + tx: validTx, validityWindow: &mockValidityWindow{ setBits: set.NewBits(), }, }, { name: "raw fee doesn't exist", - tx: validTX, + tx: validTx, err: chain.ErrFeeNotFound, }, { name: "validity window error", - tx: validTX, + tx: validTx, state: map[string][]byte{ feeKey: {}, }, @@ -107,7 +107,7 @@ func TestPreExecutor(t *testing.T) { }, { name: "duplicate transaction", - tx: validTX, + tx: validTx, state: map[string][]byte{ feeKey: {}, }, From 686da59c479df34d2d1608f3bac8b123a8be8ce2 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 17 Jan 2025 16:02:44 -0500 Subject: [PATCH 12/14] cr improvements --- chain/errors.go | 2 +- chain/pre_executor.go | 10 ++---- chain/pre_executor_test.go | 70 +++++++++++++++----------------------- 3 files changed, 32 insertions(+), 50 deletions(-) diff --git a/chain/errors.go b/chain/errors.go index 988ff8344c..29ec52aacb 100644 --- a/chain/errors.go +++ b/chain/errors.go @@ -58,7 +58,7 @@ var ( ErrKeyNotSpecified = errors.New("key not specified") // State Correctness - ErrFeeNotFound = errors.New("fee not found") + ErrFailedToFetchFee = errors.New("failed to fetch fee") // Misc ErrNotImplemented = errors.New("not implemented") diff --git a/chain/pre_executor.go b/chain/pre_executor.go index 6e02436915..1be0291263 100644 --- a/chain/pre_executor.go +++ b/chain/pre_executor.go @@ -5,10 +5,9 @@ package chain import ( "context" + "fmt" "time" - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/hypersdk/state" internalfees "github.com/ava-labs/hypersdk/internal/fees" @@ -42,11 +41,8 @@ func (p *PreExecutor) PreExecute( tx *Transaction, ) error { feeRaw, err := view.GetValue(ctx, FeeKey(p.metadataManager.FeePrefix())) - if err != nil && err != database.ErrNotFound { - return err - } - if err == database.ErrNotFound { - return ErrFeeNotFound + if err != nil { + return fmt.Errorf("%w: %w", ErrFailedToFetchFee, err) } feeManager := internalfees.NewManager(feeRaw) now := time.Now().UnixMilli() diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 13bf814c03..e5d9ce2fd0 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/hypersdk/chain" "github.com/ava-labs/hypersdk/genesis" "github.com/ava-labs/hypersdk/internal/validitywindow" + "github.com/ava-labs/hypersdk/internal/validitywindow/validitywindowtest" "github.com/ava-labs/hypersdk/state" "github.com/ava-labs/hypersdk/state/metadata" "github.com/ava-labs/hypersdk/utils" @@ -28,27 +29,22 @@ var ( errMockAuth = errors.New("mock auth error") errMockValidityWindow = errors.New("mock validity window error") - - _ chain.Auth = (*mockAuth)(nil) - _ chain.BalanceHandler = (*mockBalanceHandler)(nil) - _ chain.ValidityWindow = (*mockValidityWindow)(nil) ) -type mockValidityWindow struct { - isRepeatError error - setBits set.Bits -} - -func (*mockValidityWindow) Accept(validitywindow.ExecutionBlock[*chain.Transaction]) { - panic("unimplemented") -} - -func (m *mockValidityWindow) IsRepeat(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], []*chain.Transaction, int64) (set.Bits, error) { - return m.setBits, m.isRepeatError -} - -func (*mockValidityWindow) VerifyExpiryReplayProtection(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], int64) error { - panic("unimplemented") +func isRepeatFuncGenerator(bits set.Bits, err error) func( + ctx context.Context, + parentBlk validitywindow.ExecutionBlock[*chain.Transaction], + containers []*chain.Transaction, + currentTime int64, +) (set.Bits, error) { + return func( + context.Context, + validitywindow.ExecutionBlock[*chain.Transaction], + []*chain.Transaction, + int64, + ) (set.Bits, error) { + return bits, err + } } func TestPreExecutor(t *testing.T) { @@ -76,7 +72,6 @@ func TestPreExecutor(t *testing.T) { state map[string][]byte tx *chain.Transaction validityWindow chain.ValidityWindow - verifyAuth bool err error }{ { @@ -84,15 +79,13 @@ func TestPreExecutor(t *testing.T) { state: map[string][]byte{ feeKey: {}, }, - tx: validTx, - validityWindow: &mockValidityWindow{ - setBits: set.NewBits(), - }, + tx: validTx, + validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{}, }, { name: "raw fee doesn't exist", tx: validTx, - err: chain.ErrFeeNotFound, + err: chain.ErrFailedToFetchFee, }, { name: "validity window error", @@ -100,8 +93,8 @@ func TestPreExecutor(t *testing.T) { state: map[string][]byte{ feeKey: {}, }, - validityWindow: &mockValidityWindow{ - isRepeatError: errMockValidityWindow, + validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{ + OnIsRepeat: isRepeatFuncGenerator(set.NewBits(), errMockValidityWindow), }, err: errMockValidityWindow, }, @@ -111,8 +104,8 @@ func TestPreExecutor(t *testing.T) { state: map[string][]byte{ feeKey: {}, }, - validityWindow: &mockValidityWindow{ - setBits: set.NewBits(0), + validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{ + OnIsRepeat: isRepeatFuncGenerator(set.NewBits(0), nil), }, err: chain.ErrDuplicateTx, }, @@ -133,10 +126,8 @@ func TestPreExecutor(t *testing.T) { }, Auth: &mockAuth{}, }, - validityWindow: &mockValidityWindow{ - setBits: set.NewBits(), - }, - err: chain.ErrInvalidKeyValue, + validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{}, + err: chain.ErrInvalidKeyValue, }, { name: "verify auth error", @@ -151,11 +142,8 @@ func TestPreExecutor(t *testing.T) { verifyError: errMockAuth, }, }, - validityWindow: &mockValidityWindow{ - setBits: set.NewBits(), - }, - verifyAuth: true, - err: errMockAuth, + validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{}, + err: errMockAuth, }, { name: "transaction pre-execute error", @@ -168,10 +156,8 @@ func TestPreExecutor(t *testing.T) { }, Auth: &mockAuth{}, }, - validityWindow: &mockValidityWindow{ - setBits: set.NewBits(), - }, - err: chain.ErrTimestampTooLate, + validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{}, + err: chain.ErrTimestampTooLate, }, } From 811920c8d45c7385ee2f062f67894eff0a490b49 Mon Sep 17 00:00:00 2001 From: Rodrigo Villar Date: Fri, 17 Jan 2025 16:07:44 -0500 Subject: [PATCH 13/14] switch from view to immutable --- chain/chain.go | 4 ++-- chain/pre_executor.go | 6 +++--- chain/pre_executor_test.go | 20 +------------------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/chain/chain.go b/chain/chain.go index 4bad2415cc..7cc356fc6d 100644 --- a/chain/chain.go +++ b/chain/chain.go @@ -99,10 +99,10 @@ func (c *Chain) AsyncVerify( func (c *Chain) PreExecute( ctx context.Context, parentBlk *ExecutionBlock, - view state.View, + im state.Immutable, tx *Transaction, ) error { - return c.preExecutor.PreExecute(ctx, parentBlk, view, tx) + return c.preExecutor.PreExecute(ctx, parentBlk, im, tx) } func (c *Chain) ParseBlock(ctx context.Context, bytes []byte) (*ExecutionBlock, error) { diff --git a/chain/pre_executor.go b/chain/pre_executor.go index 1be0291263..79bf4b8bd5 100644 --- a/chain/pre_executor.go +++ b/chain/pre_executor.go @@ -37,10 +37,10 @@ func NewPreExecutor( func (p *PreExecutor) PreExecute( ctx context.Context, parentBlk *ExecutionBlock, - view state.View, + im state.Immutable, tx *Transaction, ) error { - feeRaw, err := view.GetValue(ctx, FeeKey(p.metadataManager.FeePrefix())) + feeRaw, err := im.GetValue(ctx, FeeKey(p.metadataManager.FeePrefix())) if err != nil { return fmt.Errorf("%w: %w", ErrFailedToFetchFee, err) } @@ -81,7 +81,7 @@ func (p *PreExecutor) PreExecute( // Note, [PreExecute] ensures that the pending transaction does not have // an expiry time further ahead than [ValidityWindow]. This ensures anything // added to the [Mempool] is immediately executable. - if err := tx.PreExecute(ctx, nextFeeManager, p.balanceHandler, r, view, now); err != nil { + if err := tx.PreExecute(ctx, nextFeeManager, p.balanceHandler, r, im, now); err != nil { return err } return nil diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index e5d9ce2fd0..22b6c84396 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -9,10 +9,7 @@ import ( "testing" "time" - "github.com/ava-labs/avalanchego/database/memdb" - "github.com/ava-labs/avalanchego/trace" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/x/merkledb" "github.com/stretchr/testify/require" "github.com/ava-labs/hypersdk/chain" @@ -166,21 +163,6 @@ func TestPreExecutor(t *testing.T) { r := require.New(t) ctx := context.Background() - db, err := merkledb.New( - ctx, - memdb.New(), - merkledb.Config{ - BranchFactor: merkledb.BranchFactor16, - Tracer: trace.Noop, - }, - ) - r.NoError(err) - - for k, v := range tt.state { - r.NoError(db.Put([]byte(k), v)) - } - r.NoError(db.CommitToDB(ctx)) - preExecutor := chain.NewPreExecutor( &ruleFactory, tt.validityWindow, @@ -192,7 +174,7 @@ func TestPreExecutor(t *testing.T) { preExecutor.PreExecute( ctx, nil, - db, + state.ImmutableStorage(tt.state), tt.tx, ), tt.err, ) From ff73528fce4b20f8ec745786a254a67f6c6864b0 Mon Sep 17 00:00:00 2001 From: aaronbuchwald Date: Mon, 20 Jan 2025 17:32:11 -0500 Subject: [PATCH 14/14] Remove intermediate func from pre-executor test + naming nits (#1877) --- chain/pre_executor_test.go | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/chain/pre_executor_test.go b/chain/pre_executor_test.go index 22b6c84396..a979b0fcfc 100644 --- a/chain/pre_executor_test.go +++ b/chain/pre_executor_test.go @@ -28,22 +28,6 @@ var ( errMockValidityWindow = errors.New("mock validity window error") ) -func isRepeatFuncGenerator(bits set.Bits, err error) func( - ctx context.Context, - parentBlk validitywindow.ExecutionBlock[*chain.Transaction], - containers []*chain.Transaction, - currentTime int64, -) (set.Bits, error) { - return func( - context.Context, - validitywindow.ExecutionBlock[*chain.Transaction], - []*chain.Transaction, - int64, - ) (set.Bits, error) { - return bits, err - } -} - func TestPreExecutor(t *testing.T) { testRules := genesis.NewDefaultRules() ruleFactory := genesis.ImmutableRuleFactory{ @@ -72,7 +56,7 @@ func TestPreExecutor(t *testing.T) { err error }{ { - name: "valid test case", + name: "valid tx", state: map[string][]byte{ feeKey: {}, }, @@ -80,7 +64,7 @@ func TestPreExecutor(t *testing.T) { validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{}, }, { - name: "raw fee doesn't exist", + name: "raw fee missing", tx: validTx, err: chain.ErrFailedToFetchFee, }, @@ -91,23 +75,27 @@ func TestPreExecutor(t *testing.T) { feeKey: {}, }, validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{ - OnIsRepeat: isRepeatFuncGenerator(set.NewBits(), errMockValidityWindow), + OnIsRepeat: func(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], []*chain.Transaction, int64) (set.Bits, error) { + return set.NewBits(), errMockValidityWindow + }, }, err: errMockValidityWindow, }, { - name: "duplicate transaction", + name: "duplicate tx", tx: validTx, state: map[string][]byte{ feeKey: {}, }, validityWindow: &validitywindowtest.MockTimeValidityWindow[*chain.Transaction]{ - OnIsRepeat: isRepeatFuncGenerator(set.NewBits(0), nil), + OnIsRepeat: func(context.Context, validitywindow.ExecutionBlock[*chain.Transaction], []*chain.Transaction, int64) (set.Bits, error) { + return set.NewBits(0), nil + }, }, err: chain.ErrDuplicateTx, }, { - name: "tx state keys are invalid", + name: "invalid state keys", state: map[string][]byte{ feeKey: {}, }, @@ -143,7 +131,7 @@ func TestPreExecutor(t *testing.T) { err: errMockAuth, }, { - name: "transaction pre-execute error", + name: "tx pre-execute error", state: map[string][]byte{ feeKey: {}, },