[#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 type: ByteArray
- name: signature - name: signature
type: ByteArray type: ByteArray
- name: setEACL
parameters:
- name: eACL
type: ByteArray
- name: signature
type: ByteArray
- name: publicKey
type: ByteArray
- name: StartEstimation - name: StartEstimation
parameters: parameters:
- name: epoch - name: epoch

View File

@ -276,8 +276,9 @@ func List(owner []byte) [][]byte {
return list return list
} }
func SetEACL(eACL, signature []byte) bool { func SetEACL(eACL, signature, publicKey []byte) bool {
ctx := storage.GetContext() ctx := storage.GetContext()
notaryDisabled := storage.Get(ctx, notaryDisabledKey).(bool)
// get container ID // get container ID
offset := int(eACL[1]) offset := int(eACL[1])
@ -289,19 +290,46 @@ func SetEACL(eACL, signature []byte) bool {
panic("setEACL: container does not exists") panic("setEACL: container does not exists")
} }
neofsIDContractAddr := storage.Get(ctx, neofsIDContractKey).(interop.Hash160) var ( // for invocation collection without notary
keys := contract.Call(neofsIDContractAddr, "key", contract.ReadOnly, ownerID).([]interop.PublicKey) alphabet []common.IRNode
nodeKey []byte
alphabetCall bool
)
if !verifySignature(eACL, signature, keys) { if notaryDisabled {
panic("setEACL: invalid eACL signature") 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{ rule := extendedACL{
val: eACL, val: eACL,
sig: signature, sig: signature,
pub: publicKey,
} }
key := append(eACLPrefix, containerID...) 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) common.SetSerialized(ctx, key, rule)
runtime.Log("setEACL: success") runtime.Log("setEACL: success")