forked from TrueCloudLab/frostfs-contract
[#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:
parent
dd0768aaeb
commit
3395a886fc
7 changed files with 86 additions and 166 deletions
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue