[#271] netmap: Allow to move node back to Online state

Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
Evgenii Stratonikov 2022-09-20 12:47:14 +03:00 committed by fyrchik
parent cb684994fc
commit 9785f9b2c7
2 changed files with 35 additions and 15 deletions

View file

@ -314,12 +314,13 @@ func UpdateState(state int, publicKey interop.PublicKey) {
common.CheckAlphabetWitness(common.AlphabetAddress()) common.CheckAlphabetWitness(common.AlphabetAddress())
} }
switch NodeState(state) { st := NodeState(state)
switch st {
case OfflineState: case OfflineState:
removeFromNetmap(ctx, publicKey) removeFromNetmap(ctx, publicKey)
runtime.Log("remove storage node from the network map") runtime.Log("remove storage node from the network map")
case MaintenanceState: case MaintenanceState, OnlineState:
updateNetmapState(ctx, publicKey, MaintenanceState) updateNetmapState(ctx, publicKey, st)
runtime.Log("move storage node to a maintenance state") runtime.Log("move storage node to a maintenance state")
default: default:
panic("unsupported state") panic("unsupported state")
@ -342,8 +343,8 @@ func UpdateStateIR(state NodeState, publicKey interop.PublicKey) {
switch state { switch state {
case OfflineState: case OfflineState:
removeFromNetmap(ctx, publicKey) removeFromNetmap(ctx, publicKey)
case MaintenanceState: case MaintenanceState, OnlineState:
updateNetmapState(ctx, publicKey, MaintenanceState) updateNetmapState(ctx, publicKey, state)
default: default:
panic("unsupported state") panic("unsupported state")
} }
@ -658,6 +659,9 @@ func removeFromNetmap(ctx storage.Context, key interop.PublicKey) {
func updateNetmapState(ctx storage.Context, key interop.PublicKey, state NodeState) { func updateNetmapState(ctx storage.Context, key interop.PublicKey, state NodeState) {
storageKey := append(candidatePrefix, key...) storageKey := append(candidatePrefix, key...)
raw := storage.Get(ctx, storageKey).([]byte) raw := storage.Get(ctx, storageKey).([]byte)
if raw == nil {
panic("peer is missing")
}
node := std.Deserialize(raw).(netmapNode) node := std.Deserialize(raw).(netmapNode)
node.state = state node.state = state
storage.Put(ctx, storageKey, std.Serialize(node)) storage.Put(ctx, storageKey, std.Serialize(node))

View file

@ -310,9 +310,14 @@ func TestUpdateStateIR(t *testing.T) {
cNm := newNetmapInvoker(t) cNm := newNetmapInvoker(t)
acc := cNm.NewAccount(t) acc := cNm.NewAccount(t)
pub := acc.(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()
t.Run("can't move online, need addPeerIR", func(t *testing.T) {
cNm.InvokeFail(t, "peer is missing", "updateStateIR", int64(netmap.OnlineState), pub)
})
dummyInfo := dummyNodeInfo(acc) dummyInfo := dummyNodeInfo(acc)
cNm.Invoke(t, stackitem.Null{}, "addPeerIR", dummyInfo.raw) cNm.Invoke(t, stackitem.Null{}, "addPeerIR", dummyInfo.raw)
pub := acc.(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()
acc1 := cNm.NewAccount(t) acc1 := cNm.NewAccount(t)
dummyInfo1 := dummyNodeInfo(acc1) dummyInfo1 := dummyNodeInfo(acc1)
@ -322,9 +327,6 @@ func TestUpdateStateIR(t *testing.T) {
cAcc := cNm.WithSigners(acc) cAcc := cNm.WithSigners(acc)
cAcc.InvokeFail(t, common.ErrAlphabetWitnessFailed, "updateStateIR", int64(netmap.OfflineState), pub) cAcc.InvokeFail(t, common.ErrAlphabetWitnessFailed, "updateStateIR", int64(netmap.OfflineState), pub)
}) })
t.Run("can't move online", func(t *testing.T) {
cNm.InvokeFail(t, "unsupported state", "updateStateIR", int64(netmap.OnlineState), pub)
})
t.Run("invalid state", func(t *testing.T) { t.Run("invalid state", func(t *testing.T) {
cNm.InvokeFail(t, "unsupported state", "updateStateIR", int64(42), pub) cNm.InvokeFail(t, "unsupported state", "updateStateIR", int64(42), pub)
}) })
@ -335,14 +337,28 @@ func TestUpdateStateIR(t *testing.T) {
cNm.Invoke(t, stackitem.Null{}, "updateStateIR", int64(netmap.OfflineState), pub) cNm.Invoke(t, stackitem.Null{}, "updateStateIR", int64(netmap.OfflineState), pub)
checkNetmapCandidates(t, cNm, 1) checkNetmapCandidates(t, cNm, 1)
// Move the second node in the maintenance state. checkState := func(expected netmap.NodeState) {
pub1 := acc1.(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()
cNm.Invoke(t, stackitem.Null{}, "updateStateIR", int64(netmap.MaintenanceState), pub1)
arr := checkNetmapCandidates(t, cNm, 1) arr := checkNetmapCandidates(t, cNm, 1)
nn := arr[0].Value().([]stackitem.Item) nn := arr[0].Value().([]stackitem.Item)
state, err := nn[1].TryInteger() state, err := nn[1].TryInteger()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(netmap.MaintenanceState), state.Int64()) require.Equal(t, int64(expected), state.Int64())
}
// Move the second node in the maintenance state.
pub1 := acc1.(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()
t.Run("maintenance -> add peer", func(t *testing.T) {
cNm.Invoke(t, stackitem.Null{}, "updateStateIR", int64(netmap.MaintenanceState), pub1)
checkState(netmap.MaintenanceState)
cNm.Invoke(t, stackitem.Null{}, "addPeerIR", dummyInfo1.raw)
checkState(netmap.OnlineState)
})
t.Run("maintenance -> online", func(t *testing.T) {
cNm.Invoke(t, stackitem.Null{}, "updateStateIR", int64(netmap.MaintenanceState), pub1)
checkState(netmap.MaintenanceState)
cNm.Invoke(t, stackitem.Null{}, "updateStateIR", int64(netmap.OnlineState), pub1)
checkState(netmap.OnlineState)
})
} }
func TestUpdateState(t *testing.T) { func TestUpdateState(t *testing.T) {