[#42] Share InnerRingInvoker function between contracts

Define IRNode structure in common package. Replace innerRingInvoker function
in common package and export it. Reuse this function in all contracts.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-02-02 21:26:34 +03:00 committed by Alex Vanin
parent dd0768aaeb
commit 3395a886fc
7 changed files with 86 additions and 166 deletions

View file

@ -10,12 +10,6 @@ import (
"github.com/nspcc-dev/neofs-contract/common" "github.com/nspcc-dev/neofs-contract/common"
) )
type (
irNode struct {
key []byte
}
)
const ( const (
// native gas token script hash // native gas token script hash
gasHash = "\xfb\xed\xfe\x2e\xd2\x22\x65\x92\xb6\x48\xc4\xda\x97\xb9\xc9\xcd\x5d\xc1\xa6\xa6" gasHash = "\xfb\xed\xfe\x2e\xd2\x22\x65\x92\xb6\x48\xc4\xda\x97\xb9\xc9\xcd\x5d\xc1\xa6\xa6"
@ -84,9 +78,9 @@ func balance(hash string, addr []byte) int {
return balance.(int) return balance.(int)
} }
func irList() []irNode { func irList() []common.IRNode {
netmapContractAddr := storage.Get(ctx, netmapKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapKey).([]byte)
return contract.Call(netmapContractAddr, "innerRingList").([]irNode) return contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
} }
func currentEpoch() int { func currentEpoch() int {
@ -106,7 +100,7 @@ func total() int {
return storage.Get(ctx, totalKey).(int) return storage.Get(ctx, totalKey).(int)
} }
func checkPermission(ir []irNode) bool { func checkPermission(ir []common.IRNode) bool {
index := index() // read from contract memory index := index() // read from contract memory
if len(ir) <= index { if len(ir) <= index {
@ -114,24 +108,7 @@ func checkPermission(ir []irNode) bool {
} }
node := ir[index] node := ir[index]
return runtime.CheckWitness(node.key) return runtime.CheckWitness(node.PublicKey)
}
func innerRingInvoker(ir []irNode) []byte {
amountOfContracts := total() // read from contract memory
for i := 0; i < len(ir); i++ {
if i >= amountOfContracts {
return nil
}
node := ir[i]
if runtime.CheckWitness(node.key) {
return node.key
}
}
return nil
} }
func Emit() bool { func Emit() bool {
@ -155,7 +132,7 @@ func Emit() bool {
for i := range innerRingKeys { for i := range innerRingKeys {
node := innerRingKeys[i] node := innerRingKeys[i]
address := contract.CreateStandardAccount(node.key) address := contract.CreateStandardAccount(node.PublicKey)
_ = contract.Call([]byte(gasHash), "transfer", contractHash, address, gasPerNode, nil) _ = contract.Call([]byte(gasHash), "transfer", contractHash, address, gasPerNode, nil)
} }
@ -170,7 +147,7 @@ func Vote(epoch int, candidates [][]byte) {
index := index() index := index()
name := name() name := name()
key := innerRingInvoker(innerRingKeys) key := common.InnerRingInvoker(innerRingKeys)
if len(key) == 0 { if len(key) == 0 {
panic("invalid invoker") panic("invalid invoker")
} }

View file

@ -11,10 +11,6 @@ import (
) )
type ( type (
irNode struct {
key []byte
}
// Token holds all token info. // Token holds all token info.
Token struct { Token struct {
// Ticker symbol // Ticker symbol
@ -114,10 +110,10 @@ func TransferX(from, to interop.Hash160, amount int, details []byte) bool {
) )
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("transferX: this method must be invoked from inner ring") panic("transferX: this method must be invoked from inner ring")
} }
@ -150,10 +146,10 @@ func TransferX(from, to interop.Hash160, amount int, details []byte) bool {
func Lock(txID []byte, from, to interop.Hash160, amount, until int) bool { func Lock(txID []byte, from, to interop.Hash160, amount, until int) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("lock: this method must be invoked from inner ring") panic("lock: this method must be invoked from inner ring")
} }
@ -188,10 +184,10 @@ func Lock(txID []byte, from, to interop.Hash160, amount, until int) bool {
func NewEpoch(epochNum int) bool { func NewEpoch(epochNum int) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("epochNum: this method must be invoked from inner ring") panic("epochNum: this method must be invoked from inner ring")
} }
@ -227,10 +223,10 @@ func NewEpoch(epochNum int) bool {
func Mint(to interop.Hash160, amount int, details []byte) bool { func Mint(to interop.Hash160, amount int, details []byte) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("burn: this method must be invoked from inner ring") panic("burn: this method must be invoked from inner ring")
} }
@ -258,10 +254,10 @@ func Mint(to interop.Hash160, amount int, details []byte) bool {
func Burn(from interop.Hash160, amount int, details []byte) bool { func Burn(from interop.Hash160, amount int, details []byte) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("burn: this method must be invoked from inner ring") panic("burn: this method must be invoked from inner ring")
} }
@ -381,17 +377,6 @@ func isUsableAddress(addr interop.Hash160) bool {
return false return false
} }
func innerRingInvoker(ir []irNode) []byte {
for i := 0; i < len(ir); i++ {
node := ir[i]
if runtime.CheckWitness(node.key) {
return node.key
}
}
return nil
}
func getAccount(ctx storage.Context, key interface{}) Account { func getAccount(ctx storage.Context, key interface{}) Account {
data := storage.Get(ctx, key) data := storage.Get(ctx, key)
if data != nil { if data != nil {

View file

@ -1,6 +1,9 @@
package common package common
import "github.com/nspcc-dev/neo-go/pkg/interop/crypto" import (
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
)
func InvokeID(args []interface{}, prefix []byte) []byte { func InvokeID(args []interface{}, prefix []byte) []byte {
for i := range args { for i := range args {
@ -10,3 +13,19 @@ func InvokeID(args []interface{}, prefix []byte) []byte {
return crypto.SHA256(prefix) return crypto.SHA256(prefix)
} }
type IRNode struct {
PublicKey []byte
}
// InnerRingInvoker returns public key of inner ring node that invoked contract.
func InnerRingInvoker(ir []IRNode) []byte {
for i := 0; i < len(ir); i++ {
node := ir[i]
if runtime.CheckWitness(node.PublicKey) {
return node.PublicKey
}
}
return nil
}

View file

@ -12,10 +12,6 @@ import (
) )
type ( type (
irNode struct {
key []byte
}
storageNode struct { storageNode struct {
info []byte info []byte
} }
@ -87,7 +83,7 @@ func Init(addrNetmap, addrBalance, addrID []byte) {
func Put(container, signature, publicKey []byte) bool { func Put(container, signature, publicKey []byte) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
offset := int(container[1]) offset := int(container[1])
@ -98,7 +94,7 @@ func Put(container, signature, publicKey []byte) bool {
// If invoked from storage node, ignore it. // If invoked from storage node, ignore it.
// Inner ring will find tx, validate it and send it again. // Inner ring will find tx, validate it and send it again.
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
// check provided key // check provided key
if !isSignedByOwnerKey(container, signature, ownerID, publicKey) { if !isSignedByOwnerKey(container, signature, ownerID, publicKey) {
@ -126,7 +122,7 @@ func Put(container, signature, publicKey []byte) bool {
for i := 0; i < len(innerRing); i++ { for i := 0; i < len(innerRing); i++ {
node := innerRing[i] node := innerRing[i]
to := contract.CreateStandardAccount(node.key) to := contract.CreateStandardAccount(node.PublicKey)
tx := contract.Call(balanceContractAddr, "transferX", tx := contract.Call(balanceContractAddr, "transferX",
from, from,
@ -154,7 +150,7 @@ func Put(container, signature, publicKey []byte) bool {
func Delete(containerID, signature []byte) bool { func Delete(containerID, signature []byte) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
ownerID := getOwnerByID(ctx, containerID) ownerID := getOwnerByID(ctx, containerID)
@ -164,7 +160,7 @@ func Delete(containerID, signature []byte) bool {
// If invoked from storage node, ignore it. // If invoked from storage node, ignore it.
// Inner ring will find tx, validate it and send it again. // Inner ring will find tx, validate it and send it again.
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
// check provided key // check provided key
neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).([]byte) neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).([]byte)
@ -341,10 +337,10 @@ func ListContainerSizes(epoch int) [][]byte {
func ProcessEpoch(epochNum int) { func ProcessEpoch(epochNum int) {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("processEpoch: this method must be invoked from inner ring") panic("processEpoch: this method must be invoked from inner ring")
} }
@ -365,10 +361,10 @@ func ProcessEpoch(epochNum int) {
func StartContainerEstimation(epoch int) bool { func StartContainerEstimation(epoch int) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("startEstimation: only inner ring nodes can invoke this") panic("startEstimation: only inner ring nodes can invoke this")
} }
@ -389,10 +385,10 @@ func StartContainerEstimation(epoch int) bool {
func StopContainerEstimation(epoch int) bool { func StopContainerEstimation(epoch int) bool {
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("stopEstimation: only inner ring nodes can invoke this") panic("stopEstimation: only inner ring nodes can invoke this")
} }
@ -472,17 +468,6 @@ func remove(ctx storage.Context, key interface{}, value []byte) int {
return ln return ln
} }
func innerRingInvoker(ir []irNode) []byte {
for i := 0; i < len(ir); i++ {
node := ir[i]
if runtime.CheckWitness(node.key) {
return node.key
}
}
return nil
}
func getList(ctx storage.Context, key interface{}) [][]byte { func getList(ctx storage.Context, key interface{}) [][]byte {
data := storage.Get(ctx, key) data := storage.Get(ctx, key)
if data != nil { if data != nil {

View file

@ -43,10 +43,6 @@ import (
) )
type ( type (
node struct {
pub []byte
}
cheque struct { cheque struct {
id []byte id []byte
} }
@ -102,7 +98,7 @@ func Init(args [][]byte) bool {
panic("neofs: contract already deployed") panic("neofs: contract already deployed")
} }
var irList []node var irList []common.IRNode
if len(args) < 3 { if len(args) < 3 {
panic("neofs: at least three inner ring keys must be provided") panic("neofs: at least three inner ring keys must be provided")
@ -113,13 +109,13 @@ func Init(args [][]byte) bool {
if len(pub) != publicKeySize { if len(pub) != publicKeySize {
panic("neofs: incorrect public key length") panic("neofs: incorrect public key length")
} }
irList = append(irList, node{pub: pub}) irList = append(irList, common.IRNode{PublicKey: pub})
} }
// initialize all storage slices // initialize all storage slices
common.SetSerialized(ctx, innerRingKey, irList) common.SetSerialized(ctx, innerRingKey, irList)
common.InitVote(ctx) common.InitVote(ctx)
common.SetSerialized(ctx, candidatesKey, []node{}) common.SetSerialized(ctx, candidatesKey, []common.IRNode{})
common.SetSerialized(ctx, cashedChequesKey, []cheque{}) common.SetSerialized(ctx, cashedChequesKey, []cheque{})
runtime.Log("neofs: contract initialized") runtime.Log("neofs: contract initialized")
@ -128,12 +124,12 @@ func Init(args [][]byte) bool {
} }
// InnerRingList returns array of inner ring node keys. // InnerRingList returns array of inner ring node keys.
func InnerRingList() []node { func InnerRingList() []common.IRNode {
return getInnerRingNodes(ctx, innerRingKey) return getInnerRingNodes(ctx, innerRingKey)
} }
// InnerRingCandidates returns array of inner ring candidate node keys. // InnerRingCandidates returns array of inner ring candidate node keys.
func InnerRingCandidates() []node { func InnerRingCandidates() []common.IRNode {
return getInnerRingNodes(ctx, candidatesKey) return getInnerRingNodes(ctx, candidatesKey)
} }
@ -143,12 +139,12 @@ func InnerRingCandidateRemove(key []byte) bool {
panic("irCandidateRemove: you should be the owner of the public key") panic("irCandidateRemove: you should be the owner of the public key")
} }
nodes := []node{} // it is explicit declaration of empty slice, not nil nodes := []common.IRNode{} // it is explicit declaration of empty slice, not nil
candidates := getInnerRingNodes(ctx, candidatesKey) candidates := getInnerRingNodes(ctx, candidatesKey)
for i := range candidates { for i := range candidates {
c := candidates[i] c := candidates[i]
if !common.BytesEqual(c.pub, key) { if !common.BytesEqual(c.PublicKey, key) {
nodes = append(nodes, c) nodes = append(nodes, c)
} else { } else {
runtime.Log("irCandidateRemove: candidate has been removed") runtime.Log("irCandidateRemove: candidate has been removed")
@ -166,7 +162,7 @@ func InnerRingCandidateAdd(key []byte) bool {
panic("irCandidateAdd: you should be the owner of the public key") panic("irCandidateAdd: you should be the owner of the public key")
} }
c := node{pub: key} c := common.IRNode{PublicKey: key}
candidates := getInnerRingNodes(ctx, candidatesKey) candidates := getInnerRingNodes(ctx, candidatesKey)
list, ok := addNode(candidates, c) list, ok := addNode(candidates, c)
@ -274,7 +270,7 @@ func Cheque(id, user []byte, amount int, lockAcc []byte) bool {
cashedCheques := getCashedCheques(ctx) cashedCheques := getCashedCheques(ctx)
hashID := crypto.SHA256(id) hashID := crypto.SHA256(id)
irKey := innerRingInvoker(irList) irKey := common.InnerRingInvoker(irList)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("cheque: invoked by non inner ring node") panic("cheque: invoked by non inner ring node")
} }
@ -353,7 +349,7 @@ func InnerRingUpdate(chequeID []byte, args [][]byte) bool {
irList := getInnerRingNodes(ctx, innerRingKey) irList := getInnerRingNodes(ctx, innerRingKey)
threshold := len(irList)/3*2 + 1 threshold := len(irList)/3*2 + 1
irKey := innerRingInvoker(irList) irKey := common.InnerRingInvoker(irList)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("innerRingUpdate: invoked by non inner ring node") panic("innerRingUpdate: invoked by non inner ring node")
} }
@ -369,7 +365,7 @@ func InnerRingUpdate(chequeID []byte, args [][]byte) bool {
oldNodes := 0 oldNodes := 0
candidates := getInnerRingNodes(ctx, candidatesKey) candidates := getInnerRingNodes(ctx, candidatesKey)
newIR := []node{} newIR := []common.IRNode{}
loop: loop:
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
@ -381,7 +377,7 @@ loop:
// find key in actual inner ring list // find key in actual inner ring list
for j := 0; j < len(irList); j++ { for j := 0; j < len(irList); j++ {
n := irList[j] n := irList[j]
if common.BytesEqual(n.pub, key) { if common.BytesEqual(n.PublicKey, key) {
newIR = append(newIR, n) newIR = append(newIR, n)
oldNodes++ oldNodes++
@ -427,7 +423,7 @@ func IsInnerRing(key []byte) bool {
for i := range irList { for i := range irList {
node := irList[i] node := irList[i]
if common.BytesEqual(node.pub, key) { if common.BytesEqual(node.PublicKey, key) {
return true return true
} }
} }
@ -446,7 +442,7 @@ func SetConfig(id, key, val []byte) bool {
irList := getInnerRingNodes(ctx, innerRingKey) irList := getInnerRingNodes(ctx, innerRingKey)
threshold := len(irList)/3*2 + 1 threshold := len(irList)/3*2 + 1
irKey := innerRingInvoker(irList) irKey := common.InnerRingInvoker(irList)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("setConfig: invoked by non inner ring node") panic("setConfig: invoked by non inner ring node")
} }
@ -523,26 +519,14 @@ func Version() int {
return version return version
} }
// innerRingInvoker returns public key of inner ring node that invoked contract.
func innerRingInvoker(ir []node) []byte {
for i := 0; i < len(ir); i++ {
node := ir[i]
if runtime.CheckWitness(node.pub) {
return node.pub
}
}
return nil
}
// getInnerRingNodes returns deserialized slice of inner ring nodes from storage. // getInnerRingNodes returns deserialized slice of inner ring nodes from storage.
func getInnerRingNodes(ctx storage.Context, key string) []node { func getInnerRingNodes(ctx storage.Context, key string) []common.IRNode {
data := storage.Get(ctx, key) data := storage.Get(ctx, key)
if data != nil { if data != nil {
return binary.Deserialize(data.([]byte)).([]node) return binary.Deserialize(data.([]byte)).([]common.IRNode)
} }
return []node{} return []common.IRNode{}
} }
// getInnerRingNodes returns deserialized slice of used cheques. // getInnerRingNodes returns deserialized slice of used cheques.
@ -587,9 +571,9 @@ func addCheque(lst []cheque, c cheque) ([]cheque, bool) {
// addNode returns slice of nodes with appended node 'n' and bool flag // addNode returns slice of nodes with appended node 'n' and bool flag
// that set to false if node 'n' is already presented in the slice 'lst'. // that set to false if node 'n' is already presented in the slice 'lst'.
func addNode(lst []node, n node) ([]node, bool) { func addNode(lst []common.IRNode, n common.IRNode) ([]common.IRNode, bool) {
for i := 0; i < len(lst); i++ { for i := 0; i < len(lst); i++ {
if common.BytesEqual(n.pub, lst[i].pub) { if common.BytesEqual(n.PublicKey, lst[i].PublicKey) {
return nil, false return nil, false
} }
} }
@ -602,14 +586,14 @@ func addNode(lst []node, n node) ([]node, bool) {
// rmNodeByKey returns slice of nodes without node with key 'k', // rmNodeByKey returns slice of nodes without node with key 'k',
// slices of nodes 'add' with node with key 'k' and bool flag, // slices of nodes 'add' with node with key 'k' and bool flag,
// that set to false if node with a key 'k' does not exists in the slice 'lst'. // that set to false if node with a key 'k' does not exists in the slice 'lst'.
func rmNodeByKey(lst, add []node, k []byte) ([]node, []node, bool) { func rmNodeByKey(lst, add []common.IRNode, k []byte) ([]common.IRNode, []common.IRNode, bool) {
var ( var (
flag bool flag bool
newLst = []node{} // it is explicit declaration of empty slice, not nil newLst = []common.IRNode{} // it is explicit declaration of empty slice, not nil
) )
for i := 0; i < len(lst); i++ { for i := 0; i < len(lst); i++ {
if common.BytesEqual(k, lst[i].pub) { if common.BytesEqual(k, lst[i].PublicKey) {
add = append(add, lst[i]) add = append(add, lst[i])
flag = true flag = true
} else { } else {

View file

@ -10,10 +10,6 @@ import (
) )
type ( type (
irNode struct {
key []byte
}
UserInfo struct { UserInfo struct {
Keys [][]byte Keys [][]byte
} }
@ -64,10 +60,10 @@ func AddKey(owner []byte, keys [][]byte) bool {
} }
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("addKey: invocation from non inner ring node") panic("addKey: invocation from non inner ring node")
} }
@ -118,10 +114,10 @@ func RemoveKey(owner []byte, keys [][]byte) bool {
} }
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) innerRing := contract.Call(netmapContractAddr, "innerRingList").([]common.IRNode)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("removeKey: invocation from non inner ring node") panic("removeKey: invocation from non inner ring node")
} }
@ -186,17 +182,6 @@ func getUserInfo(ctx storage.Context, key interface{}) UserInfo {
return UserInfo{Keys: [][]byte{}} return UserInfo{Keys: [][]byte{}}
} }
func innerRingInvoker(ir []irNode) []byte {
for i := 0; i < len(ir); i++ {
node := ir[i]
if runtime.CheckWitness(node.key) {
return node.key
}
}
return nil
}
func invokeIDKeys(owner []byte, keys [][]byte, prefix []byte) []byte { func invokeIDKeys(owner []byte, keys [][]byte, prefix []byte) []byte {
prefix = append(prefix, owner...) prefix = append(prefix, owner...)
for i := range keys { for i := range keys {

View file

@ -10,10 +10,6 @@ import (
) )
type ( type (
irNode struct {
key []byte
}
storageNode struct { storageNode struct {
info []byte info []byte
} }
@ -70,11 +66,11 @@ func Init(keys [][]byte) {
panic("netmap: contract already initialized") panic("netmap: contract already initialized")
} }
var irList []irNode var irList []common.IRNode
for i := 0; i < len(keys); i++ { for i := 0; i < len(keys); i++ {
key := keys[i] key := keys[i]
irList = append(irList, irNode{key: key}) irList = append(irList, common.IRNode{PublicKey: key})
} }
common.SetSerialized(ctx, innerRingKey, irList) common.SetSerialized(ctx, innerRingKey, irList)
@ -91,7 +87,7 @@ func Init(keys [][]byte) {
runtime.Log("netmap contract initialized") runtime.Log("netmap contract initialized")
} }
func InnerRingList() []irNode { func InnerRingList() []common.IRNode {
return getIRNodes(ctx) return getIRNodes(ctx)
} }
@ -99,16 +95,16 @@ func UpdateInnerRing(keys [][]byte) bool {
innerRing := getIRNodes(ctx) innerRing := getIRNodes(ctx)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("updateInnerRing: this method must be invoked by inner ring nodes") panic("updateInnerRing: this method must be invoked by inner ring nodes")
} }
var irList []irNode var irList []common.IRNode
for i := 0; i < len(keys); i++ { for i := 0; i < len(keys); i++ {
key := keys[i] key := keys[i]
irList = append(irList, irNode{key: key}) irList = append(irList, common.IRNode{PublicKey: key})
} }
rawIRList := binary.Serialize(irList) rawIRList := binary.Serialize(irList)
@ -130,7 +126,7 @@ func AddPeer(nodeInfo []byte) bool {
innerRing := getIRNodes(ctx) innerRing := getIRNodes(ctx)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
publicKey := nodeInfo[2:35] // offset:2, len:33 publicKey := nodeInfo[2:35] // offset:2, len:33
if !runtime.CheckWitness(publicKey) { if !runtime.CheckWitness(publicKey) {
@ -172,7 +168,7 @@ func UpdateState(state int, publicKey []byte) bool {
innerRing := getIRNodes(ctx) innerRing := getIRNodes(ctx)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
if !runtime.CheckWitness(publicKey) { if !runtime.CheckWitness(publicKey) {
panic("updateState: witness check failed") panic("updateState: witness check failed")
@ -205,7 +201,7 @@ func NewEpoch(epochNum int) bool {
innerRing := getIRNodes(ctx) innerRing := getIRNodes(ctx)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("newEpoch: this method must be invoked by inner ring nodes") panic("newEpoch: this method must be invoked by inner ring nodes")
} }
@ -279,7 +275,7 @@ func SetConfig(id, key, val []byte) bool {
innerRing := getIRNodes(ctx) innerRing := getIRNodes(ctx)
threshold := len(innerRing)/3*2 + 1 threshold := len(innerRing)/3*2 + 1
irKey := innerRingInvoker(innerRing) irKey := common.InnerRingInvoker(innerRing)
if len(irKey) == 0 { if len(irKey) == 0 {
panic("setConfig: invoked by non inner ring node") panic("setConfig: invoked by non inner ring node")
} }
@ -340,17 +336,6 @@ func Version() int {
return version return version
} }
func innerRingInvoker(ir []irNode) []byte {
for i := 0; i < len(ir); i++ {
node := ir[i]
if runtime.CheckWitness(node.key) {
return node.key
}
}
return nil
}
func addToNetmap(ctx storage.Context, n storageNode) []netmapNode { func addToNetmap(ctx storage.Context, n storageNode) []netmapNode {
var ( var (
newNode = n.info newNode = n.info
@ -412,13 +397,13 @@ func filterNetmap(ctx storage.Context, st nodeState) []storageNode {
return result return result
} }
func getIRNodes(ctx storage.Context) []irNode { func getIRNodes(ctx storage.Context) []common.IRNode {
data := storage.Get(ctx, innerRingKey) data := storage.Get(ctx, innerRingKey)
if data != nil { if data != nil {
return binary.Deserialize(data.([]byte)).([]irNode) return binary.Deserialize(data.([]byte)).([]common.IRNode)
} }
return []irNode{} return []common.IRNode{}
} }
func getNetmapNodes(ctx storage.Context) []netmapNode { func getNetmapNodes(ctx storage.Context) []netmapNode {