From 805f653d0fb84dadb242170646f7bd7c4a3e330b Mon Sep 17 00:00:00 2001 From: Adu Date: Wed, 19 Jan 2022 21:12:32 +0800 Subject: [PATCH 01/12] docs: ADR-049 state sync hooks --- docs/architecture/adr-049-state-sync-hooks.md | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 docs/architecture/adr-049-state-sync-hooks.md diff --git a/docs/architecture/adr-049-state-sync-hooks.md b/docs/architecture/adr-049-state-sync-hooks.md new file mode 100644 index 000000000000..23b2defab7ff --- /dev/null +++ b/docs/architecture/adr-049-state-sync-hooks.md @@ -0,0 +1,161 @@ +# ADR 049: State Sync Hooks + +## Changelog + +- Jan 19, 2022: Initial Draft + +## Status + +Draft, Under Implementation + +## Abstract + +This ADR provides hooks for app modules to publish additional state(outside of IAVL tree) for state-sync. + +## Context + +New clients uses state-sync to download snapshots of module state from peer nodes. Currently, the snapshot consists of a +stream of `SnapshotStoreItem` and `SnapshotIAVLItem`, which means for app modules that maintain their states outside of +the IAVL tree, they can not add their states to the snapshot stream for state-sync. + +## Decision + +A simple backward-compatible proposal based on our existing implementation is that, we can add two new message types: +`SnapshotExtensionMeta` and `SnapshotExtensionPayload`, and they are appended to the existing multi-store stream with `SnapshotExtensionMeta` acting as a delimiter between modules. + +```proto +// SnapshotItem is an item contained in a rootmulti.Store snapshot. +message SnapshotItem { + // item is the specific type of snapshot item. + oneof item { + SnapshotStoreItem store = 1; + SnapshotIAVLItem iavl = 2 [(gogoproto.customname) = "IAVL"]; + SnapshotExtensionMeta extension = 3; + SnapshotExtensionPayload extension_payload = 4; + } +} + +// SnapshotStoreItem contains metadata about a snapshotted store. +message SnapshotStoreItem { + string name = 1; +} + +// SnapshotIAVLItem is an exported IAVL node. +message SnapshotIAVLItem { + bytes key = 1; + bytes value = 2; + int64 version = 3; + int32 height = 4; +} + +// SnapshotExtensionMeta contains metadata about an external snapshotter. +message SnapshotExtensionMeta { + string name = 1; + uint32 format = 2; +} + +// SnapshotExtensionPayload contains payloads of an external snapshotter. +message SnapshotExtensionPayload { + bytes payload = 1; +} +``` + +The snapshot stream would look like this: + +```go +// multi-store snapshot +{SnapshotStoreItem | SnapshotIAVLItem, ...} +// module1 snapshot +SnapshotExtensionMeta +{SnapshotExtensionPayload, ...} +// module2 snapshot +SnapshotExtensionMeta +{SnapshotExtensionPayload, ...} +``` + +Add `extensions` field to snapshot `Manager` for extension snapshotters. Multistore snapshotter is a special one and it doesn't need a name because it is always placed at the beginning of the binary stream. + +```go +type Manager struct { + store *Store + multistore types.Snapshotter + extensions map[string]types.NamedSnapshotter + mtx sync.Mutex + operation operation + chRestore chan<- io.ReadCloser + chRestoreDone <-chan restoreDone + restoreChunkHashes [][]byte + restoreChunkIndex uint32 +} +``` + +As with `Snapshotter` interface for `multistore` snapshotter, two more function signatures: `SnapshotFormat` and `SupportedFormats` are added. +