native: emit Designation event on role update

This commit is contained in:
Evgeniy Stratonikov 2021-04-29 14:12:48 +03:00
parent 933743ce87
commit 8c3998593e
3 changed files with 34 additions and 3 deletions

View file

@ -4,6 +4,7 @@ import (
"encoding/binary"
"errors"
"math"
"math/big"
"sort"
"sync/atomic"
@ -57,6 +58,9 @@ const (
// maxNodeCount is the maximum number of nodes to set the role for.
maxNodeCount = 32
// DesignationEventName is the name of a designation event.
DesignationEventName = "Designation"
)
// Various errors.
@ -88,9 +92,13 @@ func newDesignate(p2pSigExtensionsEnabled bool) *Designate {
desc = newDescriptor("designateAsRole", smartcontract.VoidType,
manifest.NewParameter("role", smartcontract.IntegerType),
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.AddEvent(DesignationEventName,
manifest.NewParameter("Role", smartcontract.IntegerType),
manifest.NewParameter("BlockIndex", smartcontract.IntegerType))
return s
}
@ -319,7 +327,20 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r noderoles.Role, pubs
}
sort.Sort(pubs)
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) {

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))
if ok {
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 {
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.
func DesignateAsRole(r Role, pubs []interop.PublicKey) {
contract.Call(interop.Hash160(Hash), "designateAsRole",
contract.States, r, pubs)
contract.States|contract.AllowNotify, r, pubs)
}