Compare commits

...

6 commits

Author SHA1 Message Date
15fe9453ab
[#140] common: Update version
All checks were successful
DCO action / DCO (pull_request) Successful in 1m1s
Code generation / Generate wrappers (pull_request) Successful in 2m22s
Tests / Tests (pull_request) Successful in 2m31s
Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
2024-12-12 15:08:51 +03:00
dd6fe3f10e
[#140] common: Downgrade previous version
Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
2024-12-12 14:56:14 +03:00
f7fe65fbea
[#140] frostfsid: Remove address index in DeleteSubject()
Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
2024-12-12 14:54:25 +03:00
939dcb941e
[#140] container/test: Move container domain to constant
Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
2024-12-12 14:54:20 +03:00
9d8a3c672c
[#140] container: Add SetAdmin
SetAdmin will allow to manage the root domain of the container.

Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
2024-12-12 14:54:10 +03:00
375289f8cf
[#140] frostfsid: Make migration idempotent
Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
2024-12-12 14:53:49 +03:00
8 changed files with 70 additions and 8 deletions

View file

@ -1 +1 @@
v0.21.0
v0.21.1

View file

@ -5,14 +5,14 @@ import "github.com/nspcc-dev/neo-go/pkg/interop/native/std"
const (
major = 0
minor = 21
patch = 0
patch = 1
// Versions from which an update should be performed.
// These should be used in a group (so prevMinor can be equal to minor if there are
// any migration routines.
prevMajor = 0
prevMinor = 20
prevPatch = 0
prevMinor = 19
prevPatch = 4
Version = major*1_000_000 + minor*1_000 + patch

View file

@ -18,6 +18,7 @@ permissions:
- "register"
- "transferX"
- "update"
- "setAdmin"
events:
- name: PutSuccess

View file

@ -565,6 +565,21 @@ func NewEpoch(epochNum int) {
cleanupContainers(ctx, epochNum)
}
// SetAdmin sets admin for root container domain.
func SetAdmin(admin interop.Hash160) {
ctx := storage.GetReadOnlyContext()
if !runtime.CheckWitness(common.CommitteeAddress()) {
panic("only committee can set admin")
}
addrNNS := storage.Get(ctx, nnsContractKey).(interop.Hash160)
rootContainerDomain := storage.Get(ctx, nnsRootKey).(string)
contract.Call(addrNNS, "setAdmin", contract.All,
rootContainerDomain, admin)
}
// StartContainerEstimation method produces StartEstimation notification.
// It can be invoked only by Alphabet nodes of the Inner Ring.
func StartContainerEstimation(epoch int) {

View file

@ -103,7 +103,8 @@ func _deploy(data any, isUpdate bool) {
ctx := storage.GetContext()
args := data.(struct {
admin interop.Hash160
admin interop.Hash160
version int
})
if args.admin != nil {
@ -114,6 +115,7 @@ func _deploy(data any, isUpdate bool) {
}
if isUpdate {
common.CheckVersion(args.version)
it := storage.Find(ctx, subjectKeysPrefix, storage.ValuesOnly)
for iterator.Next(it) {
subjectRaw := iterator.Value(it)
@ -399,6 +401,7 @@ func DeleteSubject(addr interop.Hash160) {
storage.Delete(ctx, subjectAdditionalKey(subj.AdditionalKeys[i], addr))
storage.Delete(ctx, addressKey(contract.CreateStandardAccount(subj.AdditionalKeys[i])))
}
storage.Delete(ctx, addressKey(addr))
storage.Delete(ctx, sKey)
removeSubjectFromNamespace(ctx, subj.Namespace, addr)

View file

@ -270,6 +270,28 @@ func (c *Contract) PutNamedUnsigned(container []byte, signature []byte, publicKe
return c.actor.MakeUnsignedCall(c.hash, "putNamed", nil, container, signature, publicKey, token, name, zone)
}
// SetAdmin creates a transaction invoking `setAdmin` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) SetAdmin(admin util.Uint160) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "setAdmin", admin)
}
// SetAdminTransaction creates a transaction invoking `setAdmin` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) SetAdminTransaction(admin util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "setAdmin", admin)
}
// SetAdminUnsigned creates a transaction invoking `setAdmin` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) SetAdminUnsigned(admin util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "setAdmin", nil, admin)
}
// SetEACL creates a transaction invoking `setEACL` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.

View file

@ -28,13 +28,17 @@ const (
containerAliasFee = 0o_0050_0000
)
const (
containerRootDomain = "frostfs"
)
func deployContainerContract(t *testing.T, e *neotest.Executor, addrNetmap, addrBalance, addrNNS util.Uint160) util.Uint160 {
args := make([]any, 5)
args[0] = addrNetmap
args[1] = addrBalance
args[2] = util.Uint160{} // not needed for now
args[3] = addrNNS
args[4] = "frostfs"
args[4] = containerRootDomain
c := neotest.CompileFile(t, e.CommitteeHash, containerPath, path.Join(containerPath, "config.yml"))
e.DeployContract(t, c, args)
@ -207,14 +211,14 @@ func TestContainerPut(t *testing.T) {
stackitem.NewByteArray([]byte(base58.Encode(cnt.id[:]))),
})
cNNS := c.CommitteeInvoker(nnsHash)
cNNS.Invoke(t, expected, "resolve", "mycnt.frostfs", int64(nns.TXT))
cNNS.Invoke(t, expected, "resolve", "mycnt."+containerRootDomain, int64(nns.TXT))
t.Run("name is already taken", func(t *testing.T) {
c.InvokeFail(t, "name is already taken", "putNamed", putArgs...)
})
c.Invoke(t, stackitem.Null{}, "delete", cnt.id[:], cnt.sig, cnt.pub, cnt.token)
cNNS.Invoke(t, stackitem.Null{}, "resolve", "mycnt.frostfs", int64(nns.TXT))
cNNS.Invoke(t, stackitem.Null{}, "resolve", "mycnt."+containerRootDomain, int64(nns.TXT))
t.Run("register in advance", func(t *testing.T) {
cnt.value[len(cnt.value)-1] = 10
@ -241,6 +245,16 @@ func TestContainerPut(t *testing.T) {
})
})
t.Run("test setAdmin", func(t *testing.T) {
ctrNNS := neotest.CompileFile(t, c.CommitteeHash, nnsPath, path.Join(nnsPath, "config.yml"))
nnsInv := c.NewInvoker(ctrNNS.Hash, acc)
containerInv := c.WithSigners(c.Committee, acc)
nnsInv.InvokeFail(t, "not witnessed by admin", "addRecord", containerRootDomain, int64(nns.TXT), nns.Cnametgt+"=animals")
containerInv.Invoke(t, stackitem.Null{}, "setAdmin", acc.ScriptHash())
nnsInv.Invoke(t, stackitem.Null{}, "addRecord", containerRootDomain, int64(nns.TXT), nns.Cnametgt+"=animals")
})
t.Run("create global domain", func(t *testing.T) {
ctrNNS := neotest.CompileFile(t, c.CommitteeHash, nnsPath, path.Join(nnsPath, "config.yml"))
nnsHash := ctrNNS.Hash

View file

@ -629,6 +629,9 @@ func TestAdditionalKeyFromPrimarySubject(t *testing.T) {
subjDPrimaryKey, err := keys.NewPrivateKey()
require.NoError(t, err)
subjFPrimaryKey, err := keys.NewPrivateKey()
require.NoError(t, err)
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, defaultNamespace, subjAPrimaryKey.PublicKey().Bytes())
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, defaultNamespace, subjBPrimaryKey.PublicKey().Bytes())
@ -647,6 +650,10 @@ func TestAdditionalKeyFromPrimarySubject(t *testing.T) {
invoker.InvokeFail(t, "key is occupied", addSubjectKeyMethod, subjAKeyAddr, subjDPrimaryKey.PublicKey().Bytes())
invoker.Invoke(t, stackitem.Null{}, deleteSubjectMethod, subjBKeyAddr)
invoker.Invoke(t, stackitem.Null{}, addSubjectKeyMethod, subjAKeyAddr, subjDPrimaryKey.PublicKey().Bytes())
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, defaultNamespace, subjFPrimaryKey.PublicKey().Bytes())
invoker.Invoke(t, stackitem.Null{}, deleteSubjectMethod, subjFPrimaryKey.PublicKey().GetScriptHash())
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, defaultNamespace, subjFPrimaryKey.PublicKey().Bytes())
}
func checkPublicKeyResult(t *testing.T, s *vm.Stack, err error, key *keys.PrivateKey) {