[#222] *: Replace IRNode with raw public keys

Only leave `IRNode` in neofs contract because it is public.
The newly added conversion in `AlphabetList` shouldn't be a problem
because this is a read method.

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-03-21 14:01:45 +03:00 committed by Alex Vanin
parent 01a7163d1e
commit 03afb80a14
9 changed files with 87 additions and 85 deletions

View file

@ -104,7 +104,7 @@ func index(ctx storage.Context) int {
return storage.Get(ctx, indexKey).(int) return storage.Get(ctx, indexKey).(int)
} }
func checkPermission(ir []common.IRNode) bool { func checkPermission(ir []interop.PublicKey) bool {
ctx := storage.GetReadOnlyContext() ctx := storage.GetReadOnlyContext()
index := index(ctx) // read from contract memory index := index(ctx) // read from contract memory
@ -113,7 +113,7 @@ func checkPermission(ir []common.IRNode) bool {
} }
node := ir[index] node := ir[index]
return runtime.CheckWitness(node.PublicKey) return runtime.CheckWitness(node)
} }
// Emit method produces side chain GAS and distributes it among Inner Ring nodes // Emit method produces side chain GAS and distributes it among Inner Ring nodes
@ -160,7 +160,7 @@ func Emit() {
runtime.Log("utility token has been emitted to proxy contract") runtime.Log("utility token has been emitted to proxy contract")
} }
var innerRing []common.IRNode var innerRing []interop.PublicKey
if notaryDisabled { if notaryDisabled {
netmapContract := storage.Get(ctx, netmapKey).(interop.Hash160) netmapContract := storage.Get(ctx, netmapKey).(interop.Hash160)
@ -173,7 +173,7 @@ func Emit() {
if gasPerNode != 0 { if gasPerNode != 0 {
for _, node := range innerRing { for _, node := range innerRing {
address := contract.CreateStandardAccount(node.PublicKey) address := contract.CreateStandardAccount(node)
if !gas.Transfer(contractHash, address, gasPerNode, nil) { if !gas.Transfer(contractHash, address, gasPerNode, nil) {
runtime.Log("could not transfer GAS to one of IR node") runtime.Log("could not transfer GAS to one of IR node")
} }
@ -197,7 +197,7 @@ func Vote(epoch int, candidates []interop.PublicKey) {
name := name(ctx) name := name(ctx)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )

View file

@ -92,7 +92,7 @@ func Put(rawAuditResult []byte) {
ctx := storage.GetContext() ctx := storage.GetContext()
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var innerRing []common.IRNode var innerRing []interop.PublicKey
if notaryDisabled { if notaryDisabled {
netmapContract := storage.Get(ctx, netmapContractKey).(interop.Hash160) netmapContract := storage.Get(ctx, netmapContractKey).(interop.Hash160)
@ -106,7 +106,7 @@ func Put(rawAuditResult []byte) {
for i := range innerRing { for i := range innerRing {
ir := innerRing[i] ir := innerRing[i]
if common.BytesEqual(ir.PublicKey, hdr.from) { if common.BytesEqual(ir, hdr.from) {
presented = true presented = true
break break

View file

@ -149,7 +149,7 @@ func TransferX(from, to interop.Hash160, amount int, details []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
indirectCall bool indirectCall bool
) )
@ -204,7 +204,7 @@ func Lock(txDetails []byte, from, to interop.Hash160, amount, until int) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -308,7 +308,7 @@ func Mint(to interop.Hash160, amount int, txDetails []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -365,7 +365,7 @@ func Burn(from interop.Hash160, amount int, txDetails []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )

View file

@ -17,11 +17,11 @@ const irListMethod = "innerRingList"
// InnerRingInvoker returns public key of inner ring node that invoked contract. // InnerRingInvoker returns public key of inner ring node that invoked contract.
// Work around for environments without notary support. // Work around for environments without notary support.
func InnerRingInvoker(ir []IRNode) interop.PublicKey { func InnerRingInvoker(ir []interop.PublicKey) interop.PublicKey {
for i := 0; i < len(ir); i++ { for i := 0; i < len(ir); i++ {
node := ir[i] node := ir[i]
if runtime.CheckWitness(node.PublicKey) { if runtime.CheckWitness(node) {
return node.PublicKey return node
} }
} }
@ -30,23 +30,26 @@ func InnerRingInvoker(ir []IRNode) interop.PublicKey {
// InnerRingNodes return list of inner ring nodes from state validator role // InnerRingNodes return list of inner ring nodes from state validator role
// in side chain. // in side chain.
func InnerRingNodes() []IRNode { func InnerRingNodes() []interop.PublicKey {
blockHeight := ledger.CurrentIndex() blockHeight := ledger.CurrentIndex()
list := roles.GetDesignatedByRole(roles.NeoFSAlphabet, uint32(blockHeight+1)) return roles.GetDesignatedByRole(roles.NeoFSAlphabet, uint32(blockHeight+1))
return keysToNodes(list)
} }
// InnerRingNodesFromNetmap gets list of inner ring through // InnerRingNodesFromNetmap gets list of inner ring through
// calling "innerRingList" method of smart contract. // calling "innerRingList" method of smart contract.
// Work around for environments without notary support. // Work around for environments without notary support.
func InnerRingNodesFromNetmap(sc interop.Hash160) []IRNode { func InnerRingNodesFromNetmap(sc interop.Hash160) []interop.PublicKey {
return contract.Call(sc, irListMethod, contract.ReadOnly).([]IRNode) nodes := contract.Call(sc, irListMethod, contract.ReadOnly).([]IRNode)
pubs := []interop.PublicKey{}
for i := range nodes {
pubs = append(pubs, nodes[i].PublicKey)
}
return pubs
} }
// AlphabetNodes return list of alphabet nodes from committee in side chain. // AlphabetNodes return list of alphabet nodes from committee in side chain.
func AlphabetNodes() []IRNode { func AlphabetNodes() []interop.PublicKey {
list := neo.GetCommittee() return neo.GetCommittee()
return keysToNodes(list)
} }
// AlphabetAddress returns multi address of alphabet public keys. // AlphabetAddress returns multi address of alphabet public keys.
@ -71,15 +74,3 @@ func Multiaddress(n []interop.PublicKey, committee bool) []byte {
return contract.CreateMultisigAccount(threshold, n) return contract.CreateMultisigAccount(threshold, n)
} }
func keysToNodes(list []interop.PublicKey) []IRNode {
result := []IRNode{}
for i := range list {
result = append(result, IRNode{
PublicKey: list[i],
})
}
return result
}

View file

@ -257,7 +257,7 @@ func PutNamed(container []byte, signature interop.Signature,
for i := 0; i < len(alphabet); i++ { for i := 0; i < len(alphabet); i++ {
node := alphabet[i] node := alphabet[i]
to := contract.CreateStandardAccount(node.PublicKey) to := contract.CreateStandardAccount(node)
contract.Call(balanceContractAddr, "transferX", contract.Call(balanceContractAddr, "transferX",
contract.All, contract.All,
@ -609,7 +609,7 @@ func StartContainerEstimation(epoch int) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -647,7 +647,7 @@ func StopContainerEstimation(epoch int) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )

View file

@ -46,9 +46,20 @@ var (
// _deploy sets up initial alphabet node keys. // _deploy sets up initial alphabet node keys.
func _deploy(data interface{}, isUpdate bool) { func _deploy(data interface{}, isUpdate bool) {
ctx := storage.GetContext()
if isUpdate { if isUpdate {
args := data.([]interface{}) args := data.([]interface{})
common.CheckVersion(args[len(args)-1].(int)) common.CheckVersion(args[len(args)-1].(int))
data := storage.Get(ctx, alphabetKey)
alphabetNodes := std.Deserialize(data.([]byte)).([]common.IRNode)
pubs := []interop.PublicKey{}
for i := range alphabetNodes {
pubs = append(pubs, alphabetNodes[i].PublicKey)
}
common.SetSerialized(ctx, alphabetKey, pubs)
return return
} }
@ -59,10 +70,6 @@ func _deploy(data interface{}, isUpdate bool) {
config [][]byte config [][]byte
}) })
ctx := storage.GetContext()
var irList []common.IRNode
if len(args.keys) == 0 { if len(args.keys) == 0 {
panic("at least one alphabet key must be provided") panic("at least one alphabet key must be provided")
} }
@ -76,11 +83,10 @@ func _deploy(data interface{}, isUpdate bool) {
if len(pub) != interop.PublicKeyCompressedLen { if len(pub) != interop.PublicKeyCompressedLen {
panic("incorrect public key length") panic("incorrect public key length")
} }
irList = append(irList, common.IRNode{PublicKey: pub})
} }
// initialize all storage slices // initialize all storage slices
common.SetSerialized(ctx, alphabetKey, irList) common.SetSerialized(ctx, alphabetKey, args.keys)
storage.Put(ctx, processingContractKey, args.addrProc) storage.Put(ctx, processingContractKey, args.addrProc)
@ -124,7 +130,12 @@ func Update(script []byte, manifest []byte, data interface{}) {
// disabled environment. // disabled environment.
func AlphabetList() []common.IRNode { func AlphabetList() []common.IRNode {
ctx := storage.GetReadOnlyContext() ctx := storage.GetReadOnlyContext()
return getNodes(ctx, alphabetKey) pubs := getNodes(ctx, alphabetKey)
nodes := []common.IRNode{}
for i := range pubs {
nodes = append(nodes, common.IRNode{PublicKey: pubs[i]})
}
return nodes
} }
// AlphabetAddress returns 2\3n+1 multi signature address of alphabet nodes. // AlphabetAddress returns 2\3n+1 multi signature address of alphabet nodes.
@ -157,7 +168,7 @@ func InnerRingCandidateRemove(key interop.PublicKey) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -291,7 +302,7 @@ func Withdraw(user interop.Hash160, amount int) {
if notaryDisabled { if notaryDisabled {
alphabet := getNodes(ctx, alphabetKey) alphabet := getNodes(ctx, alphabetKey)
for _, node := range alphabet { for _, node := range alphabet {
processingAddr := contract.CreateStandardAccount(node.PublicKey) processingAddr := contract.CreateStandardAccount(node)
transferred := gas.Transfer(user, processingAddr, fee, []byte{}) transferred := gas.Transfer(user, processingAddr, fee, []byte{})
if !transferred { if !transferred {
@ -324,7 +335,7 @@ func Cheque(id []byte, user interop.Hash160, amount int, lockAcc []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -415,7 +426,7 @@ func AlphabetUpdate(id []byte, args []interop.PublicKey) {
} }
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -430,7 +441,7 @@ func AlphabetUpdate(id []byte, args []interop.PublicKey) {
common.CheckAlphabetWitness(multiaddr) common.CheckAlphabetWitness(multiaddr)
} }
newAlphabet := []common.IRNode{} newAlphabet := []interop.PublicKey{}
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
pubKey := args[i] pubKey := args[i]
@ -438,9 +449,7 @@ func AlphabetUpdate(id []byte, args []interop.PublicKey) {
panic("invalid public key in alphabet list") panic("invalid public key in alphabet list")
} }
newAlphabet = append(newAlphabet, common.IRNode{ newAlphabet = append(newAlphabet, pubKey)
PublicKey: pubKey,
})
} }
if notaryDisabled { if notaryDisabled {
@ -474,7 +483,7 @@ func SetConfig(id, key, val []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -533,13 +542,13 @@ func Version() int {
} }
// getNodes returns deserialized slice of nodes from storage. // getNodes returns deserialized slice of nodes from storage.
func getNodes(ctx storage.Context, key string) []common.IRNode { func getNodes(ctx storage.Context, key string) []interop.PublicKey {
data := storage.Get(ctx, key) data := storage.Get(ctx, key)
if data != nil { if data != nil {
return std.Deserialize(data.([]byte)).([]common.IRNode) return std.Deserialize(data.([]byte)).([]interop.PublicKey)
} }
return []common.IRNode{} return []interop.PublicKey{}
} }
// getConfig returns installed neofs configuration value or nil if it is not set. // getConfig returns installed neofs configuration value or nil if it is not set.
@ -560,14 +569,8 @@ func setConfig(ctx storage.Context, key, val interface{}) {
// multiaddress returns multi signature address from list of IRNode structures // multiaddress returns multi signature address from list of IRNode structures
// with m = 2/3n+1. // with m = 2/3n+1.
func multiaddress(n []common.IRNode) []byte { func multiaddress(keys []interop.PublicKey) []byte {
threshold := len(n)*2/3 + 1 threshold := len(keys)*2/3 + 1
keys := []interop.PublicKey{}
for _, node := range n {
key := node.PublicKey
keys = append(keys, key)
}
return contract.CreateMultisigAccount(threshold, keys) return contract.CreateMultisigAccount(threshold, keys)
} }

View file

@ -93,7 +93,7 @@ func AddKey(owner []byte, keys []interop.PublicKey) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
indirectCall bool indirectCall bool
) )
@ -156,7 +156,7 @@ func RemoveKey(owner []byte, keys []interop.PublicKey) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )

View file

@ -89,14 +89,24 @@ func _deploy(data interface{}, isUpdate bool) {
if isUpdate { if isUpdate {
common.CheckVersion(args.version) common.CheckVersion(args.version)
data = storage.Get(ctx, "snapshotPrevious") data := storage.Get(ctx, "snapshotPrevious")
storage.Put(ctx, snapshotKeyPrefix+"0", data) storage.Put(ctx, snapshotKeyPrefix+"0", data)
data := storage.Get(ctx, "snapshotCurrent") data = storage.Get(ctx, "snapshotCurrent")
storage.Put(ctx, snapshotKeyPrefix+"1", data) storage.Put(ctx, snapshotKeyPrefix+"1", data)
storage.Put(ctx, snapshotCurrentIDKey, 1) storage.Put(ctx, snapshotCurrentIDKey, 1)
if args.notaryDisabled {
data = storage.Get(ctx, innerRingKey)
irNodes := std.Deserialize(data.([]byte)).([]common.IRNode)
pubs := []interop.PublicKey{}
for i := range irNodes {
pubs = append(pubs, irNodes[i].PublicKey)
}
common.SetSerialized(ctx, innerRingKey, pubs)
}
return return
} }
@ -154,7 +164,12 @@ func Update(script []byte, manifest []byte, data interface{}) {
// contract of the side chain. // contract of the side chain.
func InnerRingList() []common.IRNode { func InnerRingList() []common.IRNode {
ctx := storage.GetReadOnlyContext() ctx := storage.GetReadOnlyContext()
return getIRNodes(ctx) pubs := getIRNodes(ctx)
nodes := []common.IRNode{}
for i := range pubs {
nodes = append(nodes, common.IRNode{PublicKey: pubs[i]})
}
return nodes
} }
// UpdateInnerRing method updates list of Inner Ring node keys. Should be used // UpdateInnerRing method updates list of Inner Ring node keys. Should be used
@ -167,7 +182,7 @@ func UpdateInnerRing(keys []interop.PublicKey) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -182,13 +197,6 @@ func UpdateInnerRing(keys []interop.PublicKey) {
common.CheckAlphabetWitness(multiaddr) common.CheckAlphabetWitness(multiaddr)
} }
var irList []common.IRNode
for i := 0; i < len(keys); i++ {
key := keys[i]
irList = append(irList, common.IRNode{PublicKey: key})
}
if notaryDisabled { if notaryDisabled {
threshold := len(alphabet)*2/3 + 1 threshold := len(alphabet)*2/3 + 1
id := keysID(keys, []byte("updateIR")) id := keysID(keys, []byte("updateIR"))
@ -202,7 +210,7 @@ func UpdateInnerRing(keys []interop.PublicKey) {
} }
runtime.Log("inner ring list updated") runtime.Log("inner ring list updated")
common.SetSerialized(ctx, innerRingKey, irList) common.SetSerialized(ctx, innerRingKey, keys)
} }
// AddPeerIR method tries to add new candidate to the network map. // AddPeerIR method tries to add new candidate to the network map.
@ -232,7 +240,7 @@ func AddPeer(nodeInfo []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -367,7 +375,7 @@ func NewEpoch(epochNum int) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -494,7 +502,7 @@ func SetConfig(id, key, val []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
) )
@ -630,13 +638,13 @@ func cleanup(ctx storage.Context, epoch int) {
contract.Call(containerContractAddr, cleanupEpochMethod, contract.All, epoch) contract.Call(containerContractAddr, cleanupEpochMethod, contract.All, epoch)
} }
func getIRNodes(ctx storage.Context) []common.IRNode { func getIRNodes(ctx storage.Context) []interop.PublicKey {
data := storage.Get(ctx, innerRingKey) data := storage.Get(ctx, innerRingKey)
if data != nil { if data != nil {
return std.Deserialize(data.([]byte)).([]common.IRNode) return std.Deserialize(data.([]byte)).([]interop.PublicKey)
} }
return []common.IRNode{} return []interop.PublicKey{}
} }
func keysID(args []interop.PublicKey, prefix []byte) []byte { func keysID(args []interop.PublicKey, prefix []byte) []byte {

View file

@ -63,7 +63,7 @@ func Put(epoch int, peerID []byte, value []byte) {
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
var ( // for invocation collection without notary var ( // for invocation collection without notary
alphabet []common.IRNode alphabet []interop.PublicKey
nodeKey []byte nodeKey []byte
alphabetCall bool alphabetCall bool
) )