trigger/core: split System trigger into OnPerist and PostPersist

Follow neo-project/neo#2022.
This commit is contained in:
Roman Khimov 2020-10-29 19:14:49 +03:00
parent 044786b995
commit eaa260474f
12 changed files with 49 additions and 31 deletions

View file

@ -565,7 +565,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
writeBuf.Reset() writeBuf.Reset()
if block.Index > 0 { if block.Index > 0 {
aer, err := bc.runPersist(bc.contracts.GetPersistScript(), block, cache) aer, err := bc.runPersist(bc.contracts.GetPersistScript(), block, cache, trigger.OnPersist)
if err != nil { if err != nil {
return fmt.Errorf("onPersist failed: %w", err) return fmt.Errorf("onPersist failed: %w", err)
} }
@ -635,7 +635,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
} }
} }
aer, err := bc.runPersist(bc.contracts.GetPostPersistScript(), block, cache) aer, err := bc.runPersist(bc.contracts.GetPostPersistScript(), block, cache, trigger.PostPersist)
if err != nil { if err != nil {
return fmt.Errorf("postPersist failed: %w", err) return fmt.Errorf("postPersist failed: %w", err)
} }
@ -704,8 +704,8 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
return nil return nil
} }
func (bc *Blockchain) runPersist(script []byte, block *block.Block, cache *dao.Cached) (*state.AppExecResult, error) { func (bc *Blockchain) runPersist(script []byte, block *block.Block, cache *dao.Cached, trig trigger.Type) (*state.AppExecResult, error) {
systemInterop := bc.newInteropContext(trigger.System, cache, block, nil) systemInterop := bc.newInteropContext(trig, cache, block, nil)
v := systemInterop.SpawnVM() v := systemInterop.SpawnVM()
v.LoadScriptWithFlags(script, smartcontract.AllowModifyStates|smartcontract.AllowCall) v.LoadScriptWithFlags(script, smartcontract.AllowModifyStates|smartcontract.AllowCall)
v.SetPriceGetter(getPrice) v.SetPriceGetter(getPrice)
@ -719,7 +719,7 @@ func (bc *Blockchain) runPersist(script []byte, block *block.Block, cache *dao.C
} }
return &state.AppExecResult{ return &state.AppExecResult{
TxHash: block.Hash(), // application logs can be retrieved by block hash TxHash: block.Hash(), // application logs can be retrieved by block hash
Trigger: trigger.System, Trigger: trig,
VMState: v.State(), VMState: v.State(),
GasConsumed: v.GasConsumed(), GasConsumed: v.GasConsumed(),
Stack: v.Estack().ToArray(), Stack: v.Estack().ToArray(),

View file

@ -116,8 +116,8 @@ func (cs *Contracts) GetPostPersistScript() []byte {
} }
func postPersistBase(ic *interop.Context) error { func postPersistBase(ic *interop.Context) error {
if ic.Trigger != trigger.System { if ic.Trigger != trigger.PostPersist {
return errors.New("'postPersist' should be trigered by system") return errors.New("postPersist must be trigered by system")
} }
return nil return nil
} }

View file

@ -261,8 +261,8 @@ func (c *nep5TokenNative) addTokens(ic *interop.Context, h util.Uint160, amount
} }
func (c *nep5TokenNative) OnPersist(ic *interop.Context) error { func (c *nep5TokenNative) OnPersist(ic *interop.Context) error {
if ic.Trigger != trigger.System { if ic.Trigger != trigger.OnPersist {
return errors.New("onPersist should be triggerred by system") return errors.New("onPersist must be triggerred by system")
} }
return nil return nil
} }

View file

@ -39,7 +39,7 @@ func (tn *testNative) Metadata() *interop.ContractMD {
} }
func (tn *testNative) OnPersist(ic *interop.Context, _ []stackitem.Item) stackitem.Item { func (tn *testNative) OnPersist(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
if ic.Trigger != trigger.System { if ic.Trigger != trigger.OnPersist {
panic("invalid trigger") panic("invalid trigger")
} }
select { select {

View file

@ -78,7 +78,7 @@ func TestDesignate_DesignateAsRole(t *testing.T) {
des := bc.contracts.Designate des := bc.contracts.Designate
tx := transaction.New(netmode.UnitTestNet, []byte{}, 0) tx := transaction.New(netmode.UnitTestNet, []byte{}, 0)
ic := bc.newInteropContext(trigger.System, bc.dao, nil, tx) ic := bc.newInteropContext(trigger.OnPersist, bc.dao, nil, tx)
ic.SpawnVM() ic.SpawnVM()
ic.VM.LoadScript([]byte{byte(opcode.RET)}) ic.VM.LoadScript([]byte{byte(opcode.RET)})

View file

@ -30,7 +30,7 @@ func TestNEO_Vote(t *testing.T) {
neo := bc.contracts.NEO neo := bc.contracts.NEO
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
ic := bc.newInteropContext(trigger.System, bc.dao, nil, tx) ic := bc.newInteropContext(trigger.Application, bc.dao, nil, tx)
ic.SpawnVM() ic.SpawnVM()
ic.Block = bc.newBlock(tx) ic.Block = bc.newBlock(tx)
@ -124,7 +124,7 @@ func TestNEO_SetGasPerBlock(t *testing.T) {
neo := bc.contracts.NEO neo := bc.contracts.NEO
tx := transaction.New(netmode.UnitTestNet, []byte{}, 0) tx := transaction.New(netmode.UnitTestNet, []byte{}, 0)
ic := bc.newInteropContext(trigger.System, bc.dao, nil, tx) ic := bc.newInteropContext(trigger.Application, bc.dao, nil, tx)
ic.SpawnVM() ic.SpawnVM()
ic.VM.LoadScript([]byte{byte(opcode.RET)}) ic.VM.LoadScript([]byte{byte(opcode.RET)})
@ -183,7 +183,7 @@ func TestNEO_CalculateBonus(t *testing.T) {
neo := bc.contracts.NEO neo := bc.contracts.NEO
tx := transaction.New(netmode.UnitTestNet, []byte{}, 0) tx := transaction.New(netmode.UnitTestNet, []byte{}, 0)
ic := bc.newInteropContext(trigger.System, bc.dao, nil, tx) ic := bc.newInteropContext(trigger.Application, bc.dao, nil, tx)
ic.SpawnVM() ic.SpawnVM()
ic.VM.LoadScript([]byte{byte(opcode.RET)}) ic.VM.LoadScript([]byte{byte(opcode.RET)})
t.Run("Invalid", func(t *testing.T) { t.Run("Invalid", func(t *testing.T) {

View file

@ -116,7 +116,7 @@ func TestMarshalUnmarshalJSONAppExecResult(t *testing.T) {
t.Run("positive, block", func(t *testing.T) { t.Run("positive, block", func(t *testing.T) {
appExecResult := &AppExecResult{ appExecResult := &AppExecResult{
TxHash: random.Uint256(), TxHash: random.Uint256(),
Trigger: trigger.System, Trigger: trigger.OnPersist,
VMState: vm.HaltState, VMState: vm.HaltState,
GasConsumed: 10, GasConsumed: 10,
Stack: []stackitem.Item{}, Stack: []stackitem.Item{},

View file

@ -8,7 +8,8 @@ import "github.com/nspcc-dev/neo-go/pkg/interop"
// Trigger values to compare with GetTrigger result. // Trigger values to compare with GetTrigger result.
const ( const (
System byte = 0x01 OnPersist byte = 0x01
PostPersist byte = 0x02
Application byte = 0x40 Application byte = 0x40
Verification byte = 0x20 Verification byte = 0x20
) )

View file

@ -770,7 +770,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
data := checkErrGetResult(t, body, false) data := checkErrGetResult(t, body, false)
var res state.AppExecResult var res state.AppExecResult
require.NoError(t, json.Unmarshal(data, &res)) require.NoError(t, json.Unmarshal(data, &res))
require.Equal(t, trigger.System, res.Trigger) require.Equal(t, trigger.PostPersist, res.Trigger)
require.Equal(t, vm.HaltState, res.VMState) require.Equal(t, vm.HaltState, res.VMState)
}) })

View file

@ -9,8 +9,15 @@ type Type byte
// Viable list of supported trigger type constants. // Viable list of supported trigger type constants.
const ( const (
// System is trigger type that indicates that script is being invoke internally by the system. // OnPersist is a trigger type that indicates that script is being invoked
System Type = 0x01 // internally by the system during block persistence (before transaction
// processing).
OnPersist Type = 0x01
// PostPersist is a trigger type that indicates that script is being invoked
// by the system after block persistence (transcation processing) has
// finished.
PostPersist Type = 0x02
// The verification trigger indicates that the contract is being invoked as a verification function. // The verification trigger indicates that the contract is being invoked as a verification function.
// The verification function can accept multiple parameters, and should return a boolean value that indicates the validity of the transaction or block. // The verification function can accept multiple parameters, and should return a boolean value that indicates the validity of the transaction or block.
@ -27,12 +34,12 @@ const (
Application Type = 0x40 Application Type = 0x40
// All represents any trigger type. // All represents any trigger type.
All Type = System | Verification | Application All Type = OnPersist | PostPersist | Verification | Application
) )
// FromString converts string to trigger Type // FromString converts string to trigger Type
func FromString(str string) (Type, error) { func FromString(str string) (Type, error) {
triggers := []Type{System, Verification, Application, All} triggers := []Type{OnPersist, PostPersist, Verification, Application, All}
for _, t := range triggers { for _, t := range triggers {
if t.String() == str { if t.String() == str {
return t, nil return t, nil

View file

@ -8,28 +8,34 @@ func _() {
// An "invalid array index" compiler error signifies that the constant values have changed. // An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again. // Re-run the stringer command to generate them again.
var x [1]struct{} var x [1]struct{}
_ = x[System-1] _ = x[OnPersist-1]
_ = x[PostPersist-2]
_ = x[Verification-32] _ = x[Verification-32]
_ = x[Application-64] _ = x[Application-64]
_ = x[All-97] _ = x[All-99]
} }
const ( const (
_Type_name_0 = "System" _Type_name_0 = "OnPersistPostPersist"
_Type_name_1 = "Verification" _Type_name_1 = "Verification"
_Type_name_2 = "Application" _Type_name_2 = "Application"
_Type_name_3 = "All" _Type_name_3 = "All"
) )
var (
_Type_index_0 = [...]uint8{0, 9, 20}
)
func (i Type) String() string { func (i Type) String() string {
switch { switch {
case i == 1: case 1 <= i && i <= 2:
return _Type_name_0 i -= 1
return _Type_name_0[_Type_index_0[i]:_Type_index_0[i+1]]
case i == 32: case i == 32:
return _Type_name_1 return _Type_name_1
case i == 64: case i == 64:
return _Type_name_2 return _Type_name_2
case i == 97: case i == 99:
return _Type_name_3 return _Type_name_3
default: default:
return "Type(" + strconv.FormatInt(int64(i), 10) + ")" return "Type(" + strconv.FormatInt(int64(i), 10) + ")"

View file

@ -9,7 +9,8 @@ import (
func TestStringer(t *testing.T) { func TestStringer(t *testing.T) {
tests := map[Type]string{ tests := map[Type]string{
System: "System", OnPersist: "OnPersist",
PostPersist: "PostPersist",
Application: "Application", Application: "Application",
Verification: "Verification", Verification: "Verification",
} }
@ -20,7 +21,8 @@ func TestStringer(t *testing.T) {
func TestEncodeBynary(t *testing.T) { func TestEncodeBynary(t *testing.T) {
tests := map[Type]byte{ tests := map[Type]byte{
System: 0x01, OnPersist: 0x01,
PostPersist: 0x02,
Verification: 0x20, Verification: 0x20,
Application: 0x40, Application: 0x40,
} }
@ -31,7 +33,8 @@ func TestEncodeBynary(t *testing.T) {
func TestDecodeBynary(t *testing.T) { func TestDecodeBynary(t *testing.T) {
tests := map[Type]byte{ tests := map[Type]byte{
System: 0x01, OnPersist: 0x01,
PostPersist: 0x02,
Verification: 0x20, Verification: 0x20,
Application: 0x40, Application: 0x40,
} }
@ -42,7 +45,8 @@ func TestDecodeBynary(t *testing.T) {
func TestFromString(t *testing.T) { func TestFromString(t *testing.T) {
testCases := map[string]Type{ testCases := map[string]Type{
"System": System, "OnPersist": OnPersist,
"PostPersist": PostPersist,
"Application": Application, "Application": Application,
"Verification": Verification, "Verification": Verification,
"All": All, "All": All,