core: move interopContext to a separate package
This commit is contained in:
parent
90a08986d6
commit
7ffc6c0936
7 changed files with 225 additions and 204 deletions
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
|
@ -667,11 +668,11 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
|
|
||||||
err := v.Run()
|
err := v.Run()
|
||||||
if !v.HasFailed() {
|
if !v.HasFailed() {
|
||||||
_, err := systemInterop.dao.Persist()
|
_, err := systemInterop.DAO.Persist()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to persist invocation results")
|
return errors.Wrap(err, "failed to persist invocation results")
|
||||||
}
|
}
|
||||||
for _, note := range systemInterop.notifications {
|
for _, note := range systemInterop.Notifications {
|
||||||
arr, ok := note.Item.Value().([]vm.StackItem)
|
arr, ok := note.Item.Value().([]vm.StackItem)
|
||||||
if !ok || len(arr) != 4 {
|
if !ok || len(arr) != 4 {
|
||||||
continue
|
continue
|
||||||
|
@ -710,7 +711,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
VMState: v.State(),
|
VMState: v.State(),
|
||||||
GasConsumed: v.GasConsumed(),
|
GasConsumed: v.GasConsumed(),
|
||||||
Stack: v.Estack().ToContractParameters(),
|
Stack: v.Estack().ToContractParameters(),
|
||||||
Events: systemInterop.notifications,
|
Events: systemInterop.Notifications,
|
||||||
}
|
}
|
||||||
err = cache.PutAppExecResult(aer)
|
err = cache.PutAppExecResult(aer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2024,7 +2025,7 @@ func ScriptFromWitness(hash util.Uint160, witness *transaction.Witness) ([]byte,
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyHashAgainstScript verifies given hash against the given witness.
|
// verifyHashAgainstScript verifies given hash against the given witness.
|
||||||
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, checkedHash util.Uint256, interopCtx *interopContext, useKeys bool) error {
|
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, checkedHash util.Uint256, interopCtx *interop.Context, useKeys bool) error {
|
||||||
verification, err := ScriptFromWitness(hash, witness)
|
verification, err := ScriptFromWitness(hash, witness)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2124,6 +2125,6 @@ func (bc *Blockchain) secondsPerBlock() int {
|
||||||
return bc.config.SecondsPerBlock
|
return bc.config.SecondsPerBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interopContext {
|
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interop.Context {
|
||||||
return newInteropContext(trigger, bc, d, block, tx, bc.log)
|
return interop.NewContext(trigger, bc, d, block, tx, bc.log)
|
||||||
}
|
}
|
||||||
|
|
48
pkg/core/interop/context.go
Normal file
48
pkg/core/interop/context.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package interop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
|
"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/smartcontract/trigger"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Context represents context in which interops are executed.
|
||||||
|
type Context struct {
|
||||||
|
Chain blockchainer.Blockchainer
|
||||||
|
Trigger trigger.Type
|
||||||
|
Block *block.Block
|
||||||
|
Tx *transaction.Transaction
|
||||||
|
DAO *dao.Cached
|
||||||
|
Notifications []state.NotificationEvent
|
||||||
|
Log *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContext returns new interop context.
|
||||||
|
func NewContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *Context {
|
||||||
|
dao := dao.NewCached(d)
|
||||||
|
nes := make([]state.NotificationEvent, 0)
|
||||||
|
return &Context{
|
||||||
|
Chain: bc,
|
||||||
|
Trigger: trigger,
|
||||||
|
Block: block,
|
||||||
|
Tx: tx,
|
||||||
|
DAO: dao,
|
||||||
|
Notifications: nes,
|
||||||
|
Log: log,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function binds function name, id with the function itself and price,
|
||||||
|
// it's supposed to be inited once for all interopContexts, so it doesn't use
|
||||||
|
// vm.InteropFuncPrice directly.
|
||||||
|
type Function struct {
|
||||||
|
ID uint32
|
||||||
|
Name string
|
||||||
|
Func func(*Context, *vm.VM) error
|
||||||
|
Price int
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"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/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
@ -37,7 +38,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// headerGetVersion returns version from the header.
|
// headerGetVersion returns version from the header.
|
||||||
func headerGetVersion(ic *interopContext, v *vm.VM) error {
|
func headerGetVersion(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -47,7 +48,7 @@ func headerGetVersion(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// headerGetConsensusData returns consensus data from the header.
|
// headerGetConsensusData returns consensus data from the header.
|
||||||
func headerGetConsensusData(ic *interopContext, v *vm.VM) error {
|
func headerGetConsensusData(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -57,7 +58,7 @@ func headerGetConsensusData(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// headerGetMerkleRoot returns version from the header.
|
// headerGetMerkleRoot returns version from the header.
|
||||||
func headerGetMerkleRoot(ic *interopContext, v *vm.VM) error {
|
func headerGetMerkleRoot(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -67,7 +68,7 @@ func headerGetMerkleRoot(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// headerGetNextConsensus returns version from the header.
|
// headerGetNextConsensus returns version from the header.
|
||||||
func headerGetNextConsensus(ic *interopContext, v *vm.VM) error {
|
func headerGetNextConsensus(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -77,7 +78,7 @@ func headerGetNextConsensus(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetAttributes returns current transaction attributes.
|
// txGetAttributes returns current transaction attributes.
|
||||||
func txGetAttributes(ic *interopContext, v *vm.VM) error {
|
func txGetAttributes(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -95,7 +96,7 @@ func txGetAttributes(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetInputs returns current transaction inputs.
|
// txGetInputs returns current transaction inputs.
|
||||||
func txGetInputs(ic *interopContext, v *vm.VM) error {
|
func txGetInputs(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -113,7 +114,7 @@ func txGetInputs(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetOutputs returns current transaction outputs.
|
// txGetOutputs returns current transaction outputs.
|
||||||
func txGetOutputs(ic *interopContext, v *vm.VM) error {
|
func txGetOutputs(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -131,13 +132,13 @@ func txGetOutputs(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetReferences returns current transaction references.
|
// txGetReferences returns current transaction references.
|
||||||
func txGetReferences(ic *interopContext, v *vm.VM) error {
|
func txGetReferences(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("type mismatch: %T is not a Transaction", txInterface)
|
return fmt.Errorf("type mismatch: %T is not a Transaction", txInterface)
|
||||||
}
|
}
|
||||||
refs, err := ic.bc.References(tx)
|
refs, err := ic.Chain.References(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -159,7 +160,7 @@ func txGetReferences(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetType returns current transaction type.
|
// txGetType returns current transaction type.
|
||||||
func txGetType(ic *interopContext, v *vm.VM) error {
|
func txGetType(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -170,13 +171,13 @@ func txGetType(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetUnspentCoins returns current transaction unspent coins.
|
// txGetUnspentCoins returns current transaction unspent coins.
|
||||||
func txGetUnspentCoins(ic *interopContext, v *vm.VM) error {
|
func txGetUnspentCoins(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("value is not a transaction")
|
return errors.New("value is not a transaction")
|
||||||
}
|
}
|
||||||
ucs, err := ic.dao.GetUnspentCoinState(tx.Hash())
|
ucs, err := ic.DAO.GetUnspentCoinState(tx.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("no unspent coin state found")
|
return errors.New("no unspent coin state found")
|
||||||
}
|
}
|
||||||
|
@ -185,7 +186,7 @@ func txGetUnspentCoins(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetWitnesses returns current transaction witnesses.
|
// txGetWitnesses returns current transaction witnesses.
|
||||||
func txGetWitnesses(ic *interopContext, v *vm.VM) error {
|
func txGetWitnesses(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -203,7 +204,7 @@ func txGetWitnesses(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// invocationTx_GetScript returns invocation script from the current transaction.
|
// invocationTx_GetScript returns invocation script from the current transaction.
|
||||||
func invocationTxGetScript(ic *interopContext, v *vm.VM) error {
|
func invocationTxGetScript(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -221,7 +222,7 @@ func invocationTxGetScript(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// witnessGetVerificationScript returns current witness' script.
|
// witnessGetVerificationScript returns current witness' script.
|
||||||
func witnessGetVerificationScript(ic *interopContext, v *vm.VM) error {
|
func witnessGetVerificationScript(ic *interop.Context, v *vm.VM) error {
|
||||||
witInterface := v.Estack().Pop().Value()
|
witInterface := v.Estack().Pop().Value()
|
||||||
wit, ok := witInterface.(*transaction.Witness)
|
wit, ok := witInterface.(*transaction.Witness)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -235,8 +236,8 @@ func witnessGetVerificationScript(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetValidators returns validators.
|
// bcGetValidators returns validators.
|
||||||
func bcGetValidators(ic *interopContext, v *vm.VM) error {
|
func bcGetValidators(ic *interop.Context, v *vm.VM) error {
|
||||||
validators := ic.dao.GetValidators()
|
validators := ic.DAO.GetValidators()
|
||||||
v.Estack().PushVal(validators)
|
v.Estack().PushVal(validators)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -256,7 +257,7 @@ func popInputFromVM(v *vm.VM) (*transaction.Input, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// inputGetHash returns hash from the given input.
|
// inputGetHash returns hash from the given input.
|
||||||
func inputGetHash(ic *interopContext, v *vm.VM) error {
|
func inputGetHash(ic *interop.Context, v *vm.VM) error {
|
||||||
input, err := popInputFromVM(v)
|
input, err := popInputFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -266,7 +267,7 @@ func inputGetHash(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// inputGetIndex returns index from the given input.
|
// inputGetIndex returns index from the given input.
|
||||||
func inputGetIndex(ic *interopContext, v *vm.VM) error {
|
func inputGetIndex(ic *interop.Context, v *vm.VM) error {
|
||||||
input, err := popInputFromVM(v)
|
input, err := popInputFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -290,7 +291,7 @@ func popOutputFromVM(v *vm.VM) (*transaction.Output, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// outputGetAssetId returns asset ID from the given output.
|
// outputGetAssetId returns asset ID from the given output.
|
||||||
func outputGetAssetID(ic *interopContext, v *vm.VM) error {
|
func outputGetAssetID(ic *interop.Context, v *vm.VM) error {
|
||||||
output, err := popOutputFromVM(v)
|
output, err := popOutputFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -300,7 +301,7 @@ func outputGetAssetID(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// outputGetScriptHash returns scripthash from the given output.
|
// outputGetScriptHash returns scripthash from the given output.
|
||||||
func outputGetScriptHash(ic *interopContext, v *vm.VM) error {
|
func outputGetScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||||
output, err := popOutputFromVM(v)
|
output, err := popOutputFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -310,7 +311,7 @@ func outputGetScriptHash(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// outputGetValue returns value (amount) from the given output.
|
// outputGetValue returns value (amount) from the given output.
|
||||||
func outputGetValue(ic *interopContext, v *vm.VM) error {
|
func outputGetValue(ic *interop.Context, v *vm.VM) error {
|
||||||
output, err := popOutputFromVM(v)
|
output, err := popOutputFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -320,7 +321,7 @@ func outputGetValue(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// attrGetData returns tx attribute data.
|
// attrGetData returns tx attribute data.
|
||||||
func attrGetData(ic *interopContext, v *vm.VM) error {
|
func attrGetData(ic *interop.Context, v *vm.VM) error {
|
||||||
attrInterface := v.Estack().Pop().Value()
|
attrInterface := v.Estack().Pop().Value()
|
||||||
attr, ok := attrInterface.(*transaction.Attribute)
|
attr, ok := attrInterface.(*transaction.Attribute)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -331,7 +332,7 @@ func attrGetData(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// attrGetData returns tx attribute usage field.
|
// attrGetData returns tx attribute usage field.
|
||||||
func attrGetUsage(ic *interopContext, v *vm.VM) error {
|
func attrGetUsage(ic *interop.Context, v *vm.VM) error {
|
||||||
attrInterface := v.Estack().Pop().Value()
|
attrInterface := v.Estack().Pop().Value()
|
||||||
attr, ok := attrInterface.(*transaction.Attribute)
|
attr, ok := attrInterface.(*transaction.Attribute)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -342,13 +343,13 @@ func attrGetUsage(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetAccount returns or creates an account.
|
// bcGetAccount returns or creates an account.
|
||||||
func bcGetAccount(ic *interopContext, v *vm.VM) error {
|
func bcGetAccount(ic *interop.Context, v *vm.VM) error {
|
||||||
accbytes := v.Estack().Pop().Bytes()
|
accbytes := v.Estack().Pop().Bytes()
|
||||||
acchash, err := util.Uint160DecodeBytesBE(accbytes)
|
acchash, err := util.Uint160DecodeBytesBE(accbytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
acc, err := ic.dao.GetAccountStateOrNew(acchash)
|
acc, err := ic.DAO.GetAccountStateOrNew(acchash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -357,13 +358,13 @@ func bcGetAccount(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetAsset returns an asset.
|
// bcGetAsset returns an asset.
|
||||||
func bcGetAsset(ic *interopContext, v *vm.VM) error {
|
func bcGetAsset(ic *interop.Context, v *vm.VM) error {
|
||||||
asbytes := v.Estack().Pop().Bytes()
|
asbytes := v.Estack().Pop().Bytes()
|
||||||
ashash, err := util.Uint256DecodeBytesBE(asbytes)
|
ashash, err := util.Uint256DecodeBytesBE(asbytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
as, err := ic.dao.GetAssetState(ashash)
|
as, err := ic.DAO.GetAssetState(ashash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("asset not found")
|
return errors.New("asset not found")
|
||||||
}
|
}
|
||||||
|
@ -372,7 +373,7 @@ func bcGetAsset(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// accountGetBalance returns balance for a given account.
|
// accountGetBalance returns balance for a given account.
|
||||||
func accountGetBalance(ic *interopContext, v *vm.VM) error {
|
func accountGetBalance(ic *interop.Context, v *vm.VM) error {
|
||||||
accInterface := v.Estack().Pop().Value()
|
accInterface := v.Estack().Pop().Value()
|
||||||
acc, ok := accInterface.(*state.Account)
|
acc, ok := accInterface.(*state.Account)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -392,7 +393,7 @@ func accountGetBalance(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// accountGetScriptHash returns script hash of a given account.
|
// accountGetScriptHash returns script hash of a given account.
|
||||||
func accountGetScriptHash(ic *interopContext, v *vm.VM) error {
|
func accountGetScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||||
accInterface := v.Estack().Pop().Value()
|
accInterface := v.Estack().Pop().Value()
|
||||||
acc, ok := accInterface.(*state.Account)
|
acc, ok := accInterface.(*state.Account)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -403,7 +404,7 @@ func accountGetScriptHash(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// accountGetVotes returns votes of a given account.
|
// accountGetVotes returns votes of a given account.
|
||||||
func accountGetVotes(ic *interopContext, v *vm.VM) error {
|
func accountGetVotes(ic *interop.Context, v *vm.VM) error {
|
||||||
accInterface := v.Estack().Pop().Value()
|
accInterface := v.Estack().Pop().Value()
|
||||||
acc, ok := accInterface.(*state.Account)
|
acc, ok := accInterface.(*state.Account)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -421,20 +422,20 @@ func accountGetVotes(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// accountIsStandard checks whether given account is standard.
|
// accountIsStandard checks whether given account is standard.
|
||||||
func accountIsStandard(ic *interopContext, v *vm.VM) error {
|
func accountIsStandard(ic *interop.Context, v *vm.VM) error {
|
||||||
accbytes := v.Estack().Pop().Bytes()
|
accbytes := v.Estack().Pop().Bytes()
|
||||||
acchash, err := util.Uint160DecodeBytesBE(accbytes)
|
acchash, err := util.Uint160DecodeBytesBE(accbytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
contract, err := ic.dao.GetContractState(acchash)
|
contract, err := ic.DAO.GetContractState(acchash)
|
||||||
res := err != nil || vm.IsStandardContract(contract.Script)
|
res := err != nil || vm.IsStandardContract(contract.Script)
|
||||||
v.Estack().PushVal(res)
|
v.Estack().PushVal(res)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageFind finds stored key-value pair.
|
// storageFind finds stored key-value pair.
|
||||||
func storageFind(ic *interopContext, v *vm.VM) error {
|
func storageFind(ic *interop.Context, v *vm.VM) error {
|
||||||
stcInterface := v.Estack().Pop().Value()
|
stcInterface := v.Estack().Pop().Value()
|
||||||
stc, ok := stcInterface.(*StorageContext)
|
stc, ok := stcInterface.(*StorageContext)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -445,7 +446,7 @@ func storageFind(ic *interopContext, v *vm.VM) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
prefix := string(v.Estack().Pop().Bytes())
|
prefix := string(v.Estack().Pop().Bytes())
|
||||||
siMap, err := ic.dao.GetStorageItems(stc.ScriptHash)
|
siMap, err := ic.DAO.GetStorageItems(stc.ScriptHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -467,8 +468,8 @@ func storageFind(ic *interopContext, v *vm.VM) error {
|
||||||
// createContractStateFromVM pops all contract state elements from the VM
|
// createContractStateFromVM pops all contract state elements from the VM
|
||||||
// evaluation stack, does a lot of checks and returns Contract if it
|
// evaluation stack, does a lot of checks and returns Contract if it
|
||||||
// succeeds.
|
// succeeds.
|
||||||
func createContractStateFromVM(ic *interopContext, v *vm.VM) (*state.Contract, error) {
|
func createContractStateFromVM(ic *interop.Context, v *vm.VM) (*state.Contract, error) {
|
||||||
if ic.trigger != trigger.Application {
|
if ic.Trigger != trigger.Application {
|
||||||
return nil, errors.New("can't create contract when not triggered by an application")
|
return nil, errors.New("can't create contract when not triggered by an application")
|
||||||
}
|
}
|
||||||
script := v.Estack().Pop().Bytes()
|
script := v.Estack().Pop().Bytes()
|
||||||
|
@ -520,15 +521,15 @@ func createContractStateFromVM(ic *interopContext, v *vm.VM) (*state.Contract, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractCreate creates a contract.
|
// contractCreate creates a contract.
|
||||||
func contractCreate(ic *interopContext, v *vm.VM) error {
|
func contractCreate(ic *interop.Context, v *vm.VM) error {
|
||||||
newcontract, err := createContractStateFromVM(ic, v)
|
newcontract, err := createContractStateFromVM(ic, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
contract, err := ic.dao.GetContractState(newcontract.ScriptHash())
|
contract, err := ic.DAO.GetContractState(newcontract.ScriptHash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contract = newcontract
|
contract = newcontract
|
||||||
err := ic.dao.PutContractState(contract)
|
err := ic.DAO.PutContractState(contract)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -538,7 +539,7 @@ func contractCreate(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractGetScript returns a script associated with a contract.
|
// contractGetScript returns a script associated with a contract.
|
||||||
func contractGetScript(ic *interopContext, v *vm.VM) error {
|
func contractGetScript(ic *interop.Context, v *vm.VM) error {
|
||||||
csInterface := v.Estack().Pop().Value()
|
csInterface := v.Estack().Pop().Value()
|
||||||
cs, ok := csInterface.(*state.Contract)
|
cs, ok := csInterface.(*state.Contract)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -549,7 +550,7 @@ func contractGetScript(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractIsPayable returns whether contract is payable.
|
// contractIsPayable returns whether contract is payable.
|
||||||
func contractIsPayable(ic *interopContext, v *vm.VM) error {
|
func contractIsPayable(ic *interop.Context, v *vm.VM) error {
|
||||||
csInterface := v.Estack().Pop().Value()
|
csInterface := v.Estack().Pop().Value()
|
||||||
cs, ok := csInterface.(*state.Contract)
|
cs, ok := csInterface.(*state.Contract)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -560,27 +561,27 @@ func contractIsPayable(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractMigrate migrates a contract.
|
// contractMigrate migrates a contract.
|
||||||
func contractMigrate(ic *interopContext, v *vm.VM) error {
|
func contractMigrate(ic *interop.Context, v *vm.VM) error {
|
||||||
newcontract, err := createContractStateFromVM(ic, v)
|
newcontract, err := createContractStateFromVM(ic, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
contract, err := ic.dao.GetContractState(newcontract.ScriptHash())
|
contract, err := ic.DAO.GetContractState(newcontract.ScriptHash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contract = newcontract
|
contract = newcontract
|
||||||
err := ic.dao.PutContractState(contract)
|
err := ic.DAO.PutContractState(contract)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if contract.HasStorage() {
|
if contract.HasStorage() {
|
||||||
hash := getContextScriptHash(v, 0)
|
hash := getContextScriptHash(v, 0)
|
||||||
siMap, err := ic.dao.GetStorageItems(hash)
|
siMap, err := ic.DAO.GetStorageItems(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for k, v := range siMap {
|
for k, v := range siMap {
|
||||||
v.IsConst = false
|
v.IsConst = false
|
||||||
err = ic.dao.PutStorageItem(contract.ScriptHash(), []byte(k), v)
|
err = ic.DAO.PutStorageItem(contract.ScriptHash(), []byte(k), v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -592,8 +593,8 @@ func contractMigrate(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetCreate creates an asset.
|
// assetCreate creates an asset.
|
||||||
func assetCreate(ic *interopContext, v *vm.VM) error {
|
func assetCreate(ic *interop.Context, v *vm.VM) error {
|
||||||
if ic.trigger != trigger.Application {
|
if ic.Trigger != trigger.Application {
|
||||||
return errors.New("can't create asset when not triggered by an application")
|
return errors.New("can't create asset when not triggered by an application")
|
||||||
}
|
}
|
||||||
atype := transaction.AssetType(v.Estack().Pop().BigInt().Int64())
|
atype := transaction.AssetType(v.Estack().Pop().BigInt().Int64())
|
||||||
|
@ -651,7 +652,7 @@ func assetCreate(ic *interopContext, v *vm.VM) error {
|
||||||
return gherr.Wrap(err, "failed to get issuer")
|
return gherr.Wrap(err, "failed to get issuer")
|
||||||
}
|
}
|
||||||
asset := &state.Asset{
|
asset := &state.Asset{
|
||||||
ID: ic.tx.Hash(),
|
ID: ic.Tx.Hash(),
|
||||||
AssetType: atype,
|
AssetType: atype,
|
||||||
Name: name,
|
Name: name,
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
|
@ -659,9 +660,9 @@ func assetCreate(ic *interopContext, v *vm.VM) error {
|
||||||
Owner: *owner,
|
Owner: *owner,
|
||||||
Admin: admin,
|
Admin: admin,
|
||||||
Issuer: issuer,
|
Issuer: issuer,
|
||||||
Expiration: ic.bc.BlockHeight() + DefaultAssetLifetime,
|
Expiration: ic.Chain.BlockHeight() + DefaultAssetLifetime,
|
||||||
}
|
}
|
||||||
err = ic.dao.PutAssetState(asset)
|
err = ic.DAO.PutAssetState(asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gherr.Wrap(err, "failed to Store asset")
|
return gherr.Wrap(err, "failed to Store asset")
|
||||||
}
|
}
|
||||||
|
@ -670,7 +671,7 @@ func assetCreate(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetAdmin returns asset admin.
|
// assetGetAdmin returns asset admin.
|
||||||
func assetGetAdmin(ic *interopContext, v *vm.VM) error {
|
func assetGetAdmin(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -681,7 +682,7 @@ func assetGetAdmin(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetAmount returns the overall amount of asset available.
|
// assetGetAmount returns the overall amount of asset available.
|
||||||
func assetGetAmount(ic *interopContext, v *vm.VM) error {
|
func assetGetAmount(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -692,7 +693,7 @@ func assetGetAmount(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetAssetId returns the id of an asset.
|
// assetGetAssetId returns the id of an asset.
|
||||||
func assetGetAssetID(ic *interopContext, v *vm.VM) error {
|
func assetGetAssetID(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -703,7 +704,7 @@ func assetGetAssetID(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetAssetType returns type of an asset.
|
// assetGetAssetType returns type of an asset.
|
||||||
func assetGetAssetType(ic *interopContext, v *vm.VM) error {
|
func assetGetAssetType(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -714,7 +715,7 @@ func assetGetAssetType(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetAvailable returns available (not yet issued) amount of asset.
|
// assetGetAvailable returns available (not yet issued) amount of asset.
|
||||||
func assetGetAvailable(ic *interopContext, v *vm.VM) error {
|
func assetGetAvailable(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -725,7 +726,7 @@ func assetGetAvailable(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetIssuer returns issuer of an asset.
|
// assetGetIssuer returns issuer of an asset.
|
||||||
func assetGetIssuer(ic *interopContext, v *vm.VM) error {
|
func assetGetIssuer(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -736,7 +737,7 @@ func assetGetIssuer(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetOwner returns owner of an asset.
|
// assetGetOwner returns owner of an asset.
|
||||||
func assetGetOwner(ic *interopContext, v *vm.VM) error {
|
func assetGetOwner(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -747,7 +748,7 @@ func assetGetOwner(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetGetPrecision returns precision used to measure this asset.
|
// assetGetPrecision returns precision used to measure this asset.
|
||||||
func assetGetPrecision(ic *interopContext, v *vm.VM) error {
|
func assetGetPrecision(ic *interop.Context, v *vm.VM) error {
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
as, ok := asInterface.(*state.Asset)
|
as, ok := asInterface.(*state.Asset)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -758,8 +759,8 @@ func assetGetPrecision(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assetRenew updates asset expiration date.
|
// assetRenew updates asset expiration date.
|
||||||
func assetRenew(ic *interopContext, v *vm.VM) error {
|
func assetRenew(ic *interop.Context, v *vm.VM) error {
|
||||||
if ic.trigger != trigger.Application {
|
if ic.Trigger != trigger.Application {
|
||||||
return errors.New("can't create asset when not triggered by an application")
|
return errors.New("can't create asset when not triggered by an application")
|
||||||
}
|
}
|
||||||
asInterface := v.Estack().Pop().Value()
|
asInterface := v.Estack().Pop().Value()
|
||||||
|
@ -769,19 +770,19 @@ func assetRenew(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
years := byte(v.Estack().Pop().BigInt().Int64())
|
years := byte(v.Estack().Pop().BigInt().Int64())
|
||||||
// Not sure why C# code regets an asset from the Store, but we also do it.
|
// Not sure why C# code regets an asset from the Store, but we also do it.
|
||||||
asset, err := ic.dao.GetAssetState(as.ID)
|
asset, err := ic.DAO.GetAssetState(as.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("can't renew non-existent asset")
|
return errors.New("can't renew non-existent asset")
|
||||||
}
|
}
|
||||||
if asset.Expiration < ic.bc.BlockHeight()+1 {
|
if asset.Expiration < ic.Chain.BlockHeight()+1 {
|
||||||
asset.Expiration = ic.bc.BlockHeight() + 1
|
asset.Expiration = ic.Chain.BlockHeight() + 1
|
||||||
}
|
}
|
||||||
expiration := uint64(asset.Expiration) + uint64(years)*BlocksPerYear
|
expiration := uint64(asset.Expiration) + uint64(years)*BlocksPerYear
|
||||||
if expiration > math.MaxUint32 {
|
if expiration > math.MaxUint32 {
|
||||||
expiration = math.MaxUint32
|
expiration = math.MaxUint32
|
||||||
}
|
}
|
||||||
asset.Expiration = uint32(expiration)
|
asset.Expiration = uint32(expiration)
|
||||||
err = ic.dao.PutAssetState(asset)
|
err = ic.DAO.PutAssetState(asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gherr.Wrap(err, "failed to Store asset")
|
return gherr.Wrap(err, "failed to Store asset")
|
||||||
}
|
}
|
||||||
|
@ -790,57 +791,57 @@ func assetRenew(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeSerialize serializes top stack item into a ByteArray.
|
// runtimeSerialize serializes top stack item into a ByteArray.
|
||||||
func runtimeSerialize(_ *interopContext, v *vm.VM) error {
|
func runtimeSerialize(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.RuntimeSerialize(v)
|
return vm.RuntimeSerialize(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeDeserialize deserializes ByteArray from a stack into an item.
|
// runtimeDeserialize deserializes ByteArray from a stack into an item.
|
||||||
func runtimeDeserialize(_ *interopContext, v *vm.VM) error {
|
func runtimeDeserialize(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.RuntimeDeserialize(v)
|
return vm.RuntimeDeserialize(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// enumeratorConcat concatenates 2 enumerators into a single one.
|
// enumeratorConcat concatenates 2 enumerators into a single one.
|
||||||
func enumeratorConcat(_ *interopContext, v *vm.VM) error {
|
func enumeratorConcat(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.EnumeratorConcat(v)
|
return vm.EnumeratorConcat(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// enumeratorCreate creates an enumerator from an array-like stack item.
|
// enumeratorCreate creates an enumerator from an array-like stack item.
|
||||||
func enumeratorCreate(_ *interopContext, v *vm.VM) error {
|
func enumeratorCreate(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.EnumeratorCreate(v)
|
return vm.EnumeratorCreate(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// enumeratorNext advances the enumerator, pushes true if is it was successful
|
// enumeratorNext advances the enumerator, pushes true if is it was successful
|
||||||
// and false otherwise.
|
// and false otherwise.
|
||||||
func enumeratorNext(_ *interopContext, v *vm.VM) error {
|
func enumeratorNext(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.EnumeratorNext(v)
|
return vm.EnumeratorNext(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// enumeratorValue returns the current value of the enumerator.
|
// enumeratorValue returns the current value of the enumerator.
|
||||||
func enumeratorValue(_ *interopContext, v *vm.VM) error {
|
func enumeratorValue(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.EnumeratorValue(v)
|
return vm.EnumeratorValue(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// iteratorConcat concatenates 2 iterators into a single one.
|
// iteratorConcat concatenates 2 iterators into a single one.
|
||||||
func iteratorConcat(_ *interopContext, v *vm.VM) error {
|
func iteratorConcat(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.IteratorConcat(v)
|
return vm.IteratorConcat(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// iteratorCreate creates an iterator from array-like or map stack item.
|
// iteratorCreate creates an iterator from array-like or map stack item.
|
||||||
func iteratorCreate(_ *interopContext, v *vm.VM) error {
|
func iteratorCreate(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.IteratorCreate(v)
|
return vm.IteratorCreate(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// iteratorKey returns current iterator key.
|
// iteratorKey returns current iterator key.
|
||||||
func iteratorKey(_ *interopContext, v *vm.VM) error {
|
func iteratorKey(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.IteratorKey(v)
|
return vm.IteratorKey(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// iteratorKeys returns keys of the iterator.
|
// iteratorKeys returns keys of the iterator.
|
||||||
func iteratorKeys(_ *interopContext, v *vm.VM) error {
|
func iteratorKeys(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.IteratorKeys(v)
|
return vm.IteratorKeys(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// iteratorValues returns values of the iterator.
|
// iteratorValues returns values of the iterator.
|
||||||
func iteratorValues(_ *interopContext, v *vm.VM) error {
|
func iteratorValues(_ *interop.Context, v *vm.VM) error {
|
||||||
return vm.IteratorValues(v)
|
return vm.IteratorValues(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
@ -56,12 +57,12 @@ func TestStorageFind(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, context.dao.PutContractState(contractState))
|
require.NoError(t, context.DAO.PutContractState(contractState))
|
||||||
|
|
||||||
scriptHash := contractState.ScriptHash()
|
scriptHash := contractState.ScriptHash()
|
||||||
|
|
||||||
for i := range skeys {
|
for i := range skeys {
|
||||||
err := context.dao.PutStorageItem(scriptHash, skeys[i], items[i])
|
err := context.DAO.PutStorageItem(scriptHash, skeys[i], items[i])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,7 +460,7 @@ func TestAssetGetPrecision(t *testing.T) {
|
||||||
|
|
||||||
// Helper functions to create VM, InteropContext, TX, Account, Contract, Asset.
|
// Helper functions to create VM, InteropContext, TX, Account, Contract, Asset.
|
||||||
|
|
||||||
func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interopContext, *Blockchain) {
|
func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Blockchain) {
|
||||||
v := vm.New()
|
v := vm.New()
|
||||||
block := newDumbBlock()
|
block := newDumbBlock()
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
|
@ -468,13 +469,13 @@ func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interopContext,
|
||||||
return v, block, context, chain
|
return v, block, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func createVMAndPushTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interopContext, *Blockchain) {
|
func createVMAndPushTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
|
||||||
v, tx, context, chain := createVMAndTX(t)
|
v, tx, context, chain := createVMAndTX(t)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(tx))
|
v.Estack().PushVal(vm.NewInteropItem(tx))
|
||||||
return v, tx, context, chain
|
return v, tx, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func createVMAndAssetState(t *testing.T) (*vm.VM, *state.Asset, *interopContext, *Blockchain) {
|
func createVMAndAssetState(t *testing.T) (*vm.VM, *state.Asset, *interop.Context, *Blockchain) {
|
||||||
v := vm.New()
|
v := vm.New()
|
||||||
assetState := &state.Asset{
|
assetState := &state.Asset{
|
||||||
ID: util.Uint256{},
|
ID: util.Uint256{},
|
||||||
|
@ -497,7 +498,7 @@ func createVMAndAssetState(t *testing.T) (*vm.VM, *state.Asset, *interopContext,
|
||||||
return v, assetState, context, chain
|
return v, assetState, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interopContext, *Blockchain) {
|
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
|
||||||
v := vm.New()
|
v := vm.New()
|
||||||
contractState := &state.Contract{
|
contractState := &state.Contract{
|
||||||
Script: []byte("testscript"),
|
Script: []byte("testscript"),
|
||||||
|
@ -516,7 +517,7 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interopCo
|
||||||
return v, contractState, context, chain
|
return v, contractState, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interopContext, *Blockchain) {
|
func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interop.Context, *Blockchain) {
|
||||||
v := vm.New()
|
v := vm.New()
|
||||||
rawHash := "4d3b96ae1bcc5a585e075e3b81920210dec16302"
|
rawHash := "4d3b96ae1bcc5a585e075e3b81920210dec16302"
|
||||||
hash, err := util.Uint160DecodeStringBE(rawHash)
|
hash, err := util.Uint160DecodeStringBE(rawHash)
|
||||||
|
@ -531,7 +532,7 @@ func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interopContext,
|
||||||
return v, accountState, context, chain
|
return v, accountState, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interopContext, *Blockchain) {
|
func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
|
||||||
v := vm.New()
|
v := vm.New()
|
||||||
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
|
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
|
||||||
tx := transaction.NewInvocationTX(script, 0)
|
tx := transaction.NewInvocationTX(script, 0)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"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/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
@ -49,12 +50,12 @@ func getBlockHashFromElement(bc blockchainer.Blockchainer, element *vm.Element)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetBlock returns current block.
|
// bcGetBlock returns current block.
|
||||||
func bcGetBlock(ic *interopContext, v *vm.VM) error {
|
func bcGetBlock(ic *interop.Context, v *vm.VM) error {
|
||||||
hash, err := getBlockHashFromElement(ic.bc, v.Estack().Pop())
|
hash, err := getBlockHashFromElement(ic.Chain, v.Estack().Pop())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
block, err := ic.bc.GetBlock(hash)
|
block, err := ic.Chain.GetBlock(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Estack().PushVal([]byte{})
|
v.Estack().PushVal([]byte{})
|
||||||
} else {
|
} else {
|
||||||
|
@ -64,13 +65,13 @@ func bcGetBlock(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetContract returns contract.
|
// bcGetContract returns contract.
|
||||||
func bcGetContract(ic *interopContext, v *vm.VM) error {
|
func bcGetContract(ic *interop.Context, v *vm.VM) error {
|
||||||
hashbytes := v.Estack().Pop().Bytes()
|
hashbytes := v.Estack().Pop().Bytes()
|
||||||
hash, err := util.Uint160DecodeBytesBE(hashbytes)
|
hash, err := util.Uint160DecodeBytesBE(hashbytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cs, err := ic.dao.GetContractState(hash)
|
cs, err := ic.DAO.GetContractState(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Estack().PushVal([]byte{})
|
v.Estack().PushVal([]byte{})
|
||||||
} else {
|
} else {
|
||||||
|
@ -80,12 +81,12 @@ func bcGetContract(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetHeader returns block header.
|
// bcGetHeader returns block header.
|
||||||
func bcGetHeader(ic *interopContext, v *vm.VM) error {
|
func bcGetHeader(ic *interop.Context, v *vm.VM) error {
|
||||||
hash, err := getBlockHashFromElement(ic.bc, v.Estack().Pop())
|
hash, err := getBlockHashFromElement(ic.Chain, v.Estack().Pop())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
header, err := ic.bc.GetHeader(hash)
|
header, err := ic.Chain.GetHeader(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Estack().PushVal([]byte{})
|
v.Estack().PushVal([]byte{})
|
||||||
} else {
|
} else {
|
||||||
|
@ -95,8 +96,8 @@ func bcGetHeader(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetHeight returns blockchain height.
|
// bcGetHeight returns blockchain height.
|
||||||
func bcGetHeight(ic *interopContext, v *vm.VM) error {
|
func bcGetHeight(ic *interop.Context, v *vm.VM) error {
|
||||||
v.Estack().PushVal(ic.bc.BlockHeight())
|
v.Estack().PushVal(ic.Chain.BlockHeight())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +113,8 @@ func getTransactionAndHeight(cd *dao.Cached, v *vm.VM) (*transaction.Transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetTransaction returns transaction.
|
// bcGetTransaction returns transaction.
|
||||||
func bcGetTransaction(ic *interopContext, v *vm.VM) error {
|
func bcGetTransaction(ic *interop.Context, v *vm.VM) error {
|
||||||
tx, _, err := getTransactionAndHeight(ic.dao, v)
|
tx, _, err := getTransactionAndHeight(ic.DAO, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -122,8 +123,8 @@ func bcGetTransaction(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcGetTransactionHeight returns transaction height.
|
// bcGetTransactionHeight returns transaction height.
|
||||||
func bcGetTransactionHeight(ic *interopContext, v *vm.VM) error {
|
func bcGetTransactionHeight(ic *interop.Context, v *vm.VM) error {
|
||||||
_, h, err := getTransactionAndHeight(ic.dao, v)
|
_, h, err := getTransactionAndHeight(ic.DAO, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -148,7 +149,7 @@ func popHeaderFromVM(v *vm.VM) (*block.Header, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// headerGetIndex returns block index from the header.
|
// headerGetIndex returns block index from the header.
|
||||||
func headerGetIndex(ic *interopContext, v *vm.VM) error {
|
func headerGetIndex(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -158,7 +159,7 @@ func headerGetIndex(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// headerGetHash returns header hash of the passed header.
|
// headerGetHash returns header hash of the passed header.
|
||||||
func headerGetHash(ic *interopContext, v *vm.VM) error {
|
func headerGetHash(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -168,7 +169,7 @@ func headerGetHash(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// headerGetPrevHash returns previous header hash of the passed header.
|
// headerGetPrevHash returns previous header hash of the passed header.
|
||||||
func headerGetPrevHash(ic *interopContext, v *vm.VM) error {
|
func headerGetPrevHash(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -178,7 +179,7 @@ func headerGetPrevHash(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// headerGetTimestamp returns timestamp of the passed header.
|
// headerGetTimestamp returns timestamp of the passed header.
|
||||||
func headerGetTimestamp(ic *interopContext, v *vm.VM) error {
|
func headerGetTimestamp(ic *interop.Context, v *vm.VM) error {
|
||||||
header, err := popHeaderFromVM(v)
|
header, err := popHeaderFromVM(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -188,7 +189,7 @@ func headerGetTimestamp(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// blockGetTransactionCount returns transactions count in the given block.
|
// blockGetTransactionCount returns transactions count in the given block.
|
||||||
func blockGetTransactionCount(ic *interopContext, v *vm.VM) error {
|
func blockGetTransactionCount(ic *interop.Context, v *vm.VM) error {
|
||||||
blockInterface := v.Estack().Pop().Value()
|
blockInterface := v.Estack().Pop().Value()
|
||||||
block, ok := blockInterface.(*block.Block)
|
block, ok := blockInterface.(*block.Block)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -199,7 +200,7 @@ func blockGetTransactionCount(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// blockGetTransactions returns transactions from the given block.
|
// blockGetTransactions returns transactions from the given block.
|
||||||
func blockGetTransactions(ic *interopContext, v *vm.VM) error {
|
func blockGetTransactions(ic *interop.Context, v *vm.VM) error {
|
||||||
blockInterface := v.Estack().Pop().Value()
|
blockInterface := v.Estack().Pop().Value()
|
||||||
block, ok := blockInterface.(*block.Block)
|
block, ok := blockInterface.(*block.Block)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -218,7 +219,7 @@ func blockGetTransactions(ic *interopContext, v *vm.VM) error {
|
||||||
|
|
||||||
// blockGetTransaction returns transaction with the given number from the given
|
// blockGetTransaction returns transaction with the given number from the given
|
||||||
// block.
|
// block.
|
||||||
func blockGetTransaction(ic *interopContext, v *vm.VM) error {
|
func blockGetTransaction(ic *interop.Context, v *vm.VM) error {
|
||||||
blockInterface := v.Estack().Pop().Value()
|
blockInterface := v.Estack().Pop().Value()
|
||||||
block, ok := blockInterface.(*block.Block)
|
block, ok := blockInterface.(*block.Block)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -234,7 +235,7 @@ func blockGetTransaction(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetHash returns transaction's hash.
|
// txGetHash returns transaction's hash.
|
||||||
func txGetHash(ic *interopContext, v *vm.VM) error {
|
func txGetHash(ic *interop.Context, v *vm.VM) error {
|
||||||
txInterface := v.Estack().Pop().Value()
|
txInterface := v.Estack().Pop().Value()
|
||||||
tx, ok := txInterface.(*transaction.Transaction)
|
tx, ok := txInterface.(*transaction.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -246,8 +247,8 @@ func txGetHash(ic *interopContext, v *vm.VM) error {
|
||||||
|
|
||||||
// engineGetScriptContainer returns transaction that contains the script being
|
// engineGetScriptContainer returns transaction that contains the script being
|
||||||
// run.
|
// run.
|
||||||
func engineGetScriptContainer(ic *interopContext, v *vm.VM) error {
|
func engineGetScriptContainer(ic *interop.Context, v *vm.VM) error {
|
||||||
v.Estack().PushVal(vm.NewInteropItem(ic.tx))
|
v.Estack().PushVal(vm.NewInteropItem(ic.Tx))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,36 +269,36 @@ func pushContextScriptHash(v *vm.VM, n int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// engineGetExecutingScriptHash returns executing script hash.
|
// engineGetExecutingScriptHash returns executing script hash.
|
||||||
func engineGetExecutingScriptHash(ic *interopContext, v *vm.VM) error {
|
func engineGetExecutingScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||||
return pushContextScriptHash(v, 0)
|
return pushContextScriptHash(v, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// engineGetCallingScriptHash returns calling script hash.
|
// engineGetCallingScriptHash returns calling script hash.
|
||||||
func engineGetCallingScriptHash(ic *interopContext, v *vm.VM) error {
|
func engineGetCallingScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||||
return pushContextScriptHash(v, 1)
|
return pushContextScriptHash(v, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// engineGetEntryScriptHash returns entry script hash.
|
// engineGetEntryScriptHash returns entry script hash.
|
||||||
func engineGetEntryScriptHash(ic *interopContext, v *vm.VM) error {
|
func engineGetEntryScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||||
return pushContextScriptHash(v, v.Istack().Len()-1)
|
return pushContextScriptHash(v, v.Istack().Len()-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimePlatform returns the name of the platform.
|
// runtimePlatform returns the name of the platform.
|
||||||
func runtimePlatform(ic *interopContext, v *vm.VM) error {
|
func runtimePlatform(ic *interop.Context, v *vm.VM) error {
|
||||||
v.Estack().PushVal([]byte("NEO"))
|
v.Estack().PushVal([]byte("NEO"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeGetTrigger returns the script trigger.
|
// runtimeGetTrigger returns the script trigger.
|
||||||
func runtimeGetTrigger(ic *interopContext, v *vm.VM) error {
|
func runtimeGetTrigger(ic *interop.Context, v *vm.VM) error {
|
||||||
v.Estack().PushVal(byte(ic.trigger))
|
v.Estack().PushVal(byte(ic.Trigger))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkHashedWitness checks given hash against current list of script hashes
|
// checkHashedWitness checks given hash against current list of script hashes
|
||||||
// for verifying in the interop context.
|
// for verifying in the interop context.
|
||||||
func checkHashedWitness(ic *interopContext, hash util.Uint160) (bool, error) {
|
func checkHashedWitness(ic *interop.Context, hash util.Uint160) (bool, error) {
|
||||||
hashes, err := ic.bc.GetScriptHashesForVerifying(ic.tx)
|
hashes, err := ic.Chain.GetScriptHashesForVerifying(ic.Tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, gherr.Wrap(err, "failed to get script hashes")
|
return false, gherr.Wrap(err, "failed to get script hashes")
|
||||||
}
|
}
|
||||||
|
@ -311,12 +312,12 @@ func checkHashedWitness(ic *interopContext, hash util.Uint160) (bool, error) {
|
||||||
|
|
||||||
// checkKeyedWitness checks hash of signature check contract with a given public
|
// checkKeyedWitness checks hash of signature check contract with a given public
|
||||||
// key against current list of script hashes for verifying in the interop context.
|
// key against current list of script hashes for verifying in the interop context.
|
||||||
func checkKeyedWitness(ic *interopContext, key *keys.PublicKey) (bool, error) {
|
func checkKeyedWitness(ic *interop.Context, key *keys.PublicKey) (bool, error) {
|
||||||
return checkHashedWitness(ic, key.GetScriptHash())
|
return checkHashedWitness(ic, key.GetScriptHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeCheckWitness checks witnesses.
|
// runtimeCheckWitness checks witnesses.
|
||||||
func runtimeCheckWitness(ic *interopContext, v *vm.VM) error {
|
func runtimeCheckWitness(ic *interop.Context, v *vm.VM) error {
|
||||||
var res bool
|
var res bool
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -341,7 +342,7 @@ func runtimeCheckWitness(ic *interopContext, v *vm.VM) error {
|
||||||
|
|
||||||
// runtimeNotify should pass stack item to the notify plugin to handle it, but
|
// runtimeNotify should pass stack item to the notify plugin to handle it, but
|
||||||
// in neo-go the only meaningful thing to do here is to log.
|
// in neo-go the only meaningful thing to do here is to log.
|
||||||
func runtimeNotify(ic *interopContext, v *vm.VM) error {
|
func runtimeNotify(ic *interop.Context, v *vm.VM) error {
|
||||||
// It can be just about anything.
|
// It can be just about anything.
|
||||||
e := v.Estack().Pop()
|
e := v.Estack().Pop()
|
||||||
item := e.Item()
|
item := e.Item()
|
||||||
|
@ -355,38 +356,38 @@ func runtimeNotify(ic *interopContext, v *vm.VM) error {
|
||||||
item = vm.NewByteArrayItem([]byte(fmt.Sprintf("bad notification: %v", err)))
|
item = vm.NewByteArrayItem([]byte(fmt.Sprintf("bad notification: %v", err)))
|
||||||
}
|
}
|
||||||
ne := state.NotificationEvent{ScriptHash: getContextScriptHash(v, 0), Item: item}
|
ne := state.NotificationEvent{ScriptHash: getContextScriptHash(v, 0), Item: item}
|
||||||
ic.notifications = append(ic.notifications, ne)
|
ic.Notifications = append(ic.Notifications, ne)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeLog logs the message passed.
|
// runtimeLog logs the message passed.
|
||||||
func runtimeLog(ic *interopContext, v *vm.VM) error {
|
func runtimeLog(ic *interop.Context, v *vm.VM) error {
|
||||||
msg := fmt.Sprintf("%q", v.Estack().Pop().Bytes())
|
msg := fmt.Sprintf("%q", v.Estack().Pop().Bytes())
|
||||||
ic.log.Info("runtime log",
|
ic.Log.Info("runtime log",
|
||||||
zap.Stringer("script", getContextScriptHash(v, 0)),
|
zap.Stringer("script", getContextScriptHash(v, 0)),
|
||||||
zap.String("logs", msg))
|
zap.String("logs", msg))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeGetTime returns timestamp of the block being verified, or the latest
|
// runtimeGetTime returns timestamp of the block being verified, or the latest
|
||||||
// one in the blockchain if no block is given to interopContext.
|
// one in the blockchain if no block is given to Context.
|
||||||
func runtimeGetTime(ic *interopContext, v *vm.VM) error {
|
func runtimeGetTime(ic *interop.Context, v *vm.VM) error {
|
||||||
var header *block.Header
|
var header *block.Header
|
||||||
if ic.block == nil {
|
if ic.Block == nil {
|
||||||
var err error
|
var err error
|
||||||
header, err = ic.bc.GetHeader(ic.bc.CurrentBlockHash())
|
header, err = ic.Chain.GetHeader(ic.Chain.CurrentBlockHash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
header = ic.block.Header()
|
header = ic.Block.Header()
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(header.Timestamp)
|
v.Estack().PushVal(header.Timestamp)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkStorageContext(ic *interopContext, stc *StorageContext) error {
|
func checkStorageContext(ic *interop.Context, stc *StorageContext) error {
|
||||||
contract, err := ic.dao.GetContractState(stc.ScriptHash)
|
contract, err := ic.DAO.GetContractState(stc.ScriptHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("no contract found")
|
return errors.New("no contract found")
|
||||||
}
|
}
|
||||||
|
@ -397,8 +398,8 @@ func checkStorageContext(ic *interopContext, stc *StorageContext) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageDelete deletes stored key-value pair.
|
// storageDelete deletes stored key-value pair.
|
||||||
func storageDelete(ic *interopContext, v *vm.VM) error {
|
func storageDelete(ic *interop.Context, v *vm.VM) error {
|
||||||
if ic.trigger != trigger.Application && ic.trigger != trigger.ApplicationR {
|
if ic.Trigger != trigger.Application && ic.Trigger != trigger.ApplicationR {
|
||||||
return errors.New("can't delete when the trigger is not application")
|
return errors.New("can't delete when the trigger is not application")
|
||||||
}
|
}
|
||||||
stcInterface := v.Estack().Pop().Value()
|
stcInterface := v.Estack().Pop().Value()
|
||||||
|
@ -414,15 +415,15 @@ func storageDelete(ic *interopContext, v *vm.VM) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
key := v.Estack().Pop().Bytes()
|
key := v.Estack().Pop().Bytes()
|
||||||
si := ic.dao.GetStorageItem(stc.ScriptHash, key)
|
si := ic.DAO.GetStorageItem(stc.ScriptHash, key)
|
||||||
if si != nil && si.IsConst {
|
if si != nil && si.IsConst {
|
||||||
return errors.New("storage item is constant")
|
return errors.New("storage item is constant")
|
||||||
}
|
}
|
||||||
return ic.dao.DeleteStorageItem(stc.ScriptHash, key)
|
return ic.DAO.DeleteStorageItem(stc.ScriptHash, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageGet returns stored key-value pair.
|
// storageGet returns stored key-value pair.
|
||||||
func storageGet(ic *interopContext, v *vm.VM) error {
|
func storageGet(ic *interop.Context, v *vm.VM) error {
|
||||||
stcInterface := v.Estack().Pop().Value()
|
stcInterface := v.Estack().Pop().Value()
|
||||||
stc, ok := stcInterface.(*StorageContext)
|
stc, ok := stcInterface.(*StorageContext)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -433,7 +434,7 @@ func storageGet(ic *interopContext, v *vm.VM) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
key := v.Estack().Pop().Bytes()
|
key := v.Estack().Pop().Bytes()
|
||||||
si := ic.dao.GetStorageItem(stc.ScriptHash, key)
|
si := ic.DAO.GetStorageItem(stc.ScriptHash, key)
|
||||||
if si != nil && si.Value != nil {
|
if si != nil && si.Value != nil {
|
||||||
v.Estack().PushVal(si.Value)
|
v.Estack().PushVal(si.Value)
|
||||||
} else {
|
} else {
|
||||||
|
@ -443,7 +444,7 @@ func storageGet(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageGetContext returns storage context (scripthash).
|
// storageGetContext returns storage context (scripthash).
|
||||||
func storageGetContext(ic *interopContext, v *vm.VM) error {
|
func storageGetContext(ic *interop.Context, v *vm.VM) error {
|
||||||
sc := &StorageContext{
|
sc := &StorageContext{
|
||||||
ScriptHash: getContextScriptHash(v, 0),
|
ScriptHash: getContextScriptHash(v, 0),
|
||||||
ReadOnly: false,
|
ReadOnly: false,
|
||||||
|
@ -453,7 +454,7 @@ func storageGetContext(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageGetReadOnlyContext returns read-only context (scripthash).
|
// storageGetReadOnlyContext returns read-only context (scripthash).
|
||||||
func storageGetReadOnlyContext(ic *interopContext, v *vm.VM) error {
|
func storageGetReadOnlyContext(ic *interop.Context, v *vm.VM) error {
|
||||||
sc := &StorageContext{
|
sc := &StorageContext{
|
||||||
ScriptHash: getContextScriptHash(v, 0),
|
ScriptHash: getContextScriptHash(v, 0),
|
||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
|
@ -462,8 +463,8 @@ func storageGetReadOnlyContext(ic *interopContext, v *vm.VM) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func putWithContextAndFlags(ic *interopContext, stc *StorageContext, key []byte, value []byte, isConst bool) error {
|
func putWithContextAndFlags(ic *interop.Context, stc *StorageContext, key []byte, value []byte, isConst bool) error {
|
||||||
if ic.trigger != trigger.Application && ic.trigger != trigger.ApplicationR {
|
if ic.Trigger != trigger.Application && ic.Trigger != trigger.ApplicationR {
|
||||||
return errors.New("can't delete when the trigger is not application")
|
return errors.New("can't delete when the trigger is not application")
|
||||||
}
|
}
|
||||||
if len(key) > MaxStorageKeyLen {
|
if len(key) > MaxStorageKeyLen {
|
||||||
|
@ -476,7 +477,7 @@ func putWithContextAndFlags(ic *interopContext, stc *StorageContext, key []byte,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
si := ic.dao.GetStorageItem(stc.ScriptHash, key)
|
si := ic.DAO.GetStorageItem(stc.ScriptHash, key)
|
||||||
if si == nil {
|
if si == nil {
|
||||||
si = &state.StorageItem{}
|
si = &state.StorageItem{}
|
||||||
}
|
}
|
||||||
|
@ -485,11 +486,11 @@ func putWithContextAndFlags(ic *interopContext, stc *StorageContext, key []byte,
|
||||||
}
|
}
|
||||||
si.Value = value
|
si.Value = value
|
||||||
si.IsConst = isConst
|
si.IsConst = isConst
|
||||||
return ic.dao.PutStorageItem(stc.ScriptHash, key, si)
|
return ic.DAO.PutStorageItem(stc.ScriptHash, key, si)
|
||||||
}
|
}
|
||||||
|
|
||||||
// storagePutInternal is a unified implementation of storagePut and storagePutEx.
|
// storagePutInternal is a unified implementation of storagePut and storagePutEx.
|
||||||
func storagePutInternal(ic *interopContext, v *vm.VM, getFlag bool) error {
|
func storagePutInternal(ic *interop.Context, v *vm.VM, getFlag bool) error {
|
||||||
stcInterface := v.Estack().Pop().Value()
|
stcInterface := v.Estack().Pop().Value()
|
||||||
stc, ok := stcInterface.(*StorageContext)
|
stc, ok := stcInterface.(*StorageContext)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -505,17 +506,17 @@ func storagePutInternal(ic *interopContext, v *vm.VM, getFlag bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// storagePut puts key-value pair into the storage.
|
// storagePut puts key-value pair into the storage.
|
||||||
func storagePut(ic *interopContext, v *vm.VM) error {
|
func storagePut(ic *interop.Context, v *vm.VM) error {
|
||||||
return storagePutInternal(ic, v, false)
|
return storagePutInternal(ic, v, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// storagePutEx puts key-value pair with given flags into the storage.
|
// storagePutEx puts key-value pair with given flags into the storage.
|
||||||
func storagePutEx(ic *interopContext, v *vm.VM) error {
|
func storagePutEx(ic *interop.Context, v *vm.VM) error {
|
||||||
return storagePutInternal(ic, v, true)
|
return storagePutInternal(ic, v, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageContextAsReadOnly sets given context to read-only mode.
|
// storageContextAsReadOnly sets given context to read-only mode.
|
||||||
func storageContextAsReadOnly(ic *interopContext, v *vm.VM) error {
|
func storageContextAsReadOnly(ic *interop.Context, v *vm.VM) error {
|
||||||
stcInterface := v.Estack().Pop().Value()
|
stcInterface := v.Estack().Pop().Value()
|
||||||
stc, ok := stcInterface.(*StorageContext)
|
stc, ok := stcInterface.(*StorageContext)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -533,39 +534,39 @@ func storageContextAsReadOnly(ic *interopContext, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractDestroy destroys a contract.
|
// contractDestroy destroys a contract.
|
||||||
func contractDestroy(ic *interopContext, v *vm.VM) error {
|
func contractDestroy(ic *interop.Context, v *vm.VM) error {
|
||||||
if ic.trigger != trigger.Application {
|
if ic.Trigger != trigger.Application {
|
||||||
return errors.New("can't destroy contract when not triggered by application")
|
return errors.New("can't destroy contract when not triggered by application")
|
||||||
}
|
}
|
||||||
hash := getContextScriptHash(v, 0)
|
hash := getContextScriptHash(v, 0)
|
||||||
cs, err := ic.dao.GetContractState(hash)
|
cs, err := ic.DAO.GetContractState(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = ic.dao.DeleteContractState(hash)
|
err = ic.DAO.DeleteContractState(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cs.HasStorage() {
|
if cs.HasStorage() {
|
||||||
siMap, err := ic.dao.GetStorageItems(hash)
|
siMap, err := ic.DAO.GetStorageItems(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for k := range siMap {
|
for k := range siMap {
|
||||||
_ = ic.dao.DeleteStorageItem(hash, []byte(k))
|
_ = ic.DAO.DeleteStorageItem(hash, []byte(k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractGetStorageContext retrieves StorageContext of a contract.
|
// contractGetStorageContext retrieves StorageContext of a contract.
|
||||||
func contractGetStorageContext(ic *interopContext, v *vm.VM) error {
|
func contractGetStorageContext(ic *interop.Context, v *vm.VM) error {
|
||||||
csInterface := v.Estack().Pop().Value()
|
csInterface := v.Estack().Pop().Value()
|
||||||
cs, ok := csInterface.(*state.Contract)
|
cs, ok := csInterface.(*state.Contract)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("%T is not a contract state", cs)
|
return fmt.Errorf("%T is not a contract state", cs)
|
||||||
}
|
}
|
||||||
contractState, err := ic.dao.GetContractState(cs.ScriptHash())
|
contractState, err := ic.DAO.GetContractState(cs.ScriptHash())
|
||||||
if contractState == nil || err != nil {
|
if contractState == nil || err != nil {
|
||||||
return fmt.Errorf("contract was not created in this transaction")
|
return fmt.Errorf("contract was not created in this transaction")
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,40 +10,18 @@ package core
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
|
||||||
"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/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type interopContext struct {
|
|
||||||
bc blockchainer.Blockchainer
|
|
||||||
trigger trigger.Type
|
|
||||||
block *block.Block
|
|
||||||
tx *transaction.Transaction
|
|
||||||
dao *dao.Cached
|
|
||||||
notifications []state.NotificationEvent
|
|
||||||
log *zap.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func newInteropContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *interopContext {
|
|
||||||
dao := dao.NewCached(d)
|
|
||||||
nes := make([]state.NotificationEvent, 0)
|
|
||||||
return &interopContext{bc, trigger, block, tx, dao, nes, log}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SpawnVM returns a VM with script getter and interop functions set
|
// SpawnVM returns a VM with script getter and interop functions set
|
||||||
// up for current blockchain.
|
// up for current blockchain.
|
||||||
func SpawnVM(ic *interopContext) *vm.VM {
|
func SpawnVM(ic *interop.Context) *vm.VM {
|
||||||
vm := vm.New()
|
vm := vm.New()
|
||||||
vm.SetScriptGetter(func(hash util.Uint160) ([]byte, bool) {
|
vm.SetScriptGetter(func(hash util.Uint160) ([]byte, bool) {
|
||||||
cs, err := ic.dao.GetContractState(hash)
|
cs, err := ic.DAO.GetContractState(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -55,31 +33,21 @@ func SpawnVM(ic *interopContext) *vm.VM {
|
||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
// interopedFunction binds function name, id with the function itself and price,
|
|
||||||
// it's supposed to be inited once for all interopContexts, so it doesn't use
|
|
||||||
// vm.InteropFuncPrice directly.
|
|
||||||
type interopedFunction struct {
|
|
||||||
ID uint32
|
|
||||||
Name string
|
|
||||||
Func func(*interopContext, *vm.VM) error
|
|
||||||
Price int
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSystemInterop returns matching interop function from the System namespace
|
// getSystemInterop returns matching interop function from the System namespace
|
||||||
// for a given id in the current context.
|
// for a given id in the current context.
|
||||||
func getSystemInterop(ic *interopContext) vm.InteropGetterFunc {
|
func getSystemInterop(ic *interop.Context) vm.InteropGetterFunc {
|
||||||
return getInteropFromSlice(ic, systemInterops)
|
return getInteropFromSlice(ic, systemInterops)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getNeoInterop returns matching interop function from the Neo and AntShares
|
// getNeoInterop returns matching interop function from the Neo and AntShares
|
||||||
// namespaces for a given id in the current context.
|
// namespaces for a given id in the current context.
|
||||||
func getNeoInterop(ic *interopContext) vm.InteropGetterFunc {
|
func getNeoInterop(ic *interop.Context) vm.InteropGetterFunc {
|
||||||
return getInteropFromSlice(ic, neoInterops)
|
return getInteropFromSlice(ic, neoInterops)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getInteropFromSlice returns matching interop function from the given slice of
|
// getInteropFromSlice returns matching interop function from the given slice of
|
||||||
// interop functions in the current context.
|
// interop functions in the current context.
|
||||||
func getInteropFromSlice(ic *interopContext, slice []interopedFunction) func(uint32) *vm.InteropFuncPrice {
|
func getInteropFromSlice(ic *interop.Context, slice []interop.Function) func(uint32) *vm.InteropFuncPrice {
|
||||||
return func(id uint32) *vm.InteropFuncPrice {
|
return func(id uint32) *vm.InteropFuncPrice {
|
||||||
n := sort.Search(len(slice), func(i int) bool {
|
n := sort.Search(len(slice), func(i int) bool {
|
||||||
return slice[i].ID >= id
|
return slice[i].ID >= id
|
||||||
|
@ -94,7 +62,7 @@ func getInteropFromSlice(ic *interopContext, slice []interopedFunction) func(uin
|
||||||
}
|
}
|
||||||
|
|
||||||
// All lists are sorted, keep 'em this way, please.
|
// All lists are sorted, keep 'em this way, please.
|
||||||
var systemInterops = []interopedFunction{
|
var systemInterops = []interop.Function{
|
||||||
{Name: "System.Block.GetTransaction", Func: blockGetTransaction, Price: 1},
|
{Name: "System.Block.GetTransaction", Func: blockGetTransaction, Price: 1},
|
||||||
{Name: "System.Block.GetTransactionCount", Func: blockGetTransactionCount, Price: 1},
|
{Name: "System.Block.GetTransactionCount", Func: blockGetTransactionCount, Price: 1},
|
||||||
{Name: "System.Block.GetTransactions", Func: blockGetTransactions, Price: 1},
|
{Name: "System.Block.GetTransactions", Func: blockGetTransactions, Price: 1},
|
||||||
|
@ -132,7 +100,7 @@ var systemInterops = []interopedFunction{
|
||||||
{Name: "System.Transaction.GetHash", Func: txGetHash, Price: 1},
|
{Name: "System.Transaction.GetHash", Func: txGetHash, Price: 1},
|
||||||
}
|
}
|
||||||
|
|
||||||
var neoInterops = []interopedFunction{
|
var neoInterops = []interop.Function{
|
||||||
{Name: "Neo.Account.GetBalance", Func: accountGetBalance, Price: 1},
|
{Name: "Neo.Account.GetBalance", Func: accountGetBalance, Price: 1},
|
||||||
{Name: "Neo.Account.GetScriptHash", Func: accountGetScriptHash, Price: 1},
|
{Name: "Neo.Account.GetScriptHash", Func: accountGetScriptHash, Price: 1},
|
||||||
{Name: "Neo.Account.GetVotes", Func: accountGetVotes, Price: 1},
|
{Name: "Neo.Account.GetVotes", Func: accountGetVotes, Price: 1},
|
||||||
|
@ -278,8 +246,8 @@ var neoInterops = []interopedFunction{
|
||||||
}
|
}
|
||||||
|
|
||||||
// initIDinInteropsSlice initializes IDs from names in one given
|
// initIDinInteropsSlice initializes IDs from names in one given
|
||||||
// interopedFunction slice and then sorts it.
|
// Function slice and then sorts it.
|
||||||
func initIDinInteropsSlice(iops []interopedFunction) {
|
func initIDinInteropsSlice(iops []interop.Function) {
|
||||||
for i := range iops {
|
for i := range iops {
|
||||||
iops[i].ID = vm.InteropNameToID([]byte(iops[i].Name))
|
iops[i].ID = vm.InteropNameToID([]byte(iops[i].Name))
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,14 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testNonInterop(t *testing.T, value interface{}, f func(*interopContext, *vm.VM) error) {
|
func testNonInterop(t *testing.T, value interface{}, f func(*interop.Context, *vm.VM) error) {
|
||||||
v := vm.New()
|
v := vm.New()
|
||||||
v.Estack().PushVal(value)
|
v.Estack().PushVal(value)
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
|
@ -30,7 +31,7 @@ func TestUnexpectedNonInterops(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// All of these functions expect an interop item on the stack.
|
// All of these functions expect an interop item on the stack.
|
||||||
funcs := []func(*interopContext, *vm.VM) error{
|
funcs := []func(*interop.Context, *vm.VM) error{
|
||||||
accountGetBalance,
|
accountGetBalance,
|
||||||
accountGetScriptHash,
|
accountGetScriptHash,
|
||||||
accountGetVotes,
|
accountGetVotes,
|
||||||
|
|
Loading…
Reference in a new issue