forked from TrueCloudLab/frostfs-contract
[#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:
parent
01a7163d1e
commit
03afb80a14
9 changed files with 87 additions and 85 deletions
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
37
common/ir.go
37
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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue