diff --git a/container/config.yml b/container/config.yml index 43e81ab..13affcb 100644 --- a/container/config.yml +++ b/container/config.yml @@ -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 diff --git a/container/container_contract.go b/container/container_contract.go index 17fe13f..bf3d3f6 100644 --- a/container/container_contract.go +++ b/container/container_contract.go @@ -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")