diff --git a/netmap/netmap_contract.go b/netmap/netmap_contract.go index 2342dbe..a4c3675 100644 --- a/netmap/netmap_contract.go +++ b/netmap/netmap_contract.go @@ -262,31 +262,21 @@ func UpdateState(state int, publicKey interop.PublicKey) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode - nodeKey []byte - alphabetCall bool + alphabet []common.IRNode + nodeKey []byte ) if notaryDisabled { alphabet = common.AlphabetNodes() nodeKey = common.InnerRingInvoker(alphabet) - alphabetCall = len(nodeKey) != 0 - } else { - multiaddr := common.AlphabetAddress() - alphabetCall = runtime.CheckWitness(multiaddr) - } - - if !alphabetCall { - if !runtime.CheckWitness(publicKey) { - panic("updateState: witness check failed") + if len(nodeKey) == 0 { + if !runtime.CheckWitness(publicKey) { + panic("updateState: witness check failed") + } + runtime.Notify("UpdateState", state, publicKey) + return } - runtime.Notify("UpdateState", state, publicKey) - - return - } - - if notaryDisabled { threshold := len(alphabet)*2/3 + 1 id := common.InvokeID([]interface{}{state, publicKey}, []byte("update")) @@ -296,6 +286,14 @@ func UpdateState(state int, publicKey interop.PublicKey) { } common.RemoveVotes(ctx, id) + } else { + multiaddr := common.AlphabetAddress() + if !runtime.CheckWitness(publicKey) { + panic("updateState: witness check failed") + } + if !runtime.CheckWitness(multiaddr) { + panic("updateState: alphabet witness check failed") + } } switch nodeState(state) { diff --git a/tests/netmap_test.go b/tests/netmap_test.go index 32f8ed5..1841941 100644 --- a/tests/netmap_test.go +++ b/tests/netmap_test.go @@ -96,3 +96,36 @@ func TestAddPeer(t *testing.T) { require.Equal(t, 1, len(nodes)) checkNode(t, dummyInfo, 1, nodes[0]) } + +func TestUpdateState(t *testing.T) { + bc := NewChain(t) + h := prepareNetmapContract(t, bc) + + acc := NewAccount(t, bc) + dummyInfo := dummyNodeInfo(acc) + + tx := PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "addPeer", dummyInfo) + AddBlockCheckHalt(t, bc, tx) + + t.Run("missing witness", func(t *testing.T) { + tx = PrepareInvoke(t, bc, acc, h, "updateState", int64(2), acc.PrivateKey().PublicKey().Bytes()) + AddBlock(t, bc, tx) + CheckFault(t, bc, tx.Hash(), "updateState: alphabet witness check failed") + + tx = PrepareInvoke(t, bc, CommitteeAcc, h, "updateState", int64(2), acc.PrivateKey().PublicKey().Bytes()) + AddBlock(t, bc, tx) + CheckFault(t, bc, tx.Hash(), "updateState: witness check failed") + }) + + tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, + "updateState", int64(2), acc.PrivateKey().PublicKey().Bytes()) + AddBlockCheckHalt(t, bc, tx) + + tx = PrepareInvoke(t, bc, acc, h, "netmapCandidates") + AddBlock(t, bc, tx) + + aer := CheckHalt(t, bc, tx.Hash()) + nodes, ok := aer.Stack[0].Value().([]stackitem.Item) + require.True(t, ok) + require.Equal(t, 0, len(nodes)) +}