From 92fb384c09910288de08f5354a62586024ca17c2 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Tue, 22 Sep 2020 11:09:45 +0300 Subject: [PATCH] [#35] Add snapshot method for morph/netmap client With snapshot method node can get previous network maps from previous epoch. Signed-off-by: Alex Vanin --- pkg/morph/client/netmap/client.go | 3 ++ pkg/morph/client/netmap/netmap.go | 59 ++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/pkg/morph/client/netmap/client.go b/pkg/morph/client/netmap/client.go index 210acde2..6df9cbbd 100644 --- a/pkg/morph/client/netmap/client.go +++ b/pkg/morph/client/netmap/client.go @@ -34,6 +34,7 @@ type cfg struct { addPeerMethod, // add peer method name for invocation newEpochMethod, // new epoch method name for invocation netMapMethod, // get network map method name + snapshotMethod, // get network map snapshot method name updateStateMethod, // update state method name for invocation innerRingListMethod string // IR list method name for invocation } @@ -42,6 +43,7 @@ const ( defaultAddPeerMethod = "addPeer" // default add peer method name defaultNewEpochMethod = "newEpoch" // default new epoch method name defaultNetMapMethod = "netmap" // default get network map method name + defaultSnapshotMethod = "snapshot" // default get network map snapshot method name defaultUpdateStateMethod = "updateState" // default update state method name defaultInnerRIngListMethod = "innerRingList" // default IR list method name ) @@ -51,6 +53,7 @@ func defaultConfig() *cfg { addPeerMethod: defaultAddPeerMethod, newEpochMethod: defaultNewEpochMethod, netMapMethod: defaultNetMapMethod, + snapshotMethod: defaultSnapshotMethod, updateStateMethod: defaultUpdateStateMethod, innerRingListMethod: defaultInnerRIngListMethod, } diff --git a/pkg/morph/client/netmap/netmap.go b/pkg/morph/client/netmap/netmap.go index 7351218e..86f86c2a 100644 --- a/pkg/morph/client/netmap/netmap.go +++ b/pkg/morph/client/netmap/netmap.go @@ -11,6 +11,12 @@ import ( type GetNetMapArgs struct { } +// GetSnapshotArgs groups the arguments +// of get netmap snapshot test invoke call. +type GetSnapshotArgs struct { + diff uint64 +} + // GetNetMapValues groups the stack parameters // returned by get network map test invoke. type GetNetMapValues struct { @@ -19,6 +25,12 @@ type GetNetMapValues struct { const nodeInfoFixedPrmNumber = 1 +// SetDiff sets argument for snapshot method of +// netmap contract. +func (g *GetSnapshotArgs) SetDiff(d uint64) { + g.diff = d +} + // Peers return the list of peers from // network map in a binary format. func (g GetNetMapValues) Peers() [][]byte { @@ -32,24 +44,53 @@ func (c *Client) NetMap(_ GetNetMapArgs) (*GetNetMapValues, error) { c.netMapMethod, ) if err != nil { - return nil, errors.Wrapf(err, "could not perform test invocation (%s)", c.netMapMethod) - } else if ln := len(prms); ln != 1 { - return nil, errors.Errorf("unexpected stack item count (%s): %d", c.netMapMethod, ln) + return nil, errors.Wrapf(err, + "could not perform test invocation (%s)", + c.netMapMethod) } - prms, err = client.ArrayFromStackItem(prms[0]) + return peersFromStackItems(prms, c.netMapMethod) +} + +// NetMap performs the test invoke of get snapshot of network map +// from NeoFS Netmap contract. Contract saves only one previous epoch, +// so all invokes with diff > 1 return error. +func (c *Client) Snapshot(a GetSnapshotArgs) (*GetNetMapValues, error) { + prms, err := c.client.TestInvoke( + c.snapshotMethod, + int64(a.diff), + ) if err != nil { - return nil, errors.Wrapf(err, "could not get stack item array from stack item (%s)", c.netMapMethod) + return nil, errors.Wrapf(err, + "could not perform test invocation (%s)", + c.netMapMethod) + } + + return peersFromStackItems(prms, c.snapshotMethod) +} + +func peersFromStackItems(stack []stackitem.Item, method string) (*GetNetMapValues, error) { + if ln := len(stack); ln != 1 { + return nil, errors.Errorf("unexpected stack item count (%s): %d", + method, ln) + } + + peers, err := client.ArrayFromStackItem(stack[0]) + if err != nil { + return nil, errors.Wrapf(err, + "could not get stack item array from stack item (%s)", + method) } res := &GetNetMapValues{ - peers: make([][]byte, 0, len(prms)), + peers: make([][]byte, 0, len(peers)), } - for i := range prms { - peer, err := peerInfoFromStackItem(prms[i]) + for i := range peers { + peer, err := peerInfoFromStackItem(peers[i]) if err != nil { - return nil, errors.Wrapf(err, "could not parse stack item (Peer #%d)", i) + return nil, errors.Wrapf(err, + "could not parse stack item (Peer #%d)", i) } res.peers = append(res.peers, peer)