core: add trigger types as constants. Closes #509

This commit is contained in:
Vsevolod Brekelov 2019-12-04 12:27:04 +03:00
parent 2b0ad6146d
commit ff15a0acfd
5 changed files with 57 additions and 17 deletions

View file

@ -16,6 +16,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
"github.com/CityOfZion/neo-go/pkg/io"
"github.com/CityOfZion/neo-go/pkg/smartcontract"
"github.com/CityOfZion/neo-go/pkg/smartcontract/trigger"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/CityOfZion/neo-go/pkg/vm"
"github.com/pkg/errors"
@ -487,7 +488,7 @@ func (bc *Blockchain) storeBlock(block *Block) error {
}
chainState.contracts[contract.ScriptHash()] = contract
case *transaction.InvocationTX:
systemInterop := newInteropContext(0x10, bc, chainState.store, block, tx)
systemInterop := newInteropContext(trigger.Application, bc, chainState.store, block, tx)
v := bc.spawnVMWithInterops(systemInterop)
v.SetCheckedHash(tx.VerificationHash().Bytes())
v.LoadScript(t.Script)
@ -530,7 +531,7 @@ func (bc *Blockchain) storeBlock(block *Block) error {
}
aer := &AppExecResult{
TxHash: tx.Hash(),
Trigger: 0x10,
Trigger: trigger.Application,
VMState: v.State(),
GasConsumed: util.Fixed8(0),
Stack: v.Stack("estack"),
@ -1418,7 +1419,7 @@ func (bc *Blockchain) spawnVMWithInterops(interopCtx *interopContext) *vm.VM {
// GetTestVM returns a VM and a Store setup for a test run of some sort of code.
func (bc *Blockchain) GetTestVM() (*vm.VM, storage.Store) {
tmpStore := storage.NewMemCachedStore(bc.store)
systemInterop := newInteropContext(0x10, bc, tmpStore, nil, nil)
systemInterop := newInteropContext(trigger.Application, bc, tmpStore, nil, nil)
vm := bc.spawnVMWithInterops(systemInterop)
return vm, tmpStore
}
@ -1482,7 +1483,7 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *Block
}
sort.Slice(hashes, func(i, j int) bool { return hashes[i].Less(hashes[j]) })
sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) })
interopCtx := newInteropContext(0, bc, bc.store, block, t)
interopCtx := newInteropContext(trigger.Verification, bc, bc.store, block, t)
for i := 0; i < len(hashes); i++ {
err := bc.verifyHashAgainstScript(hashes[i], witnesses[i], t.VerificationHash(), interopCtx)
if err != nil {
@ -1502,7 +1503,7 @@ func (bc *Blockchain) verifyBlockWitnesses(block *Block, prevHeader *Header) err
} else {
hash = prevHeader.NextConsensus
}
interopCtx := newInteropContext(0, bc, bc.store, nil, nil)
interopCtx := newInteropContext(trigger.Verification, bc, bc.store, nil, nil)
return bc.verifyHashAgainstScript(hash, block.Script, block.VerificationHash(), interopCtx)
}

View file

@ -8,6 +8,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
"github.com/CityOfZion/neo-go/pkg/smartcontract"
"github.com/CityOfZion/neo-go/pkg/smartcontract/trigger"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/CityOfZion/neo-go/pkg/vm"
gherr "github.com/pkg/errors"
@ -429,7 +430,7 @@ func (ic *interopContext) storageFind(v *vm.VM) error {
// evaluation stack, does a lot of checks and returns ContractState if it
// succeeds.
func (ic *interopContext) createContractStateFromVM(v *vm.VM) (*ContractState, error) {
if ic.trigger != 0x10 {
if ic.trigger != trigger.Application {
return nil, errors.New("can't create contract when not triggered by an application")
}
script := v.Estack().Pop().Bytes()
@ -551,7 +552,7 @@ func (ic *interopContext) contractMigrate(v *vm.VM) error {
// assetCreate creates an asset.
func (ic *interopContext) assetCreate(v *vm.VM) error {
if ic.trigger != 0x10 {
if ic.trigger != trigger.Application {
return errors.New("can't create asset when not triggered by an application")
}
atype := transaction.AssetType(v.Estack().Pop().BigInt().Int64())
@ -717,7 +718,7 @@ func (ic *interopContext) assetGetPrecision(v *vm.VM) error {
// assetRenew updates asset expiration date.
func (ic *interopContext) assetRenew(v *vm.VM) error {
if ic.trigger != 0x10 {
if ic.trigger != trigger.Application {
return errors.New("can't create asset when not triggered by an application")
}
asInterface := v.Estack().Pop().Value()

View file

@ -8,6 +8,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
"github.com/CityOfZion/neo-go/pkg/smartcontract"
"github.com/CityOfZion/neo-go/pkg/smartcontract/trigger"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/CityOfZion/neo-go/pkg/vm"
"github.com/stretchr/testify/require"
@ -42,7 +43,7 @@ func TestHeaderGetVersion(t *testing.T) {
func TestHeaderGetVersion_Negative(t *testing.T) {
v := vm.New()
block := newDumbBlock()
context := newInteropContext(0x10, newTestChain(t), storage.NewMemoryStore(), block, nil)
context := newInteropContext(trigger.Application, newTestChain(t), storage.NewMemoryStore(), block, nil)
v.Estack().PushVal(vm.NewBoolItem(false))
err := context.headerGetVersion(v)
@ -325,7 +326,7 @@ func TestAssetGetPrecision(t *testing.T) {
func createVMAndPushBlock(t *testing.T) (*vm.VM, *Block, *interopContext) {
v := vm.New()
block := newDumbBlock()
context := newInteropContext(0x10, newTestChain(t), storage.NewMemoryStore(), block, nil)
context := newInteropContext(trigger.Application, newTestChain(t), storage.NewMemoryStore(), block, nil)
v.Estack().PushVal(vm.NewInteropItem(block))
return v, block, context
}
@ -354,7 +355,7 @@ func createVMAndAssetState(t *testing.T) (*vm.VM, *AssetState, *interopContext)
IsFrozen: false,
}
context := newInteropContext(0x10, newTestChain(t), storage.NewMemoryStore(), nil, nil)
context := newInteropContext(trigger.Application, newTestChain(t), storage.NewMemoryStore(), nil, nil)
return v, assetState, context
}
@ -373,7 +374,7 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *ContractState, *interopCon
scriptHash: randomUint160(),
}
context := newInteropContext(0x10, newTestChain(t), storage.NewMemoryStore(), nil, nil)
context := newInteropContext(trigger.Application, newTestChain(t), storage.NewMemoryStore(), nil, nil)
return v, contractState, context
}
@ -387,7 +388,7 @@ func createVMAndAccState(t *testing.T) (*vm.VM, *AccountState, *interopContext)
accountState.Votes = []*keys.PublicKey{key}
require.NoError(t, err)
context := newInteropContext(0x10, newTestChain(t), storage.NewMemoryStore(), nil, nil)
context := newInteropContext(trigger.Application, newTestChain(t), storage.NewMemoryStore(), nil, nil)
return v, accountState, context
}
@ -416,6 +417,6 @@ func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interopCont
tx.Attributes = attributes
tx.Inputs = inputs
tx.Outputs = outputs
context := newInteropContext(0x10, newTestChain(t), storage.NewMemoryStore(), nil, tx)
context := newInteropContext(trigger.Application, newTestChain(t), storage.NewMemoryStore(), nil, tx)
return v, tx, context
}

View file

@ -8,6 +8,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
"github.com/CityOfZion/neo-go/pkg/smartcontract/trigger"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/CityOfZion/neo-go/pkg/vm"
gherr "github.com/pkg/errors"
@ -393,7 +394,7 @@ func (ic *interopContext) checkStorageContext(stc *StorageContext) error {
// storageDelete deletes stored key-value pair.
func (ic *interopContext) storageDelete(v *vm.VM) error {
if ic.trigger != 0x10 && ic.trigger != 0x11 {
if ic.trigger != trigger.Application && ic.trigger != trigger.ApplicationR {
return errors.New("can't delete when the trigger is not application")
}
stcInterface := v.Estack().Pop().Value()
@ -464,7 +465,7 @@ func (ic *interopContext) storageGetReadOnlyContext(v *vm.VM) error {
}
func (ic *interopContext) putWithContextAndFlags(stc *StorageContext, key []byte, value []byte, isConst bool) error {
if ic.trigger != 0x10 && ic.trigger != 0x11 {
if ic.trigger != trigger.Application && ic.trigger != trigger.ApplicationR {
return errors.New("can't delete when the trigger is not application")
}
if len(key) > MaxStorageKeyLen {
@ -538,7 +539,7 @@ func (ic *interopContext) storageContextAsReadOnly(v *vm.VM) error {
// contractDestroy destroys a contract.
func (ic *interopContext) contractDestroy(v *vm.VM) error {
if ic.trigger != 0x10 {
if ic.trigger != trigger.Application {
return errors.New("can't destroy contract when not triggered by application")
}
hash := getContextScriptHash(v, 0)

View file

@ -0,0 +1,36 @@
package trigger
// Trigger typed used in C# reference node: https://github.com/neo-project/neo/blob/c64748ecbac3baeb8045b16af0d518398a6ced24/neo/SmartContract/TriggerType.cs#L3
const (
// 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 entry point of the contract will be invoked if the contract is triggered by Verification:
// main(...);
// The entry point of the contract must be able to handle this type of invocation.
Verification = 0x00
// The verificationR trigger indicates that the contract is being invoked as a verification function because it is specified as a target of an output of the transaction.
// The verification function accepts no parameter, and should return a boolean value that indicates the validity of the transaction.
// The entry point of the contract will be invoked if the contract is triggered by VerificationR:
// main("receiving", new object[0]);
// The receiving function should have the following signature:
// public bool receiving()
// The receiving function will be invoked automatically when a contract is receiving assets from a transfer.
VerificationR = 0x01
// The application trigger indicates that the contract is being invoked as an application function.
// The application function can accept multiple parameters, change the states of the blockchain, and return any type of value.
// The contract can have any form of entry point, but we recommend that all contracts should have the following entry point:
// public byte[] main(string operation, params object[] args)
// The functions can be invoked by creating an InvocationTransaction.
Application = 0x10
// The ApplicationR trigger indicates that the default function received of the contract is being invoked because it is specified as a target of an output of the transaction.
// The received function accepts no parameter, changes the states of the blockchain, and returns any type of value.
// The entry point of the contract will be invoked if the contract is triggered by ApplicationR:
// main("received", new object[0]);
// The received function should have the following signature:
// public byte[] received()
// The received function will be invoked automatically when a contract is receiving assets from a transfer.
ApplicationR = 0x11
)