From 03afb80a14cc0aa38851796dbf9002fc6236800a Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Mon, 21 Mar 2022 14:01:45 +0300 Subject: [PATCH] [#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 --- alphabet/alphabet_contract.go | 10 +++--- audit/audit_contract.go | 4 +-- balance/balance_contract.go | 8 ++--- common/ir.go | 37 ++++++++------------ container/container_contract.go | 6 ++-- neofs/neofs_contract.go | 57 ++++++++++++++++--------------- neofsid/neofsid_contract.go | 4 +-- netmap/netmap_contract.go | 44 ++++++++++++++---------- reputation/reputation_contract.go | 2 +- 9 files changed, 87 insertions(+), 85 deletions(-) diff --git a/alphabet/alphabet_contract.go b/alphabet/alphabet_contract.go index d015c6d..4ec41f2 100644 --- a/alphabet/alphabet_contract.go +++ b/alphabet/alphabet_contract.go @@ -104,7 +104,7 @@ func index(ctx storage.Context) int { return storage.Get(ctx, indexKey).(int) } -func checkPermission(ir []common.IRNode) bool { +func checkPermission(ir []interop.PublicKey) bool { ctx := storage.GetReadOnlyContext() index := index(ctx) // read from contract memory @@ -113,7 +113,7 @@ func checkPermission(ir []common.IRNode) bool { } 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 @@ -160,7 +160,7 @@ func Emit() { runtime.Log("utility token has been emitted to proxy contract") } - var innerRing []common.IRNode + var innerRing []interop.PublicKey if notaryDisabled { netmapContract := storage.Get(ctx, netmapKey).(interop.Hash160) @@ -173,7 +173,7 @@ func Emit() { if gasPerNode != 0 { for _, node := range innerRing { - address := contract.CreateStandardAccount(node.PublicKey) + address := contract.CreateStandardAccount(node) if !gas.Transfer(contractHash, address, gasPerNode, nil) { 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) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) diff --git a/audit/audit_contract.go b/audit/audit_contract.go index 8c21433..4d899ec 100644 --- a/audit/audit_contract.go +++ b/audit/audit_contract.go @@ -92,7 +92,7 @@ func Put(rawAuditResult []byte) { ctx := storage.GetContext() notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) - var innerRing []common.IRNode + var innerRing []interop.PublicKey if notaryDisabled { netmapContract := storage.Get(ctx, netmapContractKey).(interop.Hash160) @@ -106,7 +106,7 @@ func Put(rawAuditResult []byte) { for i := range innerRing { ir := innerRing[i] - if common.BytesEqual(ir.PublicKey, hdr.from) { + if common.BytesEqual(ir, hdr.from) { presented = true break diff --git a/balance/balance_contract.go b/balance/balance_contract.go index 04c58fd..dbad715 100644 --- a/balance/balance_contract.go +++ b/balance/balance_contract.go @@ -149,7 +149,7 @@ func TransferX(from, to interop.Hash160, amount int, details []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte indirectCall bool ) @@ -204,7 +204,7 @@ func Lock(txDetails []byte, from, to interop.Hash160, amount, until int) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -308,7 +308,7 @@ func Mint(to interop.Hash160, amount int, txDetails []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -365,7 +365,7 @@ func Burn(from interop.Hash160, amount int, txDetails []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) diff --git a/common/ir.go b/common/ir.go index 927865d..d8b7eb1 100644 --- a/common/ir.go +++ b/common/ir.go @@ -17,11 +17,11 @@ const irListMethod = "innerRingList" // InnerRingInvoker returns public key of inner ring node that invoked contract. // 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++ { node := ir[i] - if runtime.CheckWitness(node.PublicKey) { - return node.PublicKey + if runtime.CheckWitness(node) { + return node } } @@ -30,23 +30,26 @@ func InnerRingInvoker(ir []IRNode) interop.PublicKey { // InnerRingNodes return list of inner ring nodes from state validator role // in side chain. -func InnerRingNodes() []IRNode { +func InnerRingNodes() []interop.PublicKey { blockHeight := ledger.CurrentIndex() - list := roles.GetDesignatedByRole(roles.NeoFSAlphabet, uint32(blockHeight+1)) - return keysToNodes(list) + return roles.GetDesignatedByRole(roles.NeoFSAlphabet, uint32(blockHeight+1)) } // InnerRingNodesFromNetmap gets list of inner ring through // calling "innerRingList" method of smart contract. // Work around for environments without notary support. -func InnerRingNodesFromNetmap(sc interop.Hash160) []IRNode { - return contract.Call(sc, irListMethod, contract.ReadOnly).([]IRNode) +func InnerRingNodesFromNetmap(sc interop.Hash160) []interop.PublicKey { + 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. -func AlphabetNodes() []IRNode { - list := neo.GetCommittee() - return keysToNodes(list) +func AlphabetNodes() []interop.PublicKey { + return neo.GetCommittee() } // 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) } - -func keysToNodes(list []interop.PublicKey) []IRNode { - result := []IRNode{} - - for i := range list { - result = append(result, IRNode{ - PublicKey: list[i], - }) - } - - return result -} diff --git a/container/container_contract.go b/container/container_contract.go index f132876..5502bbc 100644 --- a/container/container_contract.go +++ b/container/container_contract.go @@ -257,7 +257,7 @@ func PutNamed(container []byte, signature interop.Signature, for i := 0; i < len(alphabet); i++ { node := alphabet[i] - to := contract.CreateStandardAccount(node.PublicKey) + to := contract.CreateStandardAccount(node) contract.Call(balanceContractAddr, "transferX", contract.All, @@ -609,7 +609,7 @@ func StartContainerEstimation(epoch int) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -647,7 +647,7 @@ func StopContainerEstimation(epoch int) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) diff --git a/neofs/neofs_contract.go b/neofs/neofs_contract.go index 2cbfedc..74f1328 100644 --- a/neofs/neofs_contract.go +++ b/neofs/neofs_contract.go @@ -46,9 +46,20 @@ var ( // _deploy sets up initial alphabet node keys. func _deploy(data interface{}, isUpdate bool) { + ctx := storage.GetContext() + if isUpdate { args := data.([]interface{}) 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 } @@ -59,10 +70,6 @@ func _deploy(data interface{}, isUpdate bool) { config [][]byte }) - ctx := storage.GetContext() - - var irList []common.IRNode - if len(args.keys) == 0 { panic("at least one alphabet key must be provided") } @@ -76,11 +83,10 @@ func _deploy(data interface{}, isUpdate bool) { if len(pub) != interop.PublicKeyCompressedLen { panic("incorrect public key length") } - irList = append(irList, common.IRNode{PublicKey: pub}) } // initialize all storage slices - common.SetSerialized(ctx, alphabetKey, irList) + common.SetSerialized(ctx, alphabetKey, args.keys) storage.Put(ctx, processingContractKey, args.addrProc) @@ -124,7 +130,12 @@ func Update(script []byte, manifest []byte, data interface{}) { // disabled environment. func AlphabetList() []common.IRNode { 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. @@ -157,7 +168,7 @@ func InnerRingCandidateRemove(key interop.PublicKey) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -291,7 +302,7 @@ func Withdraw(user interop.Hash160, amount int) { if notaryDisabled { alphabet := getNodes(ctx, alphabetKey) for _, node := range alphabet { - processingAddr := contract.CreateStandardAccount(node.PublicKey) + processingAddr := contract.CreateStandardAccount(node) transferred := gas.Transfer(user, processingAddr, fee, []byte{}) if !transferred { @@ -324,7 +335,7 @@ func Cheque(id []byte, user interop.Hash160, amount int, lockAcc []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -415,7 +426,7 @@ func AlphabetUpdate(id []byte, args []interop.PublicKey) { } var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -430,7 +441,7 @@ func AlphabetUpdate(id []byte, args []interop.PublicKey) { common.CheckAlphabetWitness(multiaddr) } - newAlphabet := []common.IRNode{} + newAlphabet := []interop.PublicKey{} for i := 0; i < len(args); i++ { pubKey := args[i] @@ -438,9 +449,7 @@ func AlphabetUpdate(id []byte, args []interop.PublicKey) { panic("invalid public key in alphabet list") } - newAlphabet = append(newAlphabet, common.IRNode{ - PublicKey: pubKey, - }) + newAlphabet = append(newAlphabet, pubKey) } if notaryDisabled { @@ -474,7 +483,7 @@ func SetConfig(id, key, val []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -533,13 +542,13 @@ func Version() int { } // 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) 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. @@ -560,14 +569,8 @@ func setConfig(ctx storage.Context, key, val interface{}) { // multiaddress returns multi signature address from list of IRNode structures // with m = 2/3n+1. -func multiaddress(n []common.IRNode) []byte { - threshold := len(n)*2/3 + 1 - - keys := []interop.PublicKey{} - for _, node := range n { - key := node.PublicKey - keys = append(keys, key) - } +func multiaddress(keys []interop.PublicKey) []byte { + threshold := len(keys)*2/3 + 1 return contract.CreateMultisigAccount(threshold, keys) } diff --git a/neofsid/neofsid_contract.go b/neofsid/neofsid_contract.go index 68ab905..5935597 100644 --- a/neofsid/neofsid_contract.go +++ b/neofsid/neofsid_contract.go @@ -93,7 +93,7 @@ func AddKey(owner []byte, keys []interop.PublicKey) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte indirectCall bool ) @@ -156,7 +156,7 @@ func RemoveKey(owner []byte, keys []interop.PublicKey) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) diff --git a/netmap/netmap_contract.go b/netmap/netmap_contract.go index 703d15c..eac639d 100644 --- a/netmap/netmap_contract.go +++ b/netmap/netmap_contract.go @@ -89,14 +89,24 @@ func _deploy(data interface{}, isUpdate bool) { if isUpdate { common.CheckVersion(args.version) - data = storage.Get(ctx, "snapshotPrevious") + data := storage.Get(ctx, "snapshotPrevious") 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, 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 } @@ -154,7 +164,12 @@ func Update(script []byte, manifest []byte, data interface{}) { // contract of the side chain. func InnerRingList() []common.IRNode { 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 @@ -167,7 +182,7 @@ func UpdateInnerRing(keys []interop.PublicKey) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -182,13 +197,6 @@ func UpdateInnerRing(keys []interop.PublicKey) { 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 { threshold := len(alphabet)*2/3 + 1 id := keysID(keys, []byte("updateIR")) @@ -202,7 +210,7 @@ func UpdateInnerRing(keys []interop.PublicKey) { } 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. @@ -232,7 +240,7 @@ func AddPeer(nodeInfo []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -367,7 +375,7 @@ func NewEpoch(epochNum int) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -494,7 +502,7 @@ func SetConfig(id, key, val []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte ) @@ -630,13 +638,13 @@ func cleanup(ctx storage.Context, epoch int) { 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) 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 { diff --git a/reputation/reputation_contract.go b/reputation/reputation_contract.go index 27751d0..a8074e2 100644 --- a/reputation/reputation_contract.go +++ b/reputation/reputation_contract.go @@ -63,7 +63,7 @@ func Put(epoch int, peerID []byte, value []byte) { notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool) var ( // for invocation collection without notary - alphabet []common.IRNode + alphabet []interop.PublicKey nodeKey []byte alphabetCall bool )