[#78] container: Use alphabet approve in `SetEACL` method

Store public key of eACL signature because it might
be set up by NFT owner.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
enable-notary-in-public-chains
Alex Vanin 2021-05-11 17:42:02 +03:00 committed by Alex Vanin
parent a036bdd09d
commit 3e70c37c22
2 changed files with 41 additions and 5 deletions

View File

@ -15,6 +15,14 @@ events:
type: ByteArray
- name: signature
type: ByteArray
- name: setEACL
parameters:
- name: eACL
type: ByteArray
- name: signature
type: ByteArray
- name: publicKey
type: ByteArray
- name: StartEstimation
parameters:
- name: epoch

View File

@ -276,8 +276,9 @@ func List(owner []byte) [][]byte {
return list
}
func SetEACL(eACL, signature []byte) bool {
func SetEACL(eACL, signature, publicKey []byte) bool {
ctx := storage.GetContext()
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
// get container ID
offset := int(eACL[1])
@ -289,19 +290,46 @@ func SetEACL(eACL, signature []byte) bool {
panic("setEACL: container does not exists")
}
neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).(interop.Hash160)
keys := contract.Call(neofsIDContractAddr, "key", contract.ReadOnly, ownerID).([]interop.PublicKey)
var ( // for invocation collection without notary
alphabet []common.IRNode
nodeKey []byte
alphabetCall bool
)
if !verifySignature(eACL, signature, keys) {
panic("setEACL: invalid eACL signature")
if notaryDisabled {
alphabet = common.AlphabetNodes()
nodeKey = common.InnerRingInvoker(alphabet)
alphabetCall = len(nodeKey) != 0
} else {
multiaddr := common.AlphabetAddress()
alphabetCall = runtime.CheckWitness(multiaddr)
}
if !alphabetCall {
runtime.Notify("setEACL", eACL, signature, publicKey)
return true
}
rule := extendedACL{
val: eACL,
sig: signature,
pub: publicKey,
}
key := append(eACLPrefix, containerID...)
if notaryDisabled {
threshold := len(alphabet)*2/3 + 1
id := common.InvokeID([]interface{}{eACL}, []byte("setEACL"))
n := common.Vote(ctx, id, nodeKey)
if n < threshold {
return true
}
common.RemoveVotes(ctx, id)
}
common.SetSerialized(ctx, key, rule)
runtime.Log("setEACL: success")