forked from TrueCloudLab/frostfs-contract
Do not store multiaddress of inner ring nodes
With neo:morph environment, there will be no direct communication between inner ring nodes and storage nodes. neo:morph smart-contracts will identify inner ring nodes by their signatures.
This commit is contained in:
parent
9f33939dee
commit
78b8af8f83
2 changed files with 17 additions and 69 deletions
|
@ -9,8 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type node struct {
|
type node struct {
|
||||||
addr []byte
|
pub []byte
|
||||||
pub []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type check struct {
|
type check struct {
|
||||||
|
@ -38,9 +37,8 @@ func Main(op string, args []interface{}) interface{} {
|
||||||
|
|
||||||
User operations:
|
User operations:
|
||||||
- InnerRingList() - get list of inner ring nodes addresses and public keys
|
- InnerRingList() - get list of inner ring nodes addresses and public keys
|
||||||
- InnerRingAddress(params: address, pubKey) - update address of the inner ring node with given public key
|
|
||||||
- InnerRingCandidateRemove(params: pubKey) - remove node with given public key from the inner ring candidate queue
|
- InnerRingCandidateRemove(params: pubKey) - remove node with given public key from the inner ring candidate queue
|
||||||
- InnerRingCandidateAdd(params: address, pubKey) - add node to the inner ring candidate queue
|
- InnerRingCandidateAdd(params: pubKey) - add node to the inner ring candidate queue
|
||||||
- Deposit(params: pubKey, amount) - deposit GAS to the NeoFS account
|
- Deposit(params: pubKey, amount) - deposit GAS to the NeoFS account
|
||||||
- Withdraw(params: withdrawCheque) - withdraw GAS from the NeoFS account
|
- Withdraw(params: withdrawCheque) - withdraw GAS from the NeoFS account
|
||||||
- InnerRingUpdate(params: irCheque) - change list of inner ring nodes
|
- InnerRingUpdate(params: irCheque) - change list of inner ring nodes
|
||||||
|
@ -64,16 +62,10 @@ func Main(op string, args []interface{}) interface{} {
|
||||||
panic("contract already deployed")
|
panic("contract already deployed")
|
||||||
}
|
}
|
||||||
|
|
||||||
ln := len(args)
|
|
||||||
if ln%2 != 0 {
|
|
||||||
panic("provide pairs of inner ring address and public key")
|
|
||||||
}
|
|
||||||
|
|
||||||
irList = []node{}
|
irList = []node{}
|
||||||
for i := 0; i < ln/2; i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
addr := args[i*2].([]byte)
|
pub := args[i].([]byte)
|
||||||
pub := args[i*2+1].([]byte)
|
irList = append(irList, node{pub: pub})
|
||||||
irList = append(irList, node{addr: addr, pub: pub})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data := runtime.Serialize(irList)
|
data := runtime.Serialize(irList)
|
||||||
|
@ -88,22 +80,6 @@ func Main(op string, args []interface{}) interface{} {
|
||||||
irList := getSerialized(ctx, "InnerRingList").([]node)
|
irList := getSerialized(ctx, "InnerRingList").([]node)
|
||||||
|
|
||||||
return irList
|
return irList
|
||||||
case "InnerRingAddress":
|
|
||||||
addr := args[0].([]byte)
|
|
||||||
pub := args[1].([]byte)
|
|
||||||
irList := getSerialized(ctx, "InnerRingList").([]node)
|
|
||||||
if !containsPub(irList, pub) {
|
|
||||||
panic("inner ring node does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
if runtime.CheckWitness(pub) {
|
|
||||||
n := node{addr: addr, pub: pub}
|
|
||||||
|
|
||||||
delSerializedIR(ctx, "InnerRingList", pub)
|
|
||||||
putSerialized(ctx, "InnerRingList", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
case "InnerRingCandidateRemove":
|
case "InnerRingCandidateRemove":
|
||||||
data := args[0].([]byte) // public key
|
data := args[0].([]byte) // public key
|
||||||
if !runtime.CheckWitness(data) {
|
if !runtime.CheckWitness(data) {
|
||||||
|
@ -114,19 +90,18 @@ func Main(op string, args []interface{}) interface{} {
|
||||||
|
|
||||||
return true
|
return true
|
||||||
case "InnerRingCandidateAdd":
|
case "InnerRingCandidateAdd":
|
||||||
addr := args[0].([]byte) // valid multiaddr string
|
key := args[0].([]byte) // public key
|
||||||
data := args[1].([]byte) // public key
|
|
||||||
|
|
||||||
if !runtime.CheckWitness(data) {
|
if !runtime.CheckWitness(key) {
|
||||||
panic("you should be the owner of the public key")
|
panic("you should be the owner of the public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates := getSerialized(ctx, "InnerRingCandidates").([]node)
|
candidates := getSerialized(ctx, "InnerRingCandidates").([]node)
|
||||||
if containsPub(candidates, data) {
|
if containsPub(candidates, key) {
|
||||||
panic("is already in list")
|
panic("is already in list")
|
||||||
}
|
}
|
||||||
|
|
||||||
from := pubToScriptHash(data)
|
from := pubToScriptHash(key)
|
||||||
to := engine.GetExecutingScriptHash()
|
to := engine.GetExecutingScriptHash()
|
||||||
params := []interface{}{from, to, innerRingCandidateFee}
|
params := []interface{}{from, to, innerRingCandidateFee}
|
||||||
|
|
||||||
|
@ -135,10 +110,7 @@ func Main(op string, args []interface{}) interface{} {
|
||||||
panic("failed to transfer funds, aborting")
|
panic("failed to transfer funds, aborting")
|
||||||
}
|
}
|
||||||
|
|
||||||
candidate := node{
|
candidate := node{pub: key}
|
||||||
addr: addr,
|
|
||||||
pub: data,
|
|
||||||
}
|
|
||||||
if !putSerialized(ctx, "InnerRingCandidates", candidate) {
|
if !putSerialized(ctx, "InnerRingCandidates", candidate) {
|
||||||
panic("failed to put candidate into the queue")
|
panic("failed to put candidate into the queue")
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ var (
|
||||||
|
|
||||||
type contract struct {
|
type contract struct {
|
||||||
script []byte
|
script []byte
|
||||||
addrs []multiaddr.Multiaddr
|
|
||||||
privs []*ecdsa.PrivateKey
|
privs []*ecdsa.PrivateKey
|
||||||
cgasHash string
|
cgasHash string
|
||||||
}
|
}
|
||||||
|
@ -49,43 +48,20 @@ func TestContract(t *testing.T) {
|
||||||
|
|
||||||
plug.cgas[contractStr] = util.Fixed8FromInt64(1000)
|
plug.cgas[contractStr] = util.Fixed8FromInt64(1000)
|
||||||
|
|
||||||
// fail if odd number of arguments provided
|
|
||||||
v := initVM(contract, plug)
|
|
||||||
loadArg(t, v, "Deploy", []interface{}{contract.addrs[0].String()})
|
|
||||||
require.Error(t, v.Run())
|
|
||||||
|
|
||||||
// correct arguments
|
|
||||||
var args []interface{}
|
var args []interface{}
|
||||||
for i := range contract.addrs {
|
for i := range contract.privs {
|
||||||
args = append(args, contract.addrs[i].String())
|
|
||||||
args = append(args, crypto.MarshalPublicKey(&contract.privs[i].PublicKey))
|
args = append(args, crypto.MarshalPublicKey(&contract.privs[i].PublicKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
v = initVM(contract, plug)
|
v := initVM(contract, plug)
|
||||||
loadArg(t, v, "Deploy", args)
|
loadArg(t, v, "Deploy", args)
|
||||||
require.NoError(t, v.Run())
|
require.NoError(t, v.Run())
|
||||||
|
|
||||||
// double withdraw
|
// double deploy
|
||||||
v = initVM(contract, plug)
|
v = initVM(contract, plug)
|
||||||
loadArg(t, v, "Deploy", args)
|
loadArg(t, v, "Deploy", args)
|
||||||
require.Error(t, v.Run())
|
require.Error(t, v.Run())
|
||||||
|
|
||||||
t.Run("InnerRingAddress", func(t *testing.T) {
|
|
||||||
newAddr, err := multiaddr.NewMultiaddr("/dns6/fdb5:7305:0adf:0b0b::/tcp/8080")
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
previousAddr := contract.addrs[0]
|
|
||||||
key := crypto.MarshalPublicKey(&contract.privs[0].PublicKey)
|
|
||||||
|
|
||||||
v := initVM(contract, plug)
|
|
||||||
loadArg(t, v, "InnerRingAddress", []interface{}{newAddr.String(), key})
|
|
||||||
require.NoError(t, v.Run())
|
|
||||||
require.False(t, bytes.Contains(plug.mem["InnerRingList"], []byte(previousAddr.String())))
|
|
||||||
require.True(t, bytes.Contains(plug.mem["InnerRingList"], []byte(newAddr.String())))
|
|
||||||
|
|
||||||
contract.addrs[0] = newAddr
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Deposit", func(t *testing.T) {
|
t.Run("Deposit", func(t *testing.T) {
|
||||||
v := initVM(contract, plug)
|
v := initVM(contract, plug)
|
||||||
before := plug.cgas[contractStr]
|
before := plug.cgas[contractStr]
|
||||||
|
@ -128,7 +104,7 @@ func TestContract(t *testing.T) {
|
||||||
key := crypto.MarshalPublicKey(&test.DecodeKey(1).PublicKey)
|
key := crypto.MarshalPublicKey(&test.DecodeKey(1).PublicKey)
|
||||||
plug.setCGASBalance(key, 4000)
|
plug.setCGASBalance(key, 4000)
|
||||||
|
|
||||||
loadArg(t, v, "InnerRingCandidateAdd", []interface{}{"/ip6/2001:4860:4860::8888/tcp/80", key})
|
loadArg(t, v, "InnerRingCandidateAdd", []interface{}{key})
|
||||||
require.NoError(t, v.Run())
|
require.NoError(t, v.Run())
|
||||||
|
|
||||||
fee := util.Fixed8FromInt64(1)
|
fee := util.Fixed8FromInt64(1)
|
||||||
|
@ -140,7 +116,7 @@ func TestContract(t *testing.T) {
|
||||||
|
|
||||||
t.Run("Double InnerRingCandidateAdd", func(t *testing.T) {
|
t.Run("Double InnerRingCandidateAdd", func(t *testing.T) {
|
||||||
v := initVM(contract, plug)
|
v := initVM(contract, plug)
|
||||||
loadArg(t, v, "InnerRingCandidateAdd", []interface{}{"/ip4/8.8.8.8/tcp/80", key})
|
loadArg(t, v, "InnerRingCandidateAdd", []interface{}{key})
|
||||||
require.Error(t, v.Run())
|
require.Error(t, v.Run())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -150,7 +126,7 @@ func TestContract(t *testing.T) {
|
||||||
plug.setCGASBalance(key, 4000)
|
plug.setCGASBalance(key, 4000)
|
||||||
|
|
||||||
v := initVM(contract, plug)
|
v := initVM(contract, plug)
|
||||||
loadArg(t, v, "InnerRingCandidateAdd", []interface{}{"/ip6/2001:4860:4860::8888/tcp/80", key})
|
loadArg(t, v, "InnerRingCandidateAdd", []interface{}{key})
|
||||||
require.NoError(t, v.Run())
|
require.NoError(t, v.Run())
|
||||||
require.True(t, bytes.Contains(plug.mem["InnerRingCandidates"], key))
|
require.True(t, bytes.Contains(plug.mem["InnerRingCandidates"], key))
|
||||||
|
|
||||||
|
@ -253,7 +229,7 @@ func initGoContract(t *testing.T, path string, n int) *contract {
|
||||||
buf, err := compiler.Compile(f)
|
buf, err := compiler.Compile(f)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return &contract{script: buf, privs: getKeys(t, n), addrs: getAddrs(t, n)}
|
return &contract{script: buf, privs: getKeys(t, n)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKeys(t *testing.T, n int) []*ecdsa.PrivateKey {
|
func getKeys(t *testing.T, n int) []*ecdsa.PrivateKey {
|
||||||
|
|
Loading…
Reference in a new issue