forked from TrueCloudLab/frostfs-contract
[#109] nns: Add notification sending
Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
This commit is contained in:
parent
c142971bfd
commit
46407fbd3e
4 changed files with 414 additions and 4 deletions
|
@ -4,6 +4,26 @@ safemethods: ["balanceOf", "decimals", "symbol", "totalSupply", "tokensOf", "own
|
||||||
"tokens", "properties", "roots", "getPrice", "isAvailable", "getRecords",
|
"tokens", "properties", "roots", "getPrice", "isAvailable", "getRecords",
|
||||||
"resolve", "version"]
|
"resolve", "version"]
|
||||||
events:
|
events:
|
||||||
|
- name: RegisterDomain
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
type: String
|
||||||
|
- name: AddRecord
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
type: String
|
||||||
|
- name: type
|
||||||
|
type: Integer
|
||||||
|
- name: DeleteRecords
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
type: String
|
||||||
|
- name: type
|
||||||
|
type: Integer
|
||||||
|
- name: DeleteDomain
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
type: String
|
||||||
- name: Transfer
|
- name: Transfer
|
||||||
parameters:
|
parameters:
|
||||||
- name: from
|
- name: from
|
||||||
|
|
|
@ -407,6 +407,7 @@ func register(ctx storage.Context, name string, owner interop.Hash160, email str
|
||||||
putSoaRecord(ctx, name, email, refresh, retry, expire, ttl)
|
putSoaRecord(ctx, name, email, refresh, retry, expire, ttl)
|
||||||
updateBalance(ctx, []byte(name), owner, +1)
|
updateBalance(ctx, []byte(name), owner, +1)
|
||||||
postTransfer(oldOwner, owner, []byte(name), nil)
|
postTransfer(oldOwner, owner, []byte(name), nil)
|
||||||
|
runtime.Notify("RegisterDomain", name)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +524,7 @@ func deleteRecords(ctx storage.Context, name string, typ RecordType) {
|
||||||
storage.Delete(ctx, r)
|
storage.Delete(ctx, r)
|
||||||
}
|
}
|
||||||
updateSoaSerial(ctx, tokenID)
|
updateSoaSerial(ctx, tokenID)
|
||||||
|
runtime.Notify("DeleteRecords", name, typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteDomain deletes the domain with the given name.
|
// DeleteDomain deletes the domain with the given name.
|
||||||
|
@ -549,6 +551,7 @@ func deleteDomain(ctx storage.Context, name string) {
|
||||||
deleteRecords(ctx, name, A)
|
deleteRecords(ctx, name, A)
|
||||||
deleteRecords(ctx, name, AAAA)
|
deleteRecords(ctx, name, AAAA)
|
||||||
storage.Delete(ctx, nameKey)
|
storage.Delete(ctx, nameKey)
|
||||||
|
runtime.Notify("DeleteDomain", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve resolves given name (not more then three redirects are allowed).
|
// Resolve resolves given name (not more then three redirects are allowed).
|
||||||
|
@ -736,6 +739,7 @@ func storeRecord(ctx storage.Context, recordKey []byte, name string, typ RecordT
|
||||||
}
|
}
|
||||||
recBytes := std.Serialize(rs)
|
recBytes := std.Serialize(rs)
|
||||||
storage.Put(ctx, recordKey, recBytes)
|
storage.Put(ctx, recordKey, recBytes)
|
||||||
|
runtime.Notify("AddRecord", name, typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
// putSoaRecord stores soa domain record.
|
// putSoaRecord stores soa domain record.
|
||||||
|
@ -756,6 +760,7 @@ func putSoaRecord(ctx storage.Context, name, email string, refresh, retry, expir
|
||||||
}
|
}
|
||||||
recBytes := std.Serialize(rs)
|
recBytes := std.Serialize(rs)
|
||||||
storage.Put(ctx, recordKey, recBytes)
|
storage.Put(ctx, recordKey, recBytes)
|
||||||
|
runtime.Notify("AddRecord", name, SOA)
|
||||||
}
|
}
|
||||||
|
|
||||||
// putCnameRecord stores CNAME domain record.
|
// putCnameRecord stores CNAME domain record.
|
||||||
|
@ -772,6 +777,7 @@ func putCnameRecord(ctx storage.Context, name, data string) {
|
||||||
}
|
}
|
||||||
recBytes := std.Serialize(rs)
|
recBytes := std.Serialize(rs)
|
||||||
storage.Put(ctx, recordKey, recBytes)
|
storage.Put(ctx, recordKey, recBytes)
|
||||||
|
runtime.Notify("AddRecord", name, CNAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSoaSerial stores soa domain record.
|
// updateSoaSerial stores soa domain record.
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
package nameservice
|
package nameservice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
|
@ -13,8 +15,37 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RegisterDomainEvent represents "RegisterDomain" event emitted by the contract.
|
||||||
|
type RegisterDomainEvent struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRecordEvent represents "AddRecord" event emitted by the contract.
|
||||||
|
type AddRecordEvent struct {
|
||||||
|
Name string
|
||||||
|
Type *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRecordEvent represents "SetRecord" event emitted by the contract.
|
||||||
|
type SetRecordEvent struct {
|
||||||
|
Name string
|
||||||
|
Type *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRecordsEvent represents "DeleteRecords" event emitted by the contract.
|
||||||
|
type DeleteRecordsEvent struct {
|
||||||
|
Name string
|
||||||
|
Type *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteDomainEvent represents "DeleteDomain" event emitted by the contract.
|
||||||
|
type DeleteDomainEvent struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
// Invoker is used by ContractReader to call various safe methods.
|
// Invoker is used by ContractReader to call various safe methods.
|
||||||
type Invoker interface {
|
type Invoker interface {
|
||||||
nep11.Invoker
|
nep11.Invoker
|
||||||
|
@ -356,3 +387,326 @@ func (c *Contract) UpdateSOATransaction(name string, email string, refresh *big.
|
||||||
func (c *Contract) UpdateSOAUnsigned(name string, email string, refresh *big.Int, retry *big.Int, expire *big.Int, ttl *big.Int) (*transaction.Transaction, error) {
|
func (c *Contract) UpdateSOAUnsigned(name string, email string, refresh *big.Int, retry *big.Int, expire *big.Int, ttl *big.Int) (*transaction.Transaction, error) {
|
||||||
return c.actor.MakeUnsignedCall(c.hash, "updateSOA", nil, name, email, refresh, retry, expire, ttl)
|
return c.actor.MakeUnsignedCall(c.hash, "updateSOA", nil, name, email, refresh, retry, expire, ttl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterDomainEventsFromApplicationLog retrieves a set of all emitted events
|
||||||
|
// with "RegisterDomain" name from the provided [result.ApplicationLog].
|
||||||
|
func RegisterDomainEventsFromApplicationLog(log *result.ApplicationLog) ([]*RegisterDomainEvent, error) {
|
||||||
|
if log == nil {
|
||||||
|
return nil, errors.New("nil application log")
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []*RegisterDomainEvent
|
||||||
|
for i, ex := range log.Executions {
|
||||||
|
for j, e := range ex.Events {
|
||||||
|
if e.Name != "RegisterDomain" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
event := new(RegisterDomainEvent)
|
||||||
|
err := event.FromStackItem(e.Item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to deserialize RegisterDomainEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
|
||||||
|
}
|
||||||
|
res = append(res, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStackItem converts provided [stackitem.Array] to RegisterDomainEvent or
|
||||||
|
// returns an error if it's not possible to do to so.
|
||||||
|
func (e *RegisterDomainEvent) FromStackItem(item *stackitem.Array) error {
|
||||||
|
if item == nil {
|
||||||
|
return errors.New("nil item")
|
||||||
|
}
|
||||||
|
arr, ok := item.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("not an array")
|
||||||
|
}
|
||||||
|
if len(arr) != 1 {
|
||||||
|
return errors.New("wrong number of structure elements")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
index = -1
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
index++
|
||||||
|
e.Name, err = func(item stackitem.Item) (string, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return "", errors.New("not a UTF-8 string")
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
}(arr[index])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRecordEventsFromApplicationLog retrieves a set of all emitted events
|
||||||
|
// with "AddRecord" name from the provided [result.ApplicationLog].
|
||||||
|
func AddRecordEventsFromApplicationLog(log *result.ApplicationLog) ([]*AddRecordEvent, error) {
|
||||||
|
if log == nil {
|
||||||
|
return nil, errors.New("nil application log")
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []*AddRecordEvent
|
||||||
|
for i, ex := range log.Executions {
|
||||||
|
for j, e := range ex.Events {
|
||||||
|
if e.Name != "AddRecord" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
event := new(AddRecordEvent)
|
||||||
|
err := event.FromStackItem(e.Item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to deserialize AddRecordEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
|
||||||
|
}
|
||||||
|
res = append(res, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStackItem converts provided [stackitem.Array] to AddRecordEvent or
|
||||||
|
// returns an error if it's not possible to do to so.
|
||||||
|
func (e *AddRecordEvent) FromStackItem(item *stackitem.Array) error {
|
||||||
|
if item == nil {
|
||||||
|
return errors.New("nil item")
|
||||||
|
}
|
||||||
|
arr, ok := item.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("not an array")
|
||||||
|
}
|
||||||
|
if len(arr) != 2 {
|
||||||
|
return errors.New("wrong number of structure elements")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
index = -1
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
index++
|
||||||
|
e.Name, err = func(item stackitem.Item) (string, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return "", errors.New("not a UTF-8 string")
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
}(arr[index])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
e.Type, err = arr[index].TryInteger()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRecordEventsFromApplicationLog retrieves a set of all emitted events
|
||||||
|
// with "SetRecord" name from the provided [result.ApplicationLog].
|
||||||
|
func SetRecordEventsFromApplicationLog(log *result.ApplicationLog) ([]*SetRecordEvent, error) {
|
||||||
|
if log == nil {
|
||||||
|
return nil, errors.New("nil application log")
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []*SetRecordEvent
|
||||||
|
for i, ex := range log.Executions {
|
||||||
|
for j, e := range ex.Events {
|
||||||
|
if e.Name != "SetRecord" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
event := new(SetRecordEvent)
|
||||||
|
err := event.FromStackItem(e.Item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to deserialize SetRecordEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
|
||||||
|
}
|
||||||
|
res = append(res, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStackItem converts provided [stackitem.Array] to SetRecordEvent or
|
||||||
|
// returns an error if it's not possible to do to so.
|
||||||
|
func (e *SetRecordEvent) FromStackItem(item *stackitem.Array) error {
|
||||||
|
if item == nil {
|
||||||
|
return errors.New("nil item")
|
||||||
|
}
|
||||||
|
arr, ok := item.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("not an array")
|
||||||
|
}
|
||||||
|
if len(arr) != 2 {
|
||||||
|
return errors.New("wrong number of structure elements")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
index = -1
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
index++
|
||||||
|
e.Name, err = func(item stackitem.Item) (string, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return "", errors.New("not a UTF-8 string")
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
}(arr[index])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
e.Type, err = arr[index].TryInteger()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRecordsEventsFromApplicationLog retrieves a set of all emitted events
|
||||||
|
// with "DeleteRecords" name from the provided [result.ApplicationLog].
|
||||||
|
func DeleteRecordsEventsFromApplicationLog(log *result.ApplicationLog) ([]*DeleteRecordsEvent, error) {
|
||||||
|
if log == nil {
|
||||||
|
return nil, errors.New("nil application log")
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []*DeleteRecordsEvent
|
||||||
|
for i, ex := range log.Executions {
|
||||||
|
for j, e := range ex.Events {
|
||||||
|
if e.Name != "DeleteRecords" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
event := new(DeleteRecordsEvent)
|
||||||
|
err := event.FromStackItem(e.Item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to deserialize DeleteRecordsEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
|
||||||
|
}
|
||||||
|
res = append(res, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStackItem converts provided [stackitem.Array] to DeleteRecordsEvent or
|
||||||
|
// returns an error if it's not possible to do to so.
|
||||||
|
func (e *DeleteRecordsEvent) FromStackItem(item *stackitem.Array) error {
|
||||||
|
if item == nil {
|
||||||
|
return errors.New("nil item")
|
||||||
|
}
|
||||||
|
arr, ok := item.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("not an array")
|
||||||
|
}
|
||||||
|
if len(arr) != 2 {
|
||||||
|
return errors.New("wrong number of structure elements")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
index = -1
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
index++
|
||||||
|
e.Name, err = func(item stackitem.Item) (string, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return "", errors.New("not a UTF-8 string")
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
}(arr[index])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
e.Type, err = arr[index].TryInteger()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteDomainEventsFromApplicationLog retrieves a set of all emitted events
|
||||||
|
// with "DeleteDomain" name from the provided [result.ApplicationLog].
|
||||||
|
func DeleteDomainEventsFromApplicationLog(log *result.ApplicationLog) ([]*DeleteDomainEvent, error) {
|
||||||
|
if log == nil {
|
||||||
|
return nil, errors.New("nil application log")
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []*DeleteDomainEvent
|
||||||
|
for i, ex := range log.Executions {
|
||||||
|
for j, e := range ex.Events {
|
||||||
|
if e.Name != "DeleteDomain" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
event := new(DeleteDomainEvent)
|
||||||
|
err := event.FromStackItem(e.Item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to deserialize DeleteDomainEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
|
||||||
|
}
|
||||||
|
res = append(res, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStackItem converts provided [stackitem.Array] to DeleteDomainEvent or
|
||||||
|
// returns an error if it's not possible to do to so.
|
||||||
|
func (e *DeleteDomainEvent) FromStackItem(item *stackitem.Array) error {
|
||||||
|
if item == nil {
|
||||||
|
return errors.New("nil item")
|
||||||
|
}
|
||||||
|
arr, ok := item.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("not an array")
|
||||||
|
}
|
||||||
|
if len(arr) != 1 {
|
||||||
|
return errors.New("wrong number of structure elements")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
index = -1
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
index++
|
||||||
|
e.Name, err = func(item stackitem.Item) (string, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return "", errors.New("not a UTF-8 string")
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
}(arr[index])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field Name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
||||||
|
@ -125,19 +126,28 @@ func TestNNSRegister(t *testing.T) {
|
||||||
"test-domain.com", acc.ScriptHash(),
|
"test-domain.com", acc.ScriptHash(),
|
||||||
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
})
|
})
|
||||||
c3.Invoke(t, true, "register",
|
expected := stackitem.NewArray([]stackitem.Item{
|
||||||
|
stackitem.NewByteArray([]byte("testdomain.com")),
|
||||||
|
})
|
||||||
|
tx := c3.Invoke(t, true, "register",
|
||||||
"testdomain.com", acc.ScriptHash(),
|
"testdomain.com", acc.ScriptHash(),
|
||||||
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
"myemail@frostfs.info", refresh, retry, expire, ttl)
|
||||||
|
c.CheckTxNotificationEvent(t, tx, -1, state.NotificationEvent{ScriptHash: c.Hash, Name: "RegisterDomain", Item: expected})
|
||||||
|
|
||||||
b := c.TopBlock(t)
|
b := c.TopBlock(t)
|
||||||
expected := stackitem.NewArray([]stackitem.Item{stackitem.NewBuffer(
|
expected = stackitem.NewArray([]stackitem.Item{stackitem.NewBuffer(
|
||||||
[]byte(fmt.Sprintf("testdomain.com myemail@frostfs.info %d %d %d %d %d",
|
[]byte(fmt.Sprintf("testdomain.com myemail@frostfs.info %d %d %d %d %d",
|
||||||
b.Timestamp, refresh, retry, expire, ttl)))})
|
b.Timestamp, refresh, retry, expire, ttl)))})
|
||||||
c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.SOA))
|
c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.SOA))
|
||||||
|
|
||||||
cAcc := c.WithSigners(acc)
|
cAcc := c.WithSigners(acc)
|
||||||
cAcc.Invoke(t, stackitem.Null{}, "addRecord",
|
|
||||||
|
expected = stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray([]byte("testdomain.com")),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(nns.TXT)))})
|
||||||
|
tx = cAcc.Invoke(t, stackitem.Null{}, "addRecord",
|
||||||
"testdomain.com", int64(nns.TXT), "first TXT record")
|
"testdomain.com", int64(nns.TXT), "first TXT record")
|
||||||
|
c.CheckTxNotificationEvent(t, tx, 0, state.NotificationEvent{ScriptHash: c.Hash, Name: "AddRecord", Item: expected})
|
||||||
|
|
||||||
cAcc.InvokeFail(t, "record already exists", "addRecord",
|
cAcc.InvokeFail(t, "record already exists", "addRecord",
|
||||||
"testdomain.com", int64(nns.TXT), "first TXT record")
|
"testdomain.com", int64(nns.TXT), "first TXT record")
|
||||||
cAcc.Invoke(t, stackitem.Null{}, "addRecord",
|
cAcc.Invoke(t, stackitem.Null{}, "addRecord",
|
||||||
|
@ -149,14 +159,34 @@ func TestNNSRegister(t *testing.T) {
|
||||||
})
|
})
|
||||||
c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.TXT))
|
c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.TXT))
|
||||||
|
|
||||||
cAcc.Invoke(t, stackitem.Null{}, "setRecord",
|
expected = stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray([]byte("testdomain.com")),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(nns.TXT)))})
|
||||||
|
tx = cAcc.Invoke(t, stackitem.Null{}, "setRecord",
|
||||||
"testdomain.com", int64(nns.TXT), int64(0), "replaced first")
|
"testdomain.com", int64(nns.TXT), int64(0), "replaced first")
|
||||||
|
c.CheckTxNotificationEvent(t, tx, 0, state.NotificationEvent{ScriptHash: c.Hash, Name: "AddRecord", Item: expected})
|
||||||
|
|
||||||
expected = stackitem.NewArray([]stackitem.Item{
|
expected = stackitem.NewArray([]stackitem.Item{
|
||||||
stackitem.NewByteArray([]byte("replaced first")),
|
stackitem.NewByteArray([]byte("replaced first")),
|
||||||
stackitem.NewByteArray([]byte("second TXT record")),
|
stackitem.NewByteArray([]byte("second TXT record")),
|
||||||
})
|
})
|
||||||
c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.TXT))
|
c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.TXT))
|
||||||
|
|
||||||
|
tx = cAcc.Invoke(t, stackitem.Null{}, "deleteRecords", "testdomain.com", int64(nns.TXT))
|
||||||
|
expected = stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray([]byte("testdomain.com")),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(nns.TXT)))})
|
||||||
|
c.CheckTxNotificationEvent(t, tx, 0, state.NotificationEvent{ScriptHash: c.Hash, Name: "DeleteRecords", Item: expected})
|
||||||
|
|
||||||
|
c.Invoke(t, stackitem.Null{}, "getRecords", "testdomain.com", int64(nns.TXT))
|
||||||
|
|
||||||
|
tx = cAcc.Invoke(t, stackitem.Null{}, "deleteDomain", "testdomain.com")
|
||||||
|
expected = stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray([]byte("testdomain.com")),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(nns.CNAME)))})
|
||||||
|
c.CheckTxNotificationEvent(t, tx, 0, state.NotificationEvent{ScriptHash: c.Hash, Name: "DeleteRecords", Item: expected})
|
||||||
|
|
||||||
|
expected = stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray([]byte("testdomain.com"))})
|
||||||
|
c.CheckTxNotificationEvent(t, tx, 4, state.NotificationEvent{ScriptHash: c.Hash, Name: "DeleteDomain", Item: expected})
|
||||||
|
|
||||||
|
c.InvokeFail(t, "token not found", "getRecords", "testdomain.com", int64(nns.SOA))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGlobalDomain(t *testing.T) {
|
func TestGlobalDomain(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue