[#224] netmap: Refactor snapshot processing
Swap keys instead of unmarshaling/marshaling snapshot during `NewEpoch`. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
f6766a144f
commit
9884f8e68f
1 changed files with 32 additions and 20 deletions
|
@ -35,10 +35,13 @@ const (
|
||||||
notaryDisabledKey = "notary"
|
notaryDisabledKey = "notary"
|
||||||
innerRingKey = "innerring"
|
innerRingKey = "innerring"
|
||||||
|
|
||||||
snapshot0Key = "snapshotCurrent"
|
// SnapshotCount contains the number of previous snapshots stored by this contract.
|
||||||
snapshot1Key = "snapshotPrevious"
|
// Must be less than 255.
|
||||||
snapshotEpoch = "snapshotEpoch"
|
SnapshotCount = 2
|
||||||
snapshotBlockKey = "snapshotBlock"
|
snapshotKeyPrefix = "snapshot_"
|
||||||
|
snapshotCurrentIDKey = "snapshotCurrent"
|
||||||
|
snapshotEpoch = "snapshotEpoch"
|
||||||
|
snapshotBlockKey = "snapshotBlock"
|
||||||
|
|
||||||
containerContractKey = "containerScriptHash"
|
containerContractKey = "containerScriptHash"
|
||||||
balanceContractKey = "balanceScriptHash"
|
balanceContractKey = "balanceScriptHash"
|
||||||
|
@ -85,6 +88,15 @@ func _deploy(data interface{}, isUpdate bool) {
|
||||||
|
|
||||||
if isUpdate {
|
if isUpdate {
|
||||||
common.CheckVersion(args.version)
|
common.CheckVersion(args.version)
|
||||||
|
|
||||||
|
data = storage.Get(ctx, "snapshotPrevious")
|
||||||
|
storage.Put(ctx, snapshotKeyPrefix+"0", data)
|
||||||
|
|
||||||
|
data := storage.Get(ctx, "snapshotCurrent")
|
||||||
|
storage.Put(ctx, snapshotKeyPrefix+"1", data)
|
||||||
|
|
||||||
|
storage.Put(ctx, snapshotCurrentIDKey, 1)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +108,11 @@ func _deploy(data interface{}, isUpdate bool) {
|
||||||
storage.Put(ctx, snapshotEpoch, 0)
|
storage.Put(ctx, snapshotEpoch, 0)
|
||||||
storage.Put(ctx, snapshotBlockKey, 0)
|
storage.Put(ctx, snapshotBlockKey, 0)
|
||||||
|
|
||||||
common.SetSerialized(ctx, snapshot0Key, []netmapNode{})
|
prefix := []byte(snapshotKeyPrefix)
|
||||||
common.SetSerialized(ctx, snapshot1Key, []netmapNode{})
|
for i := 0; i < SnapshotCount; i++ {
|
||||||
|
common.SetSerialized(ctx, append(prefix, byte(i)), []storageNode{})
|
||||||
|
}
|
||||||
|
common.SetSerialized(ctx, snapshotCurrentIDKey, 0)
|
||||||
|
|
||||||
storage.Put(ctx, balanceContractKey, args.addrBalance)
|
storage.Put(ctx, balanceContractKey, args.addrBalance)
|
||||||
storage.Put(ctx, containerContractKey, args.addrContainer)
|
storage.Put(ctx, containerContractKey, args.addrContainer)
|
||||||
|
@ -381,7 +396,6 @@ func NewEpoch(epochNum int) {
|
||||||
panic("invalid epoch") // ignore invocations with invalid epoch
|
panic("invalid epoch") // ignore invocations with invalid epoch
|
||||||
}
|
}
|
||||||
|
|
||||||
data0snapshot := getSnapshot(ctx, snapshot0Key)
|
|
||||||
dataOnlineState := filterNetmap(ctx, onlineState)
|
dataOnlineState := filterNetmap(ctx, onlineState)
|
||||||
|
|
||||||
runtime.Log("process new epoch")
|
runtime.Log("process new epoch")
|
||||||
|
@ -390,11 +404,12 @@ func NewEpoch(epochNum int) {
|
||||||
storage.Put(ctx, snapshotEpoch, epochNum)
|
storage.Put(ctx, snapshotEpoch, epochNum)
|
||||||
storage.Put(ctx, snapshotBlockKey, ledger.CurrentIndex())
|
storage.Put(ctx, snapshotBlockKey, ledger.CurrentIndex())
|
||||||
|
|
||||||
// put actual snapshot into previous snapshot
|
id := storage.Get(ctx, snapshotCurrentIDKey).(int)
|
||||||
common.SetSerialized(ctx, snapshot1Key, data0snapshot)
|
id = (id + 1) % SnapshotCount
|
||||||
|
storage.Put(ctx, snapshotCurrentIDKey, id)
|
||||||
|
|
||||||
// put netmap into actual snapshot
|
// put netmap into actual snapshot
|
||||||
common.SetSerialized(ctx, snapshot0Key, dataOnlineState)
|
common.SetSerialized(ctx, snapshotKeyPrefix+string([]byte{byte(id)}), dataOnlineState)
|
||||||
|
|
||||||
// make clean up routines in other contracts
|
// make clean up routines in other contracts
|
||||||
cleanup(ctx, epochNum)
|
cleanup(ctx, epochNum)
|
||||||
|
@ -419,10 +434,11 @@ func LastEpochBlock() int {
|
||||||
// of current epoch.
|
// of current epoch.
|
||||||
func Netmap() []storageNode {
|
func Netmap() []storageNode {
|
||||||
ctx := storage.GetReadOnlyContext()
|
ctx := storage.GetReadOnlyContext()
|
||||||
return getSnapshot(ctx, snapshot0Key)
|
id := storage.Get(ctx, snapshotCurrentIDKey).(int)
|
||||||
|
return getSnapshot(ctx, snapshotKeyPrefix+string([]byte{byte(id)}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot method returns list of structures that contain node state
|
// NetmapCandidates method returns list of structures that contain node state
|
||||||
// and byte array of stable marshalled netmap.NodeInfo structure.
|
// and byte array of stable marshalled netmap.NodeInfo structure.
|
||||||
// These structure contain Storage node candidates for next epoch.
|
// These structure contain Storage node candidates for next epoch.
|
||||||
func NetmapCandidates() []netmapNode {
|
func NetmapCandidates() []netmapNode {
|
||||||
|
@ -437,18 +453,14 @@ func NetmapCandidates() []netmapNode {
|
||||||
// Netmap contract contains only two recent network map snapshot: current and
|
// Netmap contract contains only two recent network map snapshot: current and
|
||||||
// previous epoch. For diff bigger than 1 or less than 0 method throws panic.
|
// previous epoch. For diff bigger than 1 or less than 0 method throws panic.
|
||||||
func Snapshot(diff int) []storageNode {
|
func Snapshot(diff int) []storageNode {
|
||||||
var key string
|
if diff < 0 || SnapshotCount <= diff {
|
||||||
|
|
||||||
switch diff {
|
|
||||||
case 0:
|
|
||||||
key = snapshot0Key
|
|
||||||
case 1:
|
|
||||||
key = snapshot1Key
|
|
||||||
default:
|
|
||||||
panic("incorrect diff")
|
panic("incorrect diff")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := storage.GetReadOnlyContext()
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
id := storage.Get(ctx, snapshotCurrentIDKey).(int)
|
||||||
|
needID := (id - diff + SnapshotCount) % SnapshotCount
|
||||||
|
key := snapshotKeyPrefix + string([]byte{byte(needID)})
|
||||||
return getSnapshot(ctx, key)
|
return getSnapshot(ctx, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue