From c008910157df3974f1feabccf91ea2fcac4e1ccf Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 19 Oct 2021 10:33:42 +0300 Subject: [PATCH] [#152] netmap: allow only alphabet calls in `addPeer` If notary is enabled only alphabet calls are expected. Signed-off-by: Evgenii Stratonikov --- netmap/netmap_contract.go | 25 +++++++++++++---------- tests/netmap_test.go | 42 ++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/netmap/netmap_contract.go b/netmap/netmap_contract.go index fad4872..2342dbe 100644 --- a/netmap/netmap_contract.go +++ b/netmap/netmap_contract.go @@ -199,27 +199,30 @@ func AddPeer(nodeInfo []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode - nodeKey []byte - alphabetCall bool + alphabet []common.IRNode + nodeKey []byte ) + publicKey := nodeInfo[2:35] // offset:2, len:33 + if notaryDisabled { alphabet = common.AlphabetNodes() nodeKey = common.InnerRingInvoker(alphabet) - alphabetCall = len(nodeKey) != 0 + if len(nodeKey) == 0 { + if !runtime.CheckWitness(publicKey) { + panic("addPeer: witness check failed") + } + runtime.Notify("AddPeer", nodeInfo) + return + } } else { multiaddr := common.AlphabetAddress() - alphabetCall = runtime.CheckWitness(multiaddr) - } - - if !alphabetCall { - publicKey := nodeInfo[2:35] // offset:2, len:33 if !runtime.CheckWitness(publicKey) { panic("addPeer: witness check failed") } - runtime.Notify("AddPeer", nodeInfo) - return + if !runtime.CheckWitness(multiaddr) { + panic("addPeer: alphabet witness check failed") + } } candidate := storageNode{ diff --git a/tests/netmap_test.go b/tests/netmap_test.go index c93831b..32f8ed5 100644 --- a/tests/netmap_test.go +++ b/tests/netmap_test.go @@ -1,6 +1,7 @@ package tests import ( + "math/big" "math/rand" "testing" @@ -54,27 +55,44 @@ func TestAddPeer(t *testing.T) { acc := NewAccount(t, bc) dummyInfo := dummyNodeInfo(acc) - acc1 := NewAccount(t, bc) - tx := PrepareInvoke(t, bc, acc1, h, "addPeer", dummyInfo) + tx := PrepareInvoke(t, bc, CommitteeAcc, h, "addPeer", dummyInfo) AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "witness check failed") + CheckFault(t, bc, tx.Hash(), "addPeer: witness check failed") tx = PrepareInvoke(t, bc, acc, h, "addPeer", dummyInfo) AddBlock(t, bc, tx) + CheckFault(t, bc, tx.Hash(), "addPeer: alphabet witness check failed") + + tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "addPeer", dummyInfo) + AddBlockCheckHalt(t, bc, tx) + + tx = PrepareInvoke(t, bc, acc, h, "netmapCandidates") + AddBlock(t, bc, tx) + + checkNode := func(t *testing.T, info []byte, state int64, actual stackitem.Item) { + // Actual is netmap.netmapNode. + require.Equal(t, stackitem.NewStruct([]stackitem.Item{ + stackitem.NewStruct([]stackitem.Item{ + stackitem.NewByteArray(dummyInfo), + }), + stackitem.NewBigInteger(big.NewInt(state)), + }), actual) + } aer := CheckHalt(t, bc, tx.Hash()) - require.Equal(t, 1, len(aer.Events)) - require.Equal(t, "AddPeer", aer.Events[0].Name) - require.Equal(t, stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray(dummyInfo)}), - aer.Events[0].Item) + nodes, _ := aer.Stack[0].Value().([]stackitem.Item) + require.Equal(t, 1, len(nodes)) + checkNode(t, dummyInfo, 1, nodes[0]) dummyInfo[0] ^= 0xFF - tx = PrepareInvoke(t, bc, acc, h, "addPeer", dummyInfo) + tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "addPeer", dummyInfo) + AddBlockCheckHalt(t, bc, tx) + + tx = PrepareInvoke(t, bc, acc, h, "netmapCandidates") AddBlock(t, bc, tx) aer = CheckHalt(t, bc, tx.Hash()) - require.Equal(t, 1, len(aer.Events)) - require.Equal(t, "AddPeer", aer.Events[0].Name) - require.Equal(t, stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray(dummyInfo)}), - aer.Events[0].Item) + nodes, _ = aer.Stack[0].Value().([]stackitem.Item) + require.Equal(t, 1, len(nodes)) + checkNode(t, dummyInfo, 1, nodes[0]) }