Merge pull request #1938 from nspcc-dev/designate-events

native: emit `Designation` event on role update
This commit is contained in:
Roman Khimov 2021-04-29 16:40:32 +03:00 committed by GitHub
commit a34a5c1887
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 3 deletions

View file

@ -4,6 +4,7 @@ import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"math" "math"
"math/big"
"sort" "sort"
"sync/atomic" "sync/atomic"
@ -57,6 +58,9 @@ const (
// maxNodeCount is the maximum number of nodes to set the role for. // maxNodeCount is the maximum number of nodes to set the role for.
maxNodeCount = 32 maxNodeCount = 32
// DesignationEventName is the name of a designation event.
DesignationEventName = "Designation"
) )
// Various errors. // Various errors.
@ -88,9 +92,13 @@ func newDesignate(p2pSigExtensionsEnabled bool) *Designate {
desc = newDescriptor("designateAsRole", smartcontract.VoidType, desc = newDescriptor("designateAsRole", smartcontract.VoidType,
manifest.NewParameter("role", smartcontract.IntegerType), manifest.NewParameter("role", smartcontract.IntegerType),
manifest.NewParameter("nodes", smartcontract.ArrayType)) manifest.NewParameter("nodes", smartcontract.ArrayType))
md = newMethodAndPrice(s.designateAsRole, 1<<15, callflag.States) md = newMethodAndPrice(s.designateAsRole, 1<<15, callflag.States|callflag.AllowNotify)
s.AddMethod(md, desc) s.AddMethod(md, desc)
s.AddEvent(DesignationEventName,
manifest.NewParameter("Role", smartcontract.IntegerType),
manifest.NewParameter("BlockIndex", smartcontract.IntegerType))
return s return s
} }
@ -319,7 +327,20 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r noderoles.Role, pubs
} }
sort.Sort(pubs) sort.Sort(pubs)
s.rolesChangedFlag.Store(true) s.rolesChangedFlag.Store(true)
return ic.DAO.PutStorageItem(s.ID, key, NodeList(pubs).Bytes()) err := ic.DAO.PutStorageItem(s.ID, key, NodeList(pubs).Bytes())
if err != nil {
return err
}
ic.Notifications = append(ic.Notifications, state.NotificationEvent{
ScriptHash: s.Hash,
Name: DesignationEventName,
Item: stackitem.NewArray([]stackitem.Item{
stackitem.NewBigInteger(big.NewInt(int64(r))),
stackitem.NewBigInteger(big.NewInt(int64(ic.Block.Index))),
}),
})
return nil
} }
func (s *Designate) getRole(item stackitem.Item) (noderoles.Role, bool) { func (s *Designate) getRole(item stackitem.Item) (noderoles.Role, bool) {

View file

@ -58,8 +58,18 @@ func (bc *Blockchain) setNodesByRole(t *testing.T, ok bool, r noderoles.Role, no
require.Equal(t, 1, len(aer)) require.Equal(t, 1, len(aer))
if ok { if ok {
require.Equal(t, vm.HaltState, aer[0].VMState) require.Equal(t, vm.HaltState, aer[0].VMState)
require.Equal(t, 1, len(aer[0].Events))
ev := aer[0].Events[0]
require.Equal(t, bc.contracts.Designate.Hash, ev.ScriptHash)
require.Equal(t, native.DesignationEventName, ev.Name)
require.Equal(t, []stackitem.Item{
stackitem.Make(int64(r)),
stackitem.Make(bc.BlockHeight()),
}, ev.Item.Value().([]stackitem.Item))
} else { } else {
require.Equal(t, vm.FaultState, aer[0].VMState) require.Equal(t, vm.FaultState, aer[0].VMState)
require.Equal(t, 0, len(aer[0].Events))
} }
} }

View file

@ -34,5 +34,5 @@ func GetDesignatedByRole(r Role, height uint32) []interop.PublicKey {
// DesignateAsRole represents `designateAsRole` method of RoleManagement native contract. // DesignateAsRole represents `designateAsRole` method of RoleManagement native contract.
func DesignateAsRole(r Role, pubs []interop.PublicKey) { func DesignateAsRole(r Role, pubs []interop.PublicKey) {
contract.Call(interop.Hash160(Hash), "designateAsRole", contract.Call(interop.Hash160(Hash), "designateAsRole",
contract.States, r, pubs) contract.States|contract.AllowNotify, r, pubs)
} }