From 722e7aeab7ca00ded59065a9e5b0cc66acac0082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ecl=C3=A9sio=20Junior?= Date: Tue, 22 Oct 2024 10:12:42 -0400 Subject: [PATCH] feat(scripts): remove deprecated `trie-state` script (#4270) --- dot/rpc/modules/rpc.go | 1 - dot/rpc/modules/state.go | 47 ------- dot/rpc/modules/state_test.go | 93 ------------- scripts/trie_state/trie_state_script.go | 139 ------------------- scripts/trie_state/trie_state_script_test.go | 126 ----------------- tests/rpc/rpc_05-state_test.go | 29 ---- 6 files changed, 435 deletions(-) delete mode 100644 scripts/trie_state/trie_state_script.go delete mode 100644 scripts/trie_state/trie_state_script_test.go diff --git a/dot/rpc/modules/rpc.go b/dot/rpc/modules/rpc.go index 1a01adabbd..9170d76e06 100644 --- a/dot/rpc/modules/rpc.go +++ b/dot/rpc/modules/rpc.go @@ -19,7 +19,6 @@ var ( "state_getPairs", "state_getKeysPaged", "state_queryStorage", - "state_trie", } // AliasesMethods is a map that links the original methods to their aliases diff --git a/dot/rpc/modules/state.go b/dot/rpc/modules/state.go index 7fac92e561..742b023f6f 100644 --- a/dot/rpc/modules/state.go +++ b/dot/rpc/modules/state.go @@ -12,7 +12,6 @@ import ( "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/pkg/scale" - "github.com/ChainSafe/gossamer/pkg/trie" ) // StateGetReadProofRequest json fields @@ -83,10 +82,6 @@ type StateStorageQueryAtRequest struct { At common.Hash `json:"at"` } -type StateTrieAtRequest struct { - At *common.Hash `json:"at"` -} - // StateStorageKeysQuery field to store storage keys type StateStorageKeysQuery [][]byte @@ -117,8 +112,6 @@ type StateStorageResponse string // StatePairResponse is a key values type StatePairResponse []interface{} -type StateTrieResponse []string - // StateStorageKeysResponse field for storage keys type StateStorageKeysResponse []string @@ -252,46 +245,6 @@ func (sm *StateModule) GetPairs(_ *http.Request, req *StatePairRequest, res *Sta return nil } -// Trie RPC method returns a list of scale encoded trie.Entry{Key byte, Value byte} representing -// all the entries in a trie for a block hash, if no block hash is given then it uses the best block hash -func (sm *StateModule) Trie(_ *http.Request, req *StateTrieAtRequest, res *StateTrieResponse) error { - var blockHash common.Hash - - if req.At != nil { - blockHash = *req.At - } else { - blockHash = sm.blockAPI.BestBlockHash() - } - - blockHeader, err := sm.blockAPI.GetHeader(blockHash) - if err != nil { - return fmt.Errorf("getting header: %w", err) - } - - entries, err := sm.storageAPI.Entries(&blockHeader.StateRoot) - if err != nil { - return fmt.Errorf("getting entries: %w", err) - } - - entriesArr := make([]string, 0, len(entries)) - for key, value := range entries { - entry := trie.Entry{ - Key: []byte(key), - Value: value, - } - - encodedEntry, err := scale.Marshal(entry) - if err != nil { - return fmt.Errorf("scale encoding entry: %w", err) - } - - entriesArr = append(entriesArr, common.BytesToHex(encodedEntry)) - } - - *res = entriesArr - return nil -} - // Call makes a call to the runtime. func (sm *StateModule) Call(_ *http.Request, req *StateCallRequest, res *StateCallResponse) error { var blockHash common.Hash diff --git a/dot/rpc/modules/state_test.go b/dot/rpc/modules/state_test.go index 4617560416..3d6a6764eb 100644 --- a/dot/rpc/modules/state_test.go +++ b/dot/rpc/modules/state_test.go @@ -18,11 +18,9 @@ package modules import ( "errors" "net/http" - "slices" "testing" wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" - "github.com/ChainSafe/gossamer/pkg/trie" "github.com/ChainSafe/gossamer/dot/rpc/modules/mocks" testdata "github.com/ChainSafe/gossamer/dot/rpc/modules/test_data" @@ -32,7 +30,6 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -311,96 +308,6 @@ func TestCall(t *testing.T) { assert.NotEmpty(t, res) } -func TestStateTrie(t *testing.T) { - expecificBlockHash := common.Hash([32]byte{6, 6, 6, 6, 6, 6}) - var expectedEncodedSlice []string - entries := []trie.Entry{ - {Key: []byte("entry-1"), Value: []byte{0, 1, 2, 3}}, - {Key: []byte("entry-2"), Value: []byte{3, 4, 5, 6}}, - } - - for _, entry := range entries { - expectedEncodedSlice = append(expectedEncodedSlice, common.BytesToHex(scale.MustMarshal(entry))) - } - - testcases := map[string]struct { - request StateTrieAtRequest - newStateModule func(t *testing.T) *StateModule - expected StateTrieResponse - }{ - "blockhash_parameter_nil": { - request: StateTrieAtRequest{At: nil}, - expected: expectedEncodedSlice, - newStateModule: func(t *testing.T) *StateModule { - ctrl := gomock.NewController(t) - - bestBlockHash := common.Hash([32]byte{1, 0, 1, 0, 1}) - blockAPIMock := NewMockBlockAPI(ctrl) - blockAPIMock.EXPECT().BestBlockHash().Return(bestBlockHash) - - fakeStateRoot := common.Hash([32]byte{5, 5, 5, 5, 5}) - fakeBlockHeader := types.NewHeader(common.EmptyHash, fakeStateRoot, - common.EmptyHash, 1, nil) - - blockAPIMock.EXPECT().GetHeader(bestBlockHash).Return(fakeBlockHeader, nil) - - fakeEntries := map[string][]byte{ - "entry-1": {0, 1, 2, 3}, - "entry-2": {3, 4, 5, 6}, - } - storageAPIMock := NewMockStorageAPI(ctrl) - storageAPIMock.EXPECT().Entries(&fakeStateRoot). - Return(fakeEntries, nil) - - sm := NewStateModule(nil, storageAPIMock, nil, blockAPIMock) - return sm - }, - }, - "blockhash_parameter_not_nil": { - request: StateTrieAtRequest{At: &expecificBlockHash}, - expected: expectedEncodedSlice, - newStateModule: func(t *testing.T) *StateModule { - ctrl := gomock.NewController(t) - blockAPIMock := NewMockBlockAPI(ctrl) - - fakeStateRoot := common.Hash([32]byte{5, 5, 5, 5, 5}) - fakeBlockHeader := types.NewHeader(common.EmptyHash, fakeStateRoot, - common.EmptyHash, 1, nil) - - blockAPIMock.EXPECT().GetHeader(expecificBlockHash). - Return(fakeBlockHeader, nil) - - fakeEntries := map[string][]byte{ - "entry-1": {0, 1, 2, 3}, - "entry-2": {3, 4, 5, 6}, - } - storageAPIMock := NewMockStorageAPI(ctrl) - storageAPIMock.EXPECT().Entries(&fakeStateRoot). - Return(fakeEntries, nil) - - sm := NewStateModule(nil, storageAPIMock, nil, blockAPIMock) - return sm - }, - }, - } - - for tname, tt := range testcases { - tt := tt - - t.Run(tname, func(t *testing.T) { - sm := tt.newStateModule(t) - - var res StateTrieResponse - err := sm.Trie(nil, &tt.request, &res) - require.NoError(t, err) - - slices.Sort(tt.expected) - slices.Sort(res) - require.Equal(t, tt.expected, res) - }) - } -} - func TestStateModuleGetMetadata(t *testing.T) { ctrl := gomock.NewController(t) diff --git a/scripts/trie_state/trie_state_script.go b/scripts/trie_state/trie_state_script.go deleted file mode 100644 index 761755f901..0000000000 --- a/scripts/trie_state/trie_state_script.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2024 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package main - -import ( - "context" - "encoding/json" - "fmt" - "os" - "time" - - "github.com/ChainSafe/gossamer/dot/rpc/modules" - "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/pkg/scale" - "github.com/ChainSafe/gossamer/pkg/trie" - inmemory_trie "github.com/ChainSafe/gossamer/pkg/trie/inmemory" - "github.com/ChainSafe/gossamer/tests/utils/rpc" -) - -func fetchWithTimeout(ctx context.Context, - method, params string, target interface{}) { - - // Can adjust timeout as desired, default is very long - getResponseCtx, getResponseCancel := context.WithTimeout(ctx, 1000000*time.Second) - defer getResponseCancel() - err := getResponse(getResponseCtx, method, params, target) - if err != nil { - panic(fmt.Sprintf("error getting response %v", err)) - } -} - -func getResponse(ctx context.Context, method, params string, target interface{}) (err error) { - const rpcPort = "8545" - endpoint := rpc.NewEndpoint(rpcPort) - respBody, err := rpc.Post(ctx, endpoint, method, params) - if err != nil { - return fmt.Errorf("cannot RPC post: %w", err) - } - - err = rpc.Decode(respBody, &target) - if err != nil { - return fmt.Errorf("cannot decode RPC response: %w", err) - } - - return nil -} - -func writeTrieState(response modules.StateTrieResponse, destination string) { - encResponse, err := json.Marshal(response) - if err != nil { - panic(fmt.Sprintf("json marshalling response %v", err)) - } - - err = os.WriteFile(destination, encResponse, 0o600) - if err != nil { - panic(fmt.Sprintf("writing to file %v", err)) - } -} - -func fetchTrieState(ctx context.Context, blockHash common.Hash, destination string) modules.StateTrieResponse { - params := fmt.Sprintf(`["%s"]`, blockHash) - var response modules.StateTrieResponse - fetchWithTimeout(ctx, "state_trie", params, &response) - - writeTrieState(response, destination) - return response -} - -func compareStateRoots(response modules.StateTrieResponse, expectedStateRoot common.Hash, trieVersion trie.TrieLayout) { - entries := make(map[string]string, len(response)) - for _, encodedEntry := range response { - bytesEncodedEntry := common.MustHexToBytes(encodedEntry) - - entry := trie.Entry{} - err := scale.Unmarshal(bytesEncodedEntry, &entry) - if err != nil { - panic(fmt.Sprintf("error unmarshalling into trie entry %v", err)) - } - entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) - } - - newTrie, err := inmemory_trie.LoadFromMap(entries, trieVersion) - if err != nil { - panic(fmt.Sprintf("loading trie from map %v", err)) - } - - trieHash := trieVersion.MustHash(newTrie) - if expectedStateRoot != trieHash { - panic("westendDevStateRoot does not match trieHash") - } -} - -/* -This is a script to query the trie state from a specific block height from a running node. - -Example commands to run a node: - - 1. ./bin/gossamer init --chain westend-dev --key alice - - 2. ./bin/gossamer --chain westend-dev --key alice --rpc-external=true --unsafe-rpc=true - -Once the node has started and processed the block whose state you need, can execute the script like so: - 1. go run trieStateScript.go -*/ -func main() { - if len(os.Args) < 3 { - panic("expected more arguments, block hash and destination file required") - } - - blockHash, err := common.HexToHash(os.Args[1]) - if err != nil { - panic("block hash must be in hex format") - } - - destinationFile := os.Args[2] - expectedStateRoot := common.Hash{} - var trieVersion trie.TrieLayout - if len(os.Args) == 5 { - expectedStateRoot, err = common.HexToHash(os.Args[3]) - if err != nil { - panic("expected state root must be in hex format") - } - - trieVersion, err = trie.ParseVersion(os.Args[4]) - if err != nil { - panic("trie version must be an integer") - } - } else if len(os.Args) != 3 { - panic("invalid number of arguments") - } - - ctx, _ := context.WithCancel(context.Background()) //nolint - response := fetchTrieState(ctx, blockHash, destinationFile) - - if !expectedStateRoot.IsEmpty() { - compareStateRoots(response, expectedStateRoot, trieVersion) - } -} diff --git a/scripts/trie_state/trie_state_script_test.go b/scripts/trie_state/trie_state_script_test.go deleted file mode 100644 index 11703b7077..0000000000 --- a/scripts/trie_state/trie_state_script_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2024 ChainSafe Systems (ON) -// SPDX-License-Identifier: LGPL-3.0-only - -package main - -import ( - "os" - "testing" - - "github.com/ChainSafe/gossamer/dot/rpc/modules" - "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/pkg/trie" - "github.com/stretchr/testify/require" -) - -// This is fake data used just for testing purposes -var testStateData = []string{"0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000", "0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000", "0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000", "0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000", "0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000", "0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000", "0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000", "0x801cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4ca404d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0100000000000000"} //nolint - -func clean(t *testing.T, file string) { - t.Helper() - err := os.Remove(file) - require.NoError(t, err) -} - -func Test_writeTrieState(t *testing.T) { - writeTrieState(testStateData, "westendDevTestState.json") - _, err := os.Stat("./westendDevTestState.json") - require.NoError(t, err) - - clean(t, "westendDevTestState.json") -} - -func Test_compareStateRoots(t *testing.T) { - type args struct { - response modules.StateTrieResponse - expectedStateRoot common.Hash - trieVersion trie.TrieLayout - } - tests := []struct { - name string - args args - shouldPanic bool - }{ - { - name: "happy_path", - args: args{ - response: testStateData, - expectedStateRoot: common.MustHexToHash("0x3b1863ff981a31864be76037e4cf5c927b937dd8a8e1e25494128da7a95b5cdf"), - trieVersion: 0, - }, - }, - { - name: "invalid_trie_version", - args: args{ - response: testStateData, - expectedStateRoot: common.MustHexToHash("0x6120d3afde6c139305bd7c0dcf50bdff5b620203e00c7491b2c30f95dccacc32"), - trieVersion: 21, - }, - shouldPanic: true, - }, - { - name: "hashes_do_not_match", - args: args{ - response: testStateData, - expectedStateRoot: common.MustHexToHash("0x01"), - trieVersion: 21, - }, - shouldPanic: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.shouldPanic { - require.Panics(t, - func() { - compareStateRoots(tt.args.response, tt.args.expectedStateRoot, tt.args.trieVersion) - }, - "The code did not panic") - } else { - compareStateRoots(tt.args.response, tt.args.expectedStateRoot, tt.args.trieVersion) - } - }) - } -} - -func Test_cli(t *testing.T) { - tests := []struct { - name string - args []string - }{ - { - name: "no_arguments", - }, - { - name: "to_few_arguments", - args: []string{"0x01"}, - }, - { - name: "invalid_formatting_for_block_hash", - args: []string{"hello", "output.json"}, - }, - { - name: "no_trie_version", - args: []string{"0x01", "output.json", "0x01"}, - }, - { - name: "invalid_formatting_for_root_hash", - args: []string{"0x01", "output.json", "hello", "1"}, - }, - { - name: "invalid_trie_version", - args: []string{"0x01", "output.json", "0x01", "hello"}, - }, - { - name: "to_many_arguments", - args: []string{"0x01", "output.json", "0x01", "1", "0x01"}, - }, - } - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - os.Args = tt.args - require.Panics(t, func() { main() }, "The code did not panic") - }) - } -} diff --git a/tests/rpc/rpc_05-state_test.go b/tests/rpc/rpc_05-state_test.go index 02770f618e..5fa91fc87d 100644 --- a/tests/rpc/rpc_05-state_test.go +++ b/tests/rpc/rpc_05-state_test.go @@ -13,9 +13,6 @@ import ( "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/runtime" libutils "github.com/ChainSafe/gossamer/lib/utils" - "github.com/ChainSafe/gossamer/pkg/scale" - "github.com/ChainSafe/gossamer/pkg/trie" - inmemory_trie "github.com/ChainSafe/gossamer/pkg/trie/inmemory" "github.com/ChainSafe/gossamer/tests/utils/config" "github.com/ChainSafe/gossamer/tests/utils/node" "github.com/ChainSafe/gossamer/tests/utils/rpc" @@ -35,32 +32,6 @@ func TestStateRPCResponseValidation(t *testing.T) { //nolint:tparallel getBlockHashCancel() require.NoError(t, err) - t.Run("state_trie", func(t *testing.T) { - t.Parallel() - const westendDevGenesisHash = "0x276bfa91f70859348285599321ea96afd3ae681f0be47d36196bac8075ea32e8" - const westendDevStateRoot = "0x953044ba4386a72ae434d2a2fbdfca77640a28ac3841a924674cbfe7a8b9a81c" - params := fmt.Sprintf(`["%s"]`, westendDevGenesisHash) - - var response modules.StateTrieResponse - fetchWithTimeout(ctx, t, "state_trie", params, &response) - - entries := make(map[string]string, len(response)) - for _, encodedEntry := range response { - bytesEncodedEntry := common.MustHexToBytes(encodedEntry) - - entry := trie.Entry{} - err := scale.Unmarshal(bytesEncodedEntry, &entry) - require.NoError(t, err) - entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) - } - - newTrie, err := inmemory_trie.LoadFromMap(entries, trie.V0) - require.NoError(t, err) - - trieHash := newTrie.MustHash() - require.Equal(t, westendDevStateRoot, trieHash.String()) - }) - // TODO: Improve runtime tests // https://github.com/ChainSafe/gossamer/issues/3234 t.Run("state_call", func(t *testing.T) {