From 62748b0624e754e07505b9a1b6fe78ed6b7977b4 Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 27 Sep 2022 13:27:15 -0600 Subject: [PATCH 01/45] reset branch for new head --- chain/dev/config.toml | 1 + chain/dev/defaults.go | 3 + chain/gssmr/config.toml | 1 + chain/gssmr/defaults.go | 3 + chain/kusama/config.toml | 1 + chain/kusama/defaults.go | 3 + chain/polkadot/config.toml | 1 + chain/polkadot/defaults.go | 3 + cmd/gossamer/config.go | 14 +- dot/config.go | 4 + dot/config_test.go | 2 + dot/core/errors.go | 9 +- dot/core/helpers.go | 16 ++ dot/core/interface.go | 1 + dot/core/messages.go | 24 ++- dot/core/messages_test.go | 39 ++++- dot/core/mocks_test.go | 14 ++ dot/core/service.go | 72 ++++++-- dot/core/service_integration_test.go | 135 +++------------ dot/core/service_test.go | 188 ++++++++++++++++++--- dot/digest/digest_test.go | 4 +- dot/node.go | 7 +- dot/node_test.go | 6 +- dot/rpc/http_test.go | 6 +- dot/rpc/modules/author_integration_test.go | 79 ++++++--- dot/rpc/modules/childstate_test.go | 4 +- dot/rpc/modules/helpers_test.go | 3 +- dot/state/block_data_test.go | 2 +- dot/state/block_finalisation_test.go | 6 +- dot/state/block_notify_test.go | 14 +- dot/state/block_test.go | 30 ++-- dot/state/epoch_test.go | 4 +- dot/state/initialize.go | 4 +- dot/state/storage_notify_test.go | 6 +- dot/state/storage_test.go | 15 +- go.mod | 2 +- go.sum | 4 +- lib/babe/verify_integration_test.go | 13 +- lib/blocktree/hashtoruntime_test.go | 2 - lib/blocktree/mocks_generate_test.go | 6 + lib/genesis/genesis_test.go | 70 ++++---- lib/genesis/helpers.go | 40 ++++- lib/genesis/helpers_test.go | 50 +++--- lib/genesis/keys.go | 25 --- lib/genesis/test_utils.go | 108 ++++++++++++ lib/runtime/constants.go | 33 +++- lib/runtime/invalid_transaction.go | 4 +- lib/runtime/invalid_transaction_test.go | 46 +++++ lib/runtime/transaction_validity.go | 2 +- lib/runtime/unknown_transaction.go | 2 +- lib/runtime/unknown_transaction_test.go | 46 +++++ lib/runtime/version.go | 15 ++ lib/runtime/wasmer/exports.go | 8 +- lib/runtime/wasmer/exports_test.go | 63 ++++--- lib/runtime/wasmer/helpers_test.go | 19 --- lib/trie/genesis_test.go | 73 -------- lib/trie/trie.go | 4 +- lib/trie/trie_test.go | 17 +- 58 files changed, 893 insertions(+), 483 deletions(-) create mode 100644 dot/core/helpers.go create mode 100644 lib/blocktree/mocks_generate_test.go delete mode 100644 lib/genesis/keys.go create mode 100644 lib/genesis/test_utils.go create mode 100644 lib/runtime/invalid_transaction_test.go create mode 100644 lib/runtime/unknown_transaction_test.go delete mode 100644 lib/trie/genesis_test.go diff --git a/chain/dev/config.toml b/chain/dev/config.toml index 434e79f59a..c55318871b 100644 --- a/chain/dev/config.toml +++ b/chain/dev/config.toml @@ -52,6 +52,7 @@ modules = [ ws-port = 8546 [pprof] +enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/dev/defaults.go b/chain/dev/defaults.go index 88193c2da9..5e321224dd 100644 --- a/chain/dev/defaults.go +++ b/chain/dev/defaults.go @@ -96,6 +96,9 @@ var ( const ( // PprofConfig + // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. + DefaultPprofEnabled = true + // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/chain/gssmr/config.toml b/chain/gssmr/config.toml index 5165b96fa9..309ff2269b 100644 --- a/chain/gssmr/config.toml +++ b/chain/gssmr/config.toml @@ -54,6 +54,7 @@ modules = [ ws-port = 8546 [pprof] +enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/gssmr/defaults.go b/chain/gssmr/defaults.go index 0295be7a38..1417b895bf 100644 --- a/chain/gssmr/defaults.go +++ b/chain/gssmr/defaults.go @@ -104,6 +104,9 @@ var ( const ( // PprofConfig + // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. + DefaultPprofEnabled = true + // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/chain/kusama/config.toml b/chain/kusama/config.toml index 865fd01f12..3ce5a210ea 100644 --- a/chain/kusama/config.toml +++ b/chain/kusama/config.toml @@ -42,6 +42,7 @@ ws = false ws-external = false [pprof] +enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/kusama/defaults.go b/chain/kusama/defaults.go index 57183b1859..b9a00bdce6 100644 --- a/chain/kusama/defaults.go +++ b/chain/kusama/defaults.go @@ -88,6 +88,9 @@ var ( const ( // PprofConfig + // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. + DefaultPprofEnabled = false + // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/chain/polkadot/config.toml b/chain/polkadot/config.toml index 26ae4ba747..afdb693abc 100644 --- a/chain/polkadot/config.toml +++ b/chain/polkadot/config.toml @@ -39,6 +39,7 @@ modules = ["system", "author", "chain", "state", "rpc", "grandpa", "offchain", " ws-port = 8546 [pprof] +enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/polkadot/defaults.go b/chain/polkadot/defaults.go index 2a75648878..cc6a24a19e 100644 --- a/chain/polkadot/defaults.go +++ b/chain/polkadot/defaults.go @@ -86,6 +86,9 @@ var ( const ( // PprofConfig + // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. + DefaultPprofEnabled = false + // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/cmd/gossamer/config.go b/cmd/gossamer/config.go index 0042542484..5fa7eff0c7 100644 --- a/cmd/gossamer/config.go +++ b/cmd/gossamer/config.go @@ -890,10 +890,9 @@ func updateDotConfigFromGenesisData(ctx *cli.Context, cfg *dot.Config) error { } func setDotPprofConfig(ctx *cli.Context, tomlCfg ctoml.PprofConfig, cfg *dot.PprofConfig) { - // Flag takes precedence over TOML config, default is ignored. - if ctx.GlobalIsSet(PprofServerFlag.Name) { - cfg.Enabled = ctx.GlobalBool(PprofServerFlag.Name) - } else { + if !cfg.Enabled { + // only allow to enable pprof from the TOML configuration. + // If it is enabled by default, it cannot be disabled. cfg.Enabled = tomlCfg.Enabled } @@ -913,6 +912,13 @@ func setDotPprofConfig(ctx *cli.Context, tomlCfg ctoml.PprofConfig, cfg *dot.Ppr cfg.Settings.MutexProfileRate = tomlCfg.MutexRate } + // check --pprofserver flag and update node configuration + if enabled := ctx.GlobalBool(PprofServerFlag.Name); enabled || cfg.Enabled { + cfg.Enabled = true + } else if ctx.IsSet(PprofServerFlag.Name) && !enabled { + cfg.Enabled = false + } + // check --pprofaddress flag and update node configuration if address := ctx.GlobalString(PprofAddressFlag.Name); address != "" { cfg.Settings.ListeningAddress = address diff --git a/dot/config.go b/dot/config.go index eba3879b09..b1cad82f83 100644 --- a/dot/config.go +++ b/dot/config.go @@ -239,6 +239,7 @@ func GssmrConfig() *Config { WSPort: gssmr.DefaultRPCWSPort, }, Pprof: PprofConfig{ + Enabled: gssmr.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: gssmr.DefaultPprofListeningAddress, BlockProfileRate: gssmr.DefaultPprofBlockRate, @@ -296,6 +297,7 @@ func KusamaConfig() *Config { WSPort: kusama.DefaultRPCWSPort, }, Pprof: PprofConfig{ + Enabled: kusama.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: kusama.DefaultPprofListeningAddress, BlockProfileRate: kusama.DefaultPprofBlockRate, @@ -353,6 +355,7 @@ func PolkadotConfig() *Config { WSPort: polkadot.DefaultRPCWSPort, }, Pprof: PprofConfig{ + Enabled: polkadot.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: polkadot.DefaultPprofListeningAddress, BlockProfileRate: polkadot.DefaultPprofBlockRate, @@ -415,6 +418,7 @@ func DevConfig() *Config { WS: dev.DefaultWSEnabled, }, Pprof: PprofConfig{ + Enabled: dev.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: dev.DefaultPprofListeningAddress, BlockProfileRate: dev.DefaultPprofBlockRate, diff --git a/dot/config_test.go b/dot/config_test.go index ab801a0237..7e8922c7f2 100644 --- a/dot/config_test.go +++ b/dot/config_test.go @@ -74,6 +74,7 @@ func TestConfig(t *testing.T) { WS: true, }, Pprof: PprofConfig{ + Enabled: true, Settings: pprof.Settings{ ListeningAddress: "localhost:6060", }, @@ -133,6 +134,7 @@ func TestConfig(t *testing.T) { WSUnsafeExternal: false, }, Pprof: PprofConfig{ + Enabled: true, Settings: pprof.Settings{ ListeningAddress: "localhost:6060", BlockProfileRate: 0, diff --git a/dot/core/errors.go b/dot/core/errors.go index 468a29032b..5e8ab8e693 100644 --- a/dot/core/errors.go +++ b/dot/core/errors.go @@ -8,17 +8,12 @@ import ( ) var ( - - // ErrServiceStopped is returned when the service has been stopped - ErrServiceStopped = errors.New("service has been stopped") - - // ErrInvalidBlock is returned when a block cannot be verified - ErrInvalidBlock = errors.New("could not verify block") - ErrNilRuntime = errors.New("cannot have nil runtime") ErrNilBlockHandlerParameter = errors.New("unable to handle block due to nil parameter") // ErrEmptyRuntimeCode is returned when the storage :code is empty ErrEmptyRuntimeCode = errors.New("new :code is empty") + + errInvalidTransactionQueueVersion = errors.New("invalid transaction queue version") ) diff --git a/dot/core/helpers.go b/dot/core/helpers.go new file mode 100644 index 0000000000..2da5c73234 --- /dev/null +++ b/dot/core/helpers.go @@ -0,0 +1,16 @@ +// Copyright 2021 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package core + +func concatenateByteSlices(slices [][]byte) (concatenated []byte) { + length := 0 + for i := range slices { + length += len(slices[i]) + } + concatenated = make([]byte, 0, length) + for _, slice := range slices { + concatenated = append(concatenated, slice...) + } + return concatenated +} diff --git a/dot/core/interface.go b/dot/core/interface.go index 05986df2e5..aaf98ee865 100644 --- a/dot/core/interface.go +++ b/dot/core/interface.go @@ -88,6 +88,7 @@ type StorageState interface { // TransactionState is the interface for transaction state methods type TransactionState interface { + Pop() *transaction.ValidTransaction Push(vt *transaction.ValidTransaction) (common.Hash, error) AddToPool(vt *transaction.ValidTransaction) common.Hash RemoveExtrinsic(ext types.Extrinsic) diff --git a/dot/core/messages.go b/dot/core/messages.go index 464ae5640f..fe92178bb9 100644 --- a/dot/core/messages.go +++ b/dot/core/messages.go @@ -28,7 +28,11 @@ func (s *Service) validateTransaction(head *types.Header, rt RuntimeInstance, rt.SetContextStorage(ts) // validate each transaction - externalExt := types.Extrinsic(append([]byte{byte(types.TxnExternal)}, tx...)) + externalExt, err := s.buildExternalTransaction(rt, tx) + if err != nil { + return nil, fmt.Errorf("building transaction: %s", err) + } + validity, err = rt.ValidateTransaction(externalExt) if err != nil { logger.Debugf("failed to validate transaction: %s", err) @@ -70,32 +74,34 @@ func (s *Service) HandleTransactionMessage(peerID peer.ID, msg *network.Transact return false, err } - allTxnsAreValid := true + allTxsAreValid := true for _, tx := range txs { - txnIsValid := true + isValidTxn := true validity, err := s.validateTransaction(head, rt, tx) if err != nil { - txnIsValid = false - allTxnsAreValid = false - switch err := err.(type) { + switch err.(type) { case runtime.InvalidTransaction: + isValidTxn = false + allTxsAreValid = false s.net.ReportPeer(peerset.ReputationChange{ Value: peerset.BadTransactionValue, Reason: peerset.BadTransactionReason, }, peerID) case runtime.UnknownTransaction: + isValidTxn = false + allTxsAreValid = false default: - return false, fmt.Errorf("validating transaction from peerID %s: %w", peerID, err) + return false, fmt.Errorf("failed validating transaction for peerID %s: %w", peerID, err) } } - if txnIsValid && validity.Propagate { + if isValidTxn && validity.Propagate { // find tx(s) that should propagate toPropagate = append(toPropagate, tx) } } - if allTxnsAreValid { + if allTxsAreValid { s.net.ReportPeer(peerset.ReputationChange{ Value: peerset.GoodTransactionValue, Reason: peerset.GoodTransactionReason, diff --git a/dot/core/messages_test.go b/dot/core/messages_test.go index 44476ffe03..9fb1753eca 100644 --- a/dot/core/messages_test.go +++ b/dot/core/messages_test.go @@ -44,8 +44,9 @@ type mockGetRuntime struct { } type mockBlockState struct { - bestHeader *mockBestHeader - getRuntime *mockGetRuntime + bestHeader *mockBestHeader + getRuntime *mockGetRuntime + callsBestBlockHash bool } type mockStorageState struct { @@ -230,7 +231,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { }, }, expErr: errDummyErr, - expErrMsg: "validating transaction from peerID D1KeRhQ: cannot get trie state from storage" + + expErrMsg: "failed validating transaction for peerID D1KeRhQ: cannot get trie state from storage" + " for root 0x0000000000000000000000000000000000000000000000000000000000000000: dummy error for testing", }, { @@ -252,6 +253,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { getRuntime: &mockGetRuntime{ runtime: runtimeMock2, }, + callsBestBlockHash: true, }, mockStorageState: &mockStorageState{ input: &common.Hash{}, @@ -261,8 +263,12 @@ func TestServiceHandleTransactionMessage(t *testing.T) { runtime: runtimeMock2, setContextStorage: &mockSetContextStorage{trieState: &storage.TrieState{}}, validateTxn: &mockValidateTxn{ - input: types.Extrinsic(append([]byte{byte(types.TxnExternal)}, testExtrinsic[0]...)), - err: invalidTransaction, + input: types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + testExtrinsic[0], + testEmptyHeader.StateRoot.ToBytes(), + })), + err: invalidTransaction, }, }, args: args{ @@ -291,6 +297,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { getRuntime: &mockGetRuntime{ runtime: runtimeMock3, }, + callsBestBlockHash: true, }, mockStorageState: &mockStorageState{ input: &common.Hash{}, @@ -308,7 +315,11 @@ func TestServiceHandleTransactionMessage(t *testing.T) { runtime: runtimeMock3, setContextStorage: &mockSetContextStorage{trieState: &storage.TrieState{}}, validateTxn: &mockValidateTxn{ - input: types.Extrinsic(append([]byte{byte(types.TxnExternal)}, testExtrinsic[0]...)), + input: types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + testExtrinsic[0], + testEmptyHeader.StateRoot.ToBytes(), + })), validity: &transaction.Validity{Propagate: true}, }, }, @@ -344,6 +355,9 @@ func TestServiceHandleTransactionMessage(t *testing.T) { tt.mockBlockState.getRuntime.runtime, tt.mockBlockState.getRuntime.err) } + if tt.mockBlockState.callsBestBlockHash { + blockState.EXPECT().BestBlockHash().Return(common.Hash{}) + } s.blockState = blockState } if tt.mockStorageState != nil { @@ -365,6 +379,19 @@ func TestServiceHandleTransactionMessage(t *testing.T) { rt.EXPECT().SetContextStorage(tt.mockRuntime.setContextStorage.trieState) rt.EXPECT().ValidateTransaction(tt.mockRuntime.validateTxn.input). Return(tt.mockRuntime.validateTxn.validity, tt.mockRuntime.validateTxn.err) + rt.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) } res, err := s.HandleTransactionMessage(tt.args.peerID, tt.args.msg) diff --git a/dot/core/mocks_test.go b/dot/core/mocks_test.go index 7dca84b036..4dc2ceecd4 100644 --- a/dot/core/mocks_test.go +++ b/dot/core/mocks_test.go @@ -587,6 +587,20 @@ func (mr *MockTransactionStateMockRecorder) PendingInPool() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PendingInPool", reflect.TypeOf((*MockTransactionState)(nil).PendingInPool)) } +// Pop mocks base method. +func (m *MockTransactionState) Pop() *transaction.ValidTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Pop") + ret0, _ := ret[0].(*transaction.ValidTransaction) + return ret0 +} + +// Pop indicates an expected call of Pop. +func (mr *MockTransactionStateMockRecorder) Pop() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pop", reflect.TypeOf((*MockTransactionState)(nil).Pop)) +} + // Push mocks base method. func (m *MockTransactionState) Push(arg0 *transaction.ValidTransaction) (common.Hash, error) { m.ctrl.T.Helper() diff --git a/dot/core/service.go b/dot/core/service.go index 833f63e984..b201982f9a 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -31,6 +31,9 @@ var ( logger = log.NewFromGlobal(log.AddContext("pkg", "core")) ) +const supportedTxVersion = 3 +const previousSupportedTxVersion = 2 + // QueryKeyValueChanges represents the key-value data inside a block storage type QueryKeyValueChanges map[string]string @@ -293,6 +296,9 @@ func (s *Service) handleCodeSubstitution(hash common.Hash, // does not need to be completed before the next block can be imported. func (s *Service) handleBlocksAsync() { for { + // TODO Look into if this is best way to get prev + // Maybe pass in block and get parent rather than assume that + // best block hash is the parent prev := s.blockState.BestBlockHash() select { @@ -373,15 +379,17 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { continue } - externalExt := make(types.Extrinsic, 0, 1+len(ext)) - externalExt = append(externalExt, byte(types.TxnExternal)) - externalExt = append(externalExt, ext...) - txv, err := rt.ValidateTransaction(externalExt) + externalExt, err := s.buildExternalTransaction(rt, ext) + if err != nil { + return fmt.Errorf("building external transaction: %w", err) + } + + transactionValidity, err := rt.ValidateTransaction(externalExt) if err != nil { logger.Debugf("failed to validate transaction for extrinsic %s: %s", ext, err) continue } - vtx := transaction.NewValidTransaction(ext, txv) + vtx := transaction.NewValidTransaction(ext, transactionValidity) s.transactionState.AddToPool(vtx) } } @@ -399,17 +407,33 @@ func (s *Service) maintainTransactionPool(block *types.Block) { s.transactionState.RemoveExtrinsic(ext) } + bestBlockHash := s.blockState.BestBlockHash() + stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) + if err != nil { + logger.Errorf("could not get state root from block %s: %w", bestBlockHash, err) + } + + ts, err := s.storageState.TrieState(stateRoot) + if err != nil { + logger.Errorf(err.Error()) + } + // re-validate transactions in the pool and move them to the queue txs := s.transactionState.PendingInPool() for _, tx := range txs { - // get the best block corresponding runtime - rt, err := s.blockState.GetRuntime(nil) + rt, err := s.blockState.GetRuntime(&bestBlockHash) if err != nil { logger.Warnf("failed to get runtime to re-validate transactions in pool: %s", err) continue } - txnValidity, err := rt.ValidateTransaction(tx.Extrinsic) + rt.SetContextStorage(ts) + externalExt, err := s.buildExternalTransaction(rt, tx.Extrinsic) + if err != nil { + logger.Errorf("Unable to build external transaction: %s", err) + } + + txnValidity, err := rt.ValidateTransaction(externalExt) if err != nil { s.transactionState.RemoveExtrinsic(tx.Extrinsic) continue @@ -513,8 +537,12 @@ func (s *Service) HandleSubmittedExtrinsic(ext types.Extrinsic) error { } rt.SetContextStorage(ts) - // the transaction source is External - externalExt := types.Extrinsic(append([]byte{byte(types.TxnExternal)}, ext...)) + + externalExt, err := s.buildExternalTransaction(rt, ext) + if err != nil { + return fmt.Errorf("building external transaction: %w", err) + } + transactionValidity, err := rt.ValidateTransaction(externalExt) if err != nil { return err @@ -578,3 +606,27 @@ func (s *Service) GetReadProofAt(block common.Hash, keys [][]byte) ( return block, proofForKeys, nil } + +// buildExternalTransaction builds an external transaction based on the current TransactionQueueAPIVersion +// See https://github.com/paritytech/substrate/blob/polkadot-v0.9.25/primitives/transaction-pool/src/runtime_api.rs#L25-L55 +func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrinsic) (types.Extrinsic, error) { + runtimeVersion := rt.Version() + txQueueVersion := runtimeVersion.TaggedTransactionQueueVersion(runtimeVersion) + var externalExt types.Extrinsic + switch txQueueVersion { + case supportedTxVersion: + externalExt = types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + ext, + s.blockState.BestBlockHash().ToBytes(), + })) + case previousSupportedTxVersion: + externalExt = types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + ext, + })) + default: + return types.Extrinsic{}, errInvalidTransactionQueueVersion + } + return externalExt, nil +} diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index e9638ed4aa..99ee102286 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -17,87 +17,19 @@ import ( "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/sync" "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/genesis" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/transaction" + "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) -//go:generate mockgen -destination=mock_telemetry_test.go -package $GOPACKAGE github.com/ChainSafe/gossamer/dot/telemetry Client - -func balanceKey(t *testing.T, pub []byte) (bKey []byte) { - t.Helper() - - h0, err := common.Twox128Hash([]byte("System")) - require.NoError(t, err) - bKey = append(bKey, h0...) - h1, err := common.Twox128Hash([]byte("Account")) - require.NoError(t, err) - bKey = append(bKey, h1...) - h2, err := common.Blake2b128(pub) - require.NoError(t, err) - bKey = append(bKey, h2...) - bKey = append(bKey, pub...) - return -} - -func generateTestValidRemarkTxns(t *testing.T, pubKey []byte, accInfo types.AccountInfo) ([]byte, RuntimeInstance) { - t.Helper() - projectRootPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t) - gen, err := genesis.NewGenesisFromJSONRaw(projectRootPath) - require.NoError(t, err) - - genesisTrie, err := wasmer.NewTrieFromGenesis(*gen) - require.NoError(t, err) - - genState := rtstorage.NewTrieState(&genesisTrie) - - nodeStorage := runtime.NodeStorage{ - BaseDB: runtime.NewInMemoryDB(t), - } - cfg := wasmer.Config{ - Storage: genState, - LogLvl: log.Error, - NodeStorage: nodeStorage, - } - - rt, err := wasmer.NewRuntimeFromGenesis(cfg) - require.NoError(t, err) - - aliceBalanceKey := balanceKey(t, pubKey) - encBal, err := scale.Marshal(accInfo) - require.NoError(t, err) - - rt.(*wasmer.Instance).GetContext().Storage.Set(aliceBalanceKey, encBal) - // this key is System.UpgradedToDualRefCount -> set to true since all accounts have been upgraded to v0.9 format - rt.(*wasmer.Instance).GetContext().Storage.Set(common.UpgradedToDualRefKey, []byte{1}) - - genesisHeader := &types.Header{ - Number: 0, - StateRoot: genesisTrie.MustHash(), - } - - // Hash of encrypted centrifuge extrinsic - testCallArguments := []byte{0xab, 0xcd} - extHex := runtime.NewTestExtrinsic(t, rt, genesisHeader.Hash(), genesisHeader.Hash(), - 0, "System.remark", testCallArguments) - - extBytes := common.MustHexToBytes(extHex) - const txnType = byte(types.TxnExternal) - extBytes = append([]byte{txnType}, extBytes...) - - runtime.InitializeRuntimeToTest(t, rt, genesisHeader.Hash()) - return extBytes, rt -} - func TestStartService(t *testing.T) { s := NewTestService(t, nil) @@ -408,9 +340,7 @@ func TestHandleChainReorg_WithReorg_Transactions(t *testing.T) { require.Equal(t, transaction.NewValidTransaction(tx, validity), pending[0]) } -// TODO: add test against latest gssmr runtime -// See https://github.com/ChainSafe/gossamer/issues/2702 -func TestMaintainTransactionPool_EmptyBlock(t *testing.T) { +func TestMaintainTransactionPoolLatestTxnQueue_EmptyBlock(t *testing.T) { accountInfo := types.AccountInfo{ Nonce: 0, Data: types.AccountData{ @@ -423,30 +353,23 @@ func TestMaintainTransactionPool_EmptyBlock(t *testing.T) { keyring, err := keystore.NewSr25519Keyring() require.NoError(t, err) alicePub := common.MustHexToBytes(keyring.Alice().Public().Hex()) - encExt, runtimeInstance := generateTestValidRemarkTxns(t, alicePub, accountInfo) - cfg := &Config{ - Runtime: runtimeInstance, - } + genesisFilePath, err := utils.GetGssmrGenesisRawPath() + require.NoError(t, err) ctrl := gomock.NewController(t) - telemetryMock := NewMockClient(ctrl) - telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() + service, encExt := CreateTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) - transactionState := state.NewTransactionState(telemetryMock) tx := &transaction.ValidTransaction{ Extrinsic: types.Extrinsic(encExt), Validity: &transaction.Validity{Priority: 1}, } - _ = transactionState.AddToPool(tx) - - service := NewTestService(t, cfg) - service.transactionState = transactionState + _ = service.transactionState.AddToPool(tx) // provides is a list of transaction hashes that depend on this tx, see: // https://github.com/paritytech/substrate/blob/5420de3face1349a97eb954ae71c5b0b940c31de/core/sr-primitives/src/transaction_validity.rs#L195 provides := common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d00000000") txnValidity := &transaction.Validity{ - Priority: 39325240425794630, + Priority: 36074, Provides: [][]byte{provides}, Longevity: 18446744073709551614, Propagate: true, @@ -458,17 +381,15 @@ func TestMaintainTransactionPool_EmptyBlock(t *testing.T) { Body: *types.NewBody([]types.Extrinsic{}), }) - resultTx := transactionState.Pop() + resultTx := service.transactionState.Pop() require.Equal(t, expectedTx, resultTx) - transactionState.RemoveExtrinsic(tx.Extrinsic) - head := transactionState.Pop() + service.transactionState.RemoveExtrinsic(tx.Extrinsic) + head := service.transactionState.Pop() require.Nil(t, head) } -// TODO: add test against latest gssmr runtime -// See https://github.com/ChainSafe/gossamer/issues/2702 -func TestMaintainTransactionPool_BlockWithExtrinsics(t *testing.T) { +func TestMaintainTransactionPoolLatestTxnQueue_BlockWithExtrinsics(t *testing.T) { accountInfo := types.AccountInfo{ Nonce: 0, Data: types.AccountData{ @@ -481,39 +402,30 @@ func TestMaintainTransactionPool_BlockWithExtrinsics(t *testing.T) { keyring, err := keystore.NewSr25519Keyring() require.NoError(t, err) alicePub := common.MustHexToBytes(keyring.Alice().Public().Hex()) - extrinsicBytes, _ := generateTestValidRemarkTxns(t, alicePub, accountInfo) + genesisFilePath, err := utils.GetGssmrGenesisRawPath() + require.NoError(t, err) ctrl := gomock.NewController(t) - telemetryMock := NewMockClient(ctrl) - telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - - ts := state.NewTransactionState(telemetryMock) + service, encExt := CreateTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) - // Maybe replace validity tx := &transaction.ValidTransaction{ - Extrinsic: types.Extrinsic(extrinsicBytes), + Extrinsic: types.Extrinsic(encExt), Validity: &transaction.Validity{Priority: 1}, } + _ = service.transactionState.AddToPool(tx) - ts.AddToPool(tx) - - s := &Service{ - transactionState: ts, - } - - s.maintainTransactionPool(&types.Block{ - Body: types.Body([]types.Extrinsic{extrinsicBytes}), + service.maintainTransactionPool(&types.Block{ + Body: types.Body([]types.Extrinsic{encExt}), }) res := []*transaction.ValidTransaction{} for { - tx := ts.Pop() + tx := service.transactionState.Pop() if tx == nil { break } res = append(res, tx) } - // Extrinsic is removed. so empty res require.Empty(t, res) } @@ -523,7 +435,6 @@ func TestService_GetRuntimeVersion(t *testing.T) { require.NoError(t, err) rtExpected := rt.Version() - rtv, err := s.GetRuntimeVersion(nil) require.NoError(t, err) require.Equal(t, rtExpected, rtv) @@ -554,7 +465,6 @@ func TestService_HandleSubmittedExtrinsic(t *testing.T) { require.NoError(t, err) extBytes := createExtrinsic(t, rt, genHeader.Hash(), 0) - err = s.HandleSubmittedExtrinsic(extBytes) require.NoError(t, err) } @@ -577,7 +487,6 @@ func TestService_HandleRuntimeChanges(t *testing.T) { require.NoError(t, err) v := rt.Version() - currSpecVersion := v.SpecVersion // genesis runtime version. hash := s.blockState.BestBlockHash() // genesisHash @@ -661,8 +570,7 @@ func TestService_HandleCodeSubstitutes(t *testing.T) { s.blockState.StoreRuntime(blockHash, rt) - ts := rtstorage.NewTrieState(nil) - + ts := rtstorage.NewTrieState(trie.NewEmptyTrie()) err = s.handleCodeSubstitution(blockHash, ts) require.NoError(t, err) codSub := s.codeSubstitutedState.LoadCodeSubstitutedBlockHash() @@ -689,8 +597,7 @@ func TestService_HandleRuntimeChangesAfterCodeSubstitutes(t *testing.T) { Body: *body, } - ts := rtstorage.NewTrieState(nil) - + ts := rtstorage.NewTrieState(trie.NewEmptyTrie()) err = s.handleCodeSubstitution(blockHash, ts) require.NoError(t, err) require.Equal(t, codeHashBefore, parentRt.GetCodeHash()) // codeHash should remain unchanged after code substitute diff --git a/dot/core/service_test.go b/dot/core/service_test.go index bb98124291..bda466c0d1 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -8,7 +8,6 @@ import ( "context" "encoding/hex" "errors" - "fmt" "testing" "github.com/ChainSafe/gossamer/dot/network" @@ -42,6 +41,7 @@ const ( specVersion = 25 implVersion = 0 transactionVersion = 0 + stateVersion = 0 ) func generateTestCentrifugeMetadata(t *testing.T) *ctypes.Metadata { @@ -112,7 +112,12 @@ func generateExtrinsic(t *testing.T) (extrinsic, externalExtrinsic types.Extrins require.NoError(t, err) encExt := []types.Extrinsic{extEnc.Bytes()} - testExternalExt := types.Extrinsic(append([]byte{byte(types.TxnExternal)}, encExt[0]...)) + testHeader := types.NewEmptyHeader() + testExternalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + encExt[0], + testHeader.StateRoot.ToBytes(), + })) testUnencryptedBody := types.NewBody(encExt) return encExt[0], testExternalExt, testUnencryptedBody } @@ -555,20 +560,46 @@ func Test_Service_maintainTransactionPool(t *testing.T) { Propagate: true, } - extrinsic := types.Extrinsic{21} - vt := transaction.NewValidTransaction(extrinsic, validity) + ext := types.Extrinsic{21} + externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + ext, + testHeader.StateRoot.ToBytes(), + })) + vt := transaction.NewValidTransaction(ext, validity) ctrl := gomock.NewController(t) runtimeMock := NewMockRuntimeInstance(ctrl) - runtimeMock.EXPECT().ValidateTransaction(types.Extrinsic{21}).Return(nil, errTestDummyError) + runtimeMock.EXPECT().ValidateTransaction(externalExt).Return(nil, errTestDummyError) + runtimeMock.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) + runtimeMock.EXPECT().SetContextStorage(&rtstorage.TrieState{}) + mockTxnState := NewMockTransactionState(ctrl) mockTxnState.EXPECT().RemoveExtrinsic(types.Extrinsic{21}).Times(2) mockTxnState.EXPECT().PendingInPool().Return([]*transaction.ValidTransaction{vt}) mockBlockState := NewMockBlockState(ctrl) - mockBlockState.EXPECT().GetRuntime(nil).Return(runtimeMock, nil) + mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) + + mockStorageState := NewMockStorageState(ctrl) + mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) + mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) service := &Service{ transactionState: mockTxnState, blockState: mockBlockState, + storageState: mockStorageState, } service.maintainTransactionPool(&block) }) @@ -589,24 +620,49 @@ func Test_Service_maintainTransactionPool(t *testing.T) { Propagate: true, } - extrinsic := types.Extrinsic{21} - vt := transaction.NewValidTransaction(extrinsic, validity) - tx := transaction.NewValidTransaction(types.Extrinsic{21}, &transaction.Validity{Propagate: true}) + ext := types.Extrinsic{21} + externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + ext, + testHeader.StateRoot.ToBytes(), + })) + vt := transaction.NewValidTransaction(ext, validity) + tx := transaction.NewValidTransaction(ext, &transaction.Validity{Propagate: true}) ctrl := gomock.NewController(t) runtimeMock := NewMockRuntimeInstance(ctrl) - runtimeMock.EXPECT().ValidateTransaction(types.Extrinsic{21}). - Return(&transaction.Validity{Propagate: true}, nil) + runtimeMock.EXPECT().ValidateTransaction(externalExt).Return(&transaction.Validity{Propagate: true}, nil) + runtimeMock.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) + runtimeMock.EXPECT().SetContextStorage(&rtstorage.TrieState{}) mockTxnState := NewMockTransactionState(ctrl) mockTxnState.EXPECT().RemoveExtrinsic(types.Extrinsic{21}) mockTxnState.EXPECT().PendingInPool().Return([]*transaction.ValidTransaction{vt}) mockTxnState.EXPECT().Push(tx).Return(common.Hash{}, nil) mockTxnState.EXPECT().RemoveExtrinsicFromPool(types.Extrinsic{21}) + mockBlockStateOk := NewMockBlockState(ctrl) - mockBlockStateOk.EXPECT().GetRuntime(nil).Return(runtimeMock, nil) + mockBlockStateOk.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) + mockBlockStateOk.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) + + mockStorageState := NewMockStorageState(ctrl) + mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) + mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) service := &Service{ transactionState: mockTxnState, blockState: mockBlockStateOk, + storageState: mockStorageState, } service.maintainTransactionPool(&block) }) @@ -676,29 +732,55 @@ func Test_Service_handleBlocksAsync(t *testing.T) { } extrinsic := types.Extrinsic{21} + testHeader := types.NewEmptyHeader() + externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + extrinsic, + testHeader.StateRoot.ToBytes(), + })) vt := transaction.NewValidTransaction(extrinsic, validity) - testHeader := types.NewEmptyHeader() block := types.NewBlock(*testHeader, *types.NewBody([]types.Extrinsic{[]byte{21}})) block.Header.Number = 21 ctrl := gomock.NewController(t) runtimeMock := NewMockRuntimeInstance(ctrl) - runtimeMock.EXPECT().ValidateTransaction(types.Extrinsic{21}).Return(nil, errTestDummyError) + runtimeMock.EXPECT().ValidateTransaction(externalExt).Return(nil, errTestDummyError) + runtimeMock.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) + runtimeMock.EXPECT().SetContextStorage(&rtstorage.TrieState{}) mockBlockState := NewMockBlockState(ctrl) mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) mockBlockState.EXPECT().HighestCommonAncestor(common.Hash{}, block.Header.Hash()). Return(common.Hash{}, errTestDummyError) - mockBlockState.EXPECT().GetRuntime(nil).Return(runtimeMock, nil) + mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) + mockTxnStateErr := NewMockTransactionState(ctrl) mockTxnStateErr.EXPECT().RemoveExtrinsic(types.Extrinsic{21}).Times(2) mockTxnStateErr.EXPECT().PendingInPool().Return([]*transaction.ValidTransaction{vt}) + + mockStorageState := NewMockStorageState(ctrl) + mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) + mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) blockAddChan := make(chan *types.Block) go func() { blockAddChan <- &block close(blockAddChan) }() service := &Service{ + storageState: mockStorageState, blockState: mockBlockState, transactionState: mockTxnStateErr, blockAddCh: blockAddChan, @@ -813,7 +895,23 @@ func TestService_handleChainReorg(t *testing.T) { t.Run("invalid transaction", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + runtimeMockErr := NewMockRuntimeInstance(ctrl) + runtimeMockErr.EXPECT().ValidateTransaction(externExt).Return(nil, errTestDummyError) + runtimeMockErr.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) + mockBlockState := NewMockBlockState(ctrl) mockBlockState.EXPECT().HighestCommonAncestor(testPrevHash, testCurrentHash). Return(testAncestorHash, nil) @@ -821,7 +919,7 @@ func TestService_handleChainReorg(t *testing.T) { mockBlockState.EXPECT().GetRuntime(nil).Return(runtimeMockErr, nil) mockBlockState.EXPECT().GetBlockBody(testCurrentHash).Return(nil, errDummyErr) mockBlockState.EXPECT().GetBlockBody(testAncestorHash).Return(body, nil) - runtimeMockErr.EXPECT().ValidateTransaction(externExt).Return(nil, errTestDummyError) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) service := &Service{ blockState: mockBlockState, @@ -833,6 +931,21 @@ func TestService_handleChainReorg(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) runtimeMockOk := NewMockRuntimeInstance(ctrl) + runtimeMockOk.EXPECT().ValidateTransaction(externExt).Return(testValidity, nil) + runtimeMockOk.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) + mockBlockState := NewMockBlockState(ctrl) mockBlockState.EXPECT().HighestCommonAncestor(testPrevHash, testCurrentHash). Return(testAncestorHash, nil) @@ -840,7 +953,7 @@ func TestService_handleChainReorg(t *testing.T) { mockBlockState.EXPECT().GetRuntime(nil).Return(runtimeMockOk, nil) mockBlockState.EXPECT().GetBlockBody(testCurrentHash).Return(nil, errDummyErr) mockBlockState.EXPECT().GetBlockBody(testAncestorHash).Return(body, nil) - runtimeMockOk.EXPECT().ValidateTransaction(externExt).Return(testValidity, nil) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockTxnStateOk := NewMockTransactionState(ctrl) mockTxnStateOk.EXPECT().AddToPool(vtx).Return(common.Hash{}) @@ -1091,8 +1204,12 @@ func TestServiceGetRuntimeVersion(t *testing.T) { func TestServiceHandleSubmittedExtrinsic(t *testing.T) { t.Parallel() ext := types.Extrinsic{} - externalExt := types.Extrinsic(append([]byte{byte(types.TxnExternal)}, ext...)) - fmt.Println(ext) + testHeader := types.NewEmptyHeader() + externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + {byte(types.TxnExternal)}, + ext, + testHeader.StateRoot.ToBytes(), + })) execTest := func(t *testing.T, s *Service, ext types.Extrinsic, expErr error) { err := s.HandleSubmittedExtrinsic(ext) assert.ErrorIs(t, err, expErr) @@ -1157,6 +1274,7 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) runtimeMockErr := NewMockRuntimeInstance(ctrl) mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMockErr, nil).MaxTimes(2) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) @@ -1165,8 +1283,21 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { mockTxnState := NewMockTransactionState(ctrl) mockTxnState.EXPECT().Exists(types.Extrinsic{}) - runtimeMockErr.EXPECT().SetContextStorage(&rtstorage.TrieState{}) runtimeMockErr.EXPECT().ValidateTransaction(externalExt).Return(nil, errDummyErr) + runtimeMockErr.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) + runtimeMockErr.EXPECT().SetContextStorage(&rtstorage.TrieState{}) service := &Service{ storageState: mockStorageState, transactionState: mockTxnState, @@ -1184,8 +1315,23 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { mockBlockState := NewMockBlockState(ctrl) mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil).MaxTimes(2) - runtimeMock.EXPECT().SetContextStorage(&rtstorage.TrieState{}) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) + runtimeMock.EXPECT().ValidateTransaction(externalExt).Return(&transaction.Validity{Propagate: true}, nil) + runtimeMock.EXPECT().Version().Return(runtime.Version{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Ver: 3, + }}, + TransactionVersion: transactionVersion, + StateVersion: stateVersion, + }) + runtimeMock.EXPECT().SetContextStorage(&rtstorage.TrieState{}) mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) diff --git a/dot/digest/digest_test.go b/dot/digest/digest_test.go index a61e82da49..23f3a005d3 100644 --- a/dot/digest/digest_test.go +++ b/dot/digest/digest_test.go @@ -39,8 +39,8 @@ func newTestHandler(t *testing.T) (*Handler, *state.Service) { stateSrvc := state.NewService(config) stateSrvc.UseMemDB() - gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) - err := stateSrvc.Initialise(&gen, &genesisHeader, &genesisTrie) + gen, genTrie, genHeader := newTestGenesisWithTrieAndHeader(t) + err := stateSrvc.Initialise(&gen, &genHeader, &genTrie) require.NoError(t, err) err = stateSrvc.SetupBase() diff --git a/dot/node.go b/dot/node.go index 561f01925c..0aa5ff4510 100644 --- a/dot/node.go +++ b/dot/node.go @@ -32,7 +32,6 @@ import ( "github.com/ChainSafe/gossamer/lib/grandpa" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime" - "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/services" "github.com/ChainSafe/gossamer/lib/utils" ) @@ -145,13 +144,13 @@ func (*nodeBuilder) initNode(cfg *Config) error { } // create trie from genesis - t, err := wasmer.NewTrieFromGenesis(*gen) + t, err := genesis.NewTrieFromGenesis(gen) if err != nil { return fmt.Errorf("failed to create trie from genesis: %w", err) } // create genesis block from trie - header, err := t.GenesisBlock() + header, err := genesis.NewGenesisBlockFromTrie(t) if err != nil { return fmt.Errorf("failed to create genesis block from trie: %w", err) } @@ -176,7 +175,7 @@ func (*nodeBuilder) initNode(cfg *Config) error { stateSrvc := state.NewService(config) // initialise state service with genesis data, block, and trie - err = stateSrvc.Initialise(gen, &header, &t) + err = stateSrvc.Initialise(gen, header, t) if err != nil { return fmt.Errorf("failed to initialise state service: %s", err) } diff --git a/dot/node_test.go b/dot/node_test.go index ce9be33a55..bbd5a0de80 100644 --- a/dot/node_test.go +++ b/dot/node_test.go @@ -166,17 +166,17 @@ func TestNewNode(t *testing.T) { return nil, fmt.Errorf("failed to load genesis from file: %w", err) } // create trie from genesis - trie, err := wasmer.NewTrieFromGenesis(*gen) + trie, err := genesis.NewTrieFromGenesis(gen) if err != nil { return nil, fmt.Errorf("failed to create trie from genesis: %w", err) } // create genesis block from trie - header, err := trie.GenesisBlock() + header, err := genesis.NewGenesisBlockFromTrie(trie) if err != nil { return nil, fmt.Errorf("failed to create genesis block from trie: %w", err) } stateSrvc.Telemetry = mockTelemetryClient - err = stateSrvc.Initialise(gen, &header, &trie) + err = stateSrvc.Initialise(gen, header, trie) if err != nil { return nil, fmt.Errorf("failed to initialise state service: %s", err) } diff --git a/dot/rpc/http_test.go b/dot/rpc/http_test.go index e92fda121a..a3fbf3122d 100644 --- a/dot/rpc/http_test.go +++ b/dot/rpc/http_test.go @@ -364,7 +364,7 @@ func newCoreServiceTest(t *testing.T) *core.Service { testDatadirPath := t.TempDir() - gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + gen, genTrie, genHeader := newTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -379,7 +379,7 @@ func newCoreServiceTest(t *testing.T) *core.Service { stateSrvc := state.NewService(config) stateSrvc.UseMemDB() - err := stateSrvc.Initialise(&gen, &genesisHeader, &genesisTrie) + err := stateSrvc.Initialise(&gen, &genHeader, &genTrie) require.NoError(t, err) err = stateSrvc.SetupBase() @@ -406,7 +406,7 @@ func newCoreServiceTest(t *testing.T) *core.Service { var rtCfg wasmer.Config - rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) + rtCfg.Storage = rtstorage.NewTrieState(&genTrie) rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) require.NoError(t, err) diff --git a/dot/rpc/modules/author_integration_test.go b/dot/rpc/modules/author_integration_test.go index 7aac7a3b26..1462dba4b0 100644 --- a/dot/rpc/modules/author_integration_test.go +++ b/dot/rpc/modules/author_integration_test.go @@ -29,6 +29,10 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/transaction" "github.com/ChainSafe/gossamer/lib/trie" + "github.com/ChainSafe/gossamer/pkg/scale" + "github.com/centrifuge/go-substrate-rpc-client/v4/signature" + ctypes "github.com/centrifuge/go-substrate-rpc-client/v4/types" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -79,6 +83,47 @@ func useInstanceFromRuntimeV0910(t *testing.T, rtStorage *storage.TrieState) (in return runtimeInstance } +func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, nonce uint64) types.Extrinsic { + t.Helper() + rawMeta, err := rt.Metadata() + require.NoError(t, err) + + var decoded []byte + err = scale.Unmarshal(rawMeta, &decoded) + require.NoError(t, err) + + meta := &ctypes.Metadata{} + + err = ctypes.Decode(decoded, meta) + require.NoError(t, err) + + rv := rt.Version() + + c, err := ctypes.NewCall(meta, "System.remark", []byte{0xab, 0xcd}) + require.NoError(t, err) + + ext := ctypes.NewExtrinsic(c) + options := ctypes.SignatureOptions{ + BlockHash: ctypes.Hash(genHash), + Era: ctypes.ExtrinsicEra{IsImmortalEra: false}, + GenesisHash: ctypes.Hash(genHash), + Nonce: ctypes.NewUCompactFromUInt(nonce), + SpecVersion: ctypes.U32(rv.SpecVersion), + Tip: ctypes.NewUCompactFromUInt(0), + TransactionVersion: ctypes.U32(rv.TransactionVersion), + } + + // Sign the transaction using Alice's key + err = ext.Sign(signature.TestKeyringPairAlice, options) + require.NoError(t, err) + + extEnc, err := ctypes.EncodeToHex(ext) + require.NoError(t, err) + + extBytes := types.Extrinsic(common.MustHexToBytes(extEnc)) + return extBytes +} + func TestAuthorModule_Pending_Integration(t *testing.T) { t.Parallel() integrationTestController := setupStateAndRuntime(t, t.TempDir(), nil) @@ -218,6 +263,7 @@ func TestAuthorModule_SubmitExtrinsic_AlreadyInPool(t *testing.T) { // creating an extrisinc to the System.remark call using a sample argument extHex := runtime.NewTestExtrinsic(t, integrationTestController.runtime, genesisHash, genesisHash, 0, "System.remark", []byte{}) + fmt.Println(extHex) extBytes := common.MustHexToBytes(extHex) integrationTestController.storageState = &state.StorageState{} @@ -510,19 +556,11 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { integrationTestController.stateSrv.Transaction = state.NewTransactionState(telemetryMock) genesisHash := integrationTestController.genesisHeader.Hash() - - extHex := runtime.NewTestExtrinsic(t, - integrationTestController.runtime, genesisHash, genesisHash, 1, "System.remark", []byte{0xab, 0xcd}) - - // to extrinsic works with a runtime version 0910 we need to - // append the block hash bytes at the end of the extrinsics - hashBytes := genesisHash.ToBytes() - extBytes := append(common.MustHexToBytes(extHex), hashBytes...) - - extHex = common.BytesToHex(extBytes) + ext := createExtrinsic(t, integrationTestController.runtime, genesisHash, 0) + extHex := common.BytesToHex(ext) net2test := NewMockNetwork(ctrl) - net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{extBytes}}) + net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{ext}}) integrationTestController.network = net2test // setup auth module @@ -532,16 +570,13 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { err := auth.SubmitExtrinsic(nil, &Extrinsic{extHex}, res) require.NoError(t, err) - expectedExtrinsic := types.NewExtrinsic(extBytes) + expectedExtrinsic := types.NewExtrinsic(ext) expected := &transaction.ValidTransaction{ Extrinsic: expectedExtrinsic, Validity: &transaction.Validity{ Priority: 4295664014726, - Requires: [][]byte{ - common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d00000000"), - }, Provides: [][]byte{ - common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000"), + common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d00000000"), }, Longevity: 18446744073709551613, Propagate: true, @@ -571,7 +606,7 @@ type integrationTestController struct { func setupStateAndRuntime(t *testing.T, basepath string, useInstance useRuntimeInstace) *integrationTestController { t.Helper() - gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + gen, genTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -591,7 +626,7 @@ func setupStateAndRuntime(t *testing.T, basepath string, useInstance useRuntimeI state2test.UseMemDB() state2test.Transaction = state.NewTransactionState(telemetryMock) - err := state2test.Initialise(&gen, &genesisHeader, &genesisTrie) + err := state2test.Initialise(&gen, &genesisHeader, &genTrie) require.NoError(t, err) err = state2test.Start() @@ -605,7 +640,7 @@ func setupStateAndRuntime(t *testing.T, basepath string, useInstance useRuntimeI net2test := NewMockNetwork(nil) integrationTestController := &integrationTestController{ genesis: &gen, - genesisTrie: &genesisTrie, + genesisTrie: &genTrie, genesisHeader: &genesisHeader, stateSrv: state2test, storageState: state2test.Storage, @@ -631,7 +666,7 @@ func setupStateAndPopulateTrieState(t *testing.T, basepath string, useInstance useRuntimeInstace) *integrationTestController { t.Helper() - gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + gen, genTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -652,7 +687,7 @@ func setupStateAndPopulateTrieState(t *testing.T, basepath string, state2test.Transaction = state.NewTransactionState(telemetryMock) - err := state2test.Initialise(&gen, &genesisHeader, &genesisTrie) + err := state2test.Initialise(&gen, &genesisHeader, &genTrie) require.NoError(t, err) err = state2test.Start() @@ -666,7 +701,7 @@ func setupStateAndPopulateTrieState(t *testing.T, basepath string, ks := keystore.NewGlobalKeystore() integrationTestController := &integrationTestController{ genesis: &gen, - genesisTrie: &genesisTrie, + genesisTrie: &genTrie, genesisHeader: &genesisHeader, stateSrv: state2test, storageState: state2test.Storage, diff --git a/dot/rpc/modules/childstate_test.go b/dot/rpc/modules/childstate_test.go index b9d8b2ecc4..3f7d1c2c22 100644 --- a/dot/rpc/modules/childstate_test.go +++ b/dot/rpc/modules/childstate_test.go @@ -20,8 +20,8 @@ import ( func createTestTrieState(t *testing.T) (*trie.Trie, common.Hash) { t.Helper() - _, genesisTrie, _ := newTestGenesisWithTrieAndHeader(t) - tr := rtstorage.NewTrieState(&genesisTrie) + _, genTrie, _ := newTestGenesisWithTrieAndHeader(t) + tr := rtstorage.NewTrieState(&genTrie) tr.Set([]byte(":first_key"), []byte(":value1")) tr.Set([]byte(":second_key"), []byte(":second_value")) diff --git a/dot/rpc/modules/helpers_test.go b/dot/rpc/modules/helpers_test.go index 61bc9260a6..18e4060baa 100644 --- a/dot/rpc/modules/helpers_test.go +++ b/dot/rpc/modules/helpers_test.go @@ -3,8 +3,6 @@ package modules import ( - "testing" - "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/genesis" @@ -12,6 +10,7 @@ import ( "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" "github.com/stretchr/testify/require" + "testing" ) func stringToHex(s string) (hex string) { diff --git a/dot/state/block_data_test.go b/dot/state/block_data_test.go index 370282850b..a07606bb05 100644 --- a/dot/state/block_data_test.go +++ b/dot/state/block_data_test.go @@ -14,7 +14,7 @@ import ( ) func TestGetSet_ReceiptMessageQueue_Justification(t *testing.T) { - s := newTestBlockState(t, newTriesEmpty()) + s := newTestBlockState(t, nil, newTriesEmpty()) var genesisHeader = &types.Header{ Number: 0, diff --git a/dot/state/block_finalisation_test.go b/dot/state/block_finalisation_test.go index aa62f591a4..2cc0afb980 100644 --- a/dot/state/block_finalisation_test.go +++ b/dot/state/block_finalisation_test.go @@ -14,7 +14,7 @@ import ( ) func TestHighestRoundAndSetID(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) round, setID, err := bs.GetHighestRoundAndSetID() require.NoError(t, err) require.Equal(t, uint64(0), round) @@ -62,7 +62,7 @@ func TestHighestRoundAndSetID(t *testing.T) { } func TestBlockState_SetFinalisedHash(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) h, err := bs.GetFinalisedHash(0, 0) require.NoError(t, err) require.Equal(t, testGenesisHeader.Hash(), h) @@ -104,7 +104,7 @@ func TestBlockState_SetFinalisedHash(t *testing.T) { } func TestSetFinalisedHash_setFirstSlotOnFinalisation(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) firstSlot := uint64(42069) digest := types.NewDigest() diff --git a/dot/state/block_notify_test.go b/dot/state/block_notify_test.go index a8bf3c639c..2b7b827af7 100644 --- a/dot/state/block_notify_test.go +++ b/dot/state/block_notify_test.go @@ -16,7 +16,7 @@ import ( var testMessageTimeout = time.Second * 3 func TestImportChannel(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) ch := bs.GetImportedBlockNotifierChannel() defer bs.FreeImportedBlockNotifierChannel(ch) @@ -33,7 +33,7 @@ func TestImportChannel(t *testing.T) { } func TestFreeImportedBlockNotifierChannel(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) ch := bs.GetImportedBlockNotifierChannel() require.Equal(t, 1, len(bs.imported)) @@ -42,7 +42,7 @@ func TestFreeImportedBlockNotifierChannel(t *testing.T) { } func TestFinalizedChannel(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) ch := bs.GetFinalisedNotifierChannel() @@ -64,7 +64,7 @@ func TestFinalizedChannel(t *testing.T) { } func TestImportChannel_Multi(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) num := 5 chs := make([]chan *types.Block, num) @@ -96,7 +96,7 @@ func TestImportChannel_Multi(t *testing.T) { } func TestFinalizedChannel_Multi(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) num := 5 chs := make([]chan *types.FinalisationInfo, num) @@ -133,7 +133,7 @@ func TestFinalizedChannel_Multi(t *testing.T) { } func TestService_RegisterUnRegisterRuntimeUpdatedChannel(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) ch := make(chan<- runtime.Version) chID, err := bs.RegisterRuntimeUpdatedChannel(ch) require.NoError(t, err) @@ -144,7 +144,7 @@ func TestService_RegisterUnRegisterRuntimeUpdatedChannel(t *testing.T) { } func TestService_RegisterUnRegisterConcurrentCalls(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) go func() { for i := 0; i < 100; i++ { diff --git a/dot/state/block_test.go b/dot/state/block_test.go index e437a674b2..e665c8cdea 100644 --- a/dot/state/block_test.go +++ b/dot/state/block_test.go @@ -24,13 +24,15 @@ var testGenesisHeader = &types.Header{ Digest: types.NewDigest(), } -func newTestBlockState(t *testing.T, tries *Tries) *BlockState { +func newTestBlockState(t *testing.T, header *types.Header, tries *Tries) *BlockState { ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() db := NewInMemoryDB(t) - header := testGenesisHeader + if header == nil { + header = testGenesisHeader + } bs, err := NewBlockStateFromGenesis(db, tries, header, telemetryMock) require.NoError(t, err) @@ -46,7 +48,7 @@ func newTestBlockState(t *testing.T, tries *Tries) *BlockState { } func TestSetAndGetHeader(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, nil, newTriesEmpty()) header := &types.Header{ Number: 0, @@ -63,7 +65,7 @@ func TestSetAndGetHeader(t *testing.T) { } func TestHasHeader(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, nil, newTriesEmpty()) header := &types.Header{ Number: 0, @@ -80,7 +82,7 @@ func TestHasHeader(t *testing.T) { } func TestGetBlockByNumber(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) blockHeader := &types.Header{ ParentHash: testGenesisHeader.Hash(), @@ -102,7 +104,7 @@ func TestGetBlockByNumber(t *testing.T) { } func TestAddBlock(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) // Create header header0 := &types.Header{ @@ -165,7 +167,7 @@ func TestAddBlock(t *testing.T) { } func TestGetSlotForBlock(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) expectedSlot := uint64(77) babeHeader := types.NewBabeDigest() @@ -196,7 +198,7 @@ func TestGetSlotForBlock(t *testing.T) { } func TestIsBlockOnCurrentChain(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) currChain, branchChains := AddBlocksToState(t, bs, 3, false) for _, header := range currChain { @@ -219,7 +221,7 @@ func TestIsBlockOnCurrentChain(t *testing.T) { } func TestAddBlock_BlockNumberToHash(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) currChain, branchChains := AddBlocksToState(t, bs, 8, false) bestHash := bs.BestBlockHash() @@ -267,7 +269,7 @@ func TestAddBlock_BlockNumberToHash(t *testing.T) { } func TestFinalization_DeleteBlock(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) AddBlocksToState(t, bs, 5, false) btBefore := bs.bt.DeepCopy() @@ -322,7 +324,7 @@ func TestFinalization_DeleteBlock(t *testing.T) { } func TestGetHashByNumber(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) res, err := bs.GetHashByNumber(0) require.NoError(t, err) @@ -349,7 +351,7 @@ func TestGetHashByNumber(t *testing.T) { func TestAddBlock_WithReOrg(t *testing.T) { t.Skip() // TODO: this should be fixed after state refactor PR - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) header1a := &types.Header{ Number: 1, @@ -458,7 +460,7 @@ func TestAddBlock_WithReOrg(t *testing.T) { } func TestAddBlockToBlockTree(t *testing.T) { - bs := newTestBlockState(t, newTriesEmpty()) + bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) header := &types.Header{ Number: 1, @@ -480,7 +482,7 @@ func TestAddBlockToBlockTree(t *testing.T) { func TestNumberIsFinalised(t *testing.T) { tries := newTriesEmpty() - bs := newTestBlockState(t, tries) + bs := newTestBlockState(t, testGenesisHeader, tries) fin, err := bs.NumberIsFinalised(0) require.NoError(t, err) require.True(t, fin) diff --git a/dot/state/epoch_test.go b/dot/state/epoch_test.go index aa0a0903e5..75b4736560 100644 --- a/dot/state/epoch_test.go +++ b/dot/state/epoch_test.go @@ -29,7 +29,7 @@ var genesisBABEConfig = &types.BabeConfiguration{ func newEpochStateFromGenesis(t *testing.T) *EpochState { db := NewInMemoryDB(t) - blockState := newTestBlockState(t, newTriesEmpty()) + blockState := newTestBlockState(t, nil, newTriesEmpty()) s, err := NewEpochStateFromGenesis(db, blockState, genesisBABEConfig) require.NoError(t, err) return s @@ -183,7 +183,7 @@ func TestEpochState_SetAndGetSlotDuration(t *testing.T) { func TestEpochState_GetEpochFromTime(t *testing.T) { s := newEpochStateFromGenesis(t) - s.blockState = newTestBlockState(t, newTriesEmpty()) + s.blockState = newTestBlockState(t, testGenesisHeader, newTriesEmpty()) epochDuration, err := time.ParseDuration( fmt.Sprintf("%dms", diff --git a/dot/state/initialize.go b/dot/state/initialize.go index 565e30fb72..465bc19010 100644 --- a/dot/state/initialize.go +++ b/dot/state/initialize.go @@ -10,7 +10,6 @@ import ( "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/state/pruner" "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/genesis" "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" @@ -125,8 +124,7 @@ func (s *Service) loadBabeConfigurationFromRuntime(r runtime.Instance) (*types.B } func loadGrandpaAuthorities(t *trie.Trie) ([]types.GrandpaVoter, error) { - key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) - authsRaw := t.Get(key) + authsRaw := t.Get(runtime.GrandpaAuthoritiesKey) if authsRaw == nil { return []types.GrandpaVoter{}, nil } diff --git a/dot/state/storage_notify_test.go b/dot/state/storage_notify_test.go index 39cf2dbd6b..cd065d79df 100644 --- a/dot/state/storage_notify_test.go +++ b/dot/state/storage_notify_test.go @@ -18,7 +18,7 @@ import ( ) func TestStorageState_RegisterStorageObserver(t *testing.T) { - ss := newTestStorageState(t) + ss := newTestStorageState(t, newTriesEmpty()) ts, err := ss.TrieState(nil) require.NoError(t, err) @@ -57,7 +57,7 @@ func TestStorageState_RegisterStorageObserver(t *testing.T) { } func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) { - ss := newTestStorageState(t) + ss := newTestStorageState(t, newTriesEmpty()) ts, err := ss.TrieState(nil) require.NoError(t, err) @@ -95,7 +95,7 @@ func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) { func TestStorageState_RegisterStorageObserver_Multi_Filter(t *testing.T) { t.Skip() // this seems to fail often on CI - ss := newTestStorageState(t) + ss := newTestStorageState(t, newTriesEmpty()) ts, err := ss.TrieState(nil) require.NoError(t, err) diff --git a/dot/state/storage_test.go b/dot/state/storage_test.go index 968a16fad0..9b3a58a14d 100644 --- a/dot/state/storage_test.go +++ b/dot/state/storage_test.go @@ -20,11 +20,10 @@ import ( "github.com/stretchr/testify/require" ) -func newTestStorageState(t *testing.T) *StorageState { +func newTestStorageState(t *testing.T, tries *Tries) *StorageState { db := NewInMemoryDB(t) - tries := newTriesEmpty() - bs := newTestBlockState(t, tries) + bs := newTestBlockState(t, testGenesisHeader, tries) s, err := NewStorageState(db, bs, tries, pruner.Config{}) require.NoError(t, err) @@ -32,7 +31,7 @@ func newTestStorageState(t *testing.T) *StorageState { } func TestStorage_StoreAndLoadTrie(t *testing.T) { - storage := newTestStorageState(t) + storage := newTestStorageState(t, newTriesEmpty()) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) @@ -51,7 +50,7 @@ func TestStorage_StoreAndLoadTrie(t *testing.T) { } func TestStorage_GetStorageByBlockHash(t *testing.T) { - storage := newTestStorageState(t) + storage := newTestStorageState(t, newTriesEmpty()) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) @@ -86,7 +85,7 @@ func TestStorage_GetStorageByBlockHash(t *testing.T) { } func TestStorage_TrieState(t *testing.T) { - storage := newTestStorageState(t) + storage := newTestStorageState(t, newTriesEmpty()) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) ts.Set([]byte("noot"), []byte("washere")) @@ -106,7 +105,7 @@ func TestStorage_TrieState(t *testing.T) { } func TestStorage_LoadFromDB(t *testing.T) { - storage := newTestStorageState(t) + storage := newTestStorageState(t, newTriesEmpty()) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) @@ -151,7 +150,7 @@ func TestStorage_LoadFromDB(t *testing.T) { } func TestStorage_StoreTrie_NotSyncing(t *testing.T) { - storage := newTestStorageState(t) + storage := newTestStorageState(t, newTriesEmpty()) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) diff --git a/go.mod b/go.mod index af8a55f058..c56325c624 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/docker/docker v20.10.19+incompatible github.com/ethereum/go-ethereum v1.10.25 github.com/fatih/color v1.13.0 - github.com/go-playground/validator/v10 v10.11.1 + github.com/go-playground/validator/v10 v10.11.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 github.com/google/go-cmp v0.5.9 diff --git a/go.sum b/go.sum index 61775c2ac2..98652acffe 100644 --- a/go.sum +++ b/go.sum @@ -260,8 +260,8 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= -github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= +github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= diff --git a/lib/babe/verify_integration_test.go b/lib/babe/verify_integration_test.go index 4bb37dfd12..e93b8853b8 100644 --- a/lib/babe/verify_integration_test.go +++ b/lib/babe/verify_integration_test.go @@ -19,6 +19,7 @@ import ( "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/sr25519" + "github.com/ChainSafe/gossamer/lib/genesis" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/golang/mock/gomock" @@ -41,8 +42,8 @@ func newTestVerificationManager(t *testing.T, genCfg *types.BabeConfiguration) * dbSrv := state.NewService(config) dbSrv.UseMemDB() - gen, genesisTrie, genesisHeader := newDevGenesisWithTrieAndHeader(t) - err := dbSrv.Initialise(&gen, &genesisHeader, &genesisTrie) + gen, genTrie, genHeader := genesis.NewDevGenesisWithTrieAndHeader(t) + err := dbSrv.Initialise(gen, genHeader, genTrie) require.NoError(t, err) err = dbSrv.Start() @@ -498,7 +499,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { SecondarySlots: 0, } - genesis, trie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + genesis, trie, genesisHeader := genesis.NewTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -516,7 +517,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { stateService.UseMemDB() - err := stateService.Initialise(&genesis, &genesisHeader, &trie) + err := stateService.Initialise(genesis, genesisHeader, trie) require.NoError(t, err) inMemoryDB, err := chaindb.NewBadgerDB(&chaindb.Config{ @@ -546,7 +547,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { C2: 10, SecondarySlots: 1, } - aliceBlockHeader := issueConsensusDigestsBlockFromGenesis(t, &genesisHeader, keyring.KeyAlice, + aliceBlockHeader := issueConsensusDigestsBlockFromGenesis(t, genesisHeader, keyring.KeyAlice, stateService, aliceBlockNextEpoch, aliceBlockNextConfigData) bobBlockNextEpoch := types.NextEpochData{ @@ -557,7 +558,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { C2: 8, SecondarySlots: 1, } - bobBlockHeader := issueConsensusDigestsBlockFromGenesis(t, &genesisHeader, keyring.KeyBob, + bobBlockHeader := issueConsensusDigestsBlockFromGenesis(t, genesisHeader, keyring.KeyBob, stateService, bobBlockNextEpoch, bobBlockNextConfigData) // wait for digest handleBlockImport goroutine gets the imported diff --git a/lib/blocktree/hashtoruntime_test.go b/lib/blocktree/hashtoruntime_test.go index d5af93fa56..74f0f1c7ac 100644 --- a/lib/blocktree/hashtoruntime_test.go +++ b/lib/blocktree/hashtoruntime_test.go @@ -25,8 +25,6 @@ func Test_newHashToRuntime(t *testing.T) { assert.Equal(t, expected, hti) } -//go:generate mockgen -destination=mock_instance_test.go -package $GOPACKAGE github.com/ChainSafe/gossamer/lib/runtime Instance - func Test_hashToRuntime_get(t *testing.T) { t.Parallel() diff --git a/lib/blocktree/mocks_generate_test.go b/lib/blocktree/mocks_generate_test.go new file mode 100644 index 0000000000..7c0666c0d2 --- /dev/null +++ b/lib/blocktree/mocks_generate_test.go @@ -0,0 +1,6 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package blocktree + +//go:generate mockgen -destination=mock_instance_test.go -package $GOPACKAGE github.com/ChainSafe/gossamer/lib/runtime Instance diff --git a/lib/genesis/genesis_test.go b/lib/genesis/genesis_test.go index fd1ea6b213..844bddfbad 100644 --- a/lib/genesis/genesis_test.go +++ b/lib/genesis/genesis_test.go @@ -9,56 +9,44 @@ import ( "github.com/stretchr/testify/require" ) -func Test_interfaceToTelemetryEndpoint(t *testing.T) { - t.Parallel() - - testCases := map[string]struct { - endpoints []interface{} - expected []*TelemetryEndpoint +func TestInterfaceToTelemetryEndpoint(t *testing.T) { + testcases := []struct { + description string + values []interface{} + expected []*TelemetryEndpoint }{ - "sub element not a slice": { - endpoints: []interface{}{ - struct{}{}, - }, - }, - "wrong interface type": { - endpoints: []interface{}{ - []interface{}{"string"}, - }, + { + "Test with wrong interface type", + []interface{}{"string"}, + nil, }, - "wrong interface field length": { - endpoints: []interface{}{ - []interface{}{"wss://telemetry.polkadot.io/submit/"}, - }, + { + "Test with interface field len != 2", + append(testEndpoints, []interface{}{"wss://telemetry.polkadot.io/submit/"}), + nil, }, - "wrong interface field position": { - endpoints: []interface{}{ - []interface{}{float64(0), "wss://telemetry.polkadot.io/submit/"}, - }, + { + "Test with interface field 0 wrong type", + append(testEndpoints, []interface{}{float32(0), "wss://telemetry.polkadot.io/submit/"}), + nil, }, - "interface field 1 wrong type": { - endpoints: []interface{}{ - []interface{}{"wss://telemetry.polkadot.io/submit/", "1"}, - }, + { + "Test with interface field 1 wrong type", + append(testEndpoints, []interface{}{"wss://telemetry.polkadot.io/submit/", "1"}), + nil, }, - "success": { - endpoints: []interface{}{ - []interface{}{"wss://telemetry.polkadot.io/submit/", float64(1)}, - }, - expected: []*TelemetryEndpoint{{ + { + "Test with correctly formed values", + append(testEndpoints, testEndpoint1), + append([]*TelemetryEndpoint{}, &TelemetryEndpoint{ Endpoint: "wss://telemetry.polkadot.io/submit/", Verbosity: 1, - }}, + }), }, } - for name, testCase := range testCases { - testCase := testCase - t.Run(name, func(t *testing.T) { - t.Parallel() - - telemetryEndpoints := interfaceToTelemetryEndpoint(testCase.endpoints) - require.Equal(t, testCase.expected, telemetryEndpoints) - }) + for _, test := range testcases { + res := interfaceToTelemetryEndpoint(test.values) + require.Equal(t, test.expected, res) } } diff --git a/lib/genesis/helpers.go b/lib/genesis/helpers.go index 14d18cd9cf..5907b26b42 100644 --- a/lib/genesis/helpers.go +++ b/lib/genesis/helpers.go @@ -16,6 +16,8 @@ import ( "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto" + "github.com/ChainSafe/gossamer/lib/runtime" + "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/pkg/scale" ) @@ -54,6 +56,38 @@ func NewGenesisFromJSONRaw(file string) (*Genesis, error) { return g, err } +// NewTrieFromGenesis creates a new trie from the raw genesis data +func NewTrieFromGenesis(g *Genesis) (*trie.Trie, error) { + t := trie.NewEmptyTrie() + + r := g.GenesisFields().Raw["top"] + + err := t.LoadFromMap(r) + if err != nil { + return nil, fmt.Errorf("failed to create trie from genesis: %s", err) + } + + return t, nil +} + +// NewGenesisBlockFromTrie creates a genesis block from the provided trie +func NewGenesisBlockFromTrie(t *trie.Trie) (*types.Header, error) { + + // create state root from trie hash + stateRoot, err := t.Hash() + if err != nil { + return nil, fmt.Errorf("failed to create state root from trie hash: %s", err) + } + + // create genesis block header + header, err := types.NewHeader(common.NewHash([]byte{0}), stateRoot, trie.EmptyHash, 0, types.NewDigest()) + if err != nil { + return nil, fmt.Errorf("failed to create genesis block header: %s", err) + } + + return header, nil +} + // trimGenesisAuthority iterates over authorities in genesis and keeps only `authCount` number of authorities. func trimGenesisAuthority(g *Genesis, authCount int) { for k, authMap := range g.Genesis.Runtime { @@ -545,7 +579,7 @@ func buildBalances(kv *keyValue, res map[string]string) error { for i := range kv.iVal { if i%2 == 0 { // build key - bKey := common.MustHexToBytes(systemAccountKeyHex) + bKey := runtime.SystemAccountPrefix() addHash, err := common.Blake2b128(kv.iVal[i].([]byte)) if err != nil { @@ -586,7 +620,7 @@ func BuildFromMap(m map[string][]byte, gen *Genesis) error { // handle :code addCodeValue(v, gen) addRawValue(key, v, gen) - case GrandpaAuthoritiesKeyHex: + case "0x3a6772616e6470615f617574686f726974696573": // handle :grandpa_authorities // slice value since it was encoded starting with 0x01 err := addAuthoritiesValues("grandpa", "authorities", crypto.Ed25519Type, v[1:], gen) @@ -594,7 +628,7 @@ func BuildFromMap(m map[string][]byte, gen *Genesis) error { return err } addRawValue(key, v, gen) - case BABEAuthoritiesKeyHex: + case fmt.Sprintf("0x%x", runtime.BABEAuthoritiesKey()): // handle Babe Authorities err := addAuthoritiesValues("babe", "authorities", crypto.Sr25519Type, v, gen) if err != nil { diff --git a/lib/genesis/helpers_test.go b/lib/genesis/helpers_test.go index 36839cb40c..34c2a3c094 100644 --- a/lib/genesis/helpers_test.go +++ b/lib/genesis/helpers_test.go @@ -5,37 +5,23 @@ package genesis import ( "encoding/json" + "fmt" "os" "path/filepath" "testing" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/runtime" + "github.com/ChainSafe/gossamer/lib/trie" "github.com/stretchr/testify/require" ) func TestNewGenesisRawFromJSON(t *testing.T) { - expected := &Genesis{ - Name: "gossamer", - ID: "gossamer", - Bootnodes: []string{ - "/dns4/p2p.cc3-0.kusama.network/tcp/30100/p2p/QmeCit3Nif4VfNqrEJsdYHZGcKzRCnZvGxg6hha1iNj4mk", - "/dns4/p2p.cc3-1.kusama.network/tcp/30100/p2p/QmchDJtEGiEWf7Ag58HNoTg9jSGzxkSZ23VgmF6xiLKKsZ", - }, - TelemetryEndpoints: []interface{}{"wss://telemetry.polkadot.io/submit/", float64(1)}, - ProtocolID: "/gossamer/test/0", - Properties: map[string]interface{}{ - "ss58Format": float64(0), - "tokenDecimals": float64(10), - "tokenSymbol": "DOT", - }, - ForkBlocks: []string{"fork1", "forkBlock2"}, - BadBlocks: []string{"badBlock1", "badBlock2"}, - Genesis: Fields{ - Raw: map[string]map[string]string{ - "top": {"0x3a636f6465": "0x0102"}, - }, - }, - } + testRaw := map[string]map[string]string{} + testRaw["top"] = map[string]string{"0x3a636f6465": "0x0102"} + + expected := TestGenesis + expected.Genesis = Fields{Raw: testRaw} // Grab json encoded bytes bz, err := json.Marshal(expected) @@ -308,5 +294,23 @@ func TestFormatKey(t *testing.T) { out, err := formatKey(kv) require.NoError(t, err) - require.Equal(t, BABEAuthoritiesKeyHex, out) + require.Equal(t, fmt.Sprintf("0x%x", runtime.BABEAuthoritiesKey()), out) +} + +func TestNewTrieFromGenesis(t *testing.T) { + var rawGenesis = &Genesis{} + raw := make(map[string]map[string]string) + raw["top"] = make(map[string]string) + raw["top"]["0x3a636f6465"] = "0x0102" // raw :code + rawGenesis.Genesis = Fields{ + Raw: raw, + } + + expTrie := trie.NewEmptyTrie() + expTrie.Put([]byte(`:code`), []byte{1, 2}) + + trie, err := NewTrieFromGenesis(rawGenesis) + require.NoError(t, err) + + require.Equal(t, expTrie, trie) } diff --git a/lib/genesis/keys.go b/lib/genesis/keys.go deleted file mode 100644 index dcf52fefc1..0000000000 --- a/lib/genesis/keys.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2022 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package genesis - -const ( - // babePrefixHex is the hex encoding of: Twox128Hash("Babe") - babePrefixHex = "0x1cb6f36e027abb2091cfb5110ab5087f" - // BABEAuthoritiesKeyHex is the hex encoding of: - // Twox128Hash("Babe") + Twox128Hash("Authorities") - BABEAuthoritiesKeyHex = babePrefixHex + "5e0621c4869aa60c02be9adcc98a0d1d" - // BABERandomnessKeyHex is the hex encoding of: - // Twox128Hash("Babe") + Twox128Hash("Randomness") - BABERandomnessKeyHex = babePrefixHex + "7a414cb008e0e61e46722aa60abdd672" - - // GrandpaAuthoritiesKeyHex is the hex encoding of the key to the GRANDPA - // authority data in the storage trie. - GrandpaAuthoritiesKeyHex = "0x3a6772616e6470615f617574686f726974696573" - - // systemPrefixHex is the hex encoding of: Twox128Hash("System") - systemPrefixHex = "0x26aa394eea5630e07c48ae0c9558cef7" - // systemAccountKeyHex is the hex encoding of: - // Twox128Hash("Babe") + Twox128Hash("Account") - systemAccountKeyHex = systemPrefixHex + "b99d880ec681799c0cf30e8886371da9" -) diff --git a/lib/genesis/test_utils.go b/lib/genesis/test_utils.go new file mode 100644 index 0000000000..f0bfe01ec3 --- /dev/null +++ b/lib/genesis/test_utils.go @@ -0,0 +1,108 @@ +// Copyright 2021 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package genesis + +import ( + "encoding/json" + "os" + "path/filepath" + "testing" + + "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/trie" + "github.com/ChainSafe/gossamer/lib/utils" + "github.com/stretchr/testify/require" +) + +const testProtocolID = "/gossamer/test/0" + +var testBootnodes = []string{ + "/dns4/p2p.cc3-0.kusama.network/tcp/30100/p2p/QmeCit3Nif4VfNqrEJsdYHZGcKzRCnZvGxg6hha1iNj4mk", + "/dns4/p2p.cc3-1.kusama.network/tcp/30100/p2p/QmchDJtEGiEWf7Ag58HNoTg9jSGzxkSZ23VgmF6xiLKKsZ", +} + +var testEndpoints = []interface{}{} +var testEndpoint1 = []interface{}{"wss://telemetry.polkadot.io/submit/", float64(1)} +var testProperties = map[string]interface{}{ + "ss58Format": float64(0), + "tokenDecimals": float64(10), + "tokenSymbol": "DOT", +} + +var testForkBlocks = []string{"fork1", "forkBlock2"} + +var testBadBlocks = []string{"badBlock1", "badBlock2"} + +// TestGenesis instance of Genesis struct for testing +var TestGenesis = &Genesis{ + Name: "gossamer", + ID: "gossamer", + Bootnodes: testBootnodes, + TelemetryEndpoints: append(testEndpoints, testEndpoint1), + ProtocolID: testProtocolID, + Properties: testProperties, + ForkBlocks: testForkBlocks, + BadBlocks: testBadBlocks, +} + +// TestFieldsRaw instance of raw Fields struct for testing use with TestGenesis +var TestFieldsRaw = Fields{ + Raw: map[string]map[string]string{ + "top": { + "0x3a636f6465": "mocktestcode", + common.BytesToHex(common.UpgradedToDualRefKey): "0x01", + }, + }, +} + +// CreateTestGenesisJSONFile writes a genesis file using the fields given to +// the current test temporary directory. +func CreateTestGenesisJSONFile(t *testing.T, fields Fields) (filename string) { + rawGenesis := &Genesis{ + Name: "test", + ID: "", + Bootnodes: nil, + ProtocolID: "", + Genesis: fields, + } + jsonData, err := json.Marshal(rawGenesis) + require.NoError(t, err) + filename = filepath.Join(t.TempDir(), "genesis-test") + err = os.WriteFile(filename, jsonData, os.ModePerm) + require.NoError(t, err) + return filename +} + +// NewTestGenesisWithTrieAndHeader generates genesis, genesis trie and genesis header +func NewTestGenesisWithTrieAndHeader(t *testing.T) (*Genesis, *trie.Trie, *types.Header) { + genesisPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t) + gen, err := NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + + tr, h := newGenesisTrieAndHeader(t, gen) + return gen, tr, h +} + +// NewDevGenesisWithTrieAndHeader generates test dev genesis, genesis trie and genesis header +func NewDevGenesisWithTrieAndHeader(t *testing.T) (*Genesis, *trie.Trie, *types.Header) { + genesisPath := utils.GetDevV3SubstrateGenesisPath(t) + + gen, err := NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + + tr, h := newGenesisTrieAndHeader(t, gen) + return gen, tr, h +} + +func newGenesisTrieAndHeader(t *testing.T, gen *Genesis) (*trie.Trie, *types.Header) { + genTrie, err := NewTrieFromGenesis(gen) + require.NoError(t, err) + + genesisHeader, err := types.NewHeader(common.NewHash([]byte{0}), + genTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest()) + require.NoError(t, err) + + return genTrie, genesisHeader +} diff --git a/lib/runtime/constants.go b/lib/runtime/constants.go index 21034f6a8f..b599ac15a9 100644 --- a/lib/runtime/constants.go +++ b/lib/runtime/constants.go @@ -3,6 +3,10 @@ package runtime +import ( + "github.com/ChainSafe/gossamer/lib/common" +) + //nolint:revive const ( // v0.9 substrate runtime @@ -58,7 +62,7 @@ const ( "29/westend_runtime-v9290.compact.compressed.wasm?raw=true" ) -const ( +var ( // CoreVersion is the runtime API call Core_version CoreVersion = "Core_version" // CoreInitializeBlock is the runtime API call Core_initialize_block @@ -88,3 +92,30 @@ const ( // TransactionPaymentCallAPIQueryCallFeeDetails returns call query call fee details TransactionPaymentCallAPIQueryCallFeeDetails = "TransactionPaymentCallApi_query_call_fee_details" ) + +// GrandpaAuthoritiesKey is the location of GRANDPA authority data +// in the storage trie for LEGACY_NODE_RUNTIME and NODE_RUNTIME +var GrandpaAuthoritiesKey, _ = common.HexToBytes("0x3a6772616e6470615f617574686f726974696573") + +// BABEPrefix is the prefix for all BABE related storage values +var BABEPrefix, _ = common.Twox128Hash([]byte("Babe")) + +// BABEAuthoritiesKey is the location of the BABE authorities in the storage trie for NODE_RUNTIME +func BABEAuthoritiesKey() []byte { + key, _ := common.Twox128Hash([]byte("Authorities")) + return append(BABEPrefix, key...) +} + +// BABERandomnessKey is the location of the BABE initial randomness in the storage trie for NODE_RUNTIME +func BABERandomnessKey() []byte { + key, _ := common.Twox128Hash([]byte("Randomness")) + return append(BABEPrefix, key...) +} + +// SystemAccountPrefix is the prefix for all System Account related storage values +func SystemAccountPrefix() []byte { + // build prefix + prefix, _ := common.Twox128Hash([]byte(`System`)) + part2, _ := common.Twox128Hash([]byte(`Account`)) + return append(prefix, part2...) +} diff --git a/lib/runtime/invalid_transaction.go b/lib/runtime/invalid_transaction.go index b60d708944..b610516394 100644 --- a/lib/runtime/invalid_transaction.go +++ b/lib/runtime/invalid_transaction.go @@ -9,7 +9,7 @@ import ( "github.com/ChainSafe/gossamer/pkg/scale" ) -// InvalidTransaction is a child VDT of TransactionValidityError +// InvalidTransaction is child VDT of TransactionValidityError type InvalidTransaction scale.VaryingDataType // Index returns the VDT index @@ -140,7 +140,7 @@ type InvalidCustom uint8 // Index returns the VDT index func (InvalidCustom) Index() uint { return 7 } -// Error returns the error message associated with the InvalidCustom +// Error returns the error message associated with the Call func (i InvalidCustom) Error() string { return newUnknownError(i).Error() } diff --git a/lib/runtime/invalid_transaction_test.go b/lib/runtime/invalid_transaction_test.go new file mode 100644 index 0000000000..ce54626172 --- /dev/null +++ b/lib/runtime/invalid_transaction_test.go @@ -0,0 +1,46 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package runtime + +import ( + "testing" + + "github.com/ChainSafe/gossamer/lib/transaction" + + "github.com/stretchr/testify/require" +) + +func Test_InvalidTransaction_Errors(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + encodedData []byte + expErr bool + expErrMsg string + expValidity *transaction.Validity + }{ + { + name: "ancient birth block", + encodedData: []byte{1, 0, 5}, + expErrMsg: "ancient birth block", + expErr: true, + }, + } + + for _, c := range testCases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + validity, err := UnmarshalTransactionValidity(c.encodedData) + if !c.expErr { + require.NoError(t, err) + } else { + require.Error(t, err) + require.EqualError(t, err, c.expErrMsg) + } + + require.Equal(t, c.expValidity, validity) + }) + } +} diff --git a/lib/runtime/transaction_validity.go b/lib/runtime/transaction_validity.go index 368a800d72..04b790b827 100644 --- a/lib/runtime/transaction_validity.go +++ b/lib/runtime/transaction_validity.go @@ -15,7 +15,7 @@ var errInvalidTypeCast = errors.New("invalid type cast") // TransactionValidityError Information on a transaction's validity and, if valid, // on how it relates to other transactions. It is a result of the form: -// Result +// Result type TransactionValidityError scale.VaryingDataType // Set will set a VaryingDataTypeValue using the underlying VaryingDataType diff --git a/lib/runtime/unknown_transaction.go b/lib/runtime/unknown_transaction.go index f91d9350b7..d7cb74c2c5 100644 --- a/lib/runtime/unknown_transaction.go +++ b/lib/runtime/unknown_transaction.go @@ -9,7 +9,7 @@ import ( "github.com/ChainSafe/gossamer/pkg/scale" ) -// UnknownTransaction is the child VDT of TransactionValidityError +// UnknownTransaction is child VDT of TransactionValidityError type UnknownTransaction scale.VaryingDataType // Index returns the VDT index diff --git a/lib/runtime/unknown_transaction_test.go b/lib/runtime/unknown_transaction_test.go new file mode 100644 index 0000000000..2f04afb973 --- /dev/null +++ b/lib/runtime/unknown_transaction_test.go @@ -0,0 +1,46 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package runtime + +import ( + "testing" + + "github.com/ChainSafe/gossamer/lib/transaction" + + "github.com/stretchr/testify/require" +) + +func Test_UnknownTransaction_Errors(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + encodedData []byte + expErr bool + expErrMsg string + expValidity *transaction.Validity + }{ + { + name: "lookup failed", + encodedData: []byte{1, 1, 0}, + expErrMsg: "lookup failed", + expErr: true, + }, + } + + for _, c := range testCases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + validity, err := UnmarshalTransactionValidity(c.encodedData) + if !c.expErr { + require.NoError(t, err) + } else { + require.Error(t, err) + require.EqualError(t, err, c.expErrMsg) + } + + require.Equal(t, c.expValidity, validity) + }) + } +} diff --git a/lib/runtime/version.go b/lib/runtime/version.go index 349b10003d..53cb2938d6 100644 --- a/lib/runtime/version.go +++ b/lib/runtime/version.go @@ -31,9 +31,24 @@ type Version struct { } var ( + // Blake2-8("TaggedTransactionQueue") + encodedTaggedTransactionQueue = [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15} + ErrDecodingVersionField = errors.New("decoding version field") ) +// TaggedTransactionQueueVersion returns the TaggedTransactionQueueAPI version +func (*Version) TaggedTransactionQueueVersion(runtimeVersion Version) uint32 { + txQueueVersion := uint32(0) + for _, v := range runtimeVersion.APIItems { + if v.Name == encodedTaggedTransactionQueue { + txQueueVersion = v.Ver + break + } + } + return txQueueVersion +} + // DecodeVersion scale decodes the encoded version data. // For older version data with missing fields (such as `transaction_version`) // the missing field is set to its zero value (such as `0`). diff --git a/lib/runtime/wasmer/exports.go b/lib/runtime/wasmer/exports.go index 4ad2038ae0..411a1dbda6 100644 --- a/lib/runtime/wasmer/exports.go +++ b/lib/runtime/wasmer/exports.go @@ -13,9 +13,11 @@ import ( ) // ValidateTransaction runs the extrinsic through the runtime function -// TaggedTransactionQueue_validate_transaction and returns **transaction.Validity. The error can -// be a VDT of either transaction.InvalidTransaction or transaction.UnknownTransaction, or can represent -// a normal error i.e. unmarshalling error +// TaggedTransactionQueue_validate_transaction and returns *Validity. Two types of errors +// are returned here: 1) *txnvalidity.transactionValidityError is a VDT containing +// VDTs of the types of transaction validity errors. The whole VDT is returned so +// the caller can handle as it seems fit, as this will vary per use case. 2) normal error +// returned if something fails in the process i.e. unmarshalling error func (in *Instance) ValidateTransaction(e types.Extrinsic) ( *transaction.Validity, error) { ret, err := in.Exec(runtime.TaggedTransactionQueueValidateTransaction, e) diff --git a/lib/runtime/wasmer/exports_test.go b/lib/runtime/wasmer/exports_test.go index d382c72bcf..57c428fb6e 100644 --- a/lib/runtime/wasmer/exports_test.go +++ b/lib/runtime/wasmer/exports_test.go @@ -123,12 +123,13 @@ func Test_Instance_Version(t *testing.T) { "kusama": { instanceBuilder: func(t *testing.T) InstanceVersion { genesisPath := utils.GetKusamaGenesisPath(t) - kusamaGenesis := genesisFromRawJSON(t, genesisPath) - genesisTrie, err := NewTrieFromGenesis(kusamaGenesis) + kusamaGenesis, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + genesisTrie, err := genesis.NewTrieFromGenesis(kusamaGenesis) require.NoError(t, err) cfg := Config{ - Storage: storage.NewTrieState(&genesisTrie), + Storage: storage.NewTrieState(genesisTrie), LogLvl: log.Critical, } @@ -297,12 +298,14 @@ func balanceKey(t *testing.T, pub []byte) []byte { func TestNodeRuntime_ValidateTransaction(t *testing.T) { genesisPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t) - gen := genesisFromRawJSON(t, genesisPath) - genTrie, err := NewTrieFromGenesis(gen) + gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + + genTrie, err := genesis.NewTrieFromGenesis(gen) require.NoError(t, err) // set state to genesis state - genState := storage.NewTrieState(&genTrie) + genState := storage.NewTrieState(genTrie) cfg := Config{ Storage: genState, @@ -358,8 +361,7 @@ func TestInstance_GrandpaAuthorities_NodeRuntime(t *testing.T) { value, err := common.HexToBytes("0x0108eea1eabcac7d2c8a6459b7322cf997874482bfc3d2ec7a80888a3a7d714103640100000000000000b64994460e59b30364cad3c92e3df6052f9b0ebbb8f88460c194dc5794d6d7170100000000000000") //nolint:lll require.NoError(t, err) - key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) - tt.Put(key, value) + tt.Put(runtime.GrandpaAuthoritiesKey, value) rt := NewTestInstanceWithTrie(t, runtime.NODE_RUNTIME, tt) @@ -386,8 +388,7 @@ func TestInstance_GrandpaAuthorities_PolkadotRuntime(t *testing.T) { value, err := common.HexToBytes("0x0108eea1eabcac7d2c8a6459b7322cf997874482bfc3d2ec7a80888a3a7d714103640100000000000000b64994460e59b30364cad3c92e3df6052f9b0ebbb8f88460c194dc5794d6d7170100000000000000") //nolint:lll require.NoError(t, err) - key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) - tt.Put(key, value) + tt.Put(runtime.GrandpaAuthoritiesKey, value) rt := NewTestInstanceWithTrie(t, runtime.POLKADOT_RUNTIME, tt) @@ -449,14 +450,12 @@ func TestInstance_BabeConfiguration_NodeRuntime_WithAuthorities(t *testing.T) { rvalue, err := common.HexToHash("0x01") require.NoError(t, err) - key := common.MustHexToBytes(genesis.BABERandomnessKeyHex) - tt.Put(key, rvalue[:]) + tt.Put(runtime.BABERandomnessKey(), rvalue[:]) avalue, err := common.HexToBytes("0x08eea1eabcac7d2c8a6459b7322cf997874482bfc3d2ec7a80888a3a7d714103640100000000000000b64994460e59b30364cad3c92e3df6052f9b0ebbb8f88460c194dc5794d6d7170100000000000000") //nolint:lll require.NoError(t, err) - key = common.MustHexToBytes(genesis.BABEAuthoritiesKeyHex) - tt.Put(key, avalue) + tt.Put(runtime.BABEAuthoritiesKey(), avalue) rt := NewTestInstanceWithTrie(t, runtime.NODE_RUNTIME, tt) @@ -529,12 +528,14 @@ func TestInstance_ExecuteBlock_NodeRuntime(t *testing.T) { func TestInstance_ExecuteBlock_GossamerRuntime(t *testing.T) { t.Skip() // TODO: this fails with "syscall frame is no longer valid" (#1026) genesisPath := utils.GetGssmrGenesisRawPathTest(t) - gen := genesisFromRawJSON(t, genesisPath) - genTrie, err := NewTrieFromGenesis(gen) + gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + + genTrie, err := genesis.NewTrieFromGenesis(gen) require.NoError(t, err) // set state to genesis state - genState := storage.NewTrieState(&genTrie) + genState := storage.NewTrieState(genTrie) cfg := Config{ Storage: genState, @@ -547,7 +548,7 @@ func TestInstance_ExecuteBlock_GossamerRuntime(t *testing.T) { block := runtime.InitializeRuntimeToTest(t, instance, common.Hash{}) // reset state back to parent state before executing - parentState := storage.NewTrieState(&genTrie) + parentState := storage.NewTrieState(genTrie) instance.SetContextStorage(parentState) _, err = instance.ExecuteBlock(block) @@ -557,12 +558,14 @@ func TestInstance_ExecuteBlock_GossamerRuntime(t *testing.T) { func TestInstance_ApplyExtrinsic_GossamerRuntime(t *testing.T) { t.Skip() // TODO: this fails with "syscall frame is no longer valid" (#1026) genesisPath := utils.GetGssmrGenesisRawPathTest(t) - gen := genesisFromRawJSON(t, genesisPath) - genTrie, err := NewTrieFromGenesis(gen) + gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + + genTrie, err := genesis.NewTrieFromGenesis(gen) require.NoError(t, err) // set state to genesis state - genState := storage.NewTrieState(&genTrie) + genState := storage.NewTrieState(genTrie) cfg := Config{ Storage: genState, @@ -573,7 +576,7 @@ func TestInstance_ApplyExtrinsic_GossamerRuntime(t *testing.T) { require.NoError(t, err) // reset state back to parent state before executing - parentState := storage.NewTrieState(&genTrie) + parentState := storage.NewTrieState(genTrie) instance.SetContextStorage(parentState) parentHash := common.Hash{} @@ -611,15 +614,17 @@ func TestInstance_ExecuteBlock_PolkadotRuntime(t *testing.T) { func TestInstance_ExecuteBlock_PolkadotRuntime_PolkadotBlock1(t *testing.T) { genesisPath := utils.GetPolkadotGenesisPath(t) - gen := genesisFromRawJSON(t, genesisPath) - genTrie, err := NewTrieFromGenesis(gen) + gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + + genTrie, err := genesis.NewTrieFromGenesis(gen) require.NoError(t, err) expectedGenesisRoot := common.MustHexToHash("0x29d0d972cd27cbc511e9589fcb7a4506d5eb6a9e8df205f00472e5ab354a4e17") require.Equal(t, expectedGenesisRoot, genTrie.MustHash()) // set state to genesis state - genState := storage.NewTrieState(&genTrie) + genState := storage.NewTrieState(genTrie) cfg := Config{ Storage: genState, @@ -661,15 +666,17 @@ func TestInstance_ExecuteBlock_PolkadotRuntime_PolkadotBlock1(t *testing.T) { func TestInstance_ExecuteBlock_KusamaRuntime_KusamaBlock1(t *testing.T) { genesisPath := utils.GetKusamaGenesisPath(t) - gen := genesisFromRawJSON(t, genesisPath) - genTrie, err := NewTrieFromGenesis(gen) + gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + + genTrie, err := genesis.NewTrieFromGenesis(gen) require.NoError(t, err) expectedGenesisRoot := common.MustHexToHash("0xb0006203c3a6e6bd2c6a17b1d4ae8ca49a31da0f4579da950b127774b44aef6b") require.Equal(t, expectedGenesisRoot, genTrie.MustHash()) // set state to genesis state - genState := storage.NewTrieState(&genTrie) + genState := storage.NewTrieState(genTrie) cfg := Config{ Storage: genState, diff --git a/lib/runtime/wasmer/helpers_test.go b/lib/runtime/wasmer/helpers_test.go index 279dc49966..c6bda5f811 100644 --- a/lib/runtime/wasmer/helpers_test.go +++ b/lib/runtime/wasmer/helpers_test.go @@ -4,31 +4,12 @@ package wasmer import ( - "encoding/json" - "os" - "path/filepath" "testing" - "github.com/ChainSafe/gossamer/lib/genesis" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func genesisFromRawJSON(t *testing.T, jsonFilepath string) (gen genesis.Genesis) { - t.Helper() - - fp, err := filepath.Abs(jsonFilepath) - require.NoError(t, err) - - data, err := os.ReadFile(filepath.Clean(fp)) - require.NoError(t, err) - - err = json.Unmarshal(data, &gen) - require.NoError(t, err) - - return gen -} - func Test_pointerSize(t *testing.T) { t.Parallel() diff --git a/lib/trie/genesis_test.go b/lib/trie/genesis_test.go deleted file mode 100644 index e071709a0e..0000000000 --- a/lib/trie/genesis_test.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2022 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package trie - -import ( - "testing" - - "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/internal/trie/node" - "github.com/ChainSafe/gossamer/lib/common" - "github.com/stretchr/testify/assert" -) - -func Test_Trie_GenesisBlock(t *testing.T) { - t.Parallel() - - withHash := func(header types.Header) types.Header { - header.Hash() - return header - } - - testCases := map[string]struct { - trie Trie - genesisHeader types.Header - errSentinel error - errMessage string - }{ - "empty trie": { - genesisHeader: withHash(types.Header{ - ParentHash: common.Hash{0}, - StateRoot: EmptyHash, - ExtrinsicsRoot: EmptyHash, - Digest: types.NewDigest(), - }), - }, - "non empty trie": { - trie: Trie{ - root: &node.Node{ - Key: []byte{1, 2, 3}, - SubValue: []byte{4, 5, 6}, - }, - }, - genesisHeader: withHash(types.Header{ - ParentHash: common.Hash{0}, - StateRoot: common.Hash{ - 0x25, 0xc1, 0x86, 0xd4, 0x5b, 0xc9, 0x1d, 0x9f, - 0xf5, 0xfd, 0x29, 0xd3, 0x29, 0x8a, 0xa3, 0x63, - 0x83, 0xf3, 0x2d, 0x14, 0xa8, 0xbd, 0xde, 0xc9, - 0x7b, 0x57, 0x92, 0x78, 0x67, 0xfc, 0x8a, 0xfa}, - ExtrinsicsRoot: EmptyHash, - Digest: types.NewDigest(), - }), - }, - } - - for name, testCase := range testCases { - testCase := testCase - t.Run(name, func(t *testing.T) { - t.Parallel() - - trie := testCase.trie - - genesisHeader, err := trie.GenesisBlock() - - assert.ErrorIs(t, err, testCase.errSentinel) - if testCase.errSentinel != nil { - assert.EqualError(t, err, testCase.errMessage) - } - assert.Equal(t, testCase.genesisHeader, genesisHeader) - }) - } -} diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 735d32c248..aa1a49f48a 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -861,6 +861,8 @@ func (t *Trie) deleteNodesLimit(parent *Node, limit uint32, branch := parent + fullKey := concatenateSlices(prefix, branch.Key) + nilChildren := node.ChildrenCapacity - branch.NumChildren() var newDeleted, newNodesRemoved uint32 @@ -888,7 +890,7 @@ func (t *Trie) deleteNodesLimit(parent *Node, limit uint32, branch.SetDirty() - newParent, branchChildMerged = handleDeletion(branch, branch.Key) + newParent, branchChildMerged = handleDeletion(branch, fullKey) if branchChildMerged { nodesRemoved++ } diff --git a/lib/trie/trie_test.go b/lib/trie/trie_test.go index 0e9ef8d8ad..7524aa276f 100644 --- a/lib/trie/trie_test.go +++ b/lib/trie/trie_test.go @@ -2708,6 +2708,7 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { t.Parallel() testCases := map[string]struct { +<<<<<<< HEAD trie Trie parent *Node limit uint32 @@ -2715,6 +2716,15 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { newNode *Node valuesDeleted uint32 nodesRemoved uint32 +======= + trie Trie + parent *Node + prefix []byte + limit uint32 + newNode *Node + valuesDeleted uint32 + nodesRemoved uint32 +>>>>>>> ccb2005e (reset branch for new head) }{ "zero limit": { trie: Trie{ @@ -2845,7 +2855,8 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { {Key: []byte{3}, SubValue: []byte{1}}, }), }, - limit: 2, + prefix: []byte{1, 2}, + limit: 2, newNode: &Node{ Key: []byte{3, 5, 3}, SubValue: []byte{1}, @@ -2866,8 +2877,12 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { expectedTrie := *trie.DeepCopy() newNode, valuesDeleted, nodesRemoved := +<<<<<<< HEAD trie.deleteNodesLimit(testCase.parent, testCase.limit, testCase.deletedMerkleValues) +======= + trie.deleteNodesLimit(testCase.parent, testCase.prefix, testCase.limit) +>>>>>>> ccb2005e (reset branch for new head) assert.Equal(t, testCase.newNode, newNode) assert.Equal(t, testCase.valuesDeleted, valuesDeleted) From 1d651bc5aed90017f24d957fc54c94b45dfbe00c Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 27 Sep 2022 15:27:33 -0600 Subject: [PATCH 02/45] fix genesis --- lib/genesis/genesis_test.go | 70 +++++++++++++---------- lib/genesis/helpers.go | 40 +------------ lib/genesis/helpers_test.go | 50 ++++++++--------- lib/genesis/keys.go | 25 +++++++++ lib/genesis/test_utils.go | 108 ------------------------------------ 5 files changed, 92 insertions(+), 201 deletions(-) create mode 100644 lib/genesis/keys.go delete mode 100644 lib/genesis/test_utils.go diff --git a/lib/genesis/genesis_test.go b/lib/genesis/genesis_test.go index 844bddfbad..fd1ea6b213 100644 --- a/lib/genesis/genesis_test.go +++ b/lib/genesis/genesis_test.go @@ -9,44 +9,56 @@ import ( "github.com/stretchr/testify/require" ) -func TestInterfaceToTelemetryEndpoint(t *testing.T) { - testcases := []struct { - description string - values []interface{} - expected []*TelemetryEndpoint +func Test_interfaceToTelemetryEndpoint(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + endpoints []interface{} + expected []*TelemetryEndpoint }{ - { - "Test with wrong interface type", - []interface{}{"string"}, - nil, + "sub element not a slice": { + endpoints: []interface{}{ + struct{}{}, + }, + }, + "wrong interface type": { + endpoints: []interface{}{ + []interface{}{"string"}, + }, }, - { - "Test with interface field len != 2", - append(testEndpoints, []interface{}{"wss://telemetry.polkadot.io/submit/"}), - nil, + "wrong interface field length": { + endpoints: []interface{}{ + []interface{}{"wss://telemetry.polkadot.io/submit/"}, + }, }, - { - "Test with interface field 0 wrong type", - append(testEndpoints, []interface{}{float32(0), "wss://telemetry.polkadot.io/submit/"}), - nil, + "wrong interface field position": { + endpoints: []interface{}{ + []interface{}{float64(0), "wss://telemetry.polkadot.io/submit/"}, + }, }, - { - "Test with interface field 1 wrong type", - append(testEndpoints, []interface{}{"wss://telemetry.polkadot.io/submit/", "1"}), - nil, + "interface field 1 wrong type": { + endpoints: []interface{}{ + []interface{}{"wss://telemetry.polkadot.io/submit/", "1"}, + }, }, - { - "Test with correctly formed values", - append(testEndpoints, testEndpoint1), - append([]*TelemetryEndpoint{}, &TelemetryEndpoint{ + "success": { + endpoints: []interface{}{ + []interface{}{"wss://telemetry.polkadot.io/submit/", float64(1)}, + }, + expected: []*TelemetryEndpoint{{ Endpoint: "wss://telemetry.polkadot.io/submit/", Verbosity: 1, - }), + }}, }, } - for _, test := range testcases { - res := interfaceToTelemetryEndpoint(test.values) - require.Equal(t, test.expected, res) + for name, testCase := range testCases { + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() + + telemetryEndpoints := interfaceToTelemetryEndpoint(testCase.endpoints) + require.Equal(t, testCase.expected, telemetryEndpoints) + }) } } diff --git a/lib/genesis/helpers.go b/lib/genesis/helpers.go index 5907b26b42..14d18cd9cf 100644 --- a/lib/genesis/helpers.go +++ b/lib/genesis/helpers.go @@ -16,8 +16,6 @@ import ( "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto" - "github.com/ChainSafe/gossamer/lib/runtime" - "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/pkg/scale" ) @@ -56,38 +54,6 @@ func NewGenesisFromJSONRaw(file string) (*Genesis, error) { return g, err } -// NewTrieFromGenesis creates a new trie from the raw genesis data -func NewTrieFromGenesis(g *Genesis) (*trie.Trie, error) { - t := trie.NewEmptyTrie() - - r := g.GenesisFields().Raw["top"] - - err := t.LoadFromMap(r) - if err != nil { - return nil, fmt.Errorf("failed to create trie from genesis: %s", err) - } - - return t, nil -} - -// NewGenesisBlockFromTrie creates a genesis block from the provided trie -func NewGenesisBlockFromTrie(t *trie.Trie) (*types.Header, error) { - - // create state root from trie hash - stateRoot, err := t.Hash() - if err != nil { - return nil, fmt.Errorf("failed to create state root from trie hash: %s", err) - } - - // create genesis block header - header, err := types.NewHeader(common.NewHash([]byte{0}), stateRoot, trie.EmptyHash, 0, types.NewDigest()) - if err != nil { - return nil, fmt.Errorf("failed to create genesis block header: %s", err) - } - - return header, nil -} - // trimGenesisAuthority iterates over authorities in genesis and keeps only `authCount` number of authorities. func trimGenesisAuthority(g *Genesis, authCount int) { for k, authMap := range g.Genesis.Runtime { @@ -579,7 +545,7 @@ func buildBalances(kv *keyValue, res map[string]string) error { for i := range kv.iVal { if i%2 == 0 { // build key - bKey := runtime.SystemAccountPrefix() + bKey := common.MustHexToBytes(systemAccountKeyHex) addHash, err := common.Blake2b128(kv.iVal[i].([]byte)) if err != nil { @@ -620,7 +586,7 @@ func BuildFromMap(m map[string][]byte, gen *Genesis) error { // handle :code addCodeValue(v, gen) addRawValue(key, v, gen) - case "0x3a6772616e6470615f617574686f726974696573": + case GrandpaAuthoritiesKeyHex: // handle :grandpa_authorities // slice value since it was encoded starting with 0x01 err := addAuthoritiesValues("grandpa", "authorities", crypto.Ed25519Type, v[1:], gen) @@ -628,7 +594,7 @@ func BuildFromMap(m map[string][]byte, gen *Genesis) error { return err } addRawValue(key, v, gen) - case fmt.Sprintf("0x%x", runtime.BABEAuthoritiesKey()): + case BABEAuthoritiesKeyHex: // handle Babe Authorities err := addAuthoritiesValues("babe", "authorities", crypto.Sr25519Type, v, gen) if err != nil { diff --git a/lib/genesis/helpers_test.go b/lib/genesis/helpers_test.go index 34c2a3c094..36839cb40c 100644 --- a/lib/genesis/helpers_test.go +++ b/lib/genesis/helpers_test.go @@ -5,23 +5,37 @@ package genesis import ( "encoding/json" - "fmt" "os" "path/filepath" "testing" "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/runtime" - "github.com/ChainSafe/gossamer/lib/trie" "github.com/stretchr/testify/require" ) func TestNewGenesisRawFromJSON(t *testing.T) { - testRaw := map[string]map[string]string{} - testRaw["top"] = map[string]string{"0x3a636f6465": "0x0102"} - - expected := TestGenesis - expected.Genesis = Fields{Raw: testRaw} + expected := &Genesis{ + Name: "gossamer", + ID: "gossamer", + Bootnodes: []string{ + "/dns4/p2p.cc3-0.kusama.network/tcp/30100/p2p/QmeCit3Nif4VfNqrEJsdYHZGcKzRCnZvGxg6hha1iNj4mk", + "/dns4/p2p.cc3-1.kusama.network/tcp/30100/p2p/QmchDJtEGiEWf7Ag58HNoTg9jSGzxkSZ23VgmF6xiLKKsZ", + }, + TelemetryEndpoints: []interface{}{"wss://telemetry.polkadot.io/submit/", float64(1)}, + ProtocolID: "/gossamer/test/0", + Properties: map[string]interface{}{ + "ss58Format": float64(0), + "tokenDecimals": float64(10), + "tokenSymbol": "DOT", + }, + ForkBlocks: []string{"fork1", "forkBlock2"}, + BadBlocks: []string{"badBlock1", "badBlock2"}, + Genesis: Fields{ + Raw: map[string]map[string]string{ + "top": {"0x3a636f6465": "0x0102"}, + }, + }, + } // Grab json encoded bytes bz, err := json.Marshal(expected) @@ -294,23 +308,5 @@ func TestFormatKey(t *testing.T) { out, err := formatKey(kv) require.NoError(t, err) - require.Equal(t, fmt.Sprintf("0x%x", runtime.BABEAuthoritiesKey()), out) -} - -func TestNewTrieFromGenesis(t *testing.T) { - var rawGenesis = &Genesis{} - raw := make(map[string]map[string]string) - raw["top"] = make(map[string]string) - raw["top"]["0x3a636f6465"] = "0x0102" // raw :code - rawGenesis.Genesis = Fields{ - Raw: raw, - } - - expTrie := trie.NewEmptyTrie() - expTrie.Put([]byte(`:code`), []byte{1, 2}) - - trie, err := NewTrieFromGenesis(rawGenesis) - require.NoError(t, err) - - require.Equal(t, expTrie, trie) + require.Equal(t, BABEAuthoritiesKeyHex, out) } diff --git a/lib/genesis/keys.go b/lib/genesis/keys.go new file mode 100644 index 0000000000..dcf52fefc1 --- /dev/null +++ b/lib/genesis/keys.go @@ -0,0 +1,25 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package genesis + +const ( + // babePrefixHex is the hex encoding of: Twox128Hash("Babe") + babePrefixHex = "0x1cb6f36e027abb2091cfb5110ab5087f" + // BABEAuthoritiesKeyHex is the hex encoding of: + // Twox128Hash("Babe") + Twox128Hash("Authorities") + BABEAuthoritiesKeyHex = babePrefixHex + "5e0621c4869aa60c02be9adcc98a0d1d" + // BABERandomnessKeyHex is the hex encoding of: + // Twox128Hash("Babe") + Twox128Hash("Randomness") + BABERandomnessKeyHex = babePrefixHex + "7a414cb008e0e61e46722aa60abdd672" + + // GrandpaAuthoritiesKeyHex is the hex encoding of the key to the GRANDPA + // authority data in the storage trie. + GrandpaAuthoritiesKeyHex = "0x3a6772616e6470615f617574686f726974696573" + + // systemPrefixHex is the hex encoding of: Twox128Hash("System") + systemPrefixHex = "0x26aa394eea5630e07c48ae0c9558cef7" + // systemAccountKeyHex is the hex encoding of: + // Twox128Hash("Babe") + Twox128Hash("Account") + systemAccountKeyHex = systemPrefixHex + "b99d880ec681799c0cf30e8886371da9" +) diff --git a/lib/genesis/test_utils.go b/lib/genesis/test_utils.go deleted file mode 100644 index f0bfe01ec3..0000000000 --- a/lib/genesis/test_utils.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2021 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package genesis - -import ( - "encoding/json" - "os" - "path/filepath" - "testing" - - "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" - "github.com/stretchr/testify/require" -) - -const testProtocolID = "/gossamer/test/0" - -var testBootnodes = []string{ - "/dns4/p2p.cc3-0.kusama.network/tcp/30100/p2p/QmeCit3Nif4VfNqrEJsdYHZGcKzRCnZvGxg6hha1iNj4mk", - "/dns4/p2p.cc3-1.kusama.network/tcp/30100/p2p/QmchDJtEGiEWf7Ag58HNoTg9jSGzxkSZ23VgmF6xiLKKsZ", -} - -var testEndpoints = []interface{}{} -var testEndpoint1 = []interface{}{"wss://telemetry.polkadot.io/submit/", float64(1)} -var testProperties = map[string]interface{}{ - "ss58Format": float64(0), - "tokenDecimals": float64(10), - "tokenSymbol": "DOT", -} - -var testForkBlocks = []string{"fork1", "forkBlock2"} - -var testBadBlocks = []string{"badBlock1", "badBlock2"} - -// TestGenesis instance of Genesis struct for testing -var TestGenesis = &Genesis{ - Name: "gossamer", - ID: "gossamer", - Bootnodes: testBootnodes, - TelemetryEndpoints: append(testEndpoints, testEndpoint1), - ProtocolID: testProtocolID, - Properties: testProperties, - ForkBlocks: testForkBlocks, - BadBlocks: testBadBlocks, -} - -// TestFieldsRaw instance of raw Fields struct for testing use with TestGenesis -var TestFieldsRaw = Fields{ - Raw: map[string]map[string]string{ - "top": { - "0x3a636f6465": "mocktestcode", - common.BytesToHex(common.UpgradedToDualRefKey): "0x01", - }, - }, -} - -// CreateTestGenesisJSONFile writes a genesis file using the fields given to -// the current test temporary directory. -func CreateTestGenesisJSONFile(t *testing.T, fields Fields) (filename string) { - rawGenesis := &Genesis{ - Name: "test", - ID: "", - Bootnodes: nil, - ProtocolID: "", - Genesis: fields, - } - jsonData, err := json.Marshal(rawGenesis) - require.NoError(t, err) - filename = filepath.Join(t.TempDir(), "genesis-test") - err = os.WriteFile(filename, jsonData, os.ModePerm) - require.NoError(t, err) - return filename -} - -// NewTestGenesisWithTrieAndHeader generates genesis, genesis trie and genesis header -func NewTestGenesisWithTrieAndHeader(t *testing.T) (*Genesis, *trie.Trie, *types.Header) { - genesisPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t) - gen, err := NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - tr, h := newGenesisTrieAndHeader(t, gen) - return gen, tr, h -} - -// NewDevGenesisWithTrieAndHeader generates test dev genesis, genesis trie and genesis header -func NewDevGenesisWithTrieAndHeader(t *testing.T) (*Genesis, *trie.Trie, *types.Header) { - genesisPath := utils.GetDevV3SubstrateGenesisPath(t) - - gen, err := NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - tr, h := newGenesisTrieAndHeader(t, gen) - return gen, tr, h -} - -func newGenesisTrieAndHeader(t *testing.T, gen *Genesis) (*trie.Trie, *types.Header) { - genTrie, err := NewTrieFromGenesis(gen) - require.NoError(t, err) - - genesisHeader, err := types.NewHeader(common.NewHash([]byte{0}), - genTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest()) - require.NoError(t, err) - - return genTrie, genesisHeader -} From b5e7dee769dd294a69ae936c284a804b919f5211 Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 27 Sep 2022 16:09:02 -0600 Subject: [PATCH 03/45] remove unneeded code --- chain/dev/config.toml | 1 - chain/dev/defaults.go | 3 - chain/gssmr/config.toml | 1 - chain/gssmr/defaults.go | 3 - chain/kusama/config.toml | 1 - chain/kusama/defaults.go | 3 - chain/polkadot/config.toml | 1 - chain/polkadot/defaults.go | 3 - cmd/gossamer/config.go | 14 ++--- dot/config.go | 4 -- dot/config_test.go | 2 - dot/node.go | 7 ++- dot/node_test.go | 6 +- dot/rpc/http_test.go | 6 +- dot/rpc/modules/author_integration_test.go | 34 ++++++---- dot/rpc/modules/childstate_test.go | 4 +- dot/rpc/modules/helpers_test.go | 3 +- dot/state/block_data_test.go | 2 +- dot/state/block_finalisation_test.go | 6 +- dot/state/block_notify_test.go | 14 ++--- dot/state/block_test.go | 30 +++++---- dot/state/epoch_test.go | 4 +- dot/state/initialize.go | 4 +- dot/state/storage_notify_test.go | 6 +- dot/state/storage_test.go | 15 ++--- lib/babe/verify_integration_test.go | 13 ++-- lib/runtime/constants.go | 33 +--------- lib/runtime/invalid_transaction.go | 4 +- lib/runtime/invalid_transaction_test.go | 46 -------------- lib/runtime/transaction_validity.go | 2 +- lib/runtime/unknown_transaction.go | 2 +- lib/runtime/unknown_transaction_test.go | 46 -------------- lib/runtime/wasmer/exports.go | 8 +-- lib/runtime/wasmer/exports_test.go | 63 +++++++++---------- lib/runtime/wasmer/helpers_test.go | 19 ++++++ lib/trie/genesis_test.go | 73 ++++++++++++++++++++++ lib/trie/trie.go | 4 +- lib/trie/trie_test.go | 17 +---- 38 files changed, 217 insertions(+), 290 deletions(-) delete mode 100644 lib/runtime/invalid_transaction_test.go delete mode 100644 lib/runtime/unknown_transaction_test.go create mode 100644 lib/trie/genesis_test.go diff --git a/chain/dev/config.toml b/chain/dev/config.toml index c55318871b..434e79f59a 100644 --- a/chain/dev/config.toml +++ b/chain/dev/config.toml @@ -52,7 +52,6 @@ modules = [ ws-port = 8546 [pprof] -enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/dev/defaults.go b/chain/dev/defaults.go index 5e321224dd..88193c2da9 100644 --- a/chain/dev/defaults.go +++ b/chain/dev/defaults.go @@ -96,9 +96,6 @@ var ( const ( // PprofConfig - // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. - DefaultPprofEnabled = true - // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/chain/gssmr/config.toml b/chain/gssmr/config.toml index 309ff2269b..5165b96fa9 100644 --- a/chain/gssmr/config.toml +++ b/chain/gssmr/config.toml @@ -54,7 +54,6 @@ modules = [ ws-port = 8546 [pprof] -enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/gssmr/defaults.go b/chain/gssmr/defaults.go index 1417b895bf..0295be7a38 100644 --- a/chain/gssmr/defaults.go +++ b/chain/gssmr/defaults.go @@ -104,9 +104,6 @@ var ( const ( // PprofConfig - // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. - DefaultPprofEnabled = true - // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/chain/kusama/config.toml b/chain/kusama/config.toml index 3ce5a210ea..865fd01f12 100644 --- a/chain/kusama/config.toml +++ b/chain/kusama/config.toml @@ -42,7 +42,6 @@ ws = false ws-external = false [pprof] -enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/kusama/defaults.go b/chain/kusama/defaults.go index b9a00bdce6..57183b1859 100644 --- a/chain/kusama/defaults.go +++ b/chain/kusama/defaults.go @@ -88,9 +88,6 @@ var ( const ( // PprofConfig - // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. - DefaultPprofEnabled = false - // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/chain/polkadot/config.toml b/chain/polkadot/config.toml index afdb693abc..26ae4ba747 100644 --- a/chain/polkadot/config.toml +++ b/chain/polkadot/config.toml @@ -39,7 +39,6 @@ modules = ["system", "author", "chain", "state", "rpc", "grandpa", "offchain", " ws-port = 8546 [pprof] -enabled = false listening-address = "localhost:6060" block-rate = 0 mutex-rate = 0 diff --git a/chain/polkadot/defaults.go b/chain/polkadot/defaults.go index cc6a24a19e..2a75648878 100644 --- a/chain/polkadot/defaults.go +++ b/chain/polkadot/defaults.go @@ -86,9 +86,6 @@ var ( const ( // PprofConfig - // DefaultPprofEnabled to indicate the pprof http server should be enabled or not. - DefaultPprofEnabled = false - // DefaultPprofListeningAddress default pprof HTTP server listening address. DefaultPprofListeningAddress = "localhost:6060" diff --git a/cmd/gossamer/config.go b/cmd/gossamer/config.go index 5fa7eff0c7..0042542484 100644 --- a/cmd/gossamer/config.go +++ b/cmd/gossamer/config.go @@ -890,9 +890,10 @@ func updateDotConfigFromGenesisData(ctx *cli.Context, cfg *dot.Config) error { } func setDotPprofConfig(ctx *cli.Context, tomlCfg ctoml.PprofConfig, cfg *dot.PprofConfig) { - if !cfg.Enabled { - // only allow to enable pprof from the TOML configuration. - // If it is enabled by default, it cannot be disabled. + // Flag takes precedence over TOML config, default is ignored. + if ctx.GlobalIsSet(PprofServerFlag.Name) { + cfg.Enabled = ctx.GlobalBool(PprofServerFlag.Name) + } else { cfg.Enabled = tomlCfg.Enabled } @@ -912,13 +913,6 @@ func setDotPprofConfig(ctx *cli.Context, tomlCfg ctoml.PprofConfig, cfg *dot.Ppr cfg.Settings.MutexProfileRate = tomlCfg.MutexRate } - // check --pprofserver flag and update node configuration - if enabled := ctx.GlobalBool(PprofServerFlag.Name); enabled || cfg.Enabled { - cfg.Enabled = true - } else if ctx.IsSet(PprofServerFlag.Name) && !enabled { - cfg.Enabled = false - } - // check --pprofaddress flag and update node configuration if address := ctx.GlobalString(PprofAddressFlag.Name); address != "" { cfg.Settings.ListeningAddress = address diff --git a/dot/config.go b/dot/config.go index b1cad82f83..eba3879b09 100644 --- a/dot/config.go +++ b/dot/config.go @@ -239,7 +239,6 @@ func GssmrConfig() *Config { WSPort: gssmr.DefaultRPCWSPort, }, Pprof: PprofConfig{ - Enabled: gssmr.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: gssmr.DefaultPprofListeningAddress, BlockProfileRate: gssmr.DefaultPprofBlockRate, @@ -297,7 +296,6 @@ func KusamaConfig() *Config { WSPort: kusama.DefaultRPCWSPort, }, Pprof: PprofConfig{ - Enabled: kusama.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: kusama.DefaultPprofListeningAddress, BlockProfileRate: kusama.DefaultPprofBlockRate, @@ -355,7 +353,6 @@ func PolkadotConfig() *Config { WSPort: polkadot.DefaultRPCWSPort, }, Pprof: PprofConfig{ - Enabled: polkadot.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: polkadot.DefaultPprofListeningAddress, BlockProfileRate: polkadot.DefaultPprofBlockRate, @@ -418,7 +415,6 @@ func DevConfig() *Config { WS: dev.DefaultWSEnabled, }, Pprof: PprofConfig{ - Enabled: dev.DefaultPprofEnabled, Settings: pprof.Settings{ ListeningAddress: dev.DefaultPprofListeningAddress, BlockProfileRate: dev.DefaultPprofBlockRate, diff --git a/dot/config_test.go b/dot/config_test.go index 7e8922c7f2..ab801a0237 100644 --- a/dot/config_test.go +++ b/dot/config_test.go @@ -74,7 +74,6 @@ func TestConfig(t *testing.T) { WS: true, }, Pprof: PprofConfig{ - Enabled: true, Settings: pprof.Settings{ ListeningAddress: "localhost:6060", }, @@ -134,7 +133,6 @@ func TestConfig(t *testing.T) { WSUnsafeExternal: false, }, Pprof: PprofConfig{ - Enabled: true, Settings: pprof.Settings{ ListeningAddress: "localhost:6060", BlockProfileRate: 0, diff --git a/dot/node.go b/dot/node.go index 0aa5ff4510..561f01925c 100644 --- a/dot/node.go +++ b/dot/node.go @@ -32,6 +32,7 @@ import ( "github.com/ChainSafe/gossamer/lib/grandpa" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime" + "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/services" "github.com/ChainSafe/gossamer/lib/utils" ) @@ -144,13 +145,13 @@ func (*nodeBuilder) initNode(cfg *Config) error { } // create trie from genesis - t, err := genesis.NewTrieFromGenesis(gen) + t, err := wasmer.NewTrieFromGenesis(*gen) if err != nil { return fmt.Errorf("failed to create trie from genesis: %w", err) } // create genesis block from trie - header, err := genesis.NewGenesisBlockFromTrie(t) + header, err := t.GenesisBlock() if err != nil { return fmt.Errorf("failed to create genesis block from trie: %w", err) } @@ -175,7 +176,7 @@ func (*nodeBuilder) initNode(cfg *Config) error { stateSrvc := state.NewService(config) // initialise state service with genesis data, block, and trie - err = stateSrvc.Initialise(gen, header, t) + err = stateSrvc.Initialise(gen, &header, &t) if err != nil { return fmt.Errorf("failed to initialise state service: %s", err) } diff --git a/dot/node_test.go b/dot/node_test.go index bbd5a0de80..ce9be33a55 100644 --- a/dot/node_test.go +++ b/dot/node_test.go @@ -166,17 +166,17 @@ func TestNewNode(t *testing.T) { return nil, fmt.Errorf("failed to load genesis from file: %w", err) } // create trie from genesis - trie, err := genesis.NewTrieFromGenesis(gen) + trie, err := wasmer.NewTrieFromGenesis(*gen) if err != nil { return nil, fmt.Errorf("failed to create trie from genesis: %w", err) } // create genesis block from trie - header, err := genesis.NewGenesisBlockFromTrie(trie) + header, err := trie.GenesisBlock() if err != nil { return nil, fmt.Errorf("failed to create genesis block from trie: %w", err) } stateSrvc.Telemetry = mockTelemetryClient - err = stateSrvc.Initialise(gen, header, trie) + err = stateSrvc.Initialise(gen, &header, &trie) if err != nil { return nil, fmt.Errorf("failed to initialise state service: %s", err) } diff --git a/dot/rpc/http_test.go b/dot/rpc/http_test.go index a3fbf3122d..e92fda121a 100644 --- a/dot/rpc/http_test.go +++ b/dot/rpc/http_test.go @@ -364,7 +364,7 @@ func newCoreServiceTest(t *testing.T) *core.Service { testDatadirPath := t.TempDir() - gen, genTrie, genHeader := newTestGenesisWithTrieAndHeader(t) + gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -379,7 +379,7 @@ func newCoreServiceTest(t *testing.T) *core.Service { stateSrvc := state.NewService(config) stateSrvc.UseMemDB() - err := stateSrvc.Initialise(&gen, &genHeader, &genTrie) + err := stateSrvc.Initialise(&gen, &genesisHeader, &genesisTrie) require.NoError(t, err) err = stateSrvc.SetupBase() @@ -406,7 +406,7 @@ func newCoreServiceTest(t *testing.T) *core.Service { var rtCfg wasmer.Config - rtCfg.Storage = rtstorage.NewTrieState(&genTrie) + rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) require.NoError(t, err) diff --git a/dot/rpc/modules/author_integration_test.go b/dot/rpc/modules/author_integration_test.go index 1462dba4b0..5172b32599 100644 --- a/dot/rpc/modules/author_integration_test.go +++ b/dot/rpc/modules/author_integration_test.go @@ -263,7 +263,6 @@ func TestAuthorModule_SubmitExtrinsic_AlreadyInPool(t *testing.T) { // creating an extrisinc to the System.remark call using a sample argument extHex := runtime.NewTestExtrinsic(t, integrationTestController.runtime, genesisHash, genesisHash, 0, "System.remark", []byte{}) - fmt.Println(extHex) extBytes := common.MustHexToBytes(extHex) integrationTestController.storageState = &state.StorageState{} @@ -556,11 +555,19 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { integrationTestController.stateSrv.Transaction = state.NewTransactionState(telemetryMock) genesisHash := integrationTestController.genesisHeader.Hash() - ext := createExtrinsic(t, integrationTestController.runtime, genesisHash, 0) - extHex := common.BytesToHex(ext) + + extHex := runtime.NewTestExtrinsic(t, + integrationTestController.runtime, genesisHash, genesisHash, 1, "System.remark", []byte{0xab, 0xcd}) + + // to extrinsic works with a runtime version 0910 we need to + // append the block hash bytes at the end of the extrinsics + hashBytes := genesisHash.ToBytes() + extBytes := append(common.MustHexToBytes(extHex), hashBytes...) + + extHex = common.BytesToHex(extBytes) net2test := NewMockNetwork(ctrl) - net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{ext}}) + net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{extBytes}}) integrationTestController.network = net2test // setup auth module @@ -570,14 +577,17 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { err := auth.SubmitExtrinsic(nil, &Extrinsic{extHex}, res) require.NoError(t, err) - expectedExtrinsic := types.NewExtrinsic(ext) + expectedExtrinsic := types.NewExtrinsic(extBytes) expected := &transaction.ValidTransaction{ Extrinsic: expectedExtrinsic, Validity: &transaction.Validity{ Priority: 4295664014726, - Provides: [][]byte{ + Requires: [][]byte{ common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d00000000"), }, + Provides: [][]byte{ + common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000"), + }, Longevity: 18446744073709551613, Propagate: true, }, @@ -606,7 +616,7 @@ type integrationTestController struct { func setupStateAndRuntime(t *testing.T, basepath string, useInstance useRuntimeInstace) *integrationTestController { t.Helper() - gen, genTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -626,7 +636,7 @@ func setupStateAndRuntime(t *testing.T, basepath string, useInstance useRuntimeI state2test.UseMemDB() state2test.Transaction = state.NewTransactionState(telemetryMock) - err := state2test.Initialise(&gen, &genesisHeader, &genTrie) + err := state2test.Initialise(&gen, &genesisHeader, &genesisTrie) require.NoError(t, err) err = state2test.Start() @@ -640,7 +650,7 @@ func setupStateAndRuntime(t *testing.T, basepath string, useInstance useRuntimeI net2test := NewMockNetwork(nil) integrationTestController := &integrationTestController{ genesis: &gen, - genesisTrie: &genTrie, + genesisTrie: &genesisTrie, genesisHeader: &genesisHeader, stateSrv: state2test, storageState: state2test.Storage, @@ -666,7 +676,7 @@ func setupStateAndPopulateTrieState(t *testing.T, basepath string, useInstance useRuntimeInstace) *integrationTestController { t.Helper() - gen, genTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -687,7 +697,7 @@ func setupStateAndPopulateTrieState(t *testing.T, basepath string, state2test.Transaction = state.NewTransactionState(telemetryMock) - err := state2test.Initialise(&gen, &genesisHeader, &genTrie) + err := state2test.Initialise(&gen, &genesisHeader, &genesisTrie) require.NoError(t, err) err = state2test.Start() @@ -701,7 +711,7 @@ func setupStateAndPopulateTrieState(t *testing.T, basepath string, ks := keystore.NewGlobalKeystore() integrationTestController := &integrationTestController{ genesis: &gen, - genesisTrie: &genTrie, + genesisTrie: &genesisTrie, genesisHeader: &genesisHeader, stateSrv: state2test, storageState: state2test.Storage, diff --git a/dot/rpc/modules/childstate_test.go b/dot/rpc/modules/childstate_test.go index 3f7d1c2c22..b9d8b2ecc4 100644 --- a/dot/rpc/modules/childstate_test.go +++ b/dot/rpc/modules/childstate_test.go @@ -20,8 +20,8 @@ import ( func createTestTrieState(t *testing.T) (*trie.Trie, common.Hash) { t.Helper() - _, genTrie, _ := newTestGenesisWithTrieAndHeader(t) - tr := rtstorage.NewTrieState(&genTrie) + _, genesisTrie, _ := newTestGenesisWithTrieAndHeader(t) + tr := rtstorage.NewTrieState(&genesisTrie) tr.Set([]byte(":first_key"), []byte(":value1")) tr.Set([]byte(":second_key"), []byte(":second_value")) diff --git a/dot/rpc/modules/helpers_test.go b/dot/rpc/modules/helpers_test.go index 18e4060baa..61bc9260a6 100644 --- a/dot/rpc/modules/helpers_test.go +++ b/dot/rpc/modules/helpers_test.go @@ -3,6 +3,8 @@ package modules import ( + "testing" + "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/genesis" @@ -10,7 +12,6 @@ import ( "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" "github.com/stretchr/testify/require" - "testing" ) func stringToHex(s string) (hex string) { diff --git a/dot/state/block_data_test.go b/dot/state/block_data_test.go index a07606bb05..370282850b 100644 --- a/dot/state/block_data_test.go +++ b/dot/state/block_data_test.go @@ -14,7 +14,7 @@ import ( ) func TestGetSet_ReceiptMessageQueue_Justification(t *testing.T) { - s := newTestBlockState(t, nil, newTriesEmpty()) + s := newTestBlockState(t, newTriesEmpty()) var genesisHeader = &types.Header{ Number: 0, diff --git a/dot/state/block_finalisation_test.go b/dot/state/block_finalisation_test.go index 2cc0afb980..aa62f591a4 100644 --- a/dot/state/block_finalisation_test.go +++ b/dot/state/block_finalisation_test.go @@ -14,7 +14,7 @@ import ( ) func TestHighestRoundAndSetID(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) round, setID, err := bs.GetHighestRoundAndSetID() require.NoError(t, err) require.Equal(t, uint64(0), round) @@ -62,7 +62,7 @@ func TestHighestRoundAndSetID(t *testing.T) { } func TestBlockState_SetFinalisedHash(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) h, err := bs.GetFinalisedHash(0, 0) require.NoError(t, err) require.Equal(t, testGenesisHeader.Hash(), h) @@ -104,7 +104,7 @@ func TestBlockState_SetFinalisedHash(t *testing.T) { } func TestSetFinalisedHash_setFirstSlotOnFinalisation(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) firstSlot := uint64(42069) digest := types.NewDigest() diff --git a/dot/state/block_notify_test.go b/dot/state/block_notify_test.go index 2b7b827af7..a8bf3c639c 100644 --- a/dot/state/block_notify_test.go +++ b/dot/state/block_notify_test.go @@ -16,7 +16,7 @@ import ( var testMessageTimeout = time.Second * 3 func TestImportChannel(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) ch := bs.GetImportedBlockNotifierChannel() defer bs.FreeImportedBlockNotifierChannel(ch) @@ -33,7 +33,7 @@ func TestImportChannel(t *testing.T) { } func TestFreeImportedBlockNotifierChannel(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) ch := bs.GetImportedBlockNotifierChannel() require.Equal(t, 1, len(bs.imported)) @@ -42,7 +42,7 @@ func TestFreeImportedBlockNotifierChannel(t *testing.T) { } func TestFinalizedChannel(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) ch := bs.GetFinalisedNotifierChannel() @@ -64,7 +64,7 @@ func TestFinalizedChannel(t *testing.T) { } func TestImportChannel_Multi(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) num := 5 chs := make([]chan *types.Block, num) @@ -96,7 +96,7 @@ func TestImportChannel_Multi(t *testing.T) { } func TestFinalizedChannel_Multi(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) num := 5 chs := make([]chan *types.FinalisationInfo, num) @@ -133,7 +133,7 @@ func TestFinalizedChannel_Multi(t *testing.T) { } func TestService_RegisterUnRegisterRuntimeUpdatedChannel(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) ch := make(chan<- runtime.Version) chID, err := bs.RegisterRuntimeUpdatedChannel(ch) require.NoError(t, err) @@ -144,7 +144,7 @@ func TestService_RegisterUnRegisterRuntimeUpdatedChannel(t *testing.T) { } func TestService_RegisterUnRegisterConcurrentCalls(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) go func() { for i := 0; i < 100; i++ { diff --git a/dot/state/block_test.go b/dot/state/block_test.go index e665c8cdea..e437a674b2 100644 --- a/dot/state/block_test.go +++ b/dot/state/block_test.go @@ -24,15 +24,13 @@ var testGenesisHeader = &types.Header{ Digest: types.NewDigest(), } -func newTestBlockState(t *testing.T, header *types.Header, tries *Tries) *BlockState { +func newTestBlockState(t *testing.T, tries *Tries) *BlockState { ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() db := NewInMemoryDB(t) - if header == nil { - header = testGenesisHeader - } + header := testGenesisHeader bs, err := NewBlockStateFromGenesis(db, tries, header, telemetryMock) require.NoError(t, err) @@ -48,7 +46,7 @@ func newTestBlockState(t *testing.T, header *types.Header, tries *Tries) *BlockS } func TestSetAndGetHeader(t *testing.T) { - bs := newTestBlockState(t, nil, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) header := &types.Header{ Number: 0, @@ -65,7 +63,7 @@ func TestSetAndGetHeader(t *testing.T) { } func TestHasHeader(t *testing.T) { - bs := newTestBlockState(t, nil, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) header := &types.Header{ Number: 0, @@ -82,7 +80,7 @@ func TestHasHeader(t *testing.T) { } func TestGetBlockByNumber(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) blockHeader := &types.Header{ ParentHash: testGenesisHeader.Hash(), @@ -104,7 +102,7 @@ func TestGetBlockByNumber(t *testing.T) { } func TestAddBlock(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) // Create header header0 := &types.Header{ @@ -167,7 +165,7 @@ func TestAddBlock(t *testing.T) { } func TestGetSlotForBlock(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) expectedSlot := uint64(77) babeHeader := types.NewBabeDigest() @@ -198,7 +196,7 @@ func TestGetSlotForBlock(t *testing.T) { } func TestIsBlockOnCurrentChain(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) currChain, branchChains := AddBlocksToState(t, bs, 3, false) for _, header := range currChain { @@ -221,7 +219,7 @@ func TestIsBlockOnCurrentChain(t *testing.T) { } func TestAddBlock_BlockNumberToHash(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) currChain, branchChains := AddBlocksToState(t, bs, 8, false) bestHash := bs.BestBlockHash() @@ -269,7 +267,7 @@ func TestAddBlock_BlockNumberToHash(t *testing.T) { } func TestFinalization_DeleteBlock(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) AddBlocksToState(t, bs, 5, false) btBefore := bs.bt.DeepCopy() @@ -324,7 +322,7 @@ func TestFinalization_DeleteBlock(t *testing.T) { } func TestGetHashByNumber(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) res, err := bs.GetHashByNumber(0) require.NoError(t, err) @@ -351,7 +349,7 @@ func TestGetHashByNumber(t *testing.T) { func TestAddBlock_WithReOrg(t *testing.T) { t.Skip() // TODO: this should be fixed after state refactor PR - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) header1a := &types.Header{ Number: 1, @@ -460,7 +458,7 @@ func TestAddBlock_WithReOrg(t *testing.T) { } func TestAddBlockToBlockTree(t *testing.T) { - bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + bs := newTestBlockState(t, newTriesEmpty()) header := &types.Header{ Number: 1, @@ -482,7 +480,7 @@ func TestAddBlockToBlockTree(t *testing.T) { func TestNumberIsFinalised(t *testing.T) { tries := newTriesEmpty() - bs := newTestBlockState(t, testGenesisHeader, tries) + bs := newTestBlockState(t, tries) fin, err := bs.NumberIsFinalised(0) require.NoError(t, err) require.True(t, fin) diff --git a/dot/state/epoch_test.go b/dot/state/epoch_test.go index 75b4736560..aa0a0903e5 100644 --- a/dot/state/epoch_test.go +++ b/dot/state/epoch_test.go @@ -29,7 +29,7 @@ var genesisBABEConfig = &types.BabeConfiguration{ func newEpochStateFromGenesis(t *testing.T) *EpochState { db := NewInMemoryDB(t) - blockState := newTestBlockState(t, nil, newTriesEmpty()) + blockState := newTestBlockState(t, newTriesEmpty()) s, err := NewEpochStateFromGenesis(db, blockState, genesisBABEConfig) require.NoError(t, err) return s @@ -183,7 +183,7 @@ func TestEpochState_SetAndGetSlotDuration(t *testing.T) { func TestEpochState_GetEpochFromTime(t *testing.T) { s := newEpochStateFromGenesis(t) - s.blockState = newTestBlockState(t, testGenesisHeader, newTriesEmpty()) + s.blockState = newTestBlockState(t, newTriesEmpty()) epochDuration, err := time.ParseDuration( fmt.Sprintf("%dms", diff --git a/dot/state/initialize.go b/dot/state/initialize.go index 465bc19010..733c953520 100644 --- a/dot/state/initialize.go +++ b/dot/state/initialize.go @@ -5,6 +5,7 @@ package state import ( "fmt" + "github.com/ChainSafe/gossamer/lib/common" "path/filepath" "github.com/ChainSafe/chaindb" @@ -124,7 +125,8 @@ func (s *Service) loadBabeConfigurationFromRuntime(r runtime.Instance) (*types.B } func loadGrandpaAuthorities(t *trie.Trie) ([]types.GrandpaVoter, error) { - authsRaw := t.Get(runtime.GrandpaAuthoritiesKey) + key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) + authsRaw := t.Get(key) if authsRaw == nil { return []types.GrandpaVoter{}, nil } diff --git a/dot/state/storage_notify_test.go b/dot/state/storage_notify_test.go index cd065d79df..39cf2dbd6b 100644 --- a/dot/state/storage_notify_test.go +++ b/dot/state/storage_notify_test.go @@ -18,7 +18,7 @@ import ( ) func TestStorageState_RegisterStorageObserver(t *testing.T) { - ss := newTestStorageState(t, newTriesEmpty()) + ss := newTestStorageState(t) ts, err := ss.TrieState(nil) require.NoError(t, err) @@ -57,7 +57,7 @@ func TestStorageState_RegisterStorageObserver(t *testing.T) { } func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) { - ss := newTestStorageState(t, newTriesEmpty()) + ss := newTestStorageState(t) ts, err := ss.TrieState(nil) require.NoError(t, err) @@ -95,7 +95,7 @@ func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) { func TestStorageState_RegisterStorageObserver_Multi_Filter(t *testing.T) { t.Skip() // this seems to fail often on CI - ss := newTestStorageState(t, newTriesEmpty()) + ss := newTestStorageState(t) ts, err := ss.TrieState(nil) require.NoError(t, err) diff --git a/dot/state/storage_test.go b/dot/state/storage_test.go index 9b3a58a14d..968a16fad0 100644 --- a/dot/state/storage_test.go +++ b/dot/state/storage_test.go @@ -20,10 +20,11 @@ import ( "github.com/stretchr/testify/require" ) -func newTestStorageState(t *testing.T, tries *Tries) *StorageState { +func newTestStorageState(t *testing.T) *StorageState { db := NewInMemoryDB(t) - bs := newTestBlockState(t, testGenesisHeader, tries) + tries := newTriesEmpty() + bs := newTestBlockState(t, tries) s, err := NewStorageState(db, bs, tries, pruner.Config{}) require.NoError(t, err) @@ -31,7 +32,7 @@ func newTestStorageState(t *testing.T, tries *Tries) *StorageState { } func TestStorage_StoreAndLoadTrie(t *testing.T) { - storage := newTestStorageState(t, newTriesEmpty()) + storage := newTestStorageState(t) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) @@ -50,7 +51,7 @@ func TestStorage_StoreAndLoadTrie(t *testing.T) { } func TestStorage_GetStorageByBlockHash(t *testing.T) { - storage := newTestStorageState(t, newTriesEmpty()) + storage := newTestStorageState(t) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) @@ -85,7 +86,7 @@ func TestStorage_GetStorageByBlockHash(t *testing.T) { } func TestStorage_TrieState(t *testing.T) { - storage := newTestStorageState(t, newTriesEmpty()) + storage := newTestStorageState(t) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) ts.Set([]byte("noot"), []byte("washere")) @@ -105,7 +106,7 @@ func TestStorage_TrieState(t *testing.T) { } func TestStorage_LoadFromDB(t *testing.T) { - storage := newTestStorageState(t, newTriesEmpty()) + storage := newTestStorageState(t) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) @@ -150,7 +151,7 @@ func TestStorage_LoadFromDB(t *testing.T) { } func TestStorage_StoreTrie_NotSyncing(t *testing.T) { - storage := newTestStorageState(t, newTriesEmpty()) + storage := newTestStorageState(t) ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) diff --git a/lib/babe/verify_integration_test.go b/lib/babe/verify_integration_test.go index e93b8853b8..4bb37dfd12 100644 --- a/lib/babe/verify_integration_test.go +++ b/lib/babe/verify_integration_test.go @@ -19,7 +19,6 @@ import ( "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/sr25519" - "github.com/ChainSafe/gossamer/lib/genesis" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/golang/mock/gomock" @@ -42,8 +41,8 @@ func newTestVerificationManager(t *testing.T, genCfg *types.BabeConfiguration) * dbSrv := state.NewService(config) dbSrv.UseMemDB() - gen, genTrie, genHeader := genesis.NewDevGenesisWithTrieAndHeader(t) - err := dbSrv.Initialise(gen, genHeader, genTrie) + gen, genesisTrie, genesisHeader := newDevGenesisWithTrieAndHeader(t) + err := dbSrv.Initialise(&gen, &genesisHeader, &genesisTrie) require.NoError(t, err) err = dbSrv.Start() @@ -499,7 +498,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { SecondarySlots: 0, } - genesis, trie, genesisHeader := genesis.NewTestGenesisWithTrieAndHeader(t) + genesis, trie, genesisHeader := newTestGenesisWithTrieAndHeader(t) ctrl := gomock.NewController(t) telemetryMock := NewMockClient(ctrl) @@ -517,7 +516,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { stateService.UseMemDB() - err := stateService.Initialise(genesis, genesisHeader, trie) + err := stateService.Initialise(&genesis, &genesisHeader, &trie) require.NoError(t, err) inMemoryDB, err := chaindb.NewBadgerDB(&chaindb.Config{ @@ -547,7 +546,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { C2: 10, SecondarySlots: 1, } - aliceBlockHeader := issueConsensusDigestsBlockFromGenesis(t, genesisHeader, keyring.KeyAlice, + aliceBlockHeader := issueConsensusDigestsBlockFromGenesis(t, &genesisHeader, keyring.KeyAlice, stateService, aliceBlockNextEpoch, aliceBlockNextConfigData) bobBlockNextEpoch := types.NextEpochData{ @@ -558,7 +557,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { C2: 8, SecondarySlots: 1, } - bobBlockHeader := issueConsensusDigestsBlockFromGenesis(t, genesisHeader, keyring.KeyBob, + bobBlockHeader := issueConsensusDigestsBlockFromGenesis(t, &genesisHeader, keyring.KeyBob, stateService, bobBlockNextEpoch, bobBlockNextConfigData) // wait for digest handleBlockImport goroutine gets the imported diff --git a/lib/runtime/constants.go b/lib/runtime/constants.go index b599ac15a9..21034f6a8f 100644 --- a/lib/runtime/constants.go +++ b/lib/runtime/constants.go @@ -3,10 +3,6 @@ package runtime -import ( - "github.com/ChainSafe/gossamer/lib/common" -) - //nolint:revive const ( // v0.9 substrate runtime @@ -62,7 +58,7 @@ const ( "29/westend_runtime-v9290.compact.compressed.wasm?raw=true" ) -var ( +const ( // CoreVersion is the runtime API call Core_version CoreVersion = "Core_version" // CoreInitializeBlock is the runtime API call Core_initialize_block @@ -92,30 +88,3 @@ var ( // TransactionPaymentCallAPIQueryCallFeeDetails returns call query call fee details TransactionPaymentCallAPIQueryCallFeeDetails = "TransactionPaymentCallApi_query_call_fee_details" ) - -// GrandpaAuthoritiesKey is the location of GRANDPA authority data -// in the storage trie for LEGACY_NODE_RUNTIME and NODE_RUNTIME -var GrandpaAuthoritiesKey, _ = common.HexToBytes("0x3a6772616e6470615f617574686f726974696573") - -// BABEPrefix is the prefix for all BABE related storage values -var BABEPrefix, _ = common.Twox128Hash([]byte("Babe")) - -// BABEAuthoritiesKey is the location of the BABE authorities in the storage trie for NODE_RUNTIME -func BABEAuthoritiesKey() []byte { - key, _ := common.Twox128Hash([]byte("Authorities")) - return append(BABEPrefix, key...) -} - -// BABERandomnessKey is the location of the BABE initial randomness in the storage trie for NODE_RUNTIME -func BABERandomnessKey() []byte { - key, _ := common.Twox128Hash([]byte("Randomness")) - return append(BABEPrefix, key...) -} - -// SystemAccountPrefix is the prefix for all System Account related storage values -func SystemAccountPrefix() []byte { - // build prefix - prefix, _ := common.Twox128Hash([]byte(`System`)) - part2, _ := common.Twox128Hash([]byte(`Account`)) - return append(prefix, part2...) -} diff --git a/lib/runtime/invalid_transaction.go b/lib/runtime/invalid_transaction.go index b610516394..b60d708944 100644 --- a/lib/runtime/invalid_transaction.go +++ b/lib/runtime/invalid_transaction.go @@ -9,7 +9,7 @@ import ( "github.com/ChainSafe/gossamer/pkg/scale" ) -// InvalidTransaction is child VDT of TransactionValidityError +// InvalidTransaction is a child VDT of TransactionValidityError type InvalidTransaction scale.VaryingDataType // Index returns the VDT index @@ -140,7 +140,7 @@ type InvalidCustom uint8 // Index returns the VDT index func (InvalidCustom) Index() uint { return 7 } -// Error returns the error message associated with the Call +// Error returns the error message associated with the InvalidCustom func (i InvalidCustom) Error() string { return newUnknownError(i).Error() } diff --git a/lib/runtime/invalid_transaction_test.go b/lib/runtime/invalid_transaction_test.go deleted file mode 100644 index ce54626172..0000000000 --- a/lib/runtime/invalid_transaction_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2022 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package runtime - -import ( - "testing" - - "github.com/ChainSafe/gossamer/lib/transaction" - - "github.com/stretchr/testify/require" -) - -func Test_InvalidTransaction_Errors(t *testing.T) { - t.Parallel() - testCases := []struct { - name string - encodedData []byte - expErr bool - expErrMsg string - expValidity *transaction.Validity - }{ - { - name: "ancient birth block", - encodedData: []byte{1, 0, 5}, - expErrMsg: "ancient birth block", - expErr: true, - }, - } - - for _, c := range testCases { - c := c - t.Run(c.name, func(t *testing.T) { - t.Parallel() - validity, err := UnmarshalTransactionValidity(c.encodedData) - if !c.expErr { - require.NoError(t, err) - } else { - require.Error(t, err) - require.EqualError(t, err, c.expErrMsg) - } - - require.Equal(t, c.expValidity, validity) - }) - } -} diff --git a/lib/runtime/transaction_validity.go b/lib/runtime/transaction_validity.go index 04b790b827..368a800d72 100644 --- a/lib/runtime/transaction_validity.go +++ b/lib/runtime/transaction_validity.go @@ -15,7 +15,7 @@ var errInvalidTypeCast = errors.New("invalid type cast") // TransactionValidityError Information on a transaction's validity and, if valid, // on how it relates to other transactions. It is a result of the form: -// Result +// Result type TransactionValidityError scale.VaryingDataType // Set will set a VaryingDataTypeValue using the underlying VaryingDataType diff --git a/lib/runtime/unknown_transaction.go b/lib/runtime/unknown_transaction.go index d7cb74c2c5..f91d9350b7 100644 --- a/lib/runtime/unknown_transaction.go +++ b/lib/runtime/unknown_transaction.go @@ -9,7 +9,7 @@ import ( "github.com/ChainSafe/gossamer/pkg/scale" ) -// UnknownTransaction is child VDT of TransactionValidityError +// UnknownTransaction is the child VDT of TransactionValidityError type UnknownTransaction scale.VaryingDataType // Index returns the VDT index diff --git a/lib/runtime/unknown_transaction_test.go b/lib/runtime/unknown_transaction_test.go deleted file mode 100644 index 2f04afb973..0000000000 --- a/lib/runtime/unknown_transaction_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2022 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package runtime - -import ( - "testing" - - "github.com/ChainSafe/gossamer/lib/transaction" - - "github.com/stretchr/testify/require" -) - -func Test_UnknownTransaction_Errors(t *testing.T) { - t.Parallel() - testCases := []struct { - name string - encodedData []byte - expErr bool - expErrMsg string - expValidity *transaction.Validity - }{ - { - name: "lookup failed", - encodedData: []byte{1, 1, 0}, - expErrMsg: "lookup failed", - expErr: true, - }, - } - - for _, c := range testCases { - c := c - t.Run(c.name, func(t *testing.T) { - t.Parallel() - validity, err := UnmarshalTransactionValidity(c.encodedData) - if !c.expErr { - require.NoError(t, err) - } else { - require.Error(t, err) - require.EqualError(t, err, c.expErrMsg) - } - - require.Equal(t, c.expValidity, validity) - }) - } -} diff --git a/lib/runtime/wasmer/exports.go b/lib/runtime/wasmer/exports.go index 411a1dbda6..e723c22f5f 100644 --- a/lib/runtime/wasmer/exports.go +++ b/lib/runtime/wasmer/exports.go @@ -13,11 +13,9 @@ import ( ) // ValidateTransaction runs the extrinsic through the runtime function -// TaggedTransactionQueue_validate_transaction and returns *Validity. Two types of errors -// are returned here: 1) *txnvalidity.transactionValidityError is a VDT containing -// VDTs of the types of transaction validity errors. The whole VDT is returned so -// the caller can handle as it seems fit, as this will vary per use case. 2) normal error -// returned if something fails in the process i.e. unmarshalling error +// TaggedTransactionQueue_validate_transaction and returns *transaction.Validity. The error can +// be a VDT of either transaction.InvalidTransaction or transaction.UnknownTransaction, or can represent +// a normal error i.e. unmarshalling error func (in *Instance) ValidateTransaction(e types.Extrinsic) ( *transaction.Validity, error) { ret, err := in.Exec(runtime.TaggedTransactionQueueValidateTransaction, e) diff --git a/lib/runtime/wasmer/exports_test.go b/lib/runtime/wasmer/exports_test.go index 57c428fb6e..d382c72bcf 100644 --- a/lib/runtime/wasmer/exports_test.go +++ b/lib/runtime/wasmer/exports_test.go @@ -123,13 +123,12 @@ func Test_Instance_Version(t *testing.T) { "kusama": { instanceBuilder: func(t *testing.T) InstanceVersion { genesisPath := utils.GetKusamaGenesisPath(t) - kusamaGenesis, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - genesisTrie, err := genesis.NewTrieFromGenesis(kusamaGenesis) + kusamaGenesis := genesisFromRawJSON(t, genesisPath) + genesisTrie, err := NewTrieFromGenesis(kusamaGenesis) require.NoError(t, err) cfg := Config{ - Storage: storage.NewTrieState(genesisTrie), + Storage: storage.NewTrieState(&genesisTrie), LogLvl: log.Critical, } @@ -298,14 +297,12 @@ func balanceKey(t *testing.T, pub []byte) []byte { func TestNodeRuntime_ValidateTransaction(t *testing.T) { genesisPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t) - gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - genTrie, err := genesis.NewTrieFromGenesis(gen) + gen := genesisFromRawJSON(t, genesisPath) + genTrie, err := NewTrieFromGenesis(gen) require.NoError(t, err) // set state to genesis state - genState := storage.NewTrieState(genTrie) + genState := storage.NewTrieState(&genTrie) cfg := Config{ Storage: genState, @@ -361,7 +358,8 @@ func TestInstance_GrandpaAuthorities_NodeRuntime(t *testing.T) { value, err := common.HexToBytes("0x0108eea1eabcac7d2c8a6459b7322cf997874482bfc3d2ec7a80888a3a7d714103640100000000000000b64994460e59b30364cad3c92e3df6052f9b0ebbb8f88460c194dc5794d6d7170100000000000000") //nolint:lll require.NoError(t, err) - tt.Put(runtime.GrandpaAuthoritiesKey, value) + key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) + tt.Put(key, value) rt := NewTestInstanceWithTrie(t, runtime.NODE_RUNTIME, tt) @@ -388,7 +386,8 @@ func TestInstance_GrandpaAuthorities_PolkadotRuntime(t *testing.T) { value, err := common.HexToBytes("0x0108eea1eabcac7d2c8a6459b7322cf997874482bfc3d2ec7a80888a3a7d714103640100000000000000b64994460e59b30364cad3c92e3df6052f9b0ebbb8f88460c194dc5794d6d7170100000000000000") //nolint:lll require.NoError(t, err) - tt.Put(runtime.GrandpaAuthoritiesKey, value) + key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) + tt.Put(key, value) rt := NewTestInstanceWithTrie(t, runtime.POLKADOT_RUNTIME, tt) @@ -450,12 +449,14 @@ func TestInstance_BabeConfiguration_NodeRuntime_WithAuthorities(t *testing.T) { rvalue, err := common.HexToHash("0x01") require.NoError(t, err) - tt.Put(runtime.BABERandomnessKey(), rvalue[:]) + key := common.MustHexToBytes(genesis.BABERandomnessKeyHex) + tt.Put(key, rvalue[:]) avalue, err := common.HexToBytes("0x08eea1eabcac7d2c8a6459b7322cf997874482bfc3d2ec7a80888a3a7d714103640100000000000000b64994460e59b30364cad3c92e3df6052f9b0ebbb8f88460c194dc5794d6d7170100000000000000") //nolint:lll require.NoError(t, err) - tt.Put(runtime.BABEAuthoritiesKey(), avalue) + key = common.MustHexToBytes(genesis.BABEAuthoritiesKeyHex) + tt.Put(key, avalue) rt := NewTestInstanceWithTrie(t, runtime.NODE_RUNTIME, tt) @@ -528,14 +529,12 @@ func TestInstance_ExecuteBlock_NodeRuntime(t *testing.T) { func TestInstance_ExecuteBlock_GossamerRuntime(t *testing.T) { t.Skip() // TODO: this fails with "syscall frame is no longer valid" (#1026) genesisPath := utils.GetGssmrGenesisRawPathTest(t) - gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - genTrie, err := genesis.NewTrieFromGenesis(gen) + gen := genesisFromRawJSON(t, genesisPath) + genTrie, err := NewTrieFromGenesis(gen) require.NoError(t, err) // set state to genesis state - genState := storage.NewTrieState(genTrie) + genState := storage.NewTrieState(&genTrie) cfg := Config{ Storage: genState, @@ -548,7 +547,7 @@ func TestInstance_ExecuteBlock_GossamerRuntime(t *testing.T) { block := runtime.InitializeRuntimeToTest(t, instance, common.Hash{}) // reset state back to parent state before executing - parentState := storage.NewTrieState(genTrie) + parentState := storage.NewTrieState(&genTrie) instance.SetContextStorage(parentState) _, err = instance.ExecuteBlock(block) @@ -558,14 +557,12 @@ func TestInstance_ExecuteBlock_GossamerRuntime(t *testing.T) { func TestInstance_ApplyExtrinsic_GossamerRuntime(t *testing.T) { t.Skip() // TODO: this fails with "syscall frame is no longer valid" (#1026) genesisPath := utils.GetGssmrGenesisRawPathTest(t) - gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - genTrie, err := genesis.NewTrieFromGenesis(gen) + gen := genesisFromRawJSON(t, genesisPath) + genTrie, err := NewTrieFromGenesis(gen) require.NoError(t, err) // set state to genesis state - genState := storage.NewTrieState(genTrie) + genState := storage.NewTrieState(&genTrie) cfg := Config{ Storage: genState, @@ -576,7 +573,7 @@ func TestInstance_ApplyExtrinsic_GossamerRuntime(t *testing.T) { require.NoError(t, err) // reset state back to parent state before executing - parentState := storage.NewTrieState(genTrie) + parentState := storage.NewTrieState(&genTrie) instance.SetContextStorage(parentState) parentHash := common.Hash{} @@ -614,17 +611,15 @@ func TestInstance_ExecuteBlock_PolkadotRuntime(t *testing.T) { func TestInstance_ExecuteBlock_PolkadotRuntime_PolkadotBlock1(t *testing.T) { genesisPath := utils.GetPolkadotGenesisPath(t) - gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - genTrie, err := genesis.NewTrieFromGenesis(gen) + gen := genesisFromRawJSON(t, genesisPath) + genTrie, err := NewTrieFromGenesis(gen) require.NoError(t, err) expectedGenesisRoot := common.MustHexToHash("0x29d0d972cd27cbc511e9589fcb7a4506d5eb6a9e8df205f00472e5ab354a4e17") require.Equal(t, expectedGenesisRoot, genTrie.MustHash()) // set state to genesis state - genState := storage.NewTrieState(genTrie) + genState := storage.NewTrieState(&genTrie) cfg := Config{ Storage: genState, @@ -666,17 +661,15 @@ func TestInstance_ExecuteBlock_PolkadotRuntime_PolkadotBlock1(t *testing.T) { func TestInstance_ExecuteBlock_KusamaRuntime_KusamaBlock1(t *testing.T) { genesisPath := utils.GetKusamaGenesisPath(t) - gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - genTrie, err := genesis.NewTrieFromGenesis(gen) + gen := genesisFromRawJSON(t, genesisPath) + genTrie, err := NewTrieFromGenesis(gen) require.NoError(t, err) expectedGenesisRoot := common.MustHexToHash("0xb0006203c3a6e6bd2c6a17b1d4ae8ca49a31da0f4579da950b127774b44aef6b") require.Equal(t, expectedGenesisRoot, genTrie.MustHash()) // set state to genesis state - genState := storage.NewTrieState(genTrie) + genState := storage.NewTrieState(&genTrie) cfg := Config{ Storage: genState, diff --git a/lib/runtime/wasmer/helpers_test.go b/lib/runtime/wasmer/helpers_test.go index c6bda5f811..279dc49966 100644 --- a/lib/runtime/wasmer/helpers_test.go +++ b/lib/runtime/wasmer/helpers_test.go @@ -4,12 +4,31 @@ package wasmer import ( + "encoding/json" + "os" + "path/filepath" "testing" + "github.com/ChainSafe/gossamer/lib/genesis" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +func genesisFromRawJSON(t *testing.T, jsonFilepath string) (gen genesis.Genesis) { + t.Helper() + + fp, err := filepath.Abs(jsonFilepath) + require.NoError(t, err) + + data, err := os.ReadFile(filepath.Clean(fp)) + require.NoError(t, err) + + err = json.Unmarshal(data, &gen) + require.NoError(t, err) + + return gen +} + func Test_pointerSize(t *testing.T) { t.Parallel() diff --git a/lib/trie/genesis_test.go b/lib/trie/genesis_test.go new file mode 100644 index 0000000000..e071709a0e --- /dev/null +++ b/lib/trie/genesis_test.go @@ -0,0 +1,73 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package trie + +import ( + "testing" + + "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/trie/node" + "github.com/ChainSafe/gossamer/lib/common" + "github.com/stretchr/testify/assert" +) + +func Test_Trie_GenesisBlock(t *testing.T) { + t.Parallel() + + withHash := func(header types.Header) types.Header { + header.Hash() + return header + } + + testCases := map[string]struct { + trie Trie + genesisHeader types.Header + errSentinel error + errMessage string + }{ + "empty trie": { + genesisHeader: withHash(types.Header{ + ParentHash: common.Hash{0}, + StateRoot: EmptyHash, + ExtrinsicsRoot: EmptyHash, + Digest: types.NewDigest(), + }), + }, + "non empty trie": { + trie: Trie{ + root: &node.Node{ + Key: []byte{1, 2, 3}, + SubValue: []byte{4, 5, 6}, + }, + }, + genesisHeader: withHash(types.Header{ + ParentHash: common.Hash{0}, + StateRoot: common.Hash{ + 0x25, 0xc1, 0x86, 0xd4, 0x5b, 0xc9, 0x1d, 0x9f, + 0xf5, 0xfd, 0x29, 0xd3, 0x29, 0x8a, 0xa3, 0x63, + 0x83, 0xf3, 0x2d, 0x14, 0xa8, 0xbd, 0xde, 0xc9, + 0x7b, 0x57, 0x92, 0x78, 0x67, 0xfc, 0x8a, 0xfa}, + ExtrinsicsRoot: EmptyHash, + Digest: types.NewDigest(), + }), + }, + } + + for name, testCase := range testCases { + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() + + trie := testCase.trie + + genesisHeader, err := trie.GenesisBlock() + + assert.ErrorIs(t, err, testCase.errSentinel) + if testCase.errSentinel != nil { + assert.EqualError(t, err, testCase.errMessage) + } + assert.Equal(t, testCase.genesisHeader, genesisHeader) + }) + } +} diff --git a/lib/trie/trie.go b/lib/trie/trie.go index aa1a49f48a..735d32c248 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -861,8 +861,6 @@ func (t *Trie) deleteNodesLimit(parent *Node, limit uint32, branch := parent - fullKey := concatenateSlices(prefix, branch.Key) - nilChildren := node.ChildrenCapacity - branch.NumChildren() var newDeleted, newNodesRemoved uint32 @@ -890,7 +888,7 @@ func (t *Trie) deleteNodesLimit(parent *Node, limit uint32, branch.SetDirty() - newParent, branchChildMerged = handleDeletion(branch, fullKey) + newParent, branchChildMerged = handleDeletion(branch, branch.Key) if branchChildMerged { nodesRemoved++ } diff --git a/lib/trie/trie_test.go b/lib/trie/trie_test.go index 7524aa276f..0e9ef8d8ad 100644 --- a/lib/trie/trie_test.go +++ b/lib/trie/trie_test.go @@ -2708,7 +2708,6 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { t.Parallel() testCases := map[string]struct { -<<<<<<< HEAD trie Trie parent *Node limit uint32 @@ -2716,15 +2715,6 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { newNode *Node valuesDeleted uint32 nodesRemoved uint32 -======= - trie Trie - parent *Node - prefix []byte - limit uint32 - newNode *Node - valuesDeleted uint32 - nodesRemoved uint32 ->>>>>>> ccb2005e (reset branch for new head) }{ "zero limit": { trie: Trie{ @@ -2855,8 +2845,7 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { {Key: []byte{3}, SubValue: []byte{1}}, }), }, - prefix: []byte{1, 2}, - limit: 2, + limit: 2, newNode: &Node{ Key: []byte{3, 5, 3}, SubValue: []byte{1}, @@ -2877,12 +2866,8 @@ func Test_Trie_deleteNodesLimit(t *testing.T) { expectedTrie := *trie.DeepCopy() newNode, valuesDeleted, nodesRemoved := -<<<<<<< HEAD trie.deleteNodesLimit(testCase.parent, testCase.limit, testCase.deletedMerkleValues) -======= - trie.deleteNodesLimit(testCase.parent, testCase.prefix, testCase.limit) ->>>>>>> ccb2005e (reset branch for new head) assert.Equal(t, testCase.newNode, newNode) assert.Equal(t, testCase.valuesDeleted, valuesDeleted) From c2f3017a0f8df5690c3b87a902c05c6bb238689e Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 27 Sep 2022 16:11:45 -0600 Subject: [PATCH 04/45] add missing helper func --- dot/core/helpers_test.go | 193 +++++++++++++++++++++++++++++++++------ 1 file changed, 164 insertions(+), 29 deletions(-) diff --git a/dot/core/helpers_test.go b/dot/core/helpers_test.go index 419e4eb494..15790e3dd4 100644 --- a/dot/core/helpers_test.go +++ b/dot/core/helpers_test.go @@ -7,6 +7,7 @@ import ( "path/filepath" "testing" + "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/internal/log" @@ -17,12 +18,169 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/runtime/wasmer" - "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" + "github.com/ChainSafe/gossamer/pkg/scale" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) +func balanceKey(t *testing.T, pub []byte) (bKey []byte) { + t.Helper() + + h0, err := common.Twox128Hash([]byte("System")) + require.NoError(t, err) + h1, err := common.Twox128Hash([]byte("Account")) + require.NoError(t, err) + h2, err := common.Blake2b128(pub) + require.NoError(t, err) + bytes := [][]byte{h0, h1, h2, pub} + return concatenateByteSlices(bytes) +} + +// Note might need to pass in Config but will see +// CreateTestService is a new helper function to clean up orchestration for testing the txnPool +func CreateTestService(t *testing.T, genesisFilePath string, + pubKey []byte, accInfo types.AccountInfo, ctrl *gomock.Controller) (s *Service, encExtrinsic []byte) { + t.Helper() + + // Create genesis + gen, err := genesis.NewGenesisFromJSONRaw(genesisFilePath) + require.NoError(t, err) + + // Trie Created + genTrie, err := genesis.NewTrieFromGenesis(gen) + require.NoError(t, err) + + // Extrinsic and context related stuff + aliceBalanceKey := balanceKey(t, pubKey) + encodedAccountInfo, err := scale.Marshal(accInfo) + require.NoError(t, err) + + genesisHeader := &types.Header{ + StateRoot: genTrie.MustHash(), + Number: 0, + } + + cfg := &Config{} + if cfg.Keystore == nil { + cfg.Keystore = keystore.NewGlobalKeystore() + kp, err := sr25519.GenerateKeypair() + require.NoError(t, err) + err = cfg.Keystore.Acco.Insert(kp) + require.NoError(t, err) + } + + cfg.LogLvl = log.Critical + + // Create state service + var stateSrvc *state.Service + testDatadirPath := t.TempDir() + + // Set up block and storage state + if cfg.BlockState == nil || cfg.StorageState == nil || + cfg.TransactionState == nil || cfg.EpochState == nil || + cfg.CodeSubstitutedState == nil { + telemetryMock := NewMockClient(ctrl) + telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() + + config := state.Config{ + Path: testDatadirPath, + LogLevel: log.Info, + Telemetry: telemetryMock, + } + + stateSrvc = state.NewService(config) + stateSrvc.UseMemDB() + + err := stateSrvc.Initialise(gen, genesisHeader, genTrie) + require.NoError(t, err) + + // Start state service + err = stateSrvc.Start() + require.NoError(t, err) + } + + if cfg.BlockState == nil { + cfg.BlockState = stateSrvc.Block + } + + if cfg.StorageState == nil { + cfg.StorageState = stateSrvc.Storage + } + + if cfg.TransactionState == nil { + cfg.TransactionState = stateSrvc.Transaction + } + + if cfg.EpochState == nil { + cfg.EpochState = stateSrvc.Epoch + } + + if cfg.CodeSubstitutedState == nil { + cfg.CodeSubstitutedState = stateSrvc.Base + } + + // Runtime stuff + if cfg.Runtime == nil { + // Okay no errors, but test doesn't pass + var rtCfg wasmer.Config + rtCfg.Storage = rtstorage.NewTrieState(genTrie) + + var err error + rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) + require.NoError(t, err) + + nodeStorage := runtime.NodeStorage{} + + if stateSrvc != nil { + nodeStorage.BaseDB = stateSrvc.Base + } else { + nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) + require.NoError(t, err) + } + + rtCfg.NodeStorage = nodeStorage + + cfg.Runtime, err = wasmer.NewRuntimeFromGenesis(rtCfg) + require.NoError(t, err) + + cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(aliceBalanceKey, encodedAccountInfo) + // this key is System.UpgradedToDualRefCount -> set to true since all accounts have been upgraded to v0.9 format + cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(common.UpgradedToDualRefKey, []byte{1}) + } + cfg.BlockState.StoreRuntime(cfg.BlockState.BestBlockHash(), cfg.Runtime) + + // Hash of encrypted centrifuge extrinsic + testCallArguments := []byte{0xab, 0xcd} + extHex := runtime.NewTestExtrinsic(t, cfg.Runtime, genesisHeader.Hash(), cfg.BlockState.BestBlockHash(), + 0, "System.remark", testCallArguments) + encExtrinsic = common.MustHexToBytes(extHex) + + if cfg.Network == nil { + cfg.Network = new(network.Service) // only for nil check in NewService + } + + if cfg.CodeSubstitutes == nil { + cfg.CodeSubstitutes = make(map[common.Hash]string) + + genesisData, err := cfg.CodeSubstitutedState.(*state.BaseState).LoadGenesisData() + require.NoError(t, err) + + for k, v := range genesisData.CodeSubstitutes { + cfg.CodeSubstitutes[common.MustHexToHash(k)] = v + } + } + + if cfg.CodeSubstitutedState == nil { + cfg.CodeSubstitutedState = stateSrvc.Base + } + + s, err = NewService(cfg) + require.NoError(t, err) + + return s, encExtrinsic +} + // NewTestService creates a new test core service func NewTestService(t *testing.T, cfg *Config) *Service { t.Helper() @@ -47,7 +205,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { var stateSrvc *state.Service testDatadirPath := t.TempDir() - gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + gen, genTrie, genHeader := genesis.NewTestGenesisWithTrieAndHeader(t) if cfg.BlockState == nil || cfg.StorageState == nil || cfg.TransactionState == nil || cfg.EpochState == nil || @@ -64,7 +222,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { stateSrvc = state.NewService(config) stateSrvc.UseMemDB() - err := stateSrvc.Initialise(&gen, &genesisHeader, &genesisTrie) + err := stateSrvc.Initialise(gen, genHeader, genTrie) require.NoError(t, err) err = stateSrvc.Start() @@ -94,7 +252,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { if cfg.Runtime == nil { var rtCfg wasmer.Config - rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) + rtCfg.Storage = rtstorage.NewTrieState(genTrie) var err error rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) @@ -137,29 +295,6 @@ func NewTestService(t *testing.T, cfg *Config) *Service { return s } -func newTestGenesisWithTrieAndHeader(t *testing.T) ( - gen genesis.Genesis, genesisTrie trie.Trie, genesisHeader types.Header) { - t.Helper() - - genesisPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t) - genPtr, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - gen = *genPtr - - genesisTrie, err = wasmer.NewTrieFromGenesis(gen) - require.NoError(t, err) - - parentHash := common.NewHash([]byte{0}) - stateRoot := genesisTrie.MustHash() - extrinsicRoot := trie.EmptyHash - const number = 0 - digest := types.NewDigest() - genesisHeader = *types.NewHeader(parentHash, - stateRoot, extrinsicRoot, number, digest) - - return gen, genesisTrie, genesisHeader -} - func getGssmrRuntimeCode(t *testing.T) (code []byte) { t.Helper() @@ -169,10 +304,10 @@ func getGssmrRuntimeCode(t *testing.T) (code []byte) { gssmrGenesis, err := genesis.NewGenesisFromJSONRaw(path) require.NoError(t, err) - genesisTrie, err := wasmer.NewTrieFromGenesis(*gssmrGenesis) + trie, err := genesis.NewTrieFromGenesis(gssmrGenesis) require.NoError(t, err) - trieState := rtstorage.NewTrieState(&genesisTrie) + trieState := rtstorage.NewTrieState(trie) return trieState.LoadCode() } From e66f967567b27be1bb9074ef42ddfcb2bc234345 Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 27 Sep 2022 16:32:09 -0600 Subject: [PATCH 05/45] retrieve old core helper from git history --- dot/core/helpers_test.go | 42 +++++++++++++++++----- dot/rpc/modules/author_integration_test.go | 21 +++-------- dot/state/initialize.go | 2 +- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/dot/core/helpers_test.go b/dot/core/helpers_test.go index 15790e3dd4..763cf5dad1 100644 --- a/dot/core/helpers_test.go +++ b/dot/core/helpers_test.go @@ -18,6 +18,7 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/runtime/wasmer" + "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/golang/mock/gomock" @@ -48,7 +49,7 @@ func CreateTestService(t *testing.T, genesisFilePath string, require.NoError(t, err) // Trie Created - genTrie, err := genesis.NewTrieFromGenesis(gen) + genesisTrie, err := wasmer.NewTrieFromGenesis(*gen) require.NoError(t, err) // Extrinsic and context related stuff @@ -57,7 +58,7 @@ func CreateTestService(t *testing.T, genesisFilePath string, require.NoError(t, err) genesisHeader := &types.Header{ - StateRoot: genTrie.MustHash(), + StateRoot: genesisTrie.MustHash(), Number: 0, } @@ -92,7 +93,7 @@ func CreateTestService(t *testing.T, genesisFilePath string, stateSrvc = state.NewService(config) stateSrvc.UseMemDB() - err := stateSrvc.Initialise(gen, genesisHeader, genTrie) + err := stateSrvc.Initialise(gen, genesisHeader, &genesisTrie) require.NoError(t, err) // Start state service @@ -124,7 +125,7 @@ func CreateTestService(t *testing.T, genesisFilePath string, if cfg.Runtime == nil { // Okay no errors, but test doesn't pass var rtCfg wasmer.Config - rtCfg.Storage = rtstorage.NewTrieState(genTrie) + rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) var err error rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) @@ -205,7 +206,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { var stateSrvc *state.Service testDatadirPath := t.TempDir() - gen, genTrie, genHeader := genesis.NewTestGenesisWithTrieAndHeader(t) + gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) if cfg.BlockState == nil || cfg.StorageState == nil || cfg.TransactionState == nil || cfg.EpochState == nil || @@ -222,7 +223,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { stateSrvc = state.NewService(config) stateSrvc.UseMemDB() - err := stateSrvc.Initialise(gen, genHeader, genTrie) + err := stateSrvc.Initialise(&gen, &genesisHeader, &genesisTrie) require.NoError(t, err) err = stateSrvc.Start() @@ -252,7 +253,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { if cfg.Runtime == nil { var rtCfg wasmer.Config - rtCfg.Storage = rtstorage.NewTrieState(genTrie) + rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) var err error rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) @@ -295,6 +296,29 @@ func NewTestService(t *testing.T, cfg *Config) *Service { return s } +func newTestGenesisWithTrieAndHeader(t *testing.T) ( + gen genesis.Genesis, genesisTrie trie.Trie, genesisHeader types.Header) { + t.Helper() + + genesisPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t) + genPtr, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + gen = *genPtr + + genesisTrie, err = wasmer.NewTrieFromGenesis(gen) + require.NoError(t, err) + + parentHash := common.NewHash([]byte{0}) + stateRoot := genesisTrie.MustHash() + extrinsicRoot := trie.EmptyHash + const number = 0 + digest := types.NewDigest() + genesisHeader = *types.NewHeader(parentHash, + stateRoot, extrinsicRoot, number, digest) + + return gen, genesisTrie, genesisHeader +} + func getGssmrRuntimeCode(t *testing.T) (code []byte) { t.Helper() @@ -304,10 +328,10 @@ func getGssmrRuntimeCode(t *testing.T) (code []byte) { gssmrGenesis, err := genesis.NewGenesisFromJSONRaw(path) require.NoError(t, err) - trie, err := genesis.NewTrieFromGenesis(gssmrGenesis) + genesisTrie, err := wasmer.NewTrieFromGenesis(*gssmrGenesis) require.NoError(t, err) - trieState := rtstorage.NewTrieState(trie) + trieState := rtstorage.NewTrieState(&genesisTrie) return trieState.LoadCode() } diff --git a/dot/rpc/modules/author_integration_test.go b/dot/rpc/modules/author_integration_test.go index 5172b32599..7f385581b1 100644 --- a/dot/rpc/modules/author_integration_test.go +++ b/dot/rpc/modules/author_integration_test.go @@ -555,19 +555,11 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { integrationTestController.stateSrv.Transaction = state.NewTransactionState(telemetryMock) genesisHash := integrationTestController.genesisHeader.Hash() - - extHex := runtime.NewTestExtrinsic(t, - integrationTestController.runtime, genesisHash, genesisHash, 1, "System.remark", []byte{0xab, 0xcd}) - - // to extrinsic works with a runtime version 0910 we need to - // append the block hash bytes at the end of the extrinsics - hashBytes := genesisHash.ToBytes() - extBytes := append(common.MustHexToBytes(extHex), hashBytes...) - - extHex = common.BytesToHex(extBytes) + ext := createExtrinsic(t, integrationTestController.runtime, genesisHash, 0) + extHex := common.BytesToHex(ext) net2test := NewMockNetwork(ctrl) - net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{extBytes}}) + net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{ext}}) integrationTestController.network = net2test // setup auth module @@ -577,16 +569,13 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { err := auth.SubmitExtrinsic(nil, &Extrinsic{extHex}, res) require.NoError(t, err) - expectedExtrinsic := types.NewExtrinsic(extBytes) + expectedExtrinsic := types.NewExtrinsic(ext) expected := &transaction.ValidTransaction{ Extrinsic: expectedExtrinsic, Validity: &transaction.Validity{ Priority: 4295664014726, - Requires: [][]byte{ - common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d00000000"), - }, Provides: [][]byte{ - common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000"), + common.MustHexToBytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d00000000"), }, Longevity: 18446744073709551613, Propagate: true, diff --git a/dot/state/initialize.go b/dot/state/initialize.go index 733c953520..565e30fb72 100644 --- a/dot/state/initialize.go +++ b/dot/state/initialize.go @@ -5,12 +5,12 @@ package state import ( "fmt" - "github.com/ChainSafe/gossamer/lib/common" "path/filepath" "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/state/pruner" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/genesis" "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" From 811f96436014b5a88f813bfad2ad390f2e105a1a Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 27 Sep 2022 16:33:36 -0600 Subject: [PATCH 06/45] remove unneeded diff --- dot/digest/digest_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dot/digest/digest_test.go b/dot/digest/digest_test.go index 23f3a005d3..a61e82da49 100644 --- a/dot/digest/digest_test.go +++ b/dot/digest/digest_test.go @@ -39,8 +39,8 @@ func newTestHandler(t *testing.T) (*Handler, *state.Service) { stateSrvc := state.NewService(config) stateSrvc.UseMemDB() - gen, genTrie, genHeader := newTestGenesisWithTrieAndHeader(t) - err := stateSrvc.Initialise(&gen, &genHeader, &genTrie) + gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + err := stateSrvc.Initialise(&gen, &genesisHeader, &genesisTrie) require.NoError(t, err) err = stateSrvc.SetupBase() From 9a83c71139ed6a2d98add7109616f0b2aaf23294 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 28 Sep 2022 11:45:02 -0600 Subject: [PATCH 07/45] remove nil checks from createTestService --- dot/core/helpers_test.go | 128 +++++++++++++++------------------------ 1 file changed, 50 insertions(+), 78 deletions(-) diff --git a/dot/core/helpers_test.go b/dot/core/helpers_test.go index 763cf5dad1..3f5b68375d 100644 --- a/dot/core/helpers_test.go +++ b/dot/core/helpers_test.go @@ -38,7 +38,6 @@ func balanceKey(t *testing.T, pub []byte) (bKey []byte) { return concatenateByteSlices(bytes) } -// Note might need to pass in Config but will see // CreateTestService is a new helper function to clean up orchestration for testing the txnPool func CreateTestService(t *testing.T, genesisFilePath string, pubKey []byte, accInfo types.AccountInfo, ctrl *gomock.Controller) (s *Service, encExtrinsic []byte) { @@ -63,13 +62,13 @@ func CreateTestService(t *testing.T, genesisFilePath string, } cfg := &Config{} - if cfg.Keystore == nil { - cfg.Keystore = keystore.NewGlobalKeystore() - kp, err := sr25519.GenerateKeypair() - require.NoError(t, err) - err = cfg.Keystore.Acco.Insert(kp) - require.NoError(t, err) - } + + //Construct keystore + cfg.Keystore = keystore.NewGlobalKeystore() + kp, err := sr25519.GenerateKeypair() + require.NoError(t, err) + err = cfg.Keystore.Acco.Insert(kp) + require.NoError(t, err) cfg.LogLvl = log.Critical @@ -78,77 +77,56 @@ func CreateTestService(t *testing.T, genesisFilePath string, testDatadirPath := t.TempDir() // Set up block and storage state - if cfg.BlockState == nil || cfg.StorageState == nil || - cfg.TransactionState == nil || cfg.EpochState == nil || - cfg.CodeSubstitutedState == nil { - telemetryMock := NewMockClient(ctrl) - telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - - config := state.Config{ - Path: testDatadirPath, - LogLevel: log.Info, - Telemetry: telemetryMock, - } - - stateSrvc = state.NewService(config) - stateSrvc.UseMemDB() - - err := stateSrvc.Initialise(gen, genesisHeader, &genesisTrie) - require.NoError(t, err) - - // Start state service - err = stateSrvc.Start() - require.NoError(t, err) - } + telemetryMock := NewMockClient(ctrl) + telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - if cfg.BlockState == nil { - cfg.BlockState = stateSrvc.Block + config := state.Config{ + Path: testDatadirPath, + LogLevel: log.Info, + Telemetry: telemetryMock, } - if cfg.StorageState == nil { - cfg.StorageState = stateSrvc.Storage - } + stateSrvc = state.NewService(config) + stateSrvc.UseMemDB() - if cfg.TransactionState == nil { - cfg.TransactionState = stateSrvc.Transaction - } + err = stateSrvc.Initialise(gen, genesisHeader, &genesisTrie) + require.NoError(t, err) - if cfg.EpochState == nil { - cfg.EpochState = stateSrvc.Epoch - } + // Start state service + err = stateSrvc.Start() + require.NoError(t, err) - if cfg.CodeSubstitutedState == nil { - cfg.CodeSubstitutedState = stateSrvc.Base - } + cfg.BlockState = stateSrvc.Block + cfg.StorageState = stateSrvc.Storage + cfg.TransactionState = stateSrvc.Transaction + cfg.EpochState = stateSrvc.Epoch + cfg.CodeSubstitutedState = stateSrvc.Base // Runtime stuff - if cfg.Runtime == nil { - // Okay no errors, but test doesn't pass - var rtCfg wasmer.Config - rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) + var rtCfg wasmer.Config + rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) - var err error - rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) - require.NoError(t, err) + rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) + require.NoError(t, err) - nodeStorage := runtime.NodeStorage{} + nodeStorage := runtime.NodeStorage{} - if stateSrvc != nil { - nodeStorage.BaseDB = stateSrvc.Base - } else { - nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) - require.NoError(t, err) - } + if stateSrvc != nil { + nodeStorage.BaseDB = stateSrvc.Base + } else { + nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) + require.NoError(t, err) + } - rtCfg.NodeStorage = nodeStorage + rtCfg.NodeStorage = nodeStorage - cfg.Runtime, err = wasmer.NewRuntimeFromGenesis(rtCfg) - require.NoError(t, err) + cfg.Runtime, err = wasmer.NewRuntimeFromGenesis(rtCfg) + require.NoError(t, err) + + cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(aliceBalanceKey, encodedAccountInfo) + // this key is System.UpgradedToDualRefCount -> set to true since all accounts have been upgraded to v0.9 format + cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(common.UpgradedToDualRefKey, []byte{1}) - cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(aliceBalanceKey, encodedAccountInfo) - // this key is System.UpgradedToDualRefCount -> set to true since all accounts have been upgraded to v0.9 format - cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(common.UpgradedToDualRefKey, []byte{1}) - } cfg.BlockState.StoreRuntime(cfg.BlockState.BestBlockHash(), cfg.Runtime) // Hash of encrypted centrifuge extrinsic @@ -157,24 +135,18 @@ func CreateTestService(t *testing.T, genesisFilePath string, 0, "System.remark", testCallArguments) encExtrinsic = common.MustHexToBytes(extHex) - if cfg.Network == nil { - cfg.Network = new(network.Service) // only for nil check in NewService - } + cfg.Network = new(network.Service) // only for nil check in NewService - if cfg.CodeSubstitutes == nil { - cfg.CodeSubstitutes = make(map[common.Hash]string) + cfg.CodeSubstitutes = make(map[common.Hash]string) - genesisData, err := cfg.CodeSubstitutedState.(*state.BaseState).LoadGenesisData() - require.NoError(t, err) + genesisData, err := cfg.CodeSubstitutedState.(*state.BaseState).LoadGenesisData() + require.NoError(t, err) - for k, v := range genesisData.CodeSubstitutes { - cfg.CodeSubstitutes[common.MustHexToHash(k)] = v - } + for k, v := range genesisData.CodeSubstitutes { + cfg.CodeSubstitutes[common.MustHexToHash(k)] = v } - if cfg.CodeSubstitutedState == nil { - cfg.CodeSubstitutedState = stateSrvc.Base - } + cfg.CodeSubstitutedState = stateSrvc.Base s, err = NewService(cfg) require.NoError(t, err) From 453c50c29d2f168568b06abb5a6f36d6ec57edee Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 28 Sep 2022 12:23:35 -0600 Subject: [PATCH 08/45] respond to feedback --- dot/core/helpers.go | 16 ---------- dot/core/helpers_test.go | 29 +++++++------------ dot/core/messages.go | 2 +- dot/core/messages_test.go | 9 +++--- dot/core/service.go | 21 +++++--------- dot/core/service_integration_test.go | 4 +-- dot/core/service_test.go | 20 ++++++------- dot/rpc/modules/author_integration_test.go | 26 ++++++++--------- lib/blocktree/mocks_generate_test.go | 2 +- .../{mock_instance_test.go => mocks_test.go} | 0 lib/runtime/version.go | 12 ++++---- 11 files changed, 56 insertions(+), 85 deletions(-) delete mode 100644 dot/core/helpers.go rename lib/blocktree/{mock_instance_test.go => mocks_test.go} (100%) diff --git a/dot/core/helpers.go b/dot/core/helpers.go deleted file mode 100644 index 2da5c73234..0000000000 --- a/dot/core/helpers.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2021 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package core - -func concatenateByteSlices(slices [][]byte) (concatenated []byte) { - length := 0 - for i := range slices { - length += len(slices[i]) - } - concatenated = make([]byte, 0, length) - for _, slice := range slices { - concatenated = append(concatenated, slice...) - } - return concatenated -} diff --git a/dot/core/helpers_test.go b/dot/core/helpers_test.go index 3f5b68375d..810034306e 100644 --- a/dot/core/helpers_test.go +++ b/dot/core/helpers_test.go @@ -4,6 +4,7 @@ package core import ( + "bytes" "path/filepath" "testing" @@ -34,26 +35,24 @@ func balanceKey(t *testing.T, pub []byte) (bKey []byte) { require.NoError(t, err) h2, err := common.Blake2b128(pub) require.NoError(t, err) - bytes := [][]byte{h0, h1, h2, pub} - return concatenateByteSlices(bytes) + bytesToConcat := [][]byte{h0, h1, h2, pub} + return bytes.Join(bytesToConcat, nil) } -// CreateTestService is a new helper function to clean up orchestration for testing the txnPool -func CreateTestService(t *testing.T, genesisFilePath string, - pubKey []byte, accInfo types.AccountInfo, ctrl *gomock.Controller) (s *Service, encExtrinsic []byte) { +// Creates test service, used now for testing txnPool but can be used elsewhere when needed +func createTestService(t *testing.T, genesisFilePath string, + pubKey []byte, accountInfo types.AccountInfo, ctrl *gomock.Controller) (service *Service, encodedExtrinsic []byte) { t.Helper() - // Create genesis gen, err := genesis.NewGenesisFromJSONRaw(genesisFilePath) require.NoError(t, err) - // Trie Created genesisTrie, err := wasmer.NewTrieFromGenesis(*gen) require.NoError(t, err) // Extrinsic and context related stuff aliceBalanceKey := balanceKey(t, pubKey) - encodedAccountInfo, err := scale.Marshal(accInfo) + encodedAccountInfo, err := scale.Marshal(accountInfo) require.NoError(t, err) genesisHeader := &types.Header{ @@ -110,13 +109,7 @@ func CreateTestService(t *testing.T, genesisFilePath string, require.NoError(t, err) nodeStorage := runtime.NodeStorage{} - - if stateSrvc != nil { - nodeStorage.BaseDB = stateSrvc.Base - } else { - nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) - require.NoError(t, err) - } + nodeStorage.BaseDB = stateSrvc.Base rtCfg.NodeStorage = nodeStorage @@ -133,7 +126,7 @@ func CreateTestService(t *testing.T, genesisFilePath string, testCallArguments := []byte{0xab, 0xcd} extHex := runtime.NewTestExtrinsic(t, cfg.Runtime, genesisHeader.Hash(), cfg.BlockState.BestBlockHash(), 0, "System.remark", testCallArguments) - encExtrinsic = common.MustHexToBytes(extHex) + encodedExtrinsic = common.MustHexToBytes(extHex) cfg.Network = new(network.Service) // only for nil check in NewService @@ -148,10 +141,10 @@ func CreateTestService(t *testing.T, genesisFilePath string, cfg.CodeSubstitutedState = stateSrvc.Base - s, err = NewService(cfg) + service, err = NewService(cfg) require.NoError(t, err) - return s, encExtrinsic + return service, encodedExtrinsic } // NewTestService creates a new test core service diff --git a/dot/core/messages.go b/dot/core/messages.go index fe92178bb9..a5eed4c6e9 100644 --- a/dot/core/messages.go +++ b/dot/core/messages.go @@ -30,7 +30,7 @@ func (s *Service) validateTransaction(head *types.Header, rt RuntimeInstance, // validate each transaction externalExt, err := s.buildExternalTransaction(rt, tx) if err != nil { - return nil, fmt.Errorf("building transaction: %s", err) + return nil, fmt.Errorf("building external transaction: %s", err) } validity, err = rt.ValidateTransaction(externalExt) diff --git a/dot/core/messages_test.go b/dot/core/messages_test.go index 9fb1753eca..cbf1c35d48 100644 --- a/dot/core/messages_test.go +++ b/dot/core/messages_test.go @@ -4,6 +4,7 @@ package core import ( + "bytes" "errors" "testing" @@ -263,11 +264,11 @@ func TestServiceHandleTransactionMessage(t *testing.T) { runtime: runtimeMock2, setContextStorage: &mockSetContextStorage{trieState: &storage.TrieState{}}, validateTxn: &mockValidateTxn{ - input: types.Extrinsic(concatenateByteSlices([][]byte{ + input: types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, testExtrinsic[0], testEmptyHeader.StateRoot.ToBytes(), - })), + }, nil)), err: invalidTransaction, }, }, @@ -315,11 +316,11 @@ func TestServiceHandleTransactionMessage(t *testing.T) { runtime: runtimeMock3, setContextStorage: &mockSetContextStorage{trieState: &storage.TrieState{}}, validateTxn: &mockValidateTxn{ - input: types.Extrinsic(concatenateByteSlices([][]byte{ + input: types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, testExtrinsic[0], testEmptyHeader.StateRoot.ToBytes(), - })), + }, nil)), validity: &transaction.Validity{Propagate: true}, }, }, diff --git a/dot/core/service.go b/dot/core/service.go index b201982f9a..30cf489f3f 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -31,9 +31,6 @@ var ( logger = log.NewFromGlobal(log.AddContext("pkg", "core")) ) -const supportedTxVersion = 3 -const previousSupportedTxVersion = 2 - // QueryKeyValueChanges represents the key-value data inside a block storage type QueryKeyValueChanges map[string]string @@ -610,21 +607,19 @@ func (s *Service) GetReadProofAt(block common.Hash, keys [][]byte) ( // buildExternalTransaction builds an external transaction based on the current TransactionQueueAPIVersion // See https://github.com/paritytech/substrate/blob/polkadot-v0.9.25/primitives/transaction-pool/src/runtime_api.rs#L25-L55 func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrinsic) (types.Extrinsic, error) { + const supportedTxVersion = 3 + const previousSupportedTxVersion = 2 + runtimeVersion := rt.Version() - txQueueVersion := runtimeVersion.TaggedTransactionQueueVersion(runtimeVersion) + txQueueVersion := runtime.TaggedTransactionQueueVersion(runtimeVersion) var externalExt types.Extrinsic switch txQueueVersion { case supportedTxVersion: - externalExt = types.Extrinsic(concatenateByteSlices([][]byte{ - {byte(types.TxnExternal)}, - ext, - s.blockState.BestBlockHash().ToBytes(), - })) + extrinsicParts := [][]byte{{byte(types.TxnExternal)}, ext, s.blockState.BestBlockHash().ToBytes()} + externalExt = types.Extrinsic(bytes.Join(extrinsicParts, nil)) case previousSupportedTxVersion: - externalExt = types.Extrinsic(concatenateByteSlices([][]byte{ - {byte(types.TxnExternal)}, - ext, - })) + extrinsicParts := [][]byte{{byte(types.TxnExternal)}, ext} + externalExt = types.Extrinsic(bytes.Join(extrinsicParts, nil)) default: return types.Extrinsic{}, errInvalidTransactionQueueVersion } diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index 99ee102286..c09a651ec7 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -357,7 +357,7 @@ func TestMaintainTransactionPoolLatestTxnQueue_EmptyBlock(t *testing.T) { require.NoError(t, err) ctrl := gomock.NewController(t) - service, encExt := CreateTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) + service, encExt := createTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) tx := &transaction.ValidTransaction{ Extrinsic: types.Extrinsic(encExt), @@ -406,7 +406,7 @@ func TestMaintainTransactionPoolLatestTxnQueue_BlockWithExtrinsics(t *testing.T) require.NoError(t, err) ctrl := gomock.NewController(t) - service, encExt := CreateTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) + service, encExt := createTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) tx := &transaction.ValidTransaction{ Extrinsic: types.Extrinsic(encExt), diff --git a/dot/core/service_test.go b/dot/core/service_test.go index bda466c0d1..cf5658809c 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -113,11 +113,11 @@ func generateExtrinsic(t *testing.T) (extrinsic, externalExtrinsic types.Extrins encExt := []types.Extrinsic{extEnc.Bytes()} testHeader := types.NewEmptyHeader() - testExternalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + testExternalExt := types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, encExt[0], testHeader.StateRoot.ToBytes(), - })) + }, nil)) testUnencryptedBody := types.NewBody(encExt) return encExt[0], testExternalExt, testUnencryptedBody } @@ -561,11 +561,11 @@ func Test_Service_maintainTransactionPool(t *testing.T) { } ext := types.Extrinsic{21} - externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + externalExt := types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, ext, testHeader.StateRoot.ToBytes(), - })) + }, nil)) vt := transaction.NewValidTransaction(ext, validity) ctrl := gomock.NewController(t) @@ -621,11 +621,11 @@ func Test_Service_maintainTransactionPool(t *testing.T) { } ext := types.Extrinsic{21} - externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + externalExt := types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, ext, testHeader.StateRoot.ToBytes(), - })) + }, nil)) vt := transaction.NewValidTransaction(ext, validity) tx := transaction.NewValidTransaction(ext, &transaction.Validity{Propagate: true}) @@ -733,11 +733,11 @@ func Test_Service_handleBlocksAsync(t *testing.T) { extrinsic := types.Extrinsic{21} testHeader := types.NewEmptyHeader() - externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + externalExt := types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, extrinsic, testHeader.StateRoot.ToBytes(), - })) + }, nil)) vt := transaction.NewValidTransaction(extrinsic, validity) block := types.NewBlock(*testHeader, *types.NewBody([]types.Extrinsic{[]byte{21}})) @@ -1205,11 +1205,11 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { t.Parallel() ext := types.Extrinsic{} testHeader := types.NewEmptyHeader() - externalExt := types.Extrinsic(concatenateByteSlices([][]byte{ + externalExt := types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, ext, testHeader.StateRoot.ToBytes(), - })) + }, nil)) execTest := func(t *testing.T, s *Service, ext types.Extrinsic, expErr error) { err := s.HandleSubmittedExtrinsic(ext) assert.ErrorIs(t, err, expErr) diff --git a/dot/rpc/modules/author_integration_test.go b/dot/rpc/modules/author_integration_test.go index 7f385581b1..af05882d39 100644 --- a/dot/rpc/modules/author_integration_test.go +++ b/dot/rpc/modules/author_integration_test.go @@ -97,31 +97,31 @@ func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, non err = ctypes.Decode(decoded, meta) require.NoError(t, err) - rv := rt.Version() + runtimeVersion := rt.Version() - c, err := ctypes.NewCall(meta, "System.remark", []byte{0xab, 0xcd}) + metaCall, err := ctypes.NewCall(meta, "System.remark", []byte{0xab, 0xcd}) require.NoError(t, err) - ext := ctypes.NewExtrinsic(c) + extrinsic := ctypes.NewExtrinsic(metaCall) options := ctypes.SignatureOptions{ BlockHash: ctypes.Hash(genHash), Era: ctypes.ExtrinsicEra{IsImmortalEra: false}, GenesisHash: ctypes.Hash(genHash), Nonce: ctypes.NewUCompactFromUInt(nonce), - SpecVersion: ctypes.U32(rv.SpecVersion), + SpecVersion: ctypes.U32(runtimeVersion.SpecVersion), Tip: ctypes.NewUCompactFromUInt(0), - TransactionVersion: ctypes.U32(rv.TransactionVersion), + TransactionVersion: ctypes.U32(runtimeVersion.TransactionVersion), } // Sign the transaction using Alice's key - err = ext.Sign(signature.TestKeyringPairAlice, options) + err = extrinsic.Sign(signature.TestKeyringPairAlice, options) require.NoError(t, err) - extEnc, err := ctypes.EncodeToHex(ext) + extEnc, err := ctypes.EncodeToHex(extrinsic) require.NoError(t, err) - extBytes := types.Extrinsic(common.MustHexToBytes(extEnc)) - return extBytes + extrinsicBytes := common.MustHexToBytes(extEnc) + return extrinsicBytes } func TestAuthorModule_Pending_Integration(t *testing.T) { @@ -555,11 +555,11 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { integrationTestController.stateSrv.Transaction = state.NewTransactionState(telemetryMock) genesisHash := integrationTestController.genesisHeader.Hash() - ext := createExtrinsic(t, integrationTestController.runtime, genesisHash, 0) - extHex := common.BytesToHex(ext) + extrinsic := createExtrinsic(t, integrationTestController.runtime, genesisHash, 0) + extHex := common.BytesToHex(extrinsic) net2test := NewMockNetwork(ctrl) - net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{ext}}) + net2test.EXPECT().GossipMessage(&network.TransactionMessage{Extrinsics: []types.Extrinsic{extrinsic}}) integrationTestController.network = net2test // setup auth module @@ -569,7 +569,7 @@ func TestAuthorModule_SubmitExtrinsic_WithVersion_V0910(t *testing.T) { err := auth.SubmitExtrinsic(nil, &Extrinsic{extHex}, res) require.NoError(t, err) - expectedExtrinsic := types.NewExtrinsic(ext) + expectedExtrinsic := types.NewExtrinsic(extrinsic) expected := &transaction.ValidTransaction{ Extrinsic: expectedExtrinsic, Validity: &transaction.Validity{ diff --git a/lib/blocktree/mocks_generate_test.go b/lib/blocktree/mocks_generate_test.go index 7c0666c0d2..b28c8d756b 100644 --- a/lib/blocktree/mocks_generate_test.go +++ b/lib/blocktree/mocks_generate_test.go @@ -3,4 +3,4 @@ package blocktree -//go:generate mockgen -destination=mock_instance_test.go -package $GOPACKAGE github.com/ChainSafe/gossamer/lib/runtime Instance +//go:generate mockgen -destination=mocks_test.go -package $GOPACKAGE github.com/ChainSafe/gossamer/lib/runtime Instance diff --git a/lib/blocktree/mock_instance_test.go b/lib/blocktree/mocks_test.go similarity index 100% rename from lib/blocktree/mock_instance_test.go rename to lib/blocktree/mocks_test.go diff --git a/lib/runtime/version.go b/lib/runtime/version.go index 53cb2938d6..4152394278 100644 --- a/lib/runtime/version.go +++ b/lib/runtime/version.go @@ -38,15 +38,13 @@ var ( ) // TaggedTransactionQueueVersion returns the TaggedTransactionQueueAPI version -func (*Version) TaggedTransactionQueueVersion(runtimeVersion Version) uint32 { - txQueueVersion := uint32(0) - for _, v := range runtimeVersion.APIItems { - if v.Name == encodedTaggedTransactionQueue { - txQueueVersion = v.Ver - break +func TaggedTransactionQueueVersion(runtimeVersion Version) (txQueueVersion uint32) { + for _, apiItem := range runtimeVersion.APIItems { + if apiItem.Name == encodedTaggedTransactionQueue { + return apiItem.Ver } } - return txQueueVersion + return 0 } // DecodeVersion scale decodes the encoded version data. From 51b331ea6e1913a95deacd6a63f4dcd3a15b0a4f Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 4 Oct 2022 15:21:18 -0600 Subject: [PATCH 09/45] feedback --- dot/core/service.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 30cf489f3f..8cc500ffe2 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -293,9 +293,7 @@ func (s *Service) handleCodeSubstitution(hash common.Hash, // does not need to be completed before the next block can be imported. func (s *Service) handleBlocksAsync() { for { - // TODO Look into if this is best way to get prev - // Maybe pass in block and get parent rather than assume that - // best block hash is the parent + // TODO Move this down to befre handleChainReorg call prev := s.blockState.BestBlockHash() select { @@ -428,6 +426,7 @@ func (s *Service) maintainTransactionPool(block *types.Block) { externalExt, err := s.buildExternalTransaction(rt, tx.Extrinsic) if err != nil { logger.Errorf("Unable to build external transaction: %s", err) + continue } txnValidity, err := rt.ValidateTransaction(externalExt) From 621514f93a20a8848ecb74fb7fac73e35d406de4 Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 4 Oct 2022 15:54:21 -0600 Subject: [PATCH 10/45] fix author integration tests --- dot/rpc/modules/author_integration_test.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dot/rpc/modules/author_integration_test.go b/dot/rpc/modules/author_integration_test.go index af05882d39..4605281641 100644 --- a/dot/rpc/modules/author_integration_test.go +++ b/dot/rpc/modules/author_integration_test.go @@ -6,9 +6,12 @@ package modules import ( + "bytes" "context" "errors" "fmt" + cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale" + "github.com/centrifuge/go-substrate-rpc-client/v4/types/codec" "os" "testing" @@ -94,7 +97,7 @@ func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, non meta := &ctypes.Metadata{} - err = ctypes.Decode(decoded, meta) + err = codec.Decode(decoded, meta) require.NoError(t, err) runtimeVersion := rt.Version() @@ -117,11 +120,12 @@ func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, non err = extrinsic.Sign(signature.TestKeyringPairAlice, options) require.NoError(t, err) - extEnc, err := ctypes.EncodeToHex(extrinsic) + extEnc := bytes.Buffer{} + encoder := cscale.NewEncoder(&extEnc) + err = extrinsic.Encode(*encoder) require.NoError(t, err) - - extrinsicBytes := common.MustHexToBytes(extEnc) - return extrinsicBytes + + return extEnc.Bytes() } func TestAuthorModule_Pending_Integration(t *testing.T) { From 774f9765688cf7f94ca4fe355c0db096d0d63122 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 5 Oct 2022 13:47:08 -0600 Subject: [PATCH 11/45] clean up handle block async logic --- dot/core/service.go | 4 +--- dot/core/service_test.go | 14 +------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 8cc500ffe2..5ca6dd0d70 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -293,9 +293,6 @@ func (s *Service) handleCodeSubstitution(hash common.Hash, // does not need to be completed before the next block can be imported. func (s *Service) handleBlocksAsync() { for { - // TODO Move this down to befre handleChainReorg call - prev := s.blockState.BestBlockHash() - select { case block, ok := <-s.blockAddCh: if !ok { @@ -306,6 +303,7 @@ func (s *Service) handleBlocksAsync() { continue } + prev := s.blockState.BestBlockHash() if err := s.handleChainReorg(prev, block.Header.Hash()); err != nil { logger.Warnf("failed to re-add transactions to chain upon re-org: %s", err) } diff --git a/dot/core/service_test.go b/dot/core/service_test.go index cf5658809c..dc9ad90a3d 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -672,14 +672,10 @@ func Test_Service_handleBlocksAsync(t *testing.T) { t.Parallel() t.Run("cancelled context", func(t *testing.T) { t.Parallel() - ctrl := gomock.NewController(t) - mockBlockState := NewMockBlockState(ctrl) - mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) blockAddChan := make(chan *types.Block) ctx, cancel := context.WithCancel(context.Background()) cancel() service := &Service{ - blockState: mockBlockState, blockAddCh: blockAddChan, ctx: ctx, } @@ -688,13 +684,9 @@ func Test_Service_handleBlocksAsync(t *testing.T) { t.Run("channel not ok", func(t *testing.T) { t.Parallel() - ctrl := gomock.NewController(t) - mockBlockState := NewMockBlockState(ctrl) - mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) blockAddChan := make(chan *types.Block) close(blockAddChan) service := &Service{ - blockState: mockBlockState, blockAddCh: blockAddChan, ctx: context.Background(), } @@ -703,16 +695,12 @@ func Test_Service_handleBlocksAsync(t *testing.T) { t.Run("nil block", func(t *testing.T) { t.Parallel() - ctrl := gomock.NewController(t) - mockBlockState := NewMockBlockState(ctrl) - mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) blockAddChan := make(chan *types.Block) go func() { blockAddChan <- nil close(blockAddChan) }() service := &Service{ - blockState: mockBlockState, blockAddCh: blockAddChan, ctx: context.Background(), } @@ -765,7 +753,7 @@ func Test_Service_handleBlocksAsync(t *testing.T) { mockBlockState.EXPECT().HighestCommonAncestor(common.Hash{}, block.Header.Hash()). Return(common.Hash{}, errTestDummyError) mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) - mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockTxnStateErr := NewMockTransactionState(ctrl) mockTxnStateErr.EXPECT().RemoveExtrinsic(types.Extrinsic{21}).Times(2) From 7028dc2933701345a5b713dbcb039f988309de96 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 5 Oct 2022 13:56:23 -0600 Subject: [PATCH 12/45] make maintainTxnPool return error --- dot/core/service.go | 9 +++++++-- dot/core/service_integration_test.go | 6 ++++-- dot/core/service_test.go | 6 ++++-- dot/rpc/modules/author_integration_test.go | 6 +++--- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 5ca6dd0d70..61a9825007 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -308,7 +308,9 @@ func (s *Service) handleBlocksAsync() { logger.Warnf("failed to re-add transactions to chain upon re-org: %s", err) } - s.maintainTransactionPool(block) + if err := s.maintainTransactionPool(block); err != nil { + logger.Warnf("failed to maintain txn pool after re-org: %s", err) + } case <-s.ctx.Done(): return } @@ -394,7 +396,7 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { // the new block, revalidates the transactions in the pool, and moves // them to the queue if valid. // See https://github.com/paritytech/substrate/blob/74804b5649eccfb83c90aec87bdca58e5d5c8789/client/transaction-pool/src/lib.rs#L545 -func (s *Service) maintainTransactionPool(block *types.Block) { +func (s *Service) maintainTransactionPool(block *types.Block) error { // remove extrinsics included in a block for _, ext := range block.Body { s.transactionState.RemoveExtrinsic(ext) @@ -404,11 +406,13 @@ func (s *Service) maintainTransactionPool(block *types.Block) { stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) if err != nil { logger.Errorf("could not get state root from block %s: %w", bestBlockHash, err) + return err } ts, err := s.storageState.TrieState(stateRoot) if err != nil { logger.Errorf(err.Error()) + return err } // re-validate transactions in the pool and move them to the queue @@ -441,6 +445,7 @@ func (s *Service) maintainTransactionPool(block *types.Block) { s.transactionState.RemoveExtrinsicFromPool(tx.Extrinsic) logger.Tracef("moved transaction %s to queue", h) } + return nil } // InsertKey inserts keypair into the account keystore diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index c09a651ec7..8696c2ce0c 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -377,9 +377,10 @@ func TestMaintainTransactionPoolLatestTxnQueue_EmptyBlock(t *testing.T) { expectedTx := transaction.NewValidTransaction(tx.Extrinsic, txnValidity) - service.maintainTransactionPool(&types.Block{ + err = service.maintainTransactionPool(&types.Block{ Body: *types.NewBody([]types.Extrinsic{}), }) + require.NoError(t, err) resultTx := service.transactionState.Pop() require.Equal(t, expectedTx, resultTx) @@ -414,9 +415,10 @@ func TestMaintainTransactionPoolLatestTxnQueue_BlockWithExtrinsics(t *testing.T) } _ = service.transactionState.AddToPool(tx) - service.maintainTransactionPool(&types.Block{ + err = service.maintainTransactionPool(&types.Block{ Body: types.Body([]types.Extrinsic{encExt}), }) + require.NoError(t, err) res := []*transaction.ValidTransaction{} for { diff --git a/dot/core/service_test.go b/dot/core/service_test.go index dc9ad90a3d..63a8f638c8 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -601,7 +601,8 @@ func Test_Service_maintainTransactionPool(t *testing.T) { blockState: mockBlockState, storageState: mockStorageState, } - service.maintainTransactionPool(&block) + err := service.maintainTransactionPool(&block) + require.NoError(t, err) }) t.Run("Validate Transaction ok", func(t *testing.T) { @@ -664,7 +665,8 @@ func Test_Service_maintainTransactionPool(t *testing.T) { blockState: mockBlockStateOk, storageState: mockStorageState, } - service.maintainTransactionPool(&block) + err := service.maintainTransactionPool(&block) + require.NoError(t, err) }) } diff --git a/dot/rpc/modules/author_integration_test.go b/dot/rpc/modules/author_integration_test.go index 4605281641..3901596012 100644 --- a/dot/rpc/modules/author_integration_test.go +++ b/dot/rpc/modules/author_integration_test.go @@ -10,8 +10,6 @@ import ( "context" "errors" "fmt" - cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale" - "github.com/centrifuge/go-substrate-rpc-client/v4/types/codec" "os" "testing" @@ -33,8 +31,10 @@ import ( "github.com/ChainSafe/gossamer/lib/transaction" "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/pkg/scale" + cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale" "github.com/centrifuge/go-substrate-rpc-client/v4/signature" ctypes "github.com/centrifuge/go-substrate-rpc-client/v4/types" + "github.com/centrifuge/go-substrate-rpc-client/v4/types/codec" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -124,7 +124,7 @@ func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, non encoder := cscale.NewEncoder(&extEnc) err = extrinsic.Encode(*encoder) require.NoError(t, err) - + return extEnc.Bytes() } From 2cf6d8e0193d2ff25d5d5e1b7a79661a36851919 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 12 Oct 2022 13:16:28 -0600 Subject: [PATCH 13/45] add bestBlockHash as input to maintainTxnPool --- dot/core/messages.go | 12 +++++------- dot/core/service.go | 9 ++++----- dot/core/service_integration_test.go | 6 ++++-- dot/core/service_test.go | 9 ++++----- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/dot/core/messages.go b/dot/core/messages.go index a5eed4c6e9..64d15bc37d 100644 --- a/dot/core/messages.go +++ b/dot/core/messages.go @@ -30,7 +30,7 @@ func (s *Service) validateTransaction(head *types.Header, rt RuntimeInstance, // validate each transaction externalExt, err := s.buildExternalTransaction(rt, tx) if err != nil { - return nil, fmt.Errorf("building external transaction: %s", err) + return nil, fmt.Errorf("building external transaction: %w", err) } validity, err = rt.ValidateTransaction(externalExt) @@ -76,26 +76,24 @@ func (s *Service) HandleTransactionMessage(peerID peer.ID, msg *network.Transact allTxsAreValid := true for _, tx := range txs { - isValidTxn := true validity, err := s.validateTransaction(head, rt, tx) if err != nil { + allTxsAreValid = false switch err.(type) { case runtime.InvalidTransaction: - isValidTxn = false - allTxsAreValid = false s.net.ReportPeer(peerset.ReputationChange{ Value: peerset.BadTransactionValue, Reason: peerset.BadTransactionReason, }, peerID) + continue case runtime.UnknownTransaction: - isValidTxn = false - allTxsAreValid = false + continue default: return false, fmt.Errorf("failed validating transaction for peerID %s: %w", peerID, err) } } - if isValidTxn && validity.Propagate { + if validity.Propagate { // find tx(s) that should propagate toPropagate = append(toPropagate, tx) } diff --git a/dot/core/service.go b/dot/core/service.go index 61a9825007..a2e291edea 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -303,12 +303,12 @@ func (s *Service) handleBlocksAsync() { continue } - prev := s.blockState.BestBlockHash() - if err := s.handleChainReorg(prev, block.Header.Hash()); err != nil { + bestBlockHash := s.blockState.BestBlockHash() + if err := s.handleChainReorg(bestBlockHash, block.Header.Hash()); err != nil { logger.Warnf("failed to re-add transactions to chain upon re-org: %s", err) } - if err := s.maintainTransactionPool(block); err != nil { + if err := s.maintainTransactionPool(block, bestBlockHash); err != nil { logger.Warnf("failed to maintain txn pool after re-org: %s", err) } case <-s.ctx.Done(): @@ -396,13 +396,12 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { // the new block, revalidates the transactions in the pool, and moves // them to the queue if valid. // See https://github.com/paritytech/substrate/blob/74804b5649eccfb83c90aec87bdca58e5d5c8789/client/transaction-pool/src/lib.rs#L545 -func (s *Service) maintainTransactionPool(block *types.Block) error { +func (s *Service) maintainTransactionPool(block *types.Block, bestBlockHash common.Hash) error { // remove extrinsics included in a block for _, ext := range block.Body { s.transactionState.RemoveExtrinsic(ext) } - bestBlockHash := s.blockState.BestBlockHash() stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) if err != nil { logger.Errorf("could not get state root from block %s: %w", bestBlockHash, err) diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index 8696c2ce0c..708e1b62af 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -377,9 +377,10 @@ func TestMaintainTransactionPoolLatestTxnQueue_EmptyBlock(t *testing.T) { expectedTx := transaction.NewValidTransaction(tx.Extrinsic, txnValidity) + bestBlockHash := service.blockState.BestBlockHash() err = service.maintainTransactionPool(&types.Block{ Body: *types.NewBody([]types.Extrinsic{}), - }) + }, bestBlockHash) require.NoError(t, err) resultTx := service.transactionState.Pop() @@ -415,9 +416,10 @@ func TestMaintainTransactionPoolLatestTxnQueue_BlockWithExtrinsics(t *testing.T) } _ = service.transactionState.AddToPool(tx) + bestBlockHash := service.blockState.BestBlockHash() err = service.maintainTransactionPool(&types.Block{ Body: types.Body([]types.Extrinsic{encExt}), - }) + }, bestBlockHash) require.NoError(t, err) res := []*transaction.ValidTransaction{} diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 63a8f638c8..6c647f7a62 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -591,7 +591,7 @@ func Test_Service_maintainTransactionPool(t *testing.T) { mockTxnState.EXPECT().PendingInPool().Return([]*transaction.ValidTransaction{vt}) mockBlockState := NewMockBlockState(ctrl) mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) - mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) @@ -601,7 +601,7 @@ func Test_Service_maintainTransactionPool(t *testing.T) { blockState: mockBlockState, storageState: mockStorageState, } - err := service.maintainTransactionPool(&block) + err := service.maintainTransactionPool(&block, common.Hash{}) require.NoError(t, err) }) @@ -655,7 +655,7 @@ func Test_Service_maintainTransactionPool(t *testing.T) { mockBlockStateOk := NewMockBlockState(ctrl) mockBlockStateOk.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) - mockBlockStateOk.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) + mockBlockStateOk.EXPECT().BestBlockHash().Return(common.Hash{}) mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) @@ -665,7 +665,7 @@ func Test_Service_maintainTransactionPool(t *testing.T) { blockState: mockBlockStateOk, storageState: mockStorageState, } - err := service.maintainTransactionPool(&block) + err := service.maintainTransactionPool(&block, common.Hash{}) require.NoError(t, err) }) } @@ -755,7 +755,6 @@ func Test_Service_handleBlocksAsync(t *testing.T) { mockBlockState.EXPECT().HighestCommonAncestor(common.Hash{}, block.Header.Hash()). Return(common.Hash{}, errTestDummyError) mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) - mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockTxnStateErr := NewMockTransactionState(ctrl) mockTxnStateErr.EXPECT().RemoveExtrinsic(types.Extrinsic{21}).Times(2) From f45c1f99d5cfdf464a7fc8419f6b8f858d4a0192 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 12 Oct 2022 13:21:59 -0600 Subject: [PATCH 14/45] add panics to handle blocks async --- dot/core/service.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index a2e291edea..9f30a9db0c 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -305,11 +305,11 @@ func (s *Service) handleBlocksAsync() { bestBlockHash := s.blockState.BestBlockHash() if err := s.handleChainReorg(bestBlockHash, block.Header.Hash()); err != nil { - logger.Warnf("failed to re-add transactions to chain upon re-org: %s", err) + panic(fmt.Errorf("failed to re-add transactions to chain upon re-org: %s", err)) } if err := s.maintainTransactionPool(block, bestBlockHash); err != nil { - logger.Warnf("failed to maintain txn pool after re-org: %s", err) + panic(fmt.Errorf("failed to maintain txn pool after re-org: %s", err)) } case <-s.ctx.Done(): return @@ -376,7 +376,8 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { externalExt, err := s.buildExternalTransaction(rt, ext) if err != nil { - return fmt.Errorf("building external transaction: %w", err) + logger.Debugf("building external transaction: %w", err) + continue } transactionValidity, err := rt.ValidateTransaction(externalExt) @@ -608,17 +609,14 @@ func (s *Service) GetReadProofAt(block common.Hash, keys [][]byte) ( // buildExternalTransaction builds an external transaction based on the current TransactionQueueAPIVersion // See https://github.com/paritytech/substrate/blob/polkadot-v0.9.25/primitives/transaction-pool/src/runtime_api.rs#L25-L55 func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrinsic) (types.Extrinsic, error) { - const supportedTxVersion = 3 - const previousSupportedTxVersion = 2 - runtimeVersion := rt.Version() txQueueVersion := runtime.TaggedTransactionQueueVersion(runtimeVersion) var externalExt types.Extrinsic switch txQueueVersion { - case supportedTxVersion: + case 3: extrinsicParts := [][]byte{{byte(types.TxnExternal)}, ext, s.blockState.BestBlockHash().ToBytes()} externalExt = types.Extrinsic(bytes.Join(extrinsicParts, nil)) - case previousSupportedTxVersion: + case 2: extrinsicParts := [][]byte{{byte(types.TxnExternal)}, ext} externalExt = types.Extrinsic(bytes.Join(extrinsicParts, nil)) default: From f87fbdd64828cdad9ecb01b7c8713ec582a74481 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 12 Oct 2022 14:09:19 -0600 Subject: [PATCH 15/45] construct config at once in test helper --- dot/core/helpers_test.go | 59 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/dot/core/helpers_test.go b/dot/core/helpers_test.go index 810034306e..b4e0d4dbe1 100644 --- a/dot/core/helpers_test.go +++ b/dot/core/helpers_test.go @@ -60,17 +60,12 @@ func createTestService(t *testing.T, genesisFilePath string, Number: 0, } - cfg := &Config{} - - //Construct keystore - cfg.Keystore = keystore.NewGlobalKeystore() + cfgKeystore := keystore.NewGlobalKeystore() kp, err := sr25519.GenerateKeypair() require.NoError(t, err) - err = cfg.Keystore.Acco.Insert(kp) + err = cfgKeystore.Acco.Insert(kp) require.NoError(t, err) - cfg.LogLvl = log.Critical - // Create state service var stateSrvc *state.Service testDatadirPath := t.TempDir() @@ -79,13 +74,13 @@ func createTestService(t *testing.T, genesisFilePath string, telemetryMock := NewMockClient(ctrl) telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - config := state.Config{ + stateConfig := state.Config{ Path: testDatadirPath, - LogLevel: log.Info, + LogLevel: log.Critical, Telemetry: telemetryMock, } - stateSrvc = state.NewService(config) + stateSrvc = state.NewService(stateConfig) stateSrvc.UseMemDB() err = stateSrvc.Initialise(gen, genesisHeader, &genesisTrie) @@ -95,17 +90,15 @@ func createTestService(t *testing.T, genesisFilePath string, err = stateSrvc.Start() require.NoError(t, err) - cfg.BlockState = stateSrvc.Block - cfg.StorageState = stateSrvc.Storage - cfg.TransactionState = stateSrvc.Transaction - cfg.EpochState = stateSrvc.Epoch - cfg.CodeSubstitutedState = stateSrvc.Base + cfgBlockState := stateSrvc.Block + cfgStorageState := stateSrvc.Storage + cfgCodeSubstitutedState := stateSrvc.Base // Runtime stuff var rtCfg wasmer.Config rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) - rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) + rtCfg.CodeHash, err = cfgStorageState.LoadCodeHash(nil) require.NoError(t, err) nodeStorage := runtime.NodeStorage{} @@ -113,34 +106,44 @@ func createTestService(t *testing.T, genesisFilePath string, rtCfg.NodeStorage = nodeStorage - cfg.Runtime, err = wasmer.NewRuntimeFromGenesis(rtCfg) + cfgRuntime, err := wasmer.NewRuntimeFromGenesis(rtCfg) require.NoError(t, err) - cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(aliceBalanceKey, encodedAccountInfo) + cfgRuntime.(*wasmer.Instance).GetContext().Storage.Set(aliceBalanceKey, encodedAccountInfo) // this key is System.UpgradedToDualRefCount -> set to true since all accounts have been upgraded to v0.9 format - cfg.Runtime.(*wasmer.Instance).GetContext().Storage.Set(common.UpgradedToDualRefKey, []byte{1}) + cfgRuntime.(*wasmer.Instance).GetContext().Storage.Set(common.UpgradedToDualRefKey, []byte{1}) - cfg.BlockState.StoreRuntime(cfg.BlockState.BestBlockHash(), cfg.Runtime) + cfgBlockState.StoreRuntime(cfgBlockState.BestBlockHash(), cfgRuntime) // Hash of encrypted centrifuge extrinsic testCallArguments := []byte{0xab, 0xcd} - extHex := runtime.NewTestExtrinsic(t, cfg.Runtime, genesisHeader.Hash(), cfg.BlockState.BestBlockHash(), + extHex := runtime.NewTestExtrinsic(t, cfgRuntime, genesisHeader.Hash(), cfgBlockState.BestBlockHash(), 0, "System.remark", testCallArguments) encodedExtrinsic = common.MustHexToBytes(extHex) - cfg.Network = new(network.Service) // only for nil check in NewService + cfgCodeSubstitutes := make(map[common.Hash]string) - cfg.CodeSubstitutes = make(map[common.Hash]string) - - genesisData, err := cfg.CodeSubstitutedState.(*state.BaseState).LoadGenesisData() + genesisData, err := cfgCodeSubstitutedState.LoadGenesisData() require.NoError(t, err) for k, v := range genesisData.CodeSubstitutes { - cfg.CodeSubstitutes[common.MustHexToHash(k)] = v + cfgCodeSubstitutes[common.MustHexToHash(k)] = v } - cfg.CodeSubstitutedState = stateSrvc.Base - + cfgCodeSubstitutedState = stateSrvc.Base + + cfg := &Config{ + Keystore: cfgKeystore, + LogLvl: log.Critical, + BlockState: cfgBlockState, + StorageState: cfgStorageState, + TransactionState: stateSrvc.Transaction, + EpochState: stateSrvc.Epoch, + CodeSubstitutedState: cfgCodeSubstitutedState, + Runtime: cfgRuntime, + Network: new(network.Service), + CodeSubstitutes: cfgCodeSubstitutes, + } service, err = NewService(cfg) require.NoError(t, err) From 092ba0fd559d37a50d0fb82d73ab09c751eb2914 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 12 Oct 2022 14:30:51 -0600 Subject: [PATCH 16/45] fix core test --- dot/core/messages.go | 2 +- dot/core/messages_test.go | 2 +- dot/core/service_test.go | 55 +++++---------------------------------- 3 files changed, 9 insertions(+), 50 deletions(-) diff --git a/dot/core/messages.go b/dot/core/messages.go index 64d15bc37d..bc437d0823 100644 --- a/dot/core/messages.go +++ b/dot/core/messages.go @@ -89,7 +89,7 @@ func (s *Service) HandleTransactionMessage(peerID peer.ID, msg *network.Transact case runtime.UnknownTransaction: continue default: - return false, fmt.Errorf("failed validating transaction for peerID %s: %w", peerID, err) + return false, fmt.Errorf("validating transaction from peerID %s: %w", peerID, err) } } diff --git a/dot/core/messages_test.go b/dot/core/messages_test.go index cbf1c35d48..192ab9f470 100644 --- a/dot/core/messages_test.go +++ b/dot/core/messages_test.go @@ -232,7 +232,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { }, }, expErr: errDummyErr, - expErrMsg: "failed validating transaction for peerID D1KeRhQ: cannot get trie state from storage" + + expErrMsg: "validating transaction from peerID D1KeRhQ: cannot get trie state from storage" + " for root 0x0000000000000000000000000000000000000000000000000000000000000000: dummy error for testing", }, { diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 6c647f7a62..10070c0f0a 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -711,71 +711,30 @@ func Test_Service_handleBlocksAsync(t *testing.T) { t.Run("handleChainReorg error", func(t *testing.T) { t.Parallel() - validity := &transaction.Validity{ - Priority: 0x3e8, - Requires: [][]byte{{0xb5, 0x47, 0xb1, 0x90, 0x37, 0x10, 0x7e, 0x1f, 0x79, 0x4c, - 0xa8, 0x69, 0x0, 0xa1, 0xb5, 0x98}}, - Provides: [][]byte{{0xe4, 0x80, 0x7d, 0x1b, 0x67, 0x49, 0x37, 0xbf, 0xc7, 0x89, - 0xbb, 0xdd, 0x88, 0x6a, 0xdd, 0xd6}}, - Longevity: 0x40, - Propagate: true, - } - extrinsic := types.Extrinsic{21} testHeader := types.NewEmptyHeader() - externalExt := types.Extrinsic(bytes.Join([][]byte{ - {byte(types.TxnExternal)}, - extrinsic, - testHeader.StateRoot.ToBytes(), - }, nil)) - vt := transaction.NewValidTransaction(extrinsic, validity) - block := types.NewBlock(*testHeader, *types.NewBody([]types.Extrinsic{[]byte{21}})) block.Header.Number = 21 ctrl := gomock.NewController(t) - runtimeMock := NewMockRuntimeInstance(ctrl) - runtimeMock.EXPECT().ValidateTransaction(externalExt).Return(nil, errTestDummyError) - runtimeMock.EXPECT().Version().Return(runtime.Version{ - SpecName: []byte("polkadot"), - ImplName: []byte("parity-polkadot"), - AuthoringVersion: authoringVersion, - SpecVersion: specVersion, - ImplVersion: implVersion, - APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, - Ver: 3, - }}, - TransactionVersion: transactionVersion, - StateVersion: stateVersion, - }) - runtimeMock.EXPECT().SetContextStorage(&rtstorage.TrieState{}) mockBlockState := NewMockBlockState(ctrl) - mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}).Times(2) + mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockBlockState.EXPECT().HighestCommonAncestor(common.Hash{}, block.Header.Hash()). Return(common.Hash{}, errTestDummyError) - mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) - mockTxnStateErr := NewMockTransactionState(ctrl) - mockTxnStateErr.EXPECT().RemoveExtrinsic(types.Extrinsic{21}).Times(2) - mockTxnStateErr.EXPECT().PendingInPool().Return([]*transaction.ValidTransaction{vt}) - - mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) blockAddChan := make(chan *types.Block) go func() { blockAddChan <- &block close(blockAddChan) }() service := &Service{ - storageState: mockStorageState, - blockState: mockBlockState, - transactionState: mockTxnStateErr, - blockAddCh: blockAddChan, - ctx: context.Background(), + blockState: mockBlockState, + blockAddCh: blockAddChan, + ctx: context.Background(), } - service.handleBlocksAsync() + + assert.PanicsWithError(t, "failed to re-add transactions to chain upon re-org: test dummy error", + service.handleBlocksAsync, "The code panics as expected") }) } From 7dc03d9f417cafbe77f8ce474fac33764b1a3918 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 12 Oct 2022 14:34:34 -0600 Subject: [PATCH 17/45] update go mod --- dot/core/service.go | 2 +- dot/core/service_test.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 9f30a9db0c..251407e837 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -620,7 +620,7 @@ func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrin extrinsicParts := [][]byte{{byte(types.TxnExternal)}, ext} externalExt = types.Extrinsic(bytes.Join(extrinsicParts, nil)) default: - return types.Extrinsic{}, errInvalidTransactionQueueVersion + return types.Extrinsic{}, fmt.Errorf("%w: %d", errInvalidTransactionQueueVersion, txQueueVersion) } return externalExt, nil } diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 10070c0f0a..4d4803e125 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -732,7 +732,7 @@ func Test_Service_handleBlocksAsync(t *testing.T) { blockAddCh: blockAddChan, ctx: context.Background(), } - + assert.PanicsWithError(t, "failed to re-add transactions to chain upon re-org: test dummy error", service.handleBlocksAsync, "The code panics as expected") }) diff --git a/go.mod b/go.mod index c56325c624..af8a55f058 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/docker/docker v20.10.19+incompatible github.com/ethereum/go-ethereum v1.10.25 github.com/fatih/color v1.13.0 - github.com/go-playground/validator/v10 v10.11.0 + github.com/go-playground/validator/v10 v10.11.1 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 github.com/google/go-cmp v0.5.9 diff --git a/go.sum b/go.sum index 98652acffe..61775c2ac2 100644 --- a/go.sum +++ b/go.sum @@ -260,8 +260,8 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= -github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= From 089072595b0706e5850c5a1a4d5c1647481ecbdf Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 12 Oct 2022 14:47:31 -0600 Subject: [PATCH 18/45] finish feedback --- dot/rpc/modules/author_integration_test.go | 4 ++-- lib/common/hasher.go | 18 ++++++++++++++++++ lib/common/hasher_test.go | 6 ++++++ lib/runtime/version.go | 5 ++--- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/dot/rpc/modules/author_integration_test.go b/dot/rpc/modules/author_integration_test.go index 3901596012..709ec1add8 100644 --- a/dot/rpc/modules/author_integration_test.go +++ b/dot/rpc/modules/author_integration_test.go @@ -120,8 +120,8 @@ func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, non err = extrinsic.Sign(signature.TestKeyringPairAlice, options) require.NoError(t, err) - extEnc := bytes.Buffer{} - encoder := cscale.NewEncoder(&extEnc) + extEnc := bytes.NewBuffer(nil) + encoder := cscale.NewEncoder(extEnc) err = extrinsic.Encode(*encoder) require.NoError(t, err) diff --git a/lib/common/hasher.go b/lib/common/hasher.go index e9bc0732f2..fba56ff99e 100644 --- a/lib/common/hasher.go +++ b/lib/common/hasher.go @@ -27,6 +27,24 @@ func Blake2b128(in []byte) ([]byte, error) { return h.Sum(nil), nil } +// MustBlake2b8 returns the first 8 bytes of the Blake2b hash of the input data +func MustBlake2b8(data []byte) (digest [8]byte) { + const bytes = 8 + hasher, err := blake2b.New(bytes, nil) + if err != nil { + panic(err) + } + + _, err = hasher.Write(data) + if err != nil { + panic(err) + } + + digestBytes := hasher.Sum(nil) + copy(digest[:], digestBytes) + return digest +} + // Blake2bHash returns the 256-bit blake2b hash of the input data func Blake2bHash(in []byte) (Hash, error) { h, err := blake2b.New256(nil) diff --git a/lib/common/hasher_test.go b/lib/common/hasher_test.go index c347838030..5f1c6984a0 100644 --- a/lib/common/hasher_test.go +++ b/lib/common/hasher_test.go @@ -33,6 +33,12 @@ func TestBlake128(t *testing.T) { require.Equal(t, expected, h) } +func TestBlake2b8(t *testing.T) { + exp := [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15} + res := common.MustBlake2b8([]byte("TaggedTransactionQueue")) + require.Equal(t, exp, res) +} + func TestBlake2bHash_EmptyHash(t *testing.T) { // test case from https://github.com/noot/blake2b_test which uses the blake2-rfp rust crate // also see https://github.com/paritytech/substrate/blob/master/core/primitives/src/hashing.rs diff --git a/lib/runtime/version.go b/lib/runtime/version.go index 4152394278..d4a79f14b9 100644 --- a/lib/runtime/version.go +++ b/lib/runtime/version.go @@ -9,6 +9,7 @@ import ( "fmt" "io" + "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/pkg/scale" ) @@ -31,14 +32,12 @@ type Version struct { } var ( - // Blake2-8("TaggedTransactionQueue") - encodedTaggedTransactionQueue = [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15} - ErrDecodingVersionField = errors.New("decoding version field") ) // TaggedTransactionQueueVersion returns the TaggedTransactionQueueAPI version func TaggedTransactionQueueVersion(runtimeVersion Version) (txQueueVersion uint32) { + encodedTaggedTransactionQueue := common.MustBlake2b8([]byte("TaggedTransactionQueue")) for _, apiItem := range runtimeVersion.APIItems { if apiItem.Name == encodedTaggedTransactionQueue { return apiItem.Ver From 4c987075d2659f8fa7ee667063a683ec7c480f7a Mon Sep 17 00:00:00 2001 From: jimboj Date: Thu, 13 Oct 2022 14:30:30 -0600 Subject: [PATCH 19/45] fix core tests --- dot/core/messages_integration_test.go | 5 +++++ dot/core/service.go | 4 ++-- dot/core/service_integration_test.go | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/dot/core/messages_integration_test.go b/dot/core/messages_integration_test.go index c5569d9166..cdd9692cca 100644 --- a/dot/core/messages_integration_test.go +++ b/dot/core/messages_integration_test.go @@ -88,11 +88,16 @@ func TestService_HandleBlockProduced(t *testing.T) { err = digest.Add(*prd) require.NoError(t, err) + // Used to define the state root of new block for testing + genesisBlock, err := s.blockState.GetBlockByHash(s.blockState.GenesisHash()) + require.NoError(t, err) + newBlock := types.Block{ Header: types.Header{ Number: 1, ParentHash: s.blockState.BestBlockHash(), Digest: digest, + StateRoot: genesisBlock.Header.StateRoot, }, Body: *types.NewBody([]types.Extrinsic{}), } diff --git a/dot/core/service.go b/dot/core/service.go index 251407e837..4d2ed862a5 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -8,8 +8,6 @@ import ( "context" "errors" "fmt" - "sync" - "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/internal/log" @@ -24,6 +22,7 @@ import ( "github.com/ChainSafe/gossamer/lib/transaction" cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale" ctypes "github.com/centrifuge/go-substrate-rpc-client/v4/types" + "sync" ) var ( @@ -403,6 +402,7 @@ func (s *Service) maintainTransactionPool(block *types.Block, bestBlockHash comm s.transactionState.RemoveExtrinsic(ext) } + fmt.Println(bestBlockHash) stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) if err != nil { logger.Errorf("could not get state root from block %s: %w", bestBlockHash, err) diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index 708e1b62af..055abda146 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -60,11 +60,16 @@ func TestAnnounceBlock(t *testing.T) { err = digest.Add(*prd) require.NoError(t, err) + // Used to define the state root of new block for testing + genesisBlock, err := s.blockState.GetBlockByHash(s.blockState.GenesisHash()) + require.NoError(t, err) + newBlock := types.Block{ Header: types.Header{ Number: 1, ParentHash: s.blockState.BestBlockHash(), Digest: digest, + StateRoot: genesisBlock.Header.StateRoot, }, Body: *types.NewBody([]types.Extrinsic{}), } From f7645b2e17694cacb980bbbaf698c6372ca4df16 Mon Sep 17 00:00:00 2001 From: jimboj Date: Thu, 13 Oct 2022 14:34:49 -0600 Subject: [PATCH 20/45] lint --- dot/core/service.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dot/core/service.go b/dot/core/service.go index 4d2ed862a5..24d1fbe0b9 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -8,6 +8,8 @@ import ( "context" "errors" "fmt" + "sync" + "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/internal/log" @@ -20,9 +22,9 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/services" "github.com/ChainSafe/gossamer/lib/transaction" + cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale" ctypes "github.com/centrifuge/go-substrate-rpc-client/v4/types" - "sync" ) var ( From ec61473873c0071f690782eea5e2bc92e7ba367d Mon Sep 17 00:00:00 2001 From: jimboj Date: Mon, 17 Oct 2022 12:38:22 -0600 Subject: [PATCH 21/45] remove log --- dot/core/service.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 24d1fbe0b9..5463bee55b 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -403,8 +403,7 @@ func (s *Service) maintainTransactionPool(block *types.Block, bestBlockHash comm for _, ext := range block.Body { s.transactionState.RemoveExtrinsic(ext) } - - fmt.Println(bestBlockHash) + stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) if err != nil { logger.Errorf("could not get state root from block %s: %w", bestBlockHash, err) From 3f87fbd969ad175ec9d6c3e7c83b43ee6e7cfc65 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:41:55 -0600 Subject: [PATCH 22/45] Update lib/common/hasher_test.go Co-authored-by: Quentin McGaw --- lib/common/hasher_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/hasher_test.go b/lib/common/hasher_test.go index 5f1c6984a0..76105daa96 100644 --- a/lib/common/hasher_test.go +++ b/lib/common/hasher_test.go @@ -33,7 +33,7 @@ func TestBlake128(t *testing.T) { require.Equal(t, expected, h) } -func TestBlake2b8(t *testing.T) { +func Test_MustBlake2b8(t *testing.T) { exp := [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15} res := common.MustBlake2b8([]byte("TaggedTransactionQueue")) require.Equal(t, exp, res) From a8a282da748e871e12b9efaf9b75930b5c0afc5d Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:42:24 -0600 Subject: [PATCH 23/45] Update lib/common/hasher_test.go Co-authored-by: Quentin McGaw --- lib/common/hasher_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/common/hasher_test.go b/lib/common/hasher_test.go index 76105daa96..b1ae212327 100644 --- a/lib/common/hasher_test.go +++ b/lib/common/hasher_test.go @@ -34,9 +34,9 @@ func TestBlake128(t *testing.T) { } func Test_MustBlake2b8(t *testing.T) { - exp := [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15} - res := common.MustBlake2b8([]byte("TaggedTransactionQueue")) - require.Equal(t, exp, res) + expectedDigest := [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15} + digest := common.MustBlake2b8([]byte("TaggedTransactionQueue")) + require.Equal(t, expectedDigest, digest) } func TestBlake2bHash_EmptyHash(t *testing.T) { From fe26434828254f9cf65ea3210a40000dcc6ab5a3 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:42:39 -0600 Subject: [PATCH 24/45] Update dot/core/messages_test.go Co-authored-by: Quentin McGaw --- dot/core/messages_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/messages_test.go b/dot/core/messages_test.go index 192ab9f470..75679c9483 100644 --- a/dot/core/messages_test.go +++ b/dot/core/messages_test.go @@ -387,7 +387,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { SpecVersion: specVersion, ImplVersion: implVersion, APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Name: common.MustBlake2b8([]byte("TaggedTransactionQueue")), Ver: 3, }}, TransactionVersion: transactionVersion, From 0259b40fd5478701aba249270a849a83bff28088 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:43:03 -0600 Subject: [PATCH 25/45] Update dot/core/service.go Co-authored-by: Quentin McGaw --- dot/core/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service.go b/dot/core/service.go index 5463bee55b..9fdcd85f2c 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -306,7 +306,7 @@ func (s *Service) handleBlocksAsync() { bestBlockHash := s.blockState.BestBlockHash() if err := s.handleChainReorg(bestBlockHash, block.Header.Hash()); err != nil { - panic(fmt.Errorf("failed to re-add transactions to chain upon re-org: %s", err)) + panic(fmt.Sprintf("failed to re-add transactions to chain upon re-org: %s", err)) } if err := s.maintainTransactionPool(block, bestBlockHash); err != nil { From 61246d725cd20408ad10767e36910ab037328650 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:43:25 -0600 Subject: [PATCH 26/45] Update dot/core/service.go Co-authored-by: Quentin McGaw --- dot/core/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service.go b/dot/core/service.go index 9fdcd85f2c..7fe1bff15b 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -377,7 +377,7 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { externalExt, err := s.buildExternalTransaction(rt, ext) if err != nil { - logger.Debugf("building external transaction: %w", err) + logger.Debugf("building external transaction: %s", err) continue } From 8a9e26819f7d3d56edef53388f96e453f36a6855 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:44:24 -0600 Subject: [PATCH 27/45] Update dot/core/service_test.go Co-authored-by: Quentin McGaw --- dot/core/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 4d4803e125..5e988f351f 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -734,7 +734,7 @@ func Test_Service_handleBlocksAsync(t *testing.T) { } assert.PanicsWithError(t, "failed to re-add transactions to chain upon re-org: test dummy error", - service.handleBlocksAsync, "The code panics as expected") + service.handleBlocksAsync) }) } From e6c06b129fabf68885a20e7e5c1bb41d7d37b0bc Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:44:54 -0600 Subject: [PATCH 28/45] Update dot/core/service_test.go Co-authored-by: Quentin McGaw --- dot/core/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 5e988f351f..382b560769 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -578,7 +578,7 @@ func Test_Service_maintainTransactionPool(t *testing.T) { SpecVersion: specVersion, ImplVersion: implVersion, APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Name: common.MustBlake2b8([]byte("TaggedTransactionQueue")), Ver: 3, }}, TransactionVersion: transactionVersion, From fd7f33fb04c9f96402342ca073560fd7d6c04c22 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:45:18 -0600 Subject: [PATCH 29/45] Update dot/core/service_test.go Co-authored-by: Quentin McGaw --- dot/core/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 382b560769..fe7829ccd1 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -640,7 +640,7 @@ func Test_Service_maintainTransactionPool(t *testing.T) { SpecVersion: specVersion, ImplVersion: implVersion, APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Name: common.MustBlake2b8([]byte("TaggedTransactionQueue")), Ver: 3, }}, TransactionVersion: transactionVersion, From 017ce25bf2b0db0f4ebefa6b8905fd779bf1ae08 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:45:32 -0600 Subject: [PATCH 30/45] Update dot/core/service_test.go Co-authored-by: Quentin McGaw --- dot/core/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index fe7829ccd1..07e255ba66 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -853,7 +853,7 @@ func TestService_handleChainReorg(t *testing.T) { SpecVersion: specVersion, ImplVersion: implVersion, APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Name: common.MustBlake2b8([]byte("TaggedTransactionQueue")), Ver: 3, }}, TransactionVersion: transactionVersion, From a1f7d0ed825ec42df5287d3ac15fc7f4d0f045ac Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:45:43 -0600 Subject: [PATCH 31/45] Update dot/core/service_test.go Co-authored-by: Quentin McGaw --- dot/core/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 07e255ba66..647825a907 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -887,7 +887,7 @@ func TestService_handleChainReorg(t *testing.T) { SpecVersion: specVersion, ImplVersion: implVersion, APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Name: common.MustBlake2b8([]byte("TaggedTransactionQueue")), Ver: 3, }}, TransactionVersion: transactionVersion, From e776bb653bd6870c03f96f871472d035004c47a9 Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:45:54 -0600 Subject: [PATCH 32/45] Update dot/core/service_test.go Co-authored-by: Quentin McGaw --- dot/core/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 647825a907..24c106dcb7 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -1239,7 +1239,7 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { SpecVersion: specVersion, ImplVersion: implVersion, APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Name: common.MustBlake2b8([]byte("TaggedTransactionQueue")), Ver: 3, }}, TransactionVersion: transactionVersion, From e57e70ecef8de789cd9433691745c928604c3afe Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 17 Oct 2022 12:46:09 -0600 Subject: [PATCH 33/45] Update dot/core/service_test.go Co-authored-by: Quentin McGaw --- dot/core/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 24c106dcb7..5fa674e02a 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -1273,7 +1273,7 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { SpecVersion: specVersion, ImplVersion: implVersion, APIItems: []runtime.APIItem{{ - Name: [8]byte{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, + Name: common.MustBlake2b8([]byte("TaggedTransactionQueue")), Ver: 3, }}, TransactionVersion: transactionVersion, From 93ca14b76187e09662d5b76352805f01f926888f Mon Sep 17 00:00:00 2001 From: jimboj Date: Mon, 17 Oct 2022 12:51:27 -0600 Subject: [PATCH 34/45] fix core tests --- dot/core/service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 7fe1bff15b..ede76b0813 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -306,7 +306,7 @@ func (s *Service) handleBlocksAsync() { bestBlockHash := s.blockState.BestBlockHash() if err := s.handleChainReorg(bestBlockHash, block.Header.Hash()); err != nil { - panic(fmt.Sprintf("failed to re-add transactions to chain upon re-org: %s", err)) + panic(fmt.Errorf("failed to re-add transactions to chain upon re-org: %s", err)) } if err := s.maintainTransactionPool(block, bestBlockHash); err != nil { @@ -403,7 +403,7 @@ func (s *Service) maintainTransactionPool(block *types.Block, bestBlockHash comm for _, ext := range block.Body { s.transactionState.RemoveExtrinsic(ext) } - + stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) if err != nil { logger.Errorf("could not get state root from block %s: %w", bestBlockHash, err) From 3ac1392c83ed16131608e02e57af7fd2d48fbaa6 Mon Sep 17 00:00:00 2001 From: jimboj Date: Mon, 17 Oct 2022 16:27:54 -0600 Subject: [PATCH 35/45] remove errors.Is in handleChainReorg test to handle formatted errors --- dot/core/service.go | 13 +++++-------- dot/core/service_test.go | 8 ++++++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index ede76b0813..794e3028ae 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -377,14 +377,12 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { externalExt, err := s.buildExternalTransaction(rt, ext) if err != nil { - logger.Debugf("building external transaction: %s", err) - continue + return fmt.Errorf("building external transaction: %s", err) } transactionValidity, err := rt.ValidateTransaction(externalExt) if err != nil { - logger.Debugf("failed to validate transaction for extrinsic %s: %s", ext, err) - continue + return fmt.Errorf("failed to validate transaction for extrinsic %s: %s", ext, err) } vtx := transaction.NewValidTransaction(ext, transactionValidity) s.transactionState.AddToPool(vtx) @@ -421,19 +419,18 @@ func (s *Service) maintainTransactionPool(block *types.Block, bestBlockHash comm for _, tx := range txs { rt, err := s.blockState.GetRuntime(&bestBlockHash) if err != nil { - logger.Warnf("failed to get runtime to re-validate transactions in pool: %s", err) - continue + return fmt.Errorf("failed to get runtime to re-validate transactions in pool: %s", err) } rt.SetContextStorage(ts) externalExt, err := s.buildExternalTransaction(rt, tx.Extrinsic) if err != nil { - logger.Errorf("Unable to build external transaction: %s", err) - continue + return fmt.Errorf("building external transaction: %s", err) } txnValidity, err := rt.ValidateTransaction(externalExt) if err != nil { + logger.Debugf("failed to validate transaction for extrinsic %s: %s", tx.Extrinsic, err) s.transactionState.RemoveExtrinsic(tx.Extrinsic) continue } diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 5fa674e02a..b00d6e5ce7 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -8,6 +8,7 @@ import ( "context" "encoding/hex" "errors" + "fmt" "testing" "github.com/ChainSafe/gossamer/dot/network" @@ -742,7 +743,6 @@ func TestService_handleChainReorg(t *testing.T) { t.Parallel() execTest := func(t *testing.T, s *Service, prevHash common.Hash, currHash common.Hash, expErr error) { err := s.handleChainReorg(prevHash, currHash) - assert.ErrorIs(t, err, expErr) if expErr != nil { assert.EqualError(t, err, expErr.Error()) } @@ -872,7 +872,11 @@ func TestService_handleChainReorg(t *testing.T) { service := &Service{ blockState: mockBlockState, } - execTest(t, service, testPrevHash, testCurrentHash, nil) + + expErr := fmt.Errorf("failed to validate transaction for extrinsic %s: %s", + ext, + errTestDummyError) + execTest(t, service, testPrevHash, testCurrentHash, expErr) }) t.Run("happy path", func(t *testing.T) { From 472a21b68954eebfa0c82f75e0c2e3367d03445d Mon Sep 17 00:00:00 2001 From: jimboj Date: Mon, 17 Oct 2022 16:33:36 -0600 Subject: [PATCH 36/45] make taggedTransactionQueueVersion a receiver func --- dot/core/service.go | 2 +- lib/runtime/version.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 794e3028ae..5ba734281a 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -608,7 +608,7 @@ func (s *Service) GetReadProofAt(block common.Hash, keys [][]byte) ( // See https://github.com/paritytech/substrate/blob/polkadot-v0.9.25/primitives/transaction-pool/src/runtime_api.rs#L25-L55 func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrinsic) (types.Extrinsic, error) { runtimeVersion := rt.Version() - txQueueVersion := runtime.TaggedTransactionQueueVersion(runtimeVersion) + txQueueVersion := runtimeVersion.TaggedTransactionQueueVersion() var externalExt types.Extrinsic switch txQueueVersion { case 3: diff --git a/lib/runtime/version.go b/lib/runtime/version.go index d4a79f14b9..fb48e42b0e 100644 --- a/lib/runtime/version.go +++ b/lib/runtime/version.go @@ -36,9 +36,9 @@ var ( ) // TaggedTransactionQueueVersion returns the TaggedTransactionQueueAPI version -func TaggedTransactionQueueVersion(runtimeVersion Version) (txQueueVersion uint32) { +func (v Version) TaggedTransactionQueueVersion() (txQueueVersion uint32) { encodedTaggedTransactionQueue := common.MustBlake2b8([]byte("TaggedTransactionQueue")) - for _, apiItem := range runtimeVersion.APIItems { + for _, apiItem := range v.APIItems { if apiItem.Name == encodedTaggedTransactionQueue { return apiItem.Ver } From 52e58f0e27286f2a4cdc8f6338301f8064c76abe Mon Sep 17 00:00:00 2001 From: jimboj Date: Mon, 17 Oct 2022 16:43:16 -0600 Subject: [PATCH 37/45] feedback --- dot/core/service.go | 11 +++++------ dot/core/service_integration_test.go | 6 +++--- dot/core/service_test.go | 22 +++++++++++----------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 5ba734281a..c168d66392 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -609,16 +609,15 @@ func (s *Service) GetReadProofAt(block common.Hash, keys [][]byte) ( func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrinsic) (types.Extrinsic, error) { runtimeVersion := rt.Version() txQueueVersion := runtimeVersion.TaggedTransactionQueueVersion() - var externalExt types.Extrinsic + var extrinsicParts [][]byte switch txQueueVersion { case 3: - extrinsicParts := [][]byte{{byte(types.TxnExternal)}, ext, s.blockState.BestBlockHash().ToBytes()} - externalExt = types.Extrinsic(bytes.Join(extrinsicParts, nil)) + extrinsicParts = [][]byte{{byte(types.TxnExternal)}, ext, s.blockState.BestBlockHash().ToBytes()} case 2: - extrinsicParts := [][]byte{{byte(types.TxnExternal)}, ext} - externalExt = types.Extrinsic(bytes.Join(extrinsicParts, nil)) + extrinsicParts = [][]byte{{byte(types.TxnExternal)}, ext} default: return types.Extrinsic{}, fmt.Errorf("%w: %d", errInvalidTransactionQueueVersion, txQueueVersion) } - return externalExt, nil + externalTransaction := types.Extrinsic(bytes.Join(extrinsicParts, nil)) + return externalTransaction, nil } diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index 055abda146..70ba843a75 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -413,17 +413,17 @@ func TestMaintainTransactionPoolLatestTxnQueue_BlockWithExtrinsics(t *testing.T) require.NoError(t, err) ctrl := gomock.NewController(t) - service, encExt := createTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) + service, encodedExtrinsic := createTestService(t, genesisFilePath, alicePub, accountInfo, ctrl) tx := &transaction.ValidTransaction{ - Extrinsic: types.Extrinsic(encExt), + Extrinsic: types.Extrinsic(encodedExtrinsic), Validity: &transaction.Validity{Priority: 1}, } _ = service.transactionState.AddToPool(tx) bestBlockHash := service.blockState.BestBlockHash() err = service.maintainTransactionPool(&types.Block{ - Body: types.Body([]types.Extrinsic{encExt}), + Body: types.Body([]types.Extrinsic{encodedExtrinsic}), }, bestBlockHash) require.NoError(t, err) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index b00d6e5ce7..f851c3c5a2 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -561,13 +561,13 @@ func Test_Service_maintainTransactionPool(t *testing.T) { Propagate: true, } - ext := types.Extrinsic{21} + extrinsic := types.Extrinsic{21} externalExt := types.Extrinsic(bytes.Join([][]byte{ {byte(types.TxnExternal)}, - ext, + extrinsic, testHeader.StateRoot.ToBytes(), }, nil)) - vt := transaction.NewValidTransaction(ext, validity) + vt := transaction.NewValidTransaction(extrinsic, validity) ctrl := gomock.NewController(t) runtimeMock := NewMockRuntimeInstance(ctrl) @@ -591,18 +591,18 @@ func Test_Service_maintainTransactionPool(t *testing.T) { mockTxnState.EXPECT().RemoveExtrinsic(types.Extrinsic{21}).Times(2) mockTxnState.EXPECT().PendingInPool().Return([]*transaction.ValidTransaction{vt}) mockBlockState := NewMockBlockState(ctrl) - mockBlockState.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) + mockBlockState.EXPECT().GetRuntime(&common.Hash{1}).Return(runtimeMock, nil) mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) + mockStorageState.EXPECT().TrieState(&common.Hash{1}).Return(&rtstorage.TrieState{}, nil) + mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{1}).Return(&common.Hash{1}, nil) service := &Service{ transactionState: mockTxnState, blockState: mockBlockState, storageState: mockStorageState, } - err := service.maintainTransactionPool(&block, common.Hash{}) + err := service.maintainTransactionPool(&block, common.Hash{1}) require.NoError(t, err) }) @@ -655,18 +655,18 @@ func Test_Service_maintainTransactionPool(t *testing.T) { mockTxnState.EXPECT().RemoveExtrinsicFromPool(types.Extrinsic{21}) mockBlockStateOk := NewMockBlockState(ctrl) - mockBlockStateOk.EXPECT().GetRuntime(&common.Hash{}).Return(runtimeMock, nil) + mockBlockStateOk.EXPECT().GetRuntime(&common.Hash{1}).Return(runtimeMock, nil) mockBlockStateOk.EXPECT().BestBlockHash().Return(common.Hash{}) mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.TrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) + mockStorageState.EXPECT().TrieState(&common.Hash{1}).Return(&rtstorage.TrieState{}, nil) + mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{1}).Return(&common.Hash{1}, nil) service := &Service{ transactionState: mockTxnState, blockState: mockBlockStateOk, storageState: mockStorageState, } - err := service.maintainTransactionPool(&block, common.Hash{}) + err := service.maintainTransactionPool(&block, common.Hash{1}) require.NoError(t, err) }) } From 9b3fb44c3d5e2ad89875a7b9da8b4ebcd57a5743 Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 18 Oct 2022 08:57:06 -0600 Subject: [PATCH 38/45] rename allTxnsAreValid --- dot/core/messages.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dot/core/messages.go b/dot/core/messages.go index bc437d0823..16b957302d 100644 --- a/dot/core/messages.go +++ b/dot/core/messages.go @@ -74,11 +74,11 @@ func (s *Service) HandleTransactionMessage(peerID peer.ID, msg *network.Transact return false, err } - allTxsAreValid := true + allTxnsAreValid := true for _, tx := range txs { validity, err := s.validateTransaction(head, rt, tx) if err != nil { - allTxsAreValid = false + allTxnsAreValid = false switch err.(type) { case runtime.InvalidTransaction: s.net.ReportPeer(peerset.ReputationChange{ @@ -99,7 +99,7 @@ func (s *Service) HandleTransactionMessage(peerID peer.ID, msg *network.Transact } } - if allTxsAreValid { + if allTxnsAreValid { s.net.ReportPeer(peerset.ReputationChange{ Value: peerset.GoodTransactionValue, Reason: peerset.GoodTransactionReason, From 7e69fd68b0e5b8f5f2d41d36a7387e601b4a9c5c Mon Sep 17 00:00:00 2001 From: jimboj Date: Tue, 18 Oct 2022 12:18:37 -0600 Subject: [PATCH 39/45] respond to feedback --- dot/core/helpers_test.go | 4 +--- dot/core/interface.go | 1 - dot/core/messages.go | 3 +-- dot/core/messages_integration_test.go | 5 +++-- dot/core/mocks_test.go | 14 -------------- dot/core/service.go | 17 +++++++++++------ dot/core/service_integration_test.go | 6 +++--- lib/common/hasher.go | 17 +++++++++++++---- lib/runtime/version.go | 13 ++++++++----- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/dot/core/helpers_test.go b/dot/core/helpers_test.go index b4e0d4dbe1..16793586b3 100644 --- a/dot/core/helpers_test.go +++ b/dot/core/helpers_test.go @@ -35,8 +35,7 @@ func balanceKey(t *testing.T, pub []byte) (bKey []byte) { require.NoError(t, err) h2, err := common.Blake2b128(pub) require.NoError(t, err) - bytesToConcat := [][]byte{h0, h1, h2, pub} - return bytes.Join(bytesToConcat, nil) + return bytes.Join([][]byte{h0, h1, h2, pub}, nil) } // Creates test service, used now for testing txnPool but can be used elsewhere when needed @@ -94,7 +93,6 @@ func createTestService(t *testing.T, genesisFilePath string, cfgStorageState := stateSrvc.Storage cfgCodeSubstitutedState := stateSrvc.Base - // Runtime stuff var rtCfg wasmer.Config rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) diff --git a/dot/core/interface.go b/dot/core/interface.go index aaf98ee865..05986df2e5 100644 --- a/dot/core/interface.go +++ b/dot/core/interface.go @@ -88,7 +88,6 @@ type StorageState interface { // TransactionState is the interface for transaction state methods type TransactionState interface { - Pop() *transaction.ValidTransaction Push(vt *transaction.ValidTransaction) (common.Hash, error) AddToPool(vt *transaction.ValidTransaction) common.Hash RemoveExtrinsic(ext types.Extrinsic) diff --git a/dot/core/messages.go b/dot/core/messages.go index 16b957302d..155656d734 100644 --- a/dot/core/messages.go +++ b/dot/core/messages.go @@ -85,12 +85,11 @@ func (s *Service) HandleTransactionMessage(peerID peer.ID, msg *network.Transact Value: peerset.BadTransactionValue, Reason: peerset.BadTransactionReason, }, peerID) - continue case runtime.UnknownTransaction: - continue default: return false, fmt.Errorf("validating transaction from peerID %s: %w", peerID, err) } + continue } if validity.Propagate { diff --git a/dot/core/messages_integration_test.go b/dot/core/messages_integration_test.go index cdd9692cca..fbbedeb29d 100644 --- a/dot/core/messages_integration_test.go +++ b/dot/core/messages_integration_test.go @@ -89,13 +89,14 @@ func TestService_HandleBlockProduced(t *testing.T) { require.NoError(t, err) // Used to define the state root of new block for testing - genesisBlock, err := s.blockState.GetBlockByHash(s.blockState.GenesisHash()) + parentHash := s.blockState.GenesisHash() + genesisBlock, err := s.blockState.GetBlockByHash(parentHash) require.NoError(t, err) newBlock := types.Block{ Header: types.Header{ Number: 1, - ParentHash: s.blockState.BestBlockHash(), + ParentHash: parentHash, Digest: digest, StateRoot: genesisBlock.Header.StateRoot, }, diff --git a/dot/core/mocks_test.go b/dot/core/mocks_test.go index 4dc2ceecd4..7dca84b036 100644 --- a/dot/core/mocks_test.go +++ b/dot/core/mocks_test.go @@ -587,20 +587,6 @@ func (mr *MockTransactionStateMockRecorder) PendingInPool() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PendingInPool", reflect.TypeOf((*MockTransactionState)(nil).PendingInPool)) } -// Pop mocks base method. -func (m *MockTransactionState) Pop() *transaction.ValidTransaction { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Pop") - ret0, _ := ret[0].(*transaction.ValidTransaction) - return ret0 -} - -// Pop indicates an expected call of Pop. -func (mr *MockTransactionStateMockRecorder) Pop() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pop", reflect.TypeOf((*MockTransactionState)(nil).Pop)) -} - // Push mocks base method. func (m *MockTransactionState) Push(arg0 *transaction.ValidTransaction) (common.Hash, error) { m.ctrl.T.Helper() diff --git a/dot/core/service.go b/dot/core/service.go index c168d66392..a786736f96 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -367,6 +367,7 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { decExt := &ctypes.Extrinsic{} decoder := cscale.NewDecoder(bytes.NewReader(ext)) if err = decoder.Decode(&decExt); err != nil { + logger.Error(err.Error()) continue } @@ -382,7 +383,9 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { transactionValidity, err := rt.ValidateTransaction(externalExt) if err != nil { - return fmt.Errorf("failed to validate transaction for extrinsic %s: %s", ext, err) + logger.Debugf("failed to validate transaction for extrinsic %s: %s", ext, err) + s.transactionState.RemoveExtrinsic(ext) + continue } vtx := transaction.NewValidTransaction(ext, transactionValidity) s.transactionState.AddToPool(vtx) @@ -604,11 +607,14 @@ func (s *Service) GetReadProofAt(block common.Hash, keys [][]byte) ( return block, proofForKeys, nil } -// buildExternalTransaction builds an external transaction based on the current TransactionQueueAPIVersion +// buildExternalTransaction builds an external transaction based on the current transaction queue API version // See https://github.com/paritytech/substrate/blob/polkadot-v0.9.25/primitives/transaction-pool/src/runtime_api.rs#L25-L55 func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrinsic) (types.Extrinsic, error) { runtimeVersion := rt.Version() - txQueueVersion := runtimeVersion.TaggedTransactionQueueVersion() + txQueueVersion, err := runtimeVersion.TaggedTransactionQueueVersion() + if err != nil { + return nil, err + } var extrinsicParts [][]byte switch txQueueVersion { case 3: @@ -616,8 +622,7 @@ func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrin case 2: extrinsicParts = [][]byte{{byte(types.TxnExternal)}, ext} default: - return types.Extrinsic{}, fmt.Errorf("%w: %d", errInvalidTransactionQueueVersion, txQueueVersion) + return nil, fmt.Errorf("%w: %d", errInvalidTransactionQueueVersion, txQueueVersion) } - externalTransaction := types.Extrinsic(bytes.Join(extrinsicParts, nil)) - return externalTransaction, nil + return types.Extrinsic(bytes.Join(extrinsicParts, nil)), nil } diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index 70ba843a75..51b984eddf 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -388,11 +388,11 @@ func TestMaintainTransactionPoolLatestTxnQueue_EmptyBlock(t *testing.T) { }, bestBlockHash) require.NoError(t, err) - resultTx := service.transactionState.Pop() + resultTx := service.transactionState.(*state.TransactionState).Pop() require.Equal(t, expectedTx, resultTx) service.transactionState.RemoveExtrinsic(tx.Extrinsic) - head := service.transactionState.Pop() + head := service.transactionState.(*state.TransactionState).Pop() require.Nil(t, head) } @@ -429,7 +429,7 @@ func TestMaintainTransactionPoolLatestTxnQueue_BlockWithExtrinsics(t *testing.T) res := []*transaction.ValidTransaction{} for { - tx := service.transactionState.Pop() + tx := service.transactionState.(*state.TransactionState).Pop() if tx == nil { break } diff --git a/lib/common/hasher.go b/lib/common/hasher.go index fba56ff99e..003754736a 100644 --- a/lib/common/hasher.go +++ b/lib/common/hasher.go @@ -27,21 +27,30 @@ func Blake2b128(in []byte) ([]byte, error) { return h.Sum(nil), nil } -// MustBlake2b8 returns the first 8 bytes of the Blake2b hash of the input data -func MustBlake2b8(data []byte) (digest [8]byte) { +// Blake2b8 returns the first 8 bytes of the Blake2b hash of the input data +func Blake2b8(data []byte) (digest [8]byte, err error) { const bytes = 8 hasher, err := blake2b.New(bytes, nil) if err != nil { - panic(err) + return [8]byte{}, err } _, err = hasher.Write(data) if err != nil { - panic(err) + return [8]byte{}, err } digestBytes := hasher.Sum(nil) copy(digest[:], digestBytes) + return digest, nil +} + +// MustBlake2b8 returns the first 8 bytes of the Blake2b hash of the input data +func MustBlake2b8(data []byte) (digest [8]byte) { + digest, err := Blake2b8(data) + if err != nil { + panic(err) + } return digest } diff --git a/lib/runtime/version.go b/lib/runtime/version.go index fb48e42b0e..b50855918f 100644 --- a/lib/runtime/version.go +++ b/lib/runtime/version.go @@ -35,15 +35,18 @@ var ( ErrDecodingVersionField = errors.New("decoding version field") ) -// TaggedTransactionQueueVersion returns the TaggedTransactionQueueAPI version -func (v Version) TaggedTransactionQueueVersion() (txQueueVersion uint32) { - encodedTaggedTransactionQueue := common.MustBlake2b8([]byte("TaggedTransactionQueue")) +// TaggedTransactionQueueVersion returns the TaggedTransactionQueue API version +func (v Version) TaggedTransactionQueueVersion() (txQueueVersion uint32, err error) { + encodedTaggedTransactionQueue, err := common.Blake2b8([]byte("TaggedTransactionQueue")) + if err != nil { + return 0, fmt.Errorf("getting blake2b8: %s", err) + } for _, apiItem := range v.APIItems { if apiItem.Name == encodedTaggedTransactionQueue { - return apiItem.Ver + return apiItem.Ver, nil } } - return 0 + return 0, fmt.Errorf("taggedTransactionQueueAPI not found") } // DecodeVersion scale decodes the encoded version data. From 763941f350e77fe59003d98839774b8c1843f19e Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 19 Oct 2022 12:23:57 -0600 Subject: [PATCH 40/45] fix tests --- dot/core/service_test.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index f851c3c5a2..93ece3ba05 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -8,7 +8,6 @@ import ( "context" "encoding/hex" "errors" - "fmt" "testing" "github.com/ChainSafe/gossamer/dot/network" @@ -868,15 +867,15 @@ func TestService_handleChainReorg(t *testing.T) { mockBlockState.EXPECT().GetBlockBody(testCurrentHash).Return(nil, errDummyErr) mockBlockState.EXPECT().GetBlockBody(testAncestorHash).Return(body, nil) mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) + mockTxnState := NewMockTransactionState(ctrl) + mockTxnState.EXPECT().RemoveExtrinsic(ext) service := &Service{ - blockState: mockBlockState, + blockState: mockBlockState, + transactionState: mockTxnState, } - expErr := fmt.Errorf("failed to validate transaction for extrinsic %s: %s", - ext, - errTestDummyError) - execTest(t, service, testPrevHash, testCurrentHash, expErr) + execTest(t, service, testPrevHash, testCurrentHash, nil) }) t.Run("happy path", func(t *testing.T) { From 79adb4bbaf1736a0cd84d35b3c07430fd953ad39 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 21 Oct 2022 11:49:51 -0600 Subject: [PATCH 41/45] feedback --- dot/core/service.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index a786736f96..6b547e7f9e 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -367,8 +367,7 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { decExt := &ctypes.Extrinsic{} decoder := cscale.NewDecoder(bytes.NewReader(ext)) if err = decoder.Decode(&decExt); err != nil { - logger.Error(err.Error()) - continue + return fmt.Errorf("decoding extrinsic: %s", err) } // Inherent are not signed. @@ -383,7 +382,7 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error { transactionValidity, err := rt.ValidateTransaction(externalExt) if err != nil { - logger.Debugf("failed to validate transaction for extrinsic %s: %s", ext, err) + logger.Debugf("failed to validate transaction for extrinsic %s: %s skipping in chain reorg", ext, err) s.transactionState.RemoveExtrinsic(ext) continue } From 57de89d785449d766c4a74bd0d19af86b9ab83d3 Mon Sep 17 00:00:00 2001 From: jimboj Date: Sat, 22 Oct 2022 13:08:55 -0600 Subject: [PATCH 42/45] add todos to remove panic in handleBlockAsync --- dot/core/service.go | 47 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 6b547e7f9e..6776f0c820 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -128,63 +128,40 @@ func (s *Service) StorageRoot() (common.Hash, error) { // HandleBlockImport handles a block that was imported via the network func (s *Service) HandleBlockImport(block *types.Block, state *rtstorage.TrieState) error { - err := s.handleBlock(block, state) - if err != nil { - return fmt.Errorf("handling block: %w", err) - } - - bestBlockHash := s.blockState.BestBlockHash() - isBestBlock := bestBlockHash.Equal(block.Header.Hash()) - - blockAnnounce, err := createBlockAnnounce(block, isBestBlock) - if err != nil { - return fmt.Errorf("creating block announce: %w", err) - } - - s.net.GossipMessage(blockAnnounce) - return nil + return s.handleBlock(block, state) } // HandleBlockProduced handles a block that was produced by us // It is handled the same as an imported block in terms of state updates; the only difference // is we send a BlockAnnounceMessage to our peers. func (s *Service) HandleBlockProduced(block *types.Block, state *rtstorage.TrieState) error { - err := s.handleBlock(block, state) - if err != nil { - return fmt.Errorf("handling block: %w", err) - } - - blockAnnounce, err := createBlockAnnounce(block, true) - if err != nil { - return fmt.Errorf("creating block announce: %w", err) + if err := s.handleBlock(block, state); err != nil { + return err } - s.net.GossipMessage(blockAnnounce) - return nil -} - -func createBlockAnnounce(block *types.Block, isBestBlock bool) ( - blockAnnounce *network.BlockAnnounceMessage, err error) { digest := types.NewDigest() for i := range block.Header.Digest.Types { digestValue, err := block.Header.Digest.Types[i].Value() if err != nil { - return nil, fmt.Errorf("getting value of digest type at index %d: %w", i, err) + return fmt.Errorf("getting value of digest type at index %d: %w", i, err) } err = digest.Add(digestValue) if err != nil { - return nil, fmt.Errorf("adding digest value for type at index %d: %w", i, err) + return err } } - return &network.BlockAnnounceMessage{ + msg := &network.BlockAnnounceMessage{ ParentHash: block.Header.ParentHash, Number: block.Header.Number, StateRoot: block.Header.StateRoot, ExtrinsicsRoot: block.Header.ExtrinsicsRoot, Digest: digest, - BestBlock: isBestBlock, - }, nil + BestBlock: true, + } + + s.net.GossipMessage(msg) + return nil } func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) error { @@ -306,10 +283,12 @@ func (s *Service) handleBlocksAsync() { bestBlockHash := s.blockState.BestBlockHash() if err := s.handleChainReorg(bestBlockHash, block.Header.Hash()); err != nil { + // TODO remove once gossamer is in stable state panic(fmt.Errorf("failed to re-add transactions to chain upon re-org: %s", err)) } if err := s.maintainTransactionPool(block, bestBlockHash); err != nil { + // TODO remove once gossamer is in stable state panic(fmt.Errorf("failed to maintain txn pool after re-org: %s", err)) } case <-s.ctx.Done(): From 9b172fee9ec517dba992728f3d3db017809aeeae Mon Sep 17 00:00:00 2001 From: jimboj Date: Mon, 24 Oct 2022 11:54:58 -0600 Subject: [PATCH 43/45] fix logs --- dot/core/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/core/service.go b/dot/core/service.go index 6776f0c820..9fb25992b3 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -136,7 +136,7 @@ func (s *Service) HandleBlockImport(block *types.Block, state *rtstorage.TrieSta // is we send a BlockAnnounceMessage to our peers. func (s *Service) HandleBlockProduced(block *types.Block, state *rtstorage.TrieState) error { if err := s.handleBlock(block, state); err != nil { - return err + return fmt.Errorf("handling block: %w", err) } digest := types.NewDigest() From 19bb3c773eb69acc70e8c323e442c0dc04e9a57c Mon Sep 17 00:00:00 2001 From: jimboj Date: Mon, 24 Oct 2022 13:35:36 -0600 Subject: [PATCH 44/45] fix handleBlockImport to match dev --- dot/core/service.go | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 9fb25992b3..528bda8c4f 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -128,40 +128,63 @@ func (s *Service) StorageRoot() (common.Hash, error) { // HandleBlockImport handles a block that was imported via the network func (s *Service) HandleBlockImport(block *types.Block, state *rtstorage.TrieState) error { - return s.handleBlock(block, state) + err := s.handleBlock(block, state) + if err != nil { + return fmt.Errorf("handling block: %w", err) + } + + bestBlockHash := s.blockState.BestBlockHash() + isBestBlock := bestBlockHash.Equal(block.Header.Hash()) + + blockAnnounce, err := createBlockAnnounce(block, isBestBlock) + if err != nil { + return fmt.Errorf("creating block announce: %w", err) + } + + s.net.GossipMessage(blockAnnounce) + return nil } // HandleBlockProduced handles a block that was produced by us // It is handled the same as an imported block in terms of state updates; the only difference // is we send a BlockAnnounceMessage to our peers. func (s *Service) HandleBlockProduced(block *types.Block, state *rtstorage.TrieState) error { - if err := s.handleBlock(block, state); err != nil { + err := s.handleBlock(block, state) + if err != nil { return fmt.Errorf("handling block: %w", err) } + blockAnnounce, err := createBlockAnnounce(block, true) + if err != nil { + return fmt.Errorf("creating block announce: %w", err) + } + + s.net.GossipMessage(blockAnnounce) + return nil +} + +func createBlockAnnounce(block *types.Block, isBestBlock bool) ( + blockAnnounce *network.BlockAnnounceMessage, err error) { digest := types.NewDigest() for i := range block.Header.Digest.Types { digestValue, err := block.Header.Digest.Types[i].Value() if err != nil { - return fmt.Errorf("getting value of digest type at index %d: %w", i, err) + return nil, fmt.Errorf("getting value of digest type at index %d: %w", i, err) } err = digest.Add(digestValue) if err != nil { - return err + return nil, fmt.Errorf("adding digest value for type at index %d: %w", i, err) } } - msg := &network.BlockAnnounceMessage{ + return &network.BlockAnnounceMessage{ ParentHash: block.Header.ParentHash, Number: block.Header.Number, StateRoot: block.Header.StateRoot, ExtrinsicsRoot: block.Header.ExtrinsicsRoot, Digest: digest, - BestBlock: true, - } - - s.net.GossipMessage(msg) - return nil + BestBlock: isBestBlock, + }, nil } func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) error { From 0431bfbfd1c308d54b36ab63100179a10e9bf11d Mon Sep 17 00:00:00 2001 From: JimboJ <40345116+jimjbrettj@users.noreply.github.com> Date: Mon, 24 Oct 2022 13:47:29 -0600 Subject: [PATCH 45/45] Update lib/runtime/version.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Eclésio Junior --- lib/runtime/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime/version.go b/lib/runtime/version.go index b50855918f..277b3b71b0 100644 --- a/lib/runtime/version.go +++ b/lib/runtime/version.go @@ -46,7 +46,7 @@ func (v Version) TaggedTransactionQueueVersion() (txQueueVersion uint32, err err return apiItem.Ver, nil } } - return 0, fmt.Errorf("taggedTransactionQueueAPI not found") + return 0, errors.New("taggedTransactionQueueAPI not found") } // DecodeVersion scale decodes the encoded version data.