[#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)
}
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
)

View file

@ -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

View file

@ -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
)

View file

@ -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
}

View file

@ -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
)

View file

@ -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)
}

View file

@ -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
)

View file

@ -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 {

View file

@ -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
)