From 071fb61076063eb55bdab8645e32b584ebb0c8b2 Mon Sep 17 00:00:00 2001 From: Flavien Binet Date: Thu, 4 Aug 2022 14:08:32 +0200 Subject: [PATCH 1/6] feat: reenable state sync --- cmd/fetchd/cmd/root.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cmd/fetchd/cmd/root.go b/cmd/fetchd/cmd/root.go index 1f66ef252..9c3975983 100644 --- a/cmd/fetchd/cmd/root.go +++ b/cmd/fetchd/cmd/root.go @@ -3,7 +3,6 @@ package cmd import ( "bufio" "errors" - "fmt" "io" "math/big" "os" @@ -237,13 +236,6 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a panic(err) } - // Ensure node don't have snapshot feature enabled until cosmwasm properly support it. - // Snapshots would be taken properly but impossible to restore - // due to missing cosmwasm chunks. - if cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval)) > 0 { - panic(fmt.Errorf("state-sync snapshots feature is currently not supported, please set %s = 0 in command flags or ~/.fetchd/config/app.toml", server.FlagStateSyncSnapshotInterval)) - } - var wasmOpts []wasm.Option if cast.ToBool(appOpts.Get("telemetry.enabled")) { wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer)) From edabd45ff2f0ce179d50acbac27573cf46323ed1 Mon Sep 17 00:00:00 2001 From: Flavien Binet Date: Fri, 5 Aug 2022 10:35:23 +0200 Subject: [PATCH 2/6] docs: add state-sync docs --- docs/docs/state-sync.md | 108 ++++++++++++++++++++++++++++++++++++++++ docs/mkdocs.yml | 1 + 2 files changed, 109 insertions(+) create mode 100644 docs/docs/state-sync.md diff --git a/docs/docs/state-sync.md b/docs/docs/state-sync.md new file mode 100644 index 000000000..b0a7e6924 --- /dev/null +++ b/docs/docs/state-sync.md @@ -0,0 +1,108 @@ + +# State-sync + +State sync is a feature which allows you to quickly bootstrap a new node by allowing it to pull a *state snapshot* taken by other nodes. + + +## Configuring the new node + +In order to instruct the node to sync itself using state sync, it need some configuration in the `~/.fetchd/config/config.toml` file. +Open this file in an editor and lookup the `statesync` section. By default, it should looks like this: + +```yaml +####################################################### +### State Sync Configuration Options ### +####################################################### +[statesync] +# State sync rapidly bootstraps a new node by discovering, fetching, and restoring a state machine +# snapshot from peers instead of fetching and replaying historical blocks. Requires some peers in +# the network to take and serve state machine snapshots. State sync is not attempted if the node +# has any local state (LastBlockHeight > 0). The node will have a truncated block history, +# starting from the height of the snapshot. +enable = false + +# RPC servers (comma-separated) for light client verification of the synced state machine and +# retrieval of state data for node bootstrapping. Also needs a trusted height and corresponding +# header hash obtained from a trusted source, and a period during which validators can be trusted. +# +# For Cosmos SDK-based chains, trust_period should usually be about 2/3 of the unbonding time (~2 +# weeks) during which they can be financially punished (slashed) for misbehavior. +rpc_servers = "" +trust_height = 0 +trust_hash = "" +trust_period = "168h0m0s" + +# Time to spend discovering snapshots before initiating a restore. +discovery_time = "15s" + +# Temporary directory for state sync snapshot chunks, defaults to the OS tempdir (typically /tmp). +# Will create a new, randomly named directory within, and remove it when done. +temp_dir = "" + +# The timeout duration before re-requesting a chunk, possibly from a different +# peer (default: 1 minute). +chunk_request_timeout = "10s" + +# The number of concurrent chunk fetchers to run (default: 1). +chunk_fetchers = "4" +``` + +A few changes are needed: + +- First, set `enable = true` to activate the state sync engine. +- Then, **at least 2** rpc servers must be provided. A good place to find some is the [cosmos chain registry](https://github.com/cosmos/chain-registry/blob/master/fetchhub/chain.json#L62). Servers must be comma separated without space (ie: `rpc_servers = "https://rpc-fetchhub.fetch.ai:443,https://fetchapi.terminet.io"`) +- And last, a *recent* `trust_height` and `trust_hash` to start from are needed. Recent means it must be contained in the `trust_period` (~1 week old by default). These can be obtained from a RPC server **you trust to provide you correct data** (and the 2nd RPC server from `rpc_servers` will be charged of confirming that the data are correct). To retrieve the correct value for a fetch.ai RPC server, and the current network height, use: + +```bash +curl https://rpc-fetchhub.fetch.ai:443/block | jq -r '{"trusted_hash": .result.block_id.hash, "trusted_height": .result.block.header.height}' +{ + "trusted_hash": "46868B76E6C814C35B2D109FCA177EBB70689AE3D46C65E4D75DE5363A86FF97", + "trusted_height": "7041920" +} +``` + +and set these values in the config file. + +Once this is set, make sure you have the correct genesis by downloading it from the RPC node: + +```bash +wget https://storage.googleapis.com/fetch-ai-mainnet-v2-genesis/genesis-fetchhub4.json +mv genesis-fetchhub4.json ~/.fetchd/config/genesis.json +``` + +and start the node using the seeds from the chain-registry: + +```bash +fetchd start --p2p.seeds=$(curl -s https://raw.githubusercontent.com/cosmos/chain-registry/master/fetchhub/chain.json | jq -r '[foreach .peers.seeds[] as $item (""; "\($item.id)@\($item.address)")] | join(",")') +``` + +After the node initialized, it will start searching for available snapshots, and it should print log messages similar to: + +``` +8:22AM INF Discovered new snapshot format=1 hash="� ݫ/��\r�F#C(pD�<��\x066��\x1f��\x1f Date: Wed, 24 Aug 2022 11:42:08 +0200 Subject: [PATCH 3/6] docs: typos --- docs/docs/state-sync.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/docs/state-sync.md b/docs/docs/state-sync.md index b0a7e6924..dbfd7238c 100644 --- a/docs/docs/state-sync.md +++ b/docs/docs/state-sync.md @@ -66,8 +66,7 @@ and set these values in the config file. Once this is set, make sure you have the correct genesis by downloading it from the RPC node: ```bash -wget https://storage.googleapis.com/fetch-ai-mainnet-v2-genesis/genesis-fetchhub4.json -mv genesis-fetchhub4.json ~/.fetchd/config/genesis.json +curl https://raw.githubusercontent.com/fetchai/genesis-fetchhub/fetchhub-4/fetchhub-4/data/genesis_migrated_5300200.json --output ~/.fetchd/config/genesis.json ``` and start the node using the seeds from the chain-registry: @@ -85,8 +84,8 @@ After the node initialized, it will start searching for available snapshots, and ## Configure an existing node to provide snapshots -In order to provide new nodes snapshots they can start from, existing nodes need to be configure to create these snapshots. -This can be configured from the `~/.fetchd/config/app.toml` file, in the `state-sync` section. +In order to provide new nodes snapshots they can start from, existing nodes need to be configured to create these snapshots. +This requires changes in the `~/.fetchd/config/app.toml` file, in the `state-sync` section. ``` ############################################################################### From e7ec360ab241f9629583e458edb2d63d3227c938 Mon Sep 17 00:00:00 2001 From: Flavien Binet Date: Wed, 24 Aug 2022 17:50:34 +0200 Subject: [PATCH 4/6] fix: register wasm snapshotter --- app/app.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/app.go b/app/app.go index fd29e1b66..f3e4fa5f9 100644 --- a/app/app.go +++ b/app/app.go @@ -15,6 +15,7 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" wasmclient "github.com/CosmWasm/wasmd/x/wasm/client" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" @@ -594,6 +595,17 @@ func New( app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) + // must be before Loading version + // requires the snapshot store to be created and registered as a BaseAppOption + if manager := app.SnapshotManager(); manager != nil { + err := manager.RegisterExtensions( + wasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.WasmKeeper), + ) + if err != nil { + panic(fmt.Errorf("failed to register snapshot extension: %s", err)) + } + } + if loadLatest { if err := app.LoadLatestVersion(); err != nil { tmos.Exit(err.Error()) From 795c91e45b3dc33c1fb40374a0c91aebc9b92ba8 Mon Sep 17 00:00:00 2001 From: Flavien Binet Date: Thu, 25 Aug 2022 15:08:12 +0200 Subject: [PATCH 5/6] docs: update state sync docs --- docs/docs/state-sync.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/docs/state-sync.md b/docs/docs/state-sync.md index dbfd7238c..76aa78ecb 100644 --- a/docs/docs/state-sync.md +++ b/docs/docs/state-sync.md @@ -3,11 +3,14 @@ State sync is a feature which allows you to quickly bootstrap a new node by allowing it to pull a *state snapshot* taken by other nodes. +The state sync feature is only available from `fetchd v0.10.6` and later. Prior versions needed to either sync from scratch or restore a [chain snapshot](../snapshots), which both could take hours before having the node fully synced. + +With state sync, it now takes only a few minutes before having an operational node. ## Configuring the new node -In order to instruct the node to sync itself using state sync, it need some configuration in the `~/.fetchd/config/config.toml` file. -Open this file in an editor and lookup the `statesync` section. By default, it should looks like this: +In order to instruct the node to sync itself using a state sync snapshot, it need some configuration in the `~/.fetchd/config/config.toml` file. +Open this file in an editor and lookup for the `statesync` section. By default, it should looks like this: ```yaml ####################################################### @@ -50,8 +53,10 @@ chunk_fetchers = "4" A few changes are needed: - First, set `enable = true` to activate the state sync engine. -- Then, **at least 2** rpc servers must be provided. A good place to find some is the [cosmos chain registry](https://github.com/cosmos/chain-registry/blob/master/fetchhub/chain.json#L62). Servers must be comma separated without space (ie: `rpc_servers = "https://rpc-fetchhub.fetch.ai:443,https://fetchapi.terminet.io"`) -- And last, a *recent* `trust_height` and `trust_hash` to start from are needed. Recent means it must be contained in the `trust_period` (~1 week old by default). These can be obtained from a RPC server **you trust to provide you correct data** (and the 2nd RPC server from `rpc_servers` will be charged of confirming that the data are correct). To retrieve the correct value for a fetch.ai RPC server, and the current network height, use: +- Then, **at least 2** rpc servers must be provided. A good place to find some is the [cosmos chain registry](https://github.com/cosmos/chain-registry/blob/master/fetchhub/chain.json#L62). Servers must be comma separated without space (ie: `rpc_servers = "https://rpc-fetchhub.fetch.ai:443,https://fetchapi.terminet.io"`). These servers will be used to verify the snapshots, so make sure you trust them enough for this. +- And last, a *recent* `trust_height` and `trust_hash` are needed. Recent means it must be contained in the `trust_period` (168 hours, or ~1 week old by default). These can be obtained from a RPC server **you trust to provide you correct data** (and the 2nd RPC server from `rpc_servers` will be charged of confirming that the data are correct). + +To retrieve the correct value for a fetch.ai RPC server, and the current network height, use: ```bash curl https://rpc-fetchhub.fetch.ai:443/block | jq -r '{"trusted_hash": .result.block_id.hash, "trusted_height": .result.block.header.height}' @@ -82,6 +87,10 @@ After the node initialized, it will start searching for available snapshots, and 8:22AM INF Discovered new snapshot format=1 hash="F�=\x05�Gh�{�|�����,�Q'�=]\x1a�$�b�ֿQ" height=1900 module=statesync ``` +The node will select the one with the `height` value the closest to the tip of the chain, and it will then start restoring the state, and finish syncing the few blocks remaining. + +If it fails to verify any blocks or hash when restoring, it will attempt to restore the next available snapshot, and, if no more are available, will fallback in discovery mode until an usable snapshot is available. + ## Configure an existing node to provide snapshots In order to provide new nodes snapshots they can start from, existing nodes need to be configured to create these snapshots. @@ -104,4 +113,4 @@ snapshot-interval = 0 snapshot-keep-recent = 2 ``` -Here `snapshot-interval` must be set to a number of blocks between each snapshot creation and it depends on your node prunning settings. The number of snapshots to keep can be set with `snapshot-keep-recent`. \ No newline at end of file +Here `snapshot-interval` must be set to a number of blocks between each snapshot creation and it must be a multiple of your node prunning settings (default is 100, so valid values are 100, 1000, 700...). The number of snapshots to keep can be set with `snapshot-keep-recent`. \ No newline at end of file From e8bebb0eb7ba38f86041f88ae162acb3aa8c9b9d Mon Sep 17 00:00:00 2001 From: Flavien Binet Date: Thu, 25 Aug 2022 16:25:15 +0200 Subject: [PATCH 6/6] fix: add proper seeds --- docs/docs/state-sync.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/state-sync.md b/docs/docs/state-sync.md index 76aa78ecb..59c5584e3 100644 --- a/docs/docs/state-sync.md +++ b/docs/docs/state-sync.md @@ -77,7 +77,7 @@ curl https://raw.githubusercontent.com/fetchai/genesis-fetchhub/fetchhub-4/fetch and start the node using the seeds from the chain-registry: ```bash -fetchd start --p2p.seeds=$(curl -s https://raw.githubusercontent.com/cosmos/chain-registry/master/fetchhub/chain.json | jq -r '[foreach .peers.seeds[] as $item (""; "\($item.id)@\($item.address)")] | join(",")') +fetchd start --p2p.seeds="17693da418c15c95d629994a320e2c4f51a8069b@connect-fetchhub.fetch.ai:36456,a575c681c2861fe945f77cb3aba0357da294f1f2@connect-fetchhub.fetch.ai:36457,d7cda986c9f59ab9e05058a803c3d0300d15d8da@connect-fetchhub.fetch.ai:36458" ``` After the node initialized, it will start searching for available snapshots, and it should print log messages similar to: