Merge pull request #838 from nspcc-dev/refactoring/interop
core: move interop to a separate package
This commit is contained in:
commit
522e8e15af
20 changed files with 595 additions and 562 deletions
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/nspcc-dev/dbft/payload"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
coreb "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/mempool"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -77,7 +78,7 @@ type Config struct {
|
|||
// about the new block that needs to be broadcasted.
|
||||
RelayBlock func(b *coreb.Block)
|
||||
// Chain is a core.Blockchainer instance.
|
||||
Chain core.Blockchainer
|
||||
Chain blockchainer.Blockchainer
|
||||
// RequestTx is a callback to which will be called
|
||||
// when a node lacks transactions present in a block.
|
||||
RequestTx func(h ...util.Uint256)
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"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/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/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
|
@ -446,7 +447,7 @@ func (bc *Blockchain) processHeader(h *block.Header, batch storage.Batch, header
|
|||
return nil
|
||||
}
|
||||
|
||||
// bc.GetHeaderHash(int(endHeight)) returns sum of all system fees for blocks up to h.
|
||||
// getSystemFeeAmount returns sum of all system fees for blocks up to h.
|
||||
// and 0 if no such block exists.
|
||||
func (bc *Blockchain) getSystemFeeAmount(h util.Uint256) uint32 {
|
||||
_, sf, _ := bc.dao.GetBlock(h)
|
||||
|
@ -657,7 +658,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
|||
}
|
||||
case *transaction.InvocationTX:
|
||||
systemInterop := bc.newInteropContext(trigger.Application, cache, block, tx)
|
||||
v := systemInterop.SpawnVM()
|
||||
v := SpawnVM(systemInterop)
|
||||
v.SetCheckedHash(tx.VerificationHash().BytesBE())
|
||||
v.LoadScript(t.Script)
|
||||
v.SetPriceGetter(getPrice)
|
||||
|
@ -667,11 +668,11 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
|||
|
||||
err := v.Run()
|
||||
if !v.HasFailed() {
|
||||
_, err := systemInterop.dao.Persist()
|
||||
_, err := systemInterop.DAO.Persist()
|
||||
if err != nil {
|
||||
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)
|
||||
if !ok || len(arr) != 4 {
|
||||
continue
|
||||
|
@ -710,7 +711,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
|||
VMState: v.State(),
|
||||
GasConsumed: v.GasConsumed(),
|
||||
Stack: v.Estack().ToContractParameters(),
|
||||
Events: systemInterop.notifications,
|
||||
Events: systemInterop.Notifications,
|
||||
}
|
||||
err = cache.PutAppExecResult(aer)
|
||||
if err != nil {
|
||||
|
@ -2002,7 +2003,7 @@ func (bc *Blockchain) GetScriptHashesForVerifying(t *transaction.Transaction) ([
|
|||
// GetTestVM returns a VM and a Store setup for a test run of some sort of code.
|
||||
func (bc *Blockchain) GetTestVM() *vm.VM {
|
||||
systemInterop := bc.newInteropContext(trigger.Application, bc.dao, nil, nil)
|
||||
vm := systemInterop.SpawnVM()
|
||||
vm := SpawnVM(systemInterop)
|
||||
vm.SetPriceGetter(getPrice)
|
||||
return vm
|
||||
}
|
||||
|
@ -2024,13 +2025,13 @@ func ScriptFromWitness(hash util.Uint160, witness *transaction.Witness) ([]byte,
|
|||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vm := interopCtx.SpawnVM()
|
||||
vm := SpawnVM(interopCtx)
|
||||
vm.SetCheckedHash(checkedHash.BytesBE())
|
||||
vm.LoadScript(verification)
|
||||
vm.LoadScript(witness.InvocationScript)
|
||||
|
@ -2124,6 +2125,6 @@ func (bc *Blockchain) secondsPerBlock() int {
|
|||
return bc.config.SecondsPerBlock
|
||||
}
|
||||
|
||||
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interopContext {
|
||||
return newInteropContext(trigger, bc, d, block, tx, bc.log)
|
||||
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interop.Context {
|
||||
return interop.NewContext(trigger, bc, d, block, tx, bc.log)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package core
|
||||
package blockchainer
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
|
@ -19,7 +19,7 @@ func TestGetPrice(t *testing.T) {
|
|||
sdao := dao.NewSimple(storage.NewMemoryStore())
|
||||
systemInterop := bc.newInteropContext(trigger.Application, sdao, nil, nil)
|
||||
|
||||
v := systemInterop.SpawnVM()
|
||||
v := SpawnVM(systemInterop)
|
||||
v.SetPriceGetter(getPrice)
|
||||
|
||||
t.Run("Neo.Asset.Create", func(t *testing.T) {
|
||||
|
|
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
|
||||
}
|
27
pkg/core/interop/enumerator/interop.go
Normal file
27
pkg/core/interop/enumerator/interop.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package enumerator
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
)
|
||||
|
||||
// Concat concatenates 2 enumerators into a single one.
|
||||
func Concat(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.EnumeratorConcat(v)
|
||||
}
|
||||
|
||||
// Create creates an enumerator from an array-like stack item.
|
||||
func Create(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.EnumeratorCreate(v)
|
||||
}
|
||||
|
||||
// Next advances the enumerator, pushes true if is it was successful
|
||||
// and false otherwise.
|
||||
func Next(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.EnumeratorNext(v)
|
||||
}
|
||||
|
||||
// Value returns the current value of the enumerator.
|
||||
func Value(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.EnumeratorValue(v)
|
||||
}
|
31
pkg/core/interop/iterator/interop.go
Normal file
31
pkg/core/interop/iterator/interop.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package iterator
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
)
|
||||
|
||||
// Concat concatenates 2 iterators into a single one.
|
||||
func Concat(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.IteratorConcat(v)
|
||||
}
|
||||
|
||||
// Create creates an iterator from array-like or map stack item.
|
||||
func Create(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.IteratorCreate(v)
|
||||
}
|
||||
|
||||
// Key returns current iterator key.
|
||||
func Key(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.IteratorKey(v)
|
||||
}
|
||||
|
||||
// Keys returns keys of the iterator.
|
||||
func Keys(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.IteratorKeys(v)
|
||||
}
|
||||
|
||||
// Values returns values of the iterator.
|
||||
func Values(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.IteratorValues(v)
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"math"
|
||||
"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/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -37,7 +38,7 @@ const (
|
|||
)
|
||||
|
||||
// headerGetVersion returns version from the header.
|
||||
func (ic *interopContext) headerGetVersion(v *vm.VM) error {
|
||||
func headerGetVersion(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -47,7 +48,7 @@ func (ic *interopContext) headerGetVersion(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// headerGetConsensusData returns consensus data from the header.
|
||||
func (ic *interopContext) headerGetConsensusData(v *vm.VM) error {
|
||||
func headerGetConsensusData(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -57,7 +58,7 @@ func (ic *interopContext) headerGetConsensusData(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// headerGetMerkleRoot returns version from the header.
|
||||
func (ic *interopContext) headerGetMerkleRoot(v *vm.VM) error {
|
||||
func headerGetMerkleRoot(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -67,7 +68,7 @@ func (ic *interopContext) headerGetMerkleRoot(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// headerGetNextConsensus returns version from the header.
|
||||
func (ic *interopContext) headerGetNextConsensus(v *vm.VM) error {
|
||||
func headerGetNextConsensus(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -77,7 +78,7 @@ func (ic *interopContext) headerGetNextConsensus(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetAttributes returns current transaction attributes.
|
||||
func (ic *interopContext) txGetAttributes(v *vm.VM) error {
|
||||
func txGetAttributes(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
|
@ -95,7 +96,7 @@ func (ic *interopContext) txGetAttributes(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetInputs returns current transaction inputs.
|
||||
func (ic *interopContext) txGetInputs(v *vm.VM) error {
|
||||
func txGetInputs(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
|
@ -113,7 +114,7 @@ func (ic *interopContext) txGetInputs(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetOutputs returns current transaction outputs.
|
||||
func (ic *interopContext) txGetOutputs(v *vm.VM) error {
|
||||
func txGetOutputs(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
|
@ -131,13 +132,13 @@ func (ic *interopContext) txGetOutputs(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetReferences returns current transaction references.
|
||||
func (ic *interopContext) txGetReferences(v *vm.VM) error {
|
||||
func txGetReferences(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
@ -159,7 +160,7 @@ func (ic *interopContext) txGetReferences(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetType returns current transaction type.
|
||||
func (ic *interopContext) txGetType(v *vm.VM) error {
|
||||
func txGetType(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
|
@ -170,13 +171,13 @@ func (ic *interopContext) txGetType(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetUnspentCoins returns current transaction unspent coins.
|
||||
func (ic *interopContext) txGetUnspentCoins(v *vm.VM) error {
|
||||
func txGetUnspentCoins(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
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 {
|
||||
return errors.New("no unspent coin state found")
|
||||
}
|
||||
|
@ -185,7 +186,7 @@ func (ic *interopContext) txGetUnspentCoins(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetWitnesses returns current transaction witnesses.
|
||||
func (ic *interopContext) txGetWitnesses(v *vm.VM) error {
|
||||
func txGetWitnesses(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
|
@ -203,7 +204,7 @@ func (ic *interopContext) txGetWitnesses(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// invocationTx_GetScript returns invocation script from the current transaction.
|
||||
func (ic *interopContext) invocationTxGetScript(v *vm.VM) error {
|
||||
func invocationTxGetScript(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
|
@ -221,7 +222,7 @@ func (ic *interopContext) invocationTxGetScript(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// witnessGetVerificationScript returns current witness' script.
|
||||
func (ic *interopContext) witnessGetVerificationScript(v *vm.VM) error {
|
||||
func witnessGetVerificationScript(ic *interop.Context, v *vm.VM) error {
|
||||
witInterface := v.Estack().Pop().Value()
|
||||
wit, ok := witInterface.(*transaction.Witness)
|
||||
if !ok {
|
||||
|
@ -235,8 +236,8 @@ func (ic *interopContext) witnessGetVerificationScript(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// bcGetValidators returns validators.
|
||||
func (ic *interopContext) bcGetValidators(v *vm.VM) error {
|
||||
validators := ic.dao.GetValidators()
|
||||
func bcGetValidators(ic *interop.Context, v *vm.VM) error {
|
||||
validators := ic.DAO.GetValidators()
|
||||
v.Estack().PushVal(validators)
|
||||
return nil
|
||||
}
|
||||
|
@ -256,7 +257,7 @@ func popInputFromVM(v *vm.VM) (*transaction.Input, error) {
|
|||
}
|
||||
|
||||
// inputGetHash returns hash from the given input.
|
||||
func (ic *interopContext) inputGetHash(v *vm.VM) error {
|
||||
func inputGetHash(ic *interop.Context, v *vm.VM) error {
|
||||
input, err := popInputFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -266,7 +267,7 @@ func (ic *interopContext) inputGetHash(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// inputGetIndex returns index from the given input.
|
||||
func (ic *interopContext) inputGetIndex(v *vm.VM) error {
|
||||
func inputGetIndex(ic *interop.Context, v *vm.VM) error {
|
||||
input, err := popInputFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -290,7 +291,7 @@ func popOutputFromVM(v *vm.VM) (*transaction.Output, error) {
|
|||
}
|
||||
|
||||
// outputGetAssetId returns asset ID from the given output.
|
||||
func (ic *interopContext) outputGetAssetID(v *vm.VM) error {
|
||||
func outputGetAssetID(ic *interop.Context, v *vm.VM) error {
|
||||
output, err := popOutputFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -300,7 +301,7 @@ func (ic *interopContext) outputGetAssetID(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// outputGetScriptHash returns scripthash from the given output.
|
||||
func (ic *interopContext) outputGetScriptHash(v *vm.VM) error {
|
||||
func outputGetScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||
output, err := popOutputFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -310,7 +311,7 @@ func (ic *interopContext) outputGetScriptHash(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// outputGetValue returns value (amount) from the given output.
|
||||
func (ic *interopContext) outputGetValue(v *vm.VM) error {
|
||||
func outputGetValue(ic *interop.Context, v *vm.VM) error {
|
||||
output, err := popOutputFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -320,7 +321,7 @@ func (ic *interopContext) outputGetValue(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// attrGetData returns tx attribute data.
|
||||
func (ic *interopContext) attrGetData(v *vm.VM) error {
|
||||
func attrGetData(ic *interop.Context, v *vm.VM) error {
|
||||
attrInterface := v.Estack().Pop().Value()
|
||||
attr, ok := attrInterface.(*transaction.Attribute)
|
||||
if !ok {
|
||||
|
@ -331,7 +332,7 @@ func (ic *interopContext) attrGetData(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// attrGetData returns tx attribute usage field.
|
||||
func (ic *interopContext) attrGetUsage(v *vm.VM) error {
|
||||
func attrGetUsage(ic *interop.Context, v *vm.VM) error {
|
||||
attrInterface := v.Estack().Pop().Value()
|
||||
attr, ok := attrInterface.(*transaction.Attribute)
|
||||
if !ok {
|
||||
|
@ -342,13 +343,13 @@ func (ic *interopContext) attrGetUsage(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// bcGetAccount returns or creates an account.
|
||||
func (ic *interopContext) bcGetAccount(v *vm.VM) error {
|
||||
func bcGetAccount(ic *interop.Context, v *vm.VM) error {
|
||||
accbytes := v.Estack().Pop().Bytes()
|
||||
acchash, err := util.Uint160DecodeBytesBE(accbytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acc, err := ic.dao.GetAccountStateOrNew(acchash)
|
||||
acc, err := ic.DAO.GetAccountStateOrNew(acchash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -357,13 +358,13 @@ func (ic *interopContext) bcGetAccount(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// bcGetAsset returns an asset.
|
||||
func (ic *interopContext) bcGetAsset(v *vm.VM) error {
|
||||
func bcGetAsset(ic *interop.Context, v *vm.VM) error {
|
||||
asbytes := v.Estack().Pop().Bytes()
|
||||
ashash, err := util.Uint256DecodeBytesBE(asbytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
as, err := ic.dao.GetAssetState(ashash)
|
||||
as, err := ic.DAO.GetAssetState(ashash)
|
||||
if err != nil {
|
||||
return errors.New("asset not found")
|
||||
}
|
||||
|
@ -372,7 +373,7 @@ func (ic *interopContext) bcGetAsset(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// accountGetBalance returns balance for a given account.
|
||||
func (ic *interopContext) accountGetBalance(v *vm.VM) error {
|
||||
func accountGetBalance(ic *interop.Context, v *vm.VM) error {
|
||||
accInterface := v.Estack().Pop().Value()
|
||||
acc, ok := accInterface.(*state.Account)
|
||||
if !ok {
|
||||
|
@ -392,7 +393,7 @@ func (ic *interopContext) accountGetBalance(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// accountGetScriptHash returns script hash of a given account.
|
||||
func (ic *interopContext) accountGetScriptHash(v *vm.VM) error {
|
||||
func accountGetScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||
accInterface := v.Estack().Pop().Value()
|
||||
acc, ok := accInterface.(*state.Account)
|
||||
if !ok {
|
||||
|
@ -403,7 +404,7 @@ func (ic *interopContext) accountGetScriptHash(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// accountGetVotes returns votes of a given account.
|
||||
func (ic *interopContext) accountGetVotes(v *vm.VM) error {
|
||||
func accountGetVotes(ic *interop.Context, v *vm.VM) error {
|
||||
accInterface := v.Estack().Pop().Value()
|
||||
acc, ok := accInterface.(*state.Account)
|
||||
if !ok {
|
||||
|
@ -421,31 +422,31 @@ func (ic *interopContext) accountGetVotes(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// accountIsStandard checks whether given account is standard.
|
||||
func (ic *interopContext) accountIsStandard(v *vm.VM) error {
|
||||
func accountIsStandard(ic *interop.Context, v *vm.VM) error {
|
||||
accbytes := v.Estack().Pop().Bytes()
|
||||
acchash, err := util.Uint160DecodeBytesBE(accbytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
contract, err := ic.dao.GetContractState(acchash)
|
||||
contract, err := ic.DAO.GetContractState(acchash)
|
||||
res := err != nil || vm.IsStandardContract(contract.Script)
|
||||
v.Estack().PushVal(res)
|
||||
return nil
|
||||
}
|
||||
|
||||
// storageFind finds stored key-value pair.
|
||||
func (ic *interopContext) storageFind(v *vm.VM) error {
|
||||
func storageFind(ic *interop.Context, v *vm.VM) error {
|
||||
stcInterface := v.Estack().Pop().Value()
|
||||
stc, ok := stcInterface.(*StorageContext)
|
||||
if !ok {
|
||||
return fmt.Errorf("%T is not a StorageContext", stcInterface)
|
||||
}
|
||||
err := ic.checkStorageContext(stc)
|
||||
err := checkStorageContext(ic, stc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prefix := string(v.Estack().Pop().Bytes())
|
||||
siMap, err := ic.dao.GetStorageItems(stc.ScriptHash)
|
||||
siMap, err := ic.DAO.GetStorageItems(stc.ScriptHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -467,8 +468,8 @@ func (ic *interopContext) storageFind(v *vm.VM) error {
|
|||
// createContractStateFromVM pops all contract state elements from the VM
|
||||
// evaluation stack, does a lot of checks and returns Contract if it
|
||||
// succeeds.
|
||||
func (ic *interopContext) createContractStateFromVM(v *vm.VM) (*state.Contract, error) {
|
||||
if ic.trigger != trigger.Application {
|
||||
func createContractStateFromVM(ic *interop.Context, v *vm.VM) (*state.Contract, error) {
|
||||
if ic.Trigger != trigger.Application {
|
||||
return nil, errors.New("can't create contract when not triggered by an application")
|
||||
}
|
||||
script := v.Estack().Pop().Bytes()
|
||||
|
@ -520,15 +521,15 @@ func (ic *interopContext) createContractStateFromVM(v *vm.VM) (*state.Contract,
|
|||
}
|
||||
|
||||
// contractCreate creates a contract.
|
||||
func (ic *interopContext) contractCreate(v *vm.VM) error {
|
||||
newcontract, err := ic.createContractStateFromVM(v)
|
||||
func contractCreate(ic *interop.Context, v *vm.VM) error {
|
||||
newcontract, err := createContractStateFromVM(ic, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
contract, err := ic.dao.GetContractState(newcontract.ScriptHash())
|
||||
contract, err := ic.DAO.GetContractState(newcontract.ScriptHash())
|
||||
if err != nil {
|
||||
contract = newcontract
|
||||
err := ic.dao.PutContractState(contract)
|
||||
err := ic.DAO.PutContractState(contract)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -538,7 +539,7 @@ func (ic *interopContext) contractCreate(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// contractGetScript returns a script associated with a contract.
|
||||
func (ic *interopContext) contractGetScript(v *vm.VM) error {
|
||||
func contractGetScript(ic *interop.Context, v *vm.VM) error {
|
||||
csInterface := v.Estack().Pop().Value()
|
||||
cs, ok := csInterface.(*state.Contract)
|
||||
if !ok {
|
||||
|
@ -549,7 +550,7 @@ func (ic *interopContext) contractGetScript(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// contractIsPayable returns whether contract is payable.
|
||||
func (ic *interopContext) contractIsPayable(v *vm.VM) error {
|
||||
func contractIsPayable(ic *interop.Context, v *vm.VM) error {
|
||||
csInterface := v.Estack().Pop().Value()
|
||||
cs, ok := csInterface.(*state.Contract)
|
||||
if !ok {
|
||||
|
@ -560,27 +561,27 @@ func (ic *interopContext) contractIsPayable(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// contractMigrate migrates a contract.
|
||||
func (ic *interopContext) contractMigrate(v *vm.VM) error {
|
||||
newcontract, err := ic.createContractStateFromVM(v)
|
||||
func contractMigrate(ic *interop.Context, v *vm.VM) error {
|
||||
newcontract, err := createContractStateFromVM(ic, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
contract, err := ic.dao.GetContractState(newcontract.ScriptHash())
|
||||
contract, err := ic.DAO.GetContractState(newcontract.ScriptHash())
|
||||
if err != nil {
|
||||
contract = newcontract
|
||||
err := ic.dao.PutContractState(contract)
|
||||
err := ic.DAO.PutContractState(contract)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if contract.HasStorage() {
|
||||
hash := getContextScriptHash(v, 0)
|
||||
siMap, err := ic.dao.GetStorageItems(hash)
|
||||
siMap, err := ic.DAO.GetStorageItems(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range siMap {
|
||||
v.IsConst = false
|
||||
err = ic.dao.PutStorageItem(contract.ScriptHash(), []byte(k), v)
|
||||
err = ic.DAO.PutStorageItem(contract.ScriptHash(), []byte(k), v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -588,12 +589,12 @@ func (ic *interopContext) contractMigrate(v *vm.VM) error {
|
|||
}
|
||||
}
|
||||
v.Estack().PushVal(vm.NewInteropItem(contract))
|
||||
return ic.contractDestroy(v)
|
||||
return contractDestroy(ic, v)
|
||||
}
|
||||
|
||||
// assetCreate creates an asset.
|
||||
func (ic *interopContext) assetCreate(v *vm.VM) error {
|
||||
if ic.trigger != trigger.Application {
|
||||
func assetCreate(ic *interop.Context, v *vm.VM) error {
|
||||
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())
|
||||
|
@ -635,7 +636,7 @@ func (ic *interopContext) assetCreate(v *vm.VM) error {
|
|||
if owner.IsInfinity() {
|
||||
return errors.New("can't have infinity as an owner key")
|
||||
}
|
||||
witnessOk, err := ic.checkKeyedWitness(owner)
|
||||
witnessOk, err := checkKeyedWitness(ic, owner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -651,7 +652,7 @@ func (ic *interopContext) assetCreate(v *vm.VM) error {
|
|||
return gherr.Wrap(err, "failed to get issuer")
|
||||
}
|
||||
asset := &state.Asset{
|
||||
ID: ic.tx.Hash(),
|
||||
ID: ic.Tx.Hash(),
|
||||
AssetType: atype,
|
||||
Name: name,
|
||||
Amount: amount,
|
||||
|
@ -659,9 +660,9 @@ func (ic *interopContext) assetCreate(v *vm.VM) error {
|
|||
Owner: *owner,
|
||||
Admin: admin,
|
||||
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 {
|
||||
return gherr.Wrap(err, "failed to Store asset")
|
||||
}
|
||||
|
@ -670,7 +671,7 @@ func (ic *interopContext) assetCreate(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetAdmin returns asset admin.
|
||||
func (ic *interopContext) assetGetAdmin(v *vm.VM) error {
|
||||
func assetGetAdmin(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -681,7 +682,7 @@ func (ic *interopContext) assetGetAdmin(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetAmount returns the overall amount of asset available.
|
||||
func (ic *interopContext) assetGetAmount(v *vm.VM) error {
|
||||
func assetGetAmount(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -692,7 +693,7 @@ func (ic *interopContext) assetGetAmount(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetAssetId returns the id of an asset.
|
||||
func (ic *interopContext) assetGetAssetID(v *vm.VM) error {
|
||||
func assetGetAssetID(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -703,7 +704,7 @@ func (ic *interopContext) assetGetAssetID(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetAssetType returns type of an asset.
|
||||
func (ic *interopContext) assetGetAssetType(v *vm.VM) error {
|
||||
func assetGetAssetType(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -714,7 +715,7 @@ func (ic *interopContext) assetGetAssetType(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetAvailable returns available (not yet issued) amount of asset.
|
||||
func (ic *interopContext) assetGetAvailable(v *vm.VM) error {
|
||||
func assetGetAvailable(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -725,7 +726,7 @@ func (ic *interopContext) assetGetAvailable(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetIssuer returns issuer of an asset.
|
||||
func (ic *interopContext) assetGetIssuer(v *vm.VM) error {
|
||||
func assetGetIssuer(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -736,7 +737,7 @@ func (ic *interopContext) assetGetIssuer(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetOwner returns owner of an asset.
|
||||
func (ic *interopContext) assetGetOwner(v *vm.VM) error {
|
||||
func assetGetOwner(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -747,7 +748,7 @@ func (ic *interopContext) assetGetOwner(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetGetPrecision returns precision used to measure this asset.
|
||||
func (ic *interopContext) assetGetPrecision(v *vm.VM) error {
|
||||
func assetGetPrecision(ic *interop.Context, v *vm.VM) error {
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
as, ok := asInterface.(*state.Asset)
|
||||
if !ok {
|
||||
|
@ -758,8 +759,8 @@ func (ic *interopContext) assetGetPrecision(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// assetRenew updates asset expiration date.
|
||||
func (ic *interopContext) assetRenew(v *vm.VM) error {
|
||||
if ic.trigger != trigger.Application {
|
||||
func assetRenew(ic *interop.Context, v *vm.VM) error {
|
||||
if ic.Trigger != trigger.Application {
|
||||
return errors.New("can't create asset when not triggered by an application")
|
||||
}
|
||||
asInterface := v.Estack().Pop().Value()
|
||||
|
@ -769,19 +770,19 @@ func (ic *interopContext) assetRenew(v *vm.VM) error {
|
|||
}
|
||||
years := byte(v.Estack().Pop().BigInt().Int64())
|
||||
// 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 {
|
||||
return errors.New("can't renew non-existent asset")
|
||||
}
|
||||
if asset.Expiration < ic.bc.BlockHeight()+1 {
|
||||
asset.Expiration = ic.bc.BlockHeight() + 1
|
||||
if asset.Expiration < ic.Chain.BlockHeight()+1 {
|
||||
asset.Expiration = ic.Chain.BlockHeight() + 1
|
||||
}
|
||||
expiration := uint64(asset.Expiration) + uint64(years)*BlocksPerYear
|
||||
if expiration > math.MaxUint32 {
|
||||
expiration = math.MaxUint32
|
||||
}
|
||||
asset.Expiration = uint32(expiration)
|
||||
err = ic.dao.PutAssetState(asset)
|
||||
err = ic.DAO.PutAssetState(asset)
|
||||
if err != nil {
|
||||
return gherr.Wrap(err, "failed to Store asset")
|
||||
}
|
||||
|
@ -790,57 +791,11 @@ func (ic *interopContext) assetRenew(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// runtimeSerialize serializes top stack item into a ByteArray.
|
||||
func (ic *interopContext) runtimeSerialize(v *vm.VM) error {
|
||||
func runtimeSerialize(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.RuntimeSerialize(v)
|
||||
}
|
||||
|
||||
// runtimeDeserialize deserializes ByteArray from a stack into an item.
|
||||
func (ic *interopContext) runtimeDeserialize(v *vm.VM) error {
|
||||
func runtimeDeserialize(_ *interop.Context, v *vm.VM) error {
|
||||
return vm.RuntimeDeserialize(v)
|
||||
}
|
||||
|
||||
// enumeratorConcat concatenates 2 enumerators into a single one.
|
||||
func (ic *interopContext) enumeratorConcat(v *vm.VM) error {
|
||||
return vm.EnumeratorConcat(v)
|
||||
}
|
||||
|
||||
// enumeratorCreate creates an enumerator from an array-like stack item.
|
||||
func (ic *interopContext) enumeratorCreate(v *vm.VM) error {
|
||||
return vm.EnumeratorCreate(v)
|
||||
}
|
||||
|
||||
// enumeratorNext advances the enumerator, pushes true if is it was successful
|
||||
// and false otherwise.
|
||||
func (ic *interopContext) enumeratorNext(v *vm.VM) error {
|
||||
return vm.EnumeratorNext(v)
|
||||
}
|
||||
|
||||
// enumeratorValue returns the current value of the enumerator.
|
||||
func (ic *interopContext) enumeratorValue(v *vm.VM) error {
|
||||
return vm.EnumeratorValue(v)
|
||||
}
|
||||
|
||||
// iteratorConcat concatenates 2 iterators into a single one.
|
||||
func (ic *interopContext) iteratorConcat(v *vm.VM) error {
|
||||
return vm.IteratorConcat(v)
|
||||
}
|
||||
|
||||
// iteratorCreate creates an iterator from array-like or map stack item.
|
||||
func (ic *interopContext) iteratorCreate(v *vm.VM) error {
|
||||
return vm.IteratorCreate(v)
|
||||
}
|
||||
|
||||
// iteratorKey returns current iterator key.
|
||||
func (ic *interopContext) iteratorKey(v *vm.VM) error {
|
||||
return vm.IteratorKey(v)
|
||||
}
|
||||
|
||||
// iteratorKeys returns keys of the iterator.
|
||||
func (ic *interopContext) iteratorKeys(v *vm.VM) error {
|
||||
return vm.IteratorKeys(v)
|
||||
}
|
||||
|
||||
// iteratorValues returns values of the iterator.
|
||||
func (ic *interopContext) iteratorValues(v *vm.VM) error {
|
||||
return vm.IteratorValues(v)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import (
|
|||
|
||||
"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/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
|
||||
"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/transaction"
|
||||
|
@ -39,7 +42,7 @@ import (
|
|||
func TestGetTrigger(t *testing.T) {
|
||||
v, _, context, chain := createVMAndPushBlock(t)
|
||||
defer chain.Close()
|
||||
require.NoError(t, context.runtimeGetTrigger(v))
|
||||
require.NoError(t, runtimeGetTrigger(context, v))
|
||||
}
|
||||
|
||||
func TestStorageFind(t *testing.T) {
|
||||
|
@ -56,12 +59,12 @@ func TestStorageFind(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
require.NoError(t, context.dao.PutContractState(contractState))
|
||||
require.NoError(t, context.DAO.PutContractState(contractState))
|
||||
|
||||
scriptHash := contractState.ScriptHash()
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -69,25 +72,25 @@ func TestStorageFind(t *testing.T) {
|
|||
v.Estack().PushVal([]byte{0x01})
|
||||
v.Estack().PushVal(vm.NewInteropItem(&StorageContext{ScriptHash: scriptHash}))
|
||||
|
||||
err := context.storageFind(v)
|
||||
err := storageFind(context, v)
|
||||
require.NoError(t, err)
|
||||
|
||||
var iter *vm.InteropItem
|
||||
require.NotPanics(t, func() { iter = v.Estack().Top().Interop() })
|
||||
|
||||
require.NoError(t, context.enumeratorNext(v))
|
||||
require.NoError(t, enumerator.Next(context, v))
|
||||
require.True(t, v.Estack().Pop().Bool())
|
||||
|
||||
v.Estack().PushVal(iter)
|
||||
require.NoError(t, context.iteratorKey(v))
|
||||
require.NoError(t, iterator.Key(context, v))
|
||||
require.Equal(t, []byte{0x01, 0x02}, v.Estack().Pop().Bytes())
|
||||
|
||||
v.Estack().PushVal(iter)
|
||||
require.NoError(t, context.enumeratorValue(v))
|
||||
require.NoError(t, enumerator.Value(context, v))
|
||||
require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, v.Estack().Pop().Bytes())
|
||||
|
||||
v.Estack().PushVal(iter)
|
||||
require.NoError(t, context.enumeratorNext(v))
|
||||
require.NoError(t, enumerator.Next(context, v))
|
||||
require.False(t, v.Estack().Pop().Bool())
|
||||
})
|
||||
|
||||
|
@ -95,7 +98,7 @@ func TestStorageFind(t *testing.T) {
|
|||
v.Estack().PushVal([]byte{0x01})
|
||||
v.Estack().PushVal(vm.NewInteropItem(nil))
|
||||
|
||||
require.Error(t, context.storageFind(v))
|
||||
require.Error(t, storageFind(context, v))
|
||||
})
|
||||
|
||||
t.Run("invalid script hash", func(t *testing.T) {
|
||||
|
@ -105,7 +108,7 @@ func TestStorageFind(t *testing.T) {
|
|||
v.Estack().PushVal([]byte{0x01})
|
||||
v.Estack().PushVal(vm.NewInteropItem(&StorageContext{ScriptHash: invalidHash}))
|
||||
|
||||
require.Error(t, context.storageFind(v))
|
||||
require.Error(t, storageFind(context, v))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -113,7 +116,7 @@ func TestHeaderGetVersion(t *testing.T) {
|
|||
v, block, context, chain := createVMAndPushBlock(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.headerGetVersion(v)
|
||||
err := headerGetVersion(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().(*big.Int)
|
||||
require.Equal(t, uint64(block.Version), value.Uint64())
|
||||
|
@ -127,7 +130,7 @@ func TestHeaderGetVersion_Negative(t *testing.T) {
|
|||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), block, nil)
|
||||
v.Estack().PushVal(vm.NewBoolItem(false))
|
||||
|
||||
err := context.headerGetVersion(v)
|
||||
err := headerGetVersion(context, v)
|
||||
require.Errorf(t, err, "value is not a header or block")
|
||||
}
|
||||
|
||||
|
@ -135,7 +138,7 @@ func TestHeaderGetConsensusData(t *testing.T) {
|
|||
v, block, context, chain := createVMAndPushBlock(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.headerGetConsensusData(v)
|
||||
err := headerGetConsensusData(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().(*big.Int)
|
||||
require.Equal(t, block.ConsensusData, value.Uint64())
|
||||
|
@ -145,7 +148,7 @@ func TestHeaderGetMerkleRoot(t *testing.T) {
|
|||
v, block, context, chain := createVMAndPushBlock(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.headerGetMerkleRoot(v)
|
||||
err := headerGetMerkleRoot(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value()
|
||||
require.Equal(t, block.MerkleRoot.BytesBE(), value)
|
||||
|
@ -155,7 +158,7 @@ func TestHeaderGetNextConsensus(t *testing.T) {
|
|||
v, block, context, chain := createVMAndPushBlock(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.headerGetNextConsensus(v)
|
||||
err := headerGetNextConsensus(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value()
|
||||
require.Equal(t, block.NextConsensus.BytesBE(), value)
|
||||
|
@ -165,7 +168,7 @@ func TestTxGetAttributes(t *testing.T) {
|
|||
v, tx, context, chain := createVMAndPushTX(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.txGetAttributes(v)
|
||||
err := txGetAttributes(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().([]vm.StackItem)
|
||||
require.Equal(t, tx.Attributes[0].Usage, value[0].Value().(*transaction.Attribute).Usage)
|
||||
|
@ -175,7 +178,7 @@ func TestTxGetInputs(t *testing.T) {
|
|||
v, tx, context, chain := createVMAndPushTX(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.txGetInputs(v)
|
||||
err := txGetInputs(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().([]vm.StackItem)
|
||||
require.Equal(t, tx.Inputs[0], *value[0].Value().(*transaction.Input))
|
||||
|
@ -185,7 +188,7 @@ func TestTxGetOutputs(t *testing.T) {
|
|||
v, tx, context, chain := createVMAndPushTX(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.txGetOutputs(v)
|
||||
err := txGetOutputs(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().([]vm.StackItem)
|
||||
require.Equal(t, tx.Outputs[0], *value[0].Value().(*transaction.Output))
|
||||
|
@ -195,7 +198,7 @@ func TestTxGetType(t *testing.T) {
|
|||
v, tx, context, chain := createVMAndPushTX(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.txGetType(v)
|
||||
err := txGetType(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().(*big.Int)
|
||||
require.Equal(t, big.NewInt(int64(tx.Type)), value)
|
||||
|
@ -205,7 +208,7 @@ func TestInvocationTxGetScript(t *testing.T) {
|
|||
v, tx, context, chain := createVMAndPushTX(t)
|
||||
defer chain.Close()
|
||||
|
||||
err := context.invocationTxGetScript(v)
|
||||
err := invocationTxGetScript(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().([]byte)
|
||||
inv := tx.Data.(*transaction.InvocationTX)
|
||||
|
@ -222,7 +225,7 @@ func TestWitnessGetVerificationScript(t *testing.T) {
|
|||
|
||||
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, nil)
|
||||
v.Estack().PushVal(vm.NewInteropItem(&witness))
|
||||
err := context.witnessGetVerificationScript(v)
|
||||
err := witnessGetVerificationScript(context, v)
|
||||
require.NoError(t, err)
|
||||
value := v.Estack().Pop().Value().([]byte)
|
||||
require.Equal(t, witness.VerificationScript, value)
|
||||
|
@ -243,7 +246,7 @@ func TestInputGetHash(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0]))
|
||||
|
||||
err := context.inputGetHash(v)
|
||||
err := inputGetHash(context, v)
|
||||
require.NoError(t, err)
|
||||
hash := v.Estack().Pop().Value()
|
||||
require.Equal(t, tx.Inputs[0].PrevHash.BytesBE(), hash)
|
||||
|
@ -254,7 +257,7 @@ func TestInputGetIndex(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0]))
|
||||
|
||||
err := context.inputGetIndex(v)
|
||||
err := inputGetIndex(context, v)
|
||||
require.NoError(t, err)
|
||||
index := v.Estack().Pop().Value()
|
||||
require.Equal(t, big.NewInt(int64(tx.Inputs[0].PrevIndex)), index)
|
||||
|
@ -275,7 +278,7 @@ func TestOutputGetAssetID(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0]))
|
||||
|
||||
err := context.outputGetAssetID(v)
|
||||
err := outputGetAssetID(context, v)
|
||||
require.NoError(t, err)
|
||||
assetID := v.Estack().Pop().Value()
|
||||
require.Equal(t, tx.Outputs[0].AssetID.BytesBE(), assetID)
|
||||
|
@ -286,7 +289,7 @@ func TestOutputGetScriptHash(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0]))
|
||||
|
||||
err := context.outputGetScriptHash(v)
|
||||
err := outputGetScriptHash(context, v)
|
||||
require.NoError(t, err)
|
||||
scriptHash := v.Estack().Pop().Value()
|
||||
require.Equal(t, tx.Outputs[0].ScriptHash.BytesBE(), scriptHash)
|
||||
|
@ -297,7 +300,7 @@ func TestOutputGetValue(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(&tx.Outputs[0]))
|
||||
|
||||
err := context.outputGetValue(v)
|
||||
err := outputGetValue(context, v)
|
||||
require.NoError(t, err)
|
||||
amount := v.Estack().Pop().Value()
|
||||
require.Equal(t, big.NewInt(int64(tx.Outputs[0].Amount)), amount)
|
||||
|
@ -308,7 +311,7 @@ func TestAttrGetData(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(&tx.Attributes[0]))
|
||||
|
||||
err := context.attrGetData(v)
|
||||
err := attrGetData(context, v)
|
||||
require.NoError(t, err)
|
||||
data := v.Estack().Pop().Value()
|
||||
require.Equal(t, tx.Attributes[0].Data, data)
|
||||
|
@ -319,7 +322,7 @@ func TestAttrGetUsage(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(&tx.Attributes[0]))
|
||||
|
||||
err := context.attrGetUsage(v)
|
||||
err := attrGetUsage(context, v)
|
||||
require.NoError(t, err)
|
||||
usage := v.Estack().Pop().Value()
|
||||
require.Equal(t, big.NewInt(int64(tx.Attributes[0].Usage)), usage)
|
||||
|
@ -330,7 +333,7 @@ func TestAccountGetScriptHash(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(accState))
|
||||
|
||||
err := context.accountGetScriptHash(v)
|
||||
err := accountGetScriptHash(context, v)
|
||||
require.NoError(t, err)
|
||||
hash := v.Estack().Pop().Value()
|
||||
require.Equal(t, accState.ScriptHash.BytesBE(), hash)
|
||||
|
@ -341,7 +344,7 @@ func TestAccountGetVotes(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(accState))
|
||||
|
||||
err := context.accountGetVotes(v)
|
||||
err := accountGetVotes(context, v)
|
||||
require.NoError(t, err)
|
||||
votes := v.Estack().Pop().Value().([]vm.StackItem)
|
||||
require.Equal(t, vm.NewByteArrayItem(accState.Votes[0].Bytes()), votes[0])
|
||||
|
@ -352,7 +355,7 @@ func TestContractGetScript(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(contractState))
|
||||
|
||||
err := context.contractGetScript(v)
|
||||
err := contractGetScript(context, v)
|
||||
require.NoError(t, err)
|
||||
script := v.Estack().Pop().Value()
|
||||
require.Equal(t, contractState.Script, script)
|
||||
|
@ -363,7 +366,7 @@ func TestContractIsPayable(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(contractState))
|
||||
|
||||
err := context.contractIsPayable(v)
|
||||
err := contractIsPayable(context, v)
|
||||
require.NoError(t, err)
|
||||
isPayable := v.Estack().Pop().Value()
|
||||
require.Equal(t, contractState.IsPayable(), isPayable)
|
||||
|
@ -374,7 +377,7 @@ func TestAssetGetAdmin(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetAdmin(v)
|
||||
err := assetGetAdmin(context, v)
|
||||
require.NoError(t, err)
|
||||
admin := v.Estack().Pop().Value()
|
||||
require.Equal(t, assetState.Admin.BytesBE(), admin)
|
||||
|
@ -385,7 +388,7 @@ func TestAssetGetAmount(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetAmount(v)
|
||||
err := assetGetAmount(context, v)
|
||||
require.NoError(t, err)
|
||||
amount := v.Estack().Pop().Value()
|
||||
require.Equal(t, big.NewInt(int64(assetState.Amount)), amount)
|
||||
|
@ -396,7 +399,7 @@ func TestAssetGetAssetID(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetAssetID(v)
|
||||
err := assetGetAssetID(context, v)
|
||||
require.NoError(t, err)
|
||||
assetID := v.Estack().Pop().Value()
|
||||
require.Equal(t, assetState.ID.BytesBE(), assetID)
|
||||
|
@ -407,7 +410,7 @@ func TestAssetGetAssetType(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetAssetType(v)
|
||||
err := assetGetAssetType(context, v)
|
||||
require.NoError(t, err)
|
||||
assetType := v.Estack().Pop().Value()
|
||||
require.Equal(t, big.NewInt(int64(assetState.AssetType)), assetType)
|
||||
|
@ -418,7 +421,7 @@ func TestAssetGetAvailable(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetAvailable(v)
|
||||
err := assetGetAvailable(context, v)
|
||||
require.NoError(t, err)
|
||||
available := v.Estack().Pop().Value()
|
||||
require.Equal(t, big.NewInt(int64(assetState.Available)), available)
|
||||
|
@ -429,7 +432,7 @@ func TestAssetGetIssuer(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetIssuer(v)
|
||||
err := assetGetIssuer(context, v)
|
||||
require.NoError(t, err)
|
||||
issuer := v.Estack().Pop().Value()
|
||||
require.Equal(t, assetState.Issuer.BytesBE(), issuer)
|
||||
|
@ -440,7 +443,7 @@ func TestAssetGetOwner(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetOwner(v)
|
||||
err := assetGetOwner(context, v)
|
||||
require.NoError(t, err)
|
||||
owner := v.Estack().Pop().Value()
|
||||
require.Equal(t, assetState.Owner.Bytes(), owner)
|
||||
|
@ -451,7 +454,7 @@ func TestAssetGetPrecision(t *testing.T) {
|
|||
defer chain.Close()
|
||||
v.Estack().PushVal(vm.NewInteropItem(assetState))
|
||||
|
||||
err := context.assetGetPrecision(v)
|
||||
err := assetGetPrecision(context, v)
|
||||
require.NoError(t, err)
|
||||
precision := v.Estack().Pop().Value()
|
||||
require.Equal(t, big.NewInt(int64(assetState.Precision)), precision)
|
||||
|
@ -459,7 +462,7 @@ func TestAssetGetPrecision(t *testing.T) {
|
|||
|
||||
// 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()
|
||||
block := newDumbBlock()
|
||||
chain := newTestChain(t)
|
||||
|
@ -468,13 +471,13 @@ func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interopContext,
|
|||
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.Estack().PushVal(vm.NewInteropItem(tx))
|
||||
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()
|
||||
assetState := &state.Asset{
|
||||
ID: util.Uint256{},
|
||||
|
@ -497,7 +500,7 @@ func createVMAndAssetState(t *testing.T) (*vm.VM, *state.Asset, *interopContext,
|
|||
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()
|
||||
contractState := &state.Contract{
|
||||
Script: []byte("testscript"),
|
||||
|
@ -516,7 +519,7 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interopCo
|
|||
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()
|
||||
rawHash := "4d3b96ae1bcc5a585e075e3b81920210dec16302"
|
||||
hash, err := util.Uint160DecodeStringBE(rawHash)
|
||||
|
@ -531,7 +534,7 @@ func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interopContext,
|
|||
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()
|
||||
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
|
||||
tx := transaction.NewInvocationTX(script, 0)
|
||||
|
|
|
@ -6,7 +6,9 @@ import (
|
|||
"math"
|
||||
|
||||
"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/interop"
|
||||
"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/crypto/keys"
|
||||
|
@ -32,7 +34,7 @@ type StorageContext struct {
|
|||
// getBlockHashFromElement converts given vm.Element to block hash using given
|
||||
// Blockchainer if needed. Interop functions accept both block numbers and
|
||||
// block hashes as parameters, thus this function is needed.
|
||||
func getBlockHashFromElement(bc Blockchainer, element *vm.Element) (util.Uint256, error) {
|
||||
func getBlockHashFromElement(bc blockchainer.Blockchainer, element *vm.Element) (util.Uint256, error) {
|
||||
var hash util.Uint256
|
||||
hashbytes := element.Bytes()
|
||||
if len(hashbytes) <= 5 {
|
||||
|
@ -48,12 +50,12 @@ func getBlockHashFromElement(bc Blockchainer, element *vm.Element) (util.Uint256
|
|||
}
|
||||
|
||||
// bcGetBlock returns current block.
|
||||
func (ic *interopContext) bcGetBlock(v *vm.VM) error {
|
||||
hash, err := getBlockHashFromElement(ic.bc, v.Estack().Pop())
|
||||
func bcGetBlock(ic *interop.Context, v *vm.VM) error {
|
||||
hash, err := getBlockHashFromElement(ic.Chain, v.Estack().Pop())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
block, err := ic.bc.GetBlock(hash)
|
||||
block, err := ic.Chain.GetBlock(hash)
|
||||
if err != nil {
|
||||
v.Estack().PushVal([]byte{})
|
||||
} else {
|
||||
|
@ -63,13 +65,13 @@ func (ic *interopContext) bcGetBlock(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// bcGetContract returns contract.
|
||||
func (ic *interopContext) bcGetContract(v *vm.VM) error {
|
||||
func bcGetContract(ic *interop.Context, v *vm.VM) error {
|
||||
hashbytes := v.Estack().Pop().Bytes()
|
||||
hash, err := util.Uint160DecodeBytesBE(hashbytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cs, err := ic.dao.GetContractState(hash)
|
||||
cs, err := ic.DAO.GetContractState(hash)
|
||||
if err != nil {
|
||||
v.Estack().PushVal([]byte{})
|
||||
} else {
|
||||
|
@ -79,12 +81,12 @@ func (ic *interopContext) bcGetContract(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// bcGetHeader returns block header.
|
||||
func (ic *interopContext) bcGetHeader(v *vm.VM) error {
|
||||
hash, err := getBlockHashFromElement(ic.bc, v.Estack().Pop())
|
||||
func bcGetHeader(ic *interop.Context, v *vm.VM) error {
|
||||
hash, err := getBlockHashFromElement(ic.Chain, v.Estack().Pop())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header, err := ic.bc.GetHeader(hash)
|
||||
header, err := ic.Chain.GetHeader(hash)
|
||||
if err != nil {
|
||||
v.Estack().PushVal([]byte{})
|
||||
} else {
|
||||
|
@ -94,8 +96,8 @@ func (ic *interopContext) bcGetHeader(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// bcGetHeight returns blockchain height.
|
||||
func (ic *interopContext) bcGetHeight(v *vm.VM) error {
|
||||
v.Estack().PushVal(ic.bc.BlockHeight())
|
||||
func bcGetHeight(ic *interop.Context, v *vm.VM) error {
|
||||
v.Estack().PushVal(ic.Chain.BlockHeight())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -111,8 +113,8 @@ func getTransactionAndHeight(cd *dao.Cached, v *vm.VM) (*transaction.Transaction
|
|||
}
|
||||
|
||||
// bcGetTransaction returns transaction.
|
||||
func (ic *interopContext) bcGetTransaction(v *vm.VM) error {
|
||||
tx, _, err := getTransactionAndHeight(ic.dao, v)
|
||||
func bcGetTransaction(ic *interop.Context, v *vm.VM) error {
|
||||
tx, _, err := getTransactionAndHeight(ic.DAO, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -121,8 +123,8 @@ func (ic *interopContext) bcGetTransaction(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// bcGetTransactionHeight returns transaction height.
|
||||
func (ic *interopContext) bcGetTransactionHeight(v *vm.VM) error {
|
||||
_, h, err := getTransactionAndHeight(ic.dao, v)
|
||||
func bcGetTransactionHeight(ic *interop.Context, v *vm.VM) error {
|
||||
_, h, err := getTransactionAndHeight(ic.DAO, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -147,7 +149,7 @@ func popHeaderFromVM(v *vm.VM) (*block.Header, error) {
|
|||
}
|
||||
|
||||
// headerGetIndex returns block index from the header.
|
||||
func (ic *interopContext) headerGetIndex(v *vm.VM) error {
|
||||
func headerGetIndex(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -157,7 +159,7 @@ func (ic *interopContext) headerGetIndex(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// headerGetHash returns header hash of the passed header.
|
||||
func (ic *interopContext) headerGetHash(v *vm.VM) error {
|
||||
func headerGetHash(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -167,7 +169,7 @@ func (ic *interopContext) headerGetHash(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// headerGetPrevHash returns previous header hash of the passed header.
|
||||
func (ic *interopContext) headerGetPrevHash(v *vm.VM) error {
|
||||
func headerGetPrevHash(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -177,7 +179,7 @@ func (ic *interopContext) headerGetPrevHash(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// headerGetTimestamp returns timestamp of the passed header.
|
||||
func (ic *interopContext) headerGetTimestamp(v *vm.VM) error {
|
||||
func headerGetTimestamp(ic *interop.Context, v *vm.VM) error {
|
||||
header, err := popHeaderFromVM(v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -187,7 +189,7 @@ func (ic *interopContext) headerGetTimestamp(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// blockGetTransactionCount returns transactions count in the given block.
|
||||
func (ic *interopContext) blockGetTransactionCount(v *vm.VM) error {
|
||||
func blockGetTransactionCount(ic *interop.Context, v *vm.VM) error {
|
||||
blockInterface := v.Estack().Pop().Value()
|
||||
block, ok := blockInterface.(*block.Block)
|
||||
if !ok {
|
||||
|
@ -198,7 +200,7 @@ func (ic *interopContext) blockGetTransactionCount(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// blockGetTransactions returns transactions from the given block.
|
||||
func (ic *interopContext) blockGetTransactions(v *vm.VM) error {
|
||||
func blockGetTransactions(ic *interop.Context, v *vm.VM) error {
|
||||
blockInterface := v.Estack().Pop().Value()
|
||||
block, ok := blockInterface.(*block.Block)
|
||||
if !ok {
|
||||
|
@ -217,7 +219,7 @@ func (ic *interopContext) blockGetTransactions(v *vm.VM) error {
|
|||
|
||||
// blockGetTransaction returns transaction with the given number from the given
|
||||
// block.
|
||||
func (ic *interopContext) blockGetTransaction(v *vm.VM) error {
|
||||
func blockGetTransaction(ic *interop.Context, v *vm.VM) error {
|
||||
blockInterface := v.Estack().Pop().Value()
|
||||
block, ok := blockInterface.(*block.Block)
|
||||
if !ok {
|
||||
|
@ -233,7 +235,7 @@ func (ic *interopContext) blockGetTransaction(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// txGetHash returns transaction's hash.
|
||||
func (ic *interopContext) txGetHash(v *vm.VM) error {
|
||||
func txGetHash(ic *interop.Context, v *vm.VM) error {
|
||||
txInterface := v.Estack().Pop().Value()
|
||||
tx, ok := txInterface.(*transaction.Transaction)
|
||||
if !ok {
|
||||
|
@ -245,8 +247,8 @@ func (ic *interopContext) txGetHash(v *vm.VM) error {
|
|||
|
||||
// engineGetScriptContainer returns transaction that contains the script being
|
||||
// run.
|
||||
func (ic *interopContext) engineGetScriptContainer(v *vm.VM) error {
|
||||
v.Estack().PushVal(vm.NewInteropItem(ic.tx))
|
||||
func engineGetScriptContainer(ic *interop.Context, v *vm.VM) error {
|
||||
v.Estack().PushVal(vm.NewInteropItem(ic.Tx))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -267,36 +269,36 @@ func pushContextScriptHash(v *vm.VM, n int) error {
|
|||
}
|
||||
|
||||
// engineGetExecutingScriptHash returns executing script hash.
|
||||
func (ic *interopContext) engineGetExecutingScriptHash(v *vm.VM) error {
|
||||
func engineGetExecutingScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||
return pushContextScriptHash(v, 0)
|
||||
}
|
||||
|
||||
// engineGetCallingScriptHash returns calling script hash.
|
||||
func (ic *interopContext) engineGetCallingScriptHash(v *vm.VM) error {
|
||||
func engineGetCallingScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||
return pushContextScriptHash(v, 1)
|
||||
}
|
||||
|
||||
// engineGetEntryScriptHash returns entry script hash.
|
||||
func (ic *interopContext) engineGetEntryScriptHash(v *vm.VM) error {
|
||||
func engineGetEntryScriptHash(ic *interop.Context, v *vm.VM) error {
|
||||
return pushContextScriptHash(v, v.Istack().Len()-1)
|
||||
}
|
||||
|
||||
// runtimePlatform returns the name of the platform.
|
||||
func (ic *interopContext) runtimePlatform(v *vm.VM) error {
|
||||
func runtimePlatform(ic *interop.Context, v *vm.VM) error {
|
||||
v.Estack().PushVal([]byte("NEO"))
|
||||
return nil
|
||||
}
|
||||
|
||||
// runtimeGetTrigger returns the script trigger.
|
||||
func (ic *interopContext) runtimeGetTrigger(v *vm.VM) error {
|
||||
v.Estack().PushVal(byte(ic.trigger))
|
||||
func runtimeGetTrigger(ic *interop.Context, v *vm.VM) error {
|
||||
v.Estack().PushVal(byte(ic.Trigger))
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkHashedWitness checks given hash against current list of script hashes
|
||||
// for verifying in the interop context.
|
||||
func (ic *interopContext) checkHashedWitness(hash util.Uint160) (bool, error) {
|
||||
hashes, err := ic.bc.GetScriptHashesForVerifying(ic.tx)
|
||||
func checkHashedWitness(ic *interop.Context, hash util.Uint160) (bool, error) {
|
||||
hashes, err := ic.Chain.GetScriptHashesForVerifying(ic.Tx)
|
||||
if err != nil {
|
||||
return false, gherr.Wrap(err, "failed to get script hashes")
|
||||
}
|
||||
|
@ -310,12 +312,12 @@ func (ic *interopContext) checkHashedWitness(hash util.Uint160) (bool, error) {
|
|||
|
||||
// checkKeyedWitness checks hash of signature check contract with a given public
|
||||
// key against current list of script hashes for verifying in the interop context.
|
||||
func (ic *interopContext) checkKeyedWitness(key *keys.PublicKey) (bool, error) {
|
||||
return ic.checkHashedWitness(key.GetScriptHash())
|
||||
func checkKeyedWitness(ic *interop.Context, key *keys.PublicKey) (bool, error) {
|
||||
return checkHashedWitness(ic, key.GetScriptHash())
|
||||
}
|
||||
|
||||
// runtimeCheckWitness checks witnesses.
|
||||
func (ic *interopContext) runtimeCheckWitness(v *vm.VM) error {
|
||||
func runtimeCheckWitness(ic *interop.Context, v *vm.VM) error {
|
||||
var res bool
|
||||
var err error
|
||||
|
||||
|
@ -327,9 +329,9 @@ func (ic *interopContext) runtimeCheckWitness(v *vm.VM) error {
|
|||
if err != nil {
|
||||
return errors.New("parameter given is neither a key nor a hash")
|
||||
}
|
||||
res, err = ic.checkKeyedWitness(key)
|
||||
res, err = checkKeyedWitness(ic, key)
|
||||
} else {
|
||||
res, err = ic.checkHashedWitness(hash)
|
||||
res, err = checkHashedWitness(ic, hash)
|
||||
}
|
||||
if err != nil {
|
||||
return gherr.Wrap(err, "failed to check")
|
||||
|
@ -340,7 +342,7 @@ func (ic *interopContext) runtimeCheckWitness(v *vm.VM) error {
|
|||
|
||||
// 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.
|
||||
func (ic *interopContext) runtimeNotify(v *vm.VM) error {
|
||||
func runtimeNotify(ic *interop.Context, v *vm.VM) error {
|
||||
// It can be just about anything.
|
||||
e := v.Estack().Pop()
|
||||
item := e.Item()
|
||||
|
@ -354,49 +356,38 @@ func (ic *interopContext) runtimeNotify(v *vm.VM) error {
|
|||
item = vm.NewByteArrayItem([]byte(fmt.Sprintf("bad notification: %v", err)))
|
||||
}
|
||||
ne := state.NotificationEvent{ScriptHash: getContextScriptHash(v, 0), Item: item}
|
||||
ic.notifications = append(ic.notifications, ne)
|
||||
ic.Notifications = append(ic.Notifications, ne)
|
||||
return nil
|
||||
}
|
||||
|
||||
// runtimeLog logs the message passed.
|
||||
func (ic *interopContext) runtimeLog(v *vm.VM) error {
|
||||
func runtimeLog(ic *interop.Context, v *vm.VM) error {
|
||||
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.String("logs", msg))
|
||||
return nil
|
||||
}
|
||||
|
||||
// runtimeGetTime returns timestamp of the block being verified, or the latest
|
||||
// one in the blockchain if no block is given to interopContext.
|
||||
func (ic *interopContext) runtimeGetTime(v *vm.VM) error {
|
||||
// one in the blockchain if no block is given to Context.
|
||||
func runtimeGetTime(ic *interop.Context, v *vm.VM) error {
|
||||
var header *block.Header
|
||||
if ic.block == nil {
|
||||
if ic.Block == nil {
|
||||
var err error
|
||||
header, err = ic.bc.GetHeader(ic.bc.CurrentBlockHash())
|
||||
header, err = ic.Chain.GetHeader(ic.Chain.CurrentBlockHash())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
header = ic.block.Header()
|
||||
header = ic.Block.Header()
|
||||
}
|
||||
v.Estack().PushVal(header.Timestamp)
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
// runtimeSerialize serializes given stack item.
|
||||
func (ic *interopContext) runtimeSerialize(v *vm.VM) error {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
// runtimeDeserialize deserializes given stack item.
|
||||
func (ic *interopContext) runtimeDeserialize(v *vm.VM) error {
|
||||
panic("TODO")
|
||||
}
|
||||
*/
|
||||
func (ic *interopContext) checkStorageContext(stc *StorageContext) error {
|
||||
contract, err := ic.dao.GetContractState(stc.ScriptHash)
|
||||
func checkStorageContext(ic *interop.Context, stc *StorageContext) error {
|
||||
contract, err := ic.DAO.GetContractState(stc.ScriptHash)
|
||||
if err != nil {
|
||||
return errors.New("no contract found")
|
||||
}
|
||||
|
@ -407,8 +398,8 @@ func (ic *interopContext) checkStorageContext(stc *StorageContext) error {
|
|||
}
|
||||
|
||||
// storageDelete deletes stored key-value pair.
|
||||
func (ic *interopContext) storageDelete(v *vm.VM) error {
|
||||
if ic.trigger != trigger.Application && ic.trigger != trigger.ApplicationR {
|
||||
func storageDelete(ic *interop.Context, v *vm.VM) error {
|
||||
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()
|
||||
|
@ -419,31 +410,31 @@ func (ic *interopContext) storageDelete(v *vm.VM) error {
|
|||
if stc.ReadOnly {
|
||||
return errors.New("StorageContext is read only")
|
||||
}
|
||||
err := ic.checkStorageContext(stc)
|
||||
err := checkStorageContext(ic, stc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := v.Estack().Pop().Bytes()
|
||||
si := ic.dao.GetStorageItem(stc.ScriptHash, key)
|
||||
si := ic.DAO.GetStorageItem(stc.ScriptHash, key)
|
||||
if si != nil && si.IsConst {
|
||||
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.
|
||||
func (ic *interopContext) storageGet(v *vm.VM) error {
|
||||
func storageGet(ic *interop.Context, v *vm.VM) error {
|
||||
stcInterface := v.Estack().Pop().Value()
|
||||
stc, ok := stcInterface.(*StorageContext)
|
||||
if !ok {
|
||||
return fmt.Errorf("%T is not a StorageContext", stcInterface)
|
||||
}
|
||||
err := ic.checkStorageContext(stc)
|
||||
err := checkStorageContext(ic, stc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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 {
|
||||
v.Estack().PushVal(si.Value)
|
||||
} else {
|
||||
|
@ -453,7 +444,7 @@ func (ic *interopContext) storageGet(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// storageGetContext returns storage context (scripthash).
|
||||
func (ic *interopContext) storageGetContext(v *vm.VM) error {
|
||||
func storageGetContext(ic *interop.Context, v *vm.VM) error {
|
||||
sc := &StorageContext{
|
||||
ScriptHash: getContextScriptHash(v, 0),
|
||||
ReadOnly: false,
|
||||
|
@ -463,7 +454,7 @@ func (ic *interopContext) storageGetContext(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// storageGetReadOnlyContext returns read-only context (scripthash).
|
||||
func (ic *interopContext) storageGetReadOnlyContext(v *vm.VM) error {
|
||||
func storageGetReadOnlyContext(ic *interop.Context, v *vm.VM) error {
|
||||
sc := &StorageContext{
|
||||
ScriptHash: getContextScriptHash(v, 0),
|
||||
ReadOnly: true,
|
||||
|
@ -472,8 +463,8 @@ func (ic *interopContext) storageGetReadOnlyContext(v *vm.VM) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ic *interopContext) putWithContextAndFlags(stc *StorageContext, key []byte, value []byte, isConst bool) error {
|
||||
if ic.trigger != trigger.Application && ic.trigger != trigger.ApplicationR {
|
||||
func putWithContextAndFlags(ic *interop.Context, stc *StorageContext, key []byte, value []byte, isConst bool) error {
|
||||
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 {
|
||||
|
@ -482,11 +473,11 @@ func (ic *interopContext) putWithContextAndFlags(stc *StorageContext, key []byte
|
|||
if stc.ReadOnly {
|
||||
return errors.New("StorageContext is read only")
|
||||
}
|
||||
err := ic.checkStorageContext(stc)
|
||||
err := checkStorageContext(ic, stc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
si := ic.dao.GetStorageItem(stc.ScriptHash, key)
|
||||
si := ic.DAO.GetStorageItem(stc.ScriptHash, key)
|
||||
if si == nil {
|
||||
si = &state.StorageItem{}
|
||||
}
|
||||
|
@ -495,11 +486,11 @@ func (ic *interopContext) putWithContextAndFlags(stc *StorageContext, key []byte
|
|||
}
|
||||
si.Value = value
|
||||
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.
|
||||
func (ic *interopContext) storagePutInternal(v *vm.VM, getFlag bool) error {
|
||||
func storagePutInternal(ic *interop.Context, v *vm.VM, getFlag bool) error {
|
||||
stcInterface := v.Estack().Pop().Value()
|
||||
stc, ok := stcInterface.(*StorageContext)
|
||||
if !ok {
|
||||
|
@ -511,21 +502,21 @@ func (ic *interopContext) storagePutInternal(v *vm.VM, getFlag bool) error {
|
|||
if getFlag {
|
||||
flag = int(v.Estack().Pop().BigInt().Int64())
|
||||
}
|
||||
return ic.putWithContextAndFlags(stc, key, value, flag == 1)
|
||||
return putWithContextAndFlags(ic, stc, key, value, flag == 1)
|
||||
}
|
||||
|
||||
// storagePut puts key-value pair into the storage.
|
||||
func (ic *interopContext) storagePut(v *vm.VM) error {
|
||||
return ic.storagePutInternal(v, false)
|
||||
func storagePut(ic *interop.Context, v *vm.VM) error {
|
||||
return storagePutInternal(ic, v, false)
|
||||
}
|
||||
|
||||
// storagePutEx puts key-value pair with given flags into the storage.
|
||||
func (ic *interopContext) storagePutEx(v *vm.VM) error {
|
||||
return ic.storagePutInternal(v, true)
|
||||
func storagePutEx(ic *interop.Context, v *vm.VM) error {
|
||||
return storagePutInternal(ic, v, true)
|
||||
}
|
||||
|
||||
// storageContextAsReadOnly sets given context to read-only mode.
|
||||
func (ic *interopContext) storageContextAsReadOnly(v *vm.VM) error {
|
||||
func storageContextAsReadOnly(ic *interop.Context, v *vm.VM) error {
|
||||
stcInterface := v.Estack().Pop().Value()
|
||||
stc, ok := stcInterface.(*StorageContext)
|
||||
if !ok {
|
||||
|
@ -543,39 +534,39 @@ func (ic *interopContext) storageContextAsReadOnly(v *vm.VM) error {
|
|||
}
|
||||
|
||||
// contractDestroy destroys a contract.
|
||||
func (ic *interopContext) contractDestroy(v *vm.VM) error {
|
||||
if ic.trigger != trigger.Application {
|
||||
func contractDestroy(ic *interop.Context, v *vm.VM) error {
|
||||
if ic.Trigger != trigger.Application {
|
||||
return errors.New("can't destroy contract when not triggered by application")
|
||||
}
|
||||
hash := getContextScriptHash(v, 0)
|
||||
cs, err := ic.dao.GetContractState(hash)
|
||||
cs, err := ic.DAO.GetContractState(hash)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
err = ic.dao.DeleteContractState(hash)
|
||||
err = ic.DAO.DeleteContractState(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cs.HasStorage() {
|
||||
siMap, err := ic.dao.GetStorageItems(hash)
|
||||
siMap, err := ic.DAO.GetStorageItems(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k := range siMap {
|
||||
_ = ic.dao.DeleteStorageItem(hash, []byte(k))
|
||||
_ = ic.DAO.DeleteStorageItem(hash, []byte(k))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// contractGetStorageContext retrieves StorageContext of a contract.
|
||||
func (ic *interopContext) contractGetStorageContext(v *vm.VM) error {
|
||||
func contractGetStorageContext(ic *interop.Context, v *vm.VM) error {
|
||||
csInterface := v.Estack().Pop().Value()
|
||||
cs, ok := csInterface.(*state.Contract)
|
||||
if !ok {
|
||||
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 {
|
||||
return fmt.Errorf("contract was not created in this transaction")
|
||||
}
|
||||
|
|
|
@ -10,274 +10,246 @@ package core
|
|||
import (
|
||||
"sort"
|
||||
|
||||
"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/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
|
||||
"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/vm"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type interopContext struct {
|
||||
bc 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, 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
|
||||
// up for current blockchain.
|
||||
func (ic *interopContext) SpawnVM() *vm.VM {
|
||||
func SpawnVM(ic *interop.Context) *vm.VM {
|
||||
vm := vm.New()
|
||||
vm.SetScriptGetter(func(hash util.Uint160) ([]byte, bool) {
|
||||
cs, err := ic.dao.GetContractState(hash)
|
||||
cs, err := ic.DAO.GetContractState(hash)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
hasDynamicInvoke := (cs.Properties & smartcontract.HasDynamicInvoke) != 0
|
||||
return cs.Script, hasDynamicInvoke
|
||||
})
|
||||
vm.RegisterInteropGetter(ic.getSystemInterop)
|
||||
vm.RegisterInteropGetter(ic.getNeoInterop)
|
||||
vm.RegisterInteropGetter(getSystemInterop(ic))
|
||||
vm.RegisterInteropGetter(getNeoInterop(ic))
|
||||
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
|
||||
// for a given id in the current context.
|
||||
func (ic *interopContext) getSystemInterop(id uint32) *vm.InteropFuncPrice {
|
||||
return ic.getInteropFromSlice(id, systemInterops)
|
||||
func getSystemInterop(ic *interop.Context) vm.InteropGetterFunc {
|
||||
return getInteropFromSlice(ic, systemInterops)
|
||||
}
|
||||
|
||||
// getNeoInterop returns matching interop function from the Neo and AntShares
|
||||
// namespaces for a given id in the current context.
|
||||
func (ic *interopContext) getNeoInterop(id uint32) *vm.InteropFuncPrice {
|
||||
return ic.getInteropFromSlice(id, neoInterops)
|
||||
func getNeoInterop(ic *interop.Context) vm.InteropGetterFunc {
|
||||
return getInteropFromSlice(ic, neoInterops)
|
||||
}
|
||||
|
||||
// getInteropFromSlice returns matching interop function from the given slice of
|
||||
// interop functions in the current context.
|
||||
func (ic *interopContext) getInteropFromSlice(id uint32, slice []interopedFunction) *vm.InteropFuncPrice {
|
||||
n := sort.Search(len(slice), func(i int) bool {
|
||||
return slice[i].ID >= id
|
||||
})
|
||||
if n < len(slice) && slice[n].ID == id {
|
||||
// Currying, yay!
|
||||
return &vm.InteropFuncPrice{Func: func(v *vm.VM) error {
|
||||
return slice[n].Func(ic, v)
|
||||
}, Price: slice[n].Price}
|
||||
func getInteropFromSlice(ic *interop.Context, slice []interop.Function) func(uint32) *vm.InteropFuncPrice {
|
||||
return func(id uint32) *vm.InteropFuncPrice {
|
||||
n := sort.Search(len(slice), func(i int) bool {
|
||||
return slice[i].ID >= id
|
||||
})
|
||||
if n < len(slice) && slice[n].ID == id {
|
||||
return &vm.InteropFuncPrice{Func: func(v *vm.VM) error {
|
||||
return slice[n].Func(ic, v)
|
||||
}, Price: slice[n].Price}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// All lists are sorted, keep 'em this way, please.
|
||||
var systemInterops = []interopedFunction{
|
||||
{Name: "System.Block.GetTransaction", Func: (*interopContext).blockGetTransaction, Price: 1},
|
||||
{Name: "System.Block.GetTransactionCount", Func: (*interopContext).blockGetTransactionCount, Price: 1},
|
||||
{Name: "System.Block.GetTransactions", Func: (*interopContext).blockGetTransactions, Price: 1},
|
||||
{Name: "System.Blockchain.GetBlock", Func: (*interopContext).bcGetBlock, Price: 200},
|
||||
{Name: "System.Blockchain.GetContract", Func: (*interopContext).bcGetContract, Price: 100},
|
||||
{Name: "System.Blockchain.GetHeader", Func: (*interopContext).bcGetHeader, Price: 100},
|
||||
{Name: "System.Blockchain.GetHeight", Func: (*interopContext).bcGetHeight, Price: 1},
|
||||
{Name: "System.Blockchain.GetTransaction", Func: (*interopContext).bcGetTransaction, Price: 200},
|
||||
{Name: "System.Blockchain.GetTransactionHeight", Func: (*interopContext).bcGetTransactionHeight, Price: 100},
|
||||
{Name: "System.Contract.Destroy", Func: (*interopContext).contractDestroy, Price: 1},
|
||||
{Name: "System.Contract.GetStorageContext", Func: (*interopContext).contractGetStorageContext, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetCallingScriptHash", Func: (*interopContext).engineGetCallingScriptHash, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetEntryScriptHash", Func: (*interopContext).engineGetEntryScriptHash, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetExecutingScriptHash", Func: (*interopContext).engineGetExecutingScriptHash, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetScriptContainer", Func: (*interopContext).engineGetScriptContainer, Price: 1},
|
||||
{Name: "System.Header.GetHash", Func: (*interopContext).headerGetHash, Price: 1},
|
||||
{Name: "System.Header.GetIndex", Func: (*interopContext).headerGetIndex, Price: 1},
|
||||
{Name: "System.Header.GetPrevHash", Func: (*interopContext).headerGetPrevHash, Price: 1},
|
||||
{Name: "System.Header.GetTimestamp", Func: (*interopContext).headerGetTimestamp, Price: 1},
|
||||
{Name: "System.Runtime.CheckWitness", Func: (*interopContext).runtimeCheckWitness, Price: 200},
|
||||
{Name: "System.Runtime.Deserialize", Func: (*interopContext).runtimeDeserialize, Price: 1},
|
||||
{Name: "System.Runtime.GetTime", Func: (*interopContext).runtimeGetTime, Price: 1},
|
||||
{Name: "System.Runtime.GetTrigger", Func: (*interopContext).runtimeGetTrigger, Price: 1},
|
||||
{Name: "System.Runtime.Log", Func: (*interopContext).runtimeLog, Price: 1},
|
||||
{Name: "System.Runtime.Notify", Func: (*interopContext).runtimeNotify, Price: 1},
|
||||
{Name: "System.Runtime.Platform", Func: (*interopContext).runtimePlatform, Price: 1},
|
||||
{Name: "System.Runtime.Serialize", Func: (*interopContext).runtimeSerialize, Price: 1},
|
||||
{Name: "System.Storage.Delete", Func: (*interopContext).storageDelete, Price: 100},
|
||||
{Name: "System.Storage.Get", Func: (*interopContext).storageGet, Price: 100},
|
||||
{Name: "System.Storage.GetContext", Func: (*interopContext).storageGetContext, Price: 1},
|
||||
{Name: "System.Storage.GetReadOnlyContext", Func: (*interopContext).storageGetReadOnlyContext, Price: 1},
|
||||
{Name: "System.Storage.Put", Func: (*interopContext).storagePut, Price: 0}, // These don't have static price in C# code.
|
||||
{Name: "System.Storage.PutEx", Func: (*interopContext).storagePutEx, Price: 0},
|
||||
{Name: "System.StorageContext.AsReadOnly", Func: (*interopContext).storageContextAsReadOnly, Price: 1},
|
||||
{Name: "System.Transaction.GetHash", Func: (*interopContext).txGetHash, Price: 1},
|
||||
var systemInterops = []interop.Function{
|
||||
{Name: "System.Block.GetTransaction", Func: blockGetTransaction, Price: 1},
|
||||
{Name: "System.Block.GetTransactionCount", Func: blockGetTransactionCount, Price: 1},
|
||||
{Name: "System.Block.GetTransactions", Func: blockGetTransactions, Price: 1},
|
||||
{Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 200},
|
||||
{Name: "System.Blockchain.GetContract", Func: bcGetContract, Price: 100},
|
||||
{Name: "System.Blockchain.GetHeader", Func: bcGetHeader, Price: 100},
|
||||
{Name: "System.Blockchain.GetHeight", Func: bcGetHeight, Price: 1},
|
||||
{Name: "System.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 200},
|
||||
{Name: "System.Blockchain.GetTransactionHeight", Func: bcGetTransactionHeight, Price: 100},
|
||||
{Name: "System.Contract.Destroy", Func: contractDestroy, Price: 1},
|
||||
{Name: "System.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetCallingScriptHash", Func: engineGetCallingScriptHash, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetEntryScriptHash", Func: engineGetEntryScriptHash, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetExecutingScriptHash", Func: engineGetExecutingScriptHash, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetScriptContainer", Func: engineGetScriptContainer, Price: 1},
|
||||
{Name: "System.Header.GetHash", Func: headerGetHash, Price: 1},
|
||||
{Name: "System.Header.GetIndex", Func: headerGetIndex, Price: 1},
|
||||
{Name: "System.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1},
|
||||
{Name: "System.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1},
|
||||
{Name: "System.Runtime.CheckWitness", Func: runtimeCheckWitness, Price: 200},
|
||||
{Name: "System.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1},
|
||||
{Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1},
|
||||
{Name: "System.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 1},
|
||||
{Name: "System.Runtime.Log", Func: runtimeLog, Price: 1},
|
||||
{Name: "System.Runtime.Notify", Func: runtimeNotify, Price: 1},
|
||||
{Name: "System.Runtime.Platform", Func: runtimePlatform, Price: 1},
|
||||
{Name: "System.Runtime.Serialize", Func: runtimeSerialize, Price: 1},
|
||||
{Name: "System.Storage.Delete", Func: storageDelete, Price: 100},
|
||||
{Name: "System.Storage.Get", Func: storageGet, Price: 100},
|
||||
{Name: "System.Storage.GetContext", Func: storageGetContext, Price: 1},
|
||||
{Name: "System.Storage.GetReadOnlyContext", Func: storageGetReadOnlyContext, Price: 1},
|
||||
{Name: "System.Storage.Put", Func: storagePut, Price: 0}, // These don't have static price in C# code.
|
||||
{Name: "System.Storage.PutEx", Func: storagePutEx, Price: 0},
|
||||
{Name: "System.StorageContext.AsReadOnly", Func: storageContextAsReadOnly, Price: 1},
|
||||
{Name: "System.Transaction.GetHash", Func: txGetHash, Price: 1},
|
||||
}
|
||||
|
||||
var neoInterops = []interopedFunction{
|
||||
{Name: "Neo.Account.GetBalance", Func: (*interopContext).accountGetBalance, Price: 1},
|
||||
{Name: "Neo.Account.GetScriptHash", Func: (*interopContext).accountGetScriptHash, Price: 1},
|
||||
{Name: "Neo.Account.GetVotes", Func: (*interopContext).accountGetVotes, Price: 1},
|
||||
{Name: "Neo.Account.IsStandard", Func: (*interopContext).accountIsStandard, Price: 100},
|
||||
{Name: "Neo.Asset.Create", Func: (*interopContext).assetCreate, Price: 0},
|
||||
{Name: "Neo.Asset.GetAdmin", Func: (*interopContext).assetGetAdmin, Price: 1},
|
||||
{Name: "Neo.Asset.GetAmount", Func: (*interopContext).assetGetAmount, Price: 1},
|
||||
{Name: "Neo.Asset.GetAssetId", Func: (*interopContext).assetGetAssetID, Price: 1},
|
||||
{Name: "Neo.Asset.GetAssetType", Func: (*interopContext).assetGetAssetType, Price: 1},
|
||||
{Name: "Neo.Asset.GetAvailable", Func: (*interopContext).assetGetAvailable, Price: 1},
|
||||
{Name: "Neo.Asset.GetIssuer", Func: (*interopContext).assetGetIssuer, Price: 1},
|
||||
{Name: "Neo.Asset.GetOwner", Func: (*interopContext).assetGetOwner, Price: 1},
|
||||
{Name: "Neo.Asset.GetPrecision", Func: (*interopContext).assetGetPrecision, Price: 1},
|
||||
{Name: "Neo.Asset.Renew", Func: (*interopContext).assetRenew, Price: 0},
|
||||
{Name: "Neo.Attribute.GetData", Func: (*interopContext).attrGetData, Price: 1},
|
||||
{Name: "Neo.Attribute.GetUsage", Func: (*interopContext).attrGetUsage, Price: 1},
|
||||
{Name: "Neo.Block.GetTransaction", Func: (*interopContext).blockGetTransaction, Price: 1},
|
||||
{Name: "Neo.Block.GetTransactionCount", Func: (*interopContext).blockGetTransactionCount, Price: 1},
|
||||
{Name: "Neo.Block.GetTransactions", Func: (*interopContext).blockGetTransactions, Price: 1},
|
||||
{Name: "Neo.Blockchain.GetAccount", Func: (*interopContext).bcGetAccount, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetAsset", Func: (*interopContext).bcGetAsset, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetBlock", Func: (*interopContext).bcGetBlock, Price: 200},
|
||||
{Name: "Neo.Blockchain.GetContract", Func: (*interopContext).bcGetContract, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetHeader", Func: (*interopContext).bcGetHeader, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetHeight", Func: (*interopContext).bcGetHeight, Price: 1},
|
||||
{Name: "Neo.Blockchain.GetTransaction", Func: (*interopContext).bcGetTransaction, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetTransactionHeight", Func: (*interopContext).bcGetTransactionHeight, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetValidators", Func: (*interopContext).bcGetValidators, Price: 200},
|
||||
{Name: "Neo.Contract.Create", Func: (*interopContext).contractCreate, Price: 0},
|
||||
{Name: "Neo.Contract.Destroy", Func: (*interopContext).contractDestroy, Price: 1},
|
||||
{Name: "Neo.Contract.GetScript", Func: (*interopContext).contractGetScript, Price: 1},
|
||||
{Name: "Neo.Contract.GetStorageContext", Func: (*interopContext).contractGetStorageContext, Price: 1},
|
||||
{Name: "Neo.Contract.IsPayable", Func: (*interopContext).contractIsPayable, Price: 1},
|
||||
{Name: "Neo.Contract.Migrate", Func: (*interopContext).contractMigrate, Price: 0},
|
||||
{Name: "Neo.Enumerator.Concat", Func: (*interopContext).enumeratorConcat, Price: 1},
|
||||
{Name: "Neo.Enumerator.Create", Func: (*interopContext).enumeratorCreate, Price: 1},
|
||||
{Name: "Neo.Enumerator.Next", Func: (*interopContext).enumeratorNext, Price: 1},
|
||||
{Name: "Neo.Enumerator.Value", Func: (*interopContext).enumeratorValue, Price: 1},
|
||||
{Name: "Neo.Header.GetConsensusData", Func: (*interopContext).headerGetConsensusData, Price: 1},
|
||||
{Name: "Neo.Header.GetHash", Func: (*interopContext).headerGetHash, Price: 1},
|
||||
{Name: "Neo.Header.GetIndex", Func: (*interopContext).headerGetIndex, Price: 1},
|
||||
{Name: "Neo.Header.GetMerkleRoot", Func: (*interopContext).headerGetMerkleRoot, Price: 1},
|
||||
{Name: "Neo.Header.GetNextConsensus", Func: (*interopContext).headerGetNextConsensus, Price: 1},
|
||||
{Name: "Neo.Header.GetPrevHash", Func: (*interopContext).headerGetPrevHash, Price: 1},
|
||||
{Name: "Neo.Header.GetTimestamp", Func: (*interopContext).headerGetTimestamp, Price: 1},
|
||||
{Name: "Neo.Header.GetVersion", Func: (*interopContext).headerGetVersion, Price: 1},
|
||||
{Name: "Neo.Input.GetHash", Func: (*interopContext).inputGetHash, Price: 1},
|
||||
{Name: "Neo.Input.GetIndex", Func: (*interopContext).inputGetIndex, Price: 1},
|
||||
{Name: "Neo.InvocationTransaction.GetScript", Func: (*interopContext).invocationTxGetScript, Price: 1},
|
||||
{Name: "Neo.Iterator.Concat", Func: (*interopContext).iteratorConcat, Price: 1},
|
||||
{Name: "Neo.Iterator.Create", Func: (*interopContext).iteratorCreate, Price: 1},
|
||||
{Name: "Neo.Iterator.Key", Func: (*interopContext).iteratorKey, Price: 1},
|
||||
{Name: "Neo.Iterator.Keys", Func: (*interopContext).iteratorKeys, Price: 1},
|
||||
{Name: "Neo.Iterator.Values", Func: (*interopContext).iteratorValues, Price: 1},
|
||||
{Name: "Neo.Output.GetAssetId", Func: (*interopContext).outputGetAssetID, Price: 1},
|
||||
{Name: "Neo.Output.GetScriptHash", Func: (*interopContext).outputGetScriptHash, Price: 1},
|
||||
{Name: "Neo.Output.GetValue", Func: (*interopContext).outputGetValue, Price: 1},
|
||||
{Name: "Neo.Runtime.CheckWitness", Func: (*interopContext).runtimeCheckWitness, Price: 200},
|
||||
{Name: "Neo.Runtime.Deserialize", Func: (*interopContext).runtimeDeserialize, Price: 1},
|
||||
{Name: "Neo.Runtime.GetTime", Func: (*interopContext).runtimeGetTime, Price: 1},
|
||||
{Name: "Neo.Runtime.GetTrigger", Func: (*interopContext).runtimeGetTrigger, Price: 1},
|
||||
{Name: "Neo.Runtime.Log", Func: (*interopContext).runtimeLog, Price: 1},
|
||||
{Name: "Neo.Runtime.Notify", Func: (*interopContext).runtimeNotify, Price: 1},
|
||||
{Name: "Neo.Runtime.Serialize", Func: (*interopContext).runtimeSerialize, Price: 1},
|
||||
{Name: "Neo.Storage.Delete", Func: (*interopContext).storageDelete, Price: 100},
|
||||
{Name: "Neo.Storage.Find", Func: (*interopContext).storageFind, Price: 1},
|
||||
{Name: "Neo.Storage.Get", Func: (*interopContext).storageGet, Price: 100},
|
||||
{Name: "Neo.Storage.GetContext", Func: (*interopContext).storageGetContext, Price: 1},
|
||||
{Name: "Neo.Storage.GetReadOnlyContext", Func: (*interopContext).storageGetReadOnlyContext, Price: 1},
|
||||
{Name: "Neo.Storage.Put", Func: (*interopContext).storagePut, Price: 0},
|
||||
{Name: "Neo.StorageContext.AsReadOnly", Func: (*interopContext).storageContextAsReadOnly, Price: 1},
|
||||
{Name: "Neo.Transaction.GetAttributes", Func: (*interopContext).txGetAttributes, Price: 1},
|
||||
{Name: "Neo.Transaction.GetHash", Func: (*interopContext).txGetHash, Price: 1},
|
||||
{Name: "Neo.Transaction.GetInputs", Func: (*interopContext).txGetInputs, Price: 1},
|
||||
{Name: "Neo.Transaction.GetOutputs", Func: (*interopContext).txGetOutputs, Price: 1},
|
||||
{Name: "Neo.Transaction.GetReferences", Func: (*interopContext).txGetReferences, Price: 200},
|
||||
{Name: "Neo.Transaction.GetType", Func: (*interopContext).txGetType, Price: 1},
|
||||
{Name: "Neo.Transaction.GetUnspentCoins", Func: (*interopContext).txGetUnspentCoins, Price: 200},
|
||||
{Name: "Neo.Transaction.GetWitnesses", Func: (*interopContext).txGetWitnesses, Price: 200},
|
||||
{Name: "Neo.Witness.GetVerificationScript", Func: (*interopContext).witnessGetVerificationScript, Price: 100},
|
||||
var neoInterops = []interop.Function{
|
||||
{Name: "Neo.Account.GetBalance", Func: accountGetBalance, Price: 1},
|
||||
{Name: "Neo.Account.GetScriptHash", Func: accountGetScriptHash, Price: 1},
|
||||
{Name: "Neo.Account.GetVotes", Func: accountGetVotes, Price: 1},
|
||||
{Name: "Neo.Account.IsStandard", Func: accountIsStandard, Price: 100},
|
||||
{Name: "Neo.Asset.Create", Func: assetCreate, Price: 0},
|
||||
{Name: "Neo.Asset.GetAdmin", Func: assetGetAdmin, Price: 1},
|
||||
{Name: "Neo.Asset.GetAmount", Func: assetGetAmount, Price: 1},
|
||||
{Name: "Neo.Asset.GetAssetId", Func: assetGetAssetID, Price: 1},
|
||||
{Name: "Neo.Asset.GetAssetType", Func: assetGetAssetType, Price: 1},
|
||||
{Name: "Neo.Asset.GetAvailable", Func: assetGetAvailable, Price: 1},
|
||||
{Name: "Neo.Asset.GetIssuer", Func: assetGetIssuer, Price: 1},
|
||||
{Name: "Neo.Asset.GetOwner", Func: assetGetOwner, Price: 1},
|
||||
{Name: "Neo.Asset.GetPrecision", Func: assetGetPrecision, Price: 1},
|
||||
{Name: "Neo.Asset.Renew", Func: assetRenew, Price: 0},
|
||||
{Name: "Neo.Attribute.GetData", Func: attrGetData, Price: 1},
|
||||
{Name: "Neo.Attribute.GetUsage", Func: attrGetUsage, Price: 1},
|
||||
{Name: "Neo.Block.GetTransaction", Func: blockGetTransaction, Price: 1},
|
||||
{Name: "Neo.Block.GetTransactionCount", Func: blockGetTransactionCount, Price: 1},
|
||||
{Name: "Neo.Block.GetTransactions", Func: blockGetTransactions, Price: 1},
|
||||
{Name: "Neo.Blockchain.GetAccount", Func: bcGetAccount, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetAsset", Func: bcGetAsset, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetBlock", Func: bcGetBlock, Price: 200},
|
||||
{Name: "Neo.Blockchain.GetContract", Func: bcGetContract, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetHeader", Func: bcGetHeader, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetHeight", Func: bcGetHeight, Price: 1},
|
||||
{Name: "Neo.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetTransactionHeight", Func: bcGetTransactionHeight, Price: 100},
|
||||
{Name: "Neo.Blockchain.GetValidators", Func: bcGetValidators, Price: 200},
|
||||
{Name: "Neo.Contract.Create", Func: contractCreate, Price: 0},
|
||||
{Name: "Neo.Contract.Destroy", Func: contractDestroy, Price: 1},
|
||||
{Name: "Neo.Contract.GetScript", Func: contractGetScript, Price: 1},
|
||||
{Name: "Neo.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
|
||||
{Name: "Neo.Contract.IsPayable", Func: contractIsPayable, Price: 1},
|
||||
{Name: "Neo.Contract.Migrate", Func: contractMigrate, Price: 0},
|
||||
{Name: "Neo.Enumerator.Concat", Func: enumerator.Concat, Price: 1},
|
||||
{Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1},
|
||||
{Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1},
|
||||
{Name: "Neo.Enumerator.Value", Func: enumerator.Value, Price: 1},
|
||||
{Name: "Neo.Header.GetConsensusData", Func: headerGetConsensusData, Price: 1},
|
||||
{Name: "Neo.Header.GetHash", Func: headerGetHash, Price: 1},
|
||||
{Name: "Neo.Header.GetIndex", Func: headerGetIndex, Price: 1},
|
||||
{Name: "Neo.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1},
|
||||
{Name: "Neo.Header.GetNextConsensus", Func: headerGetNextConsensus, Price: 1},
|
||||
{Name: "Neo.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1},
|
||||
{Name: "Neo.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1},
|
||||
{Name: "Neo.Header.GetVersion", Func: headerGetVersion, Price: 1},
|
||||
{Name: "Neo.Input.GetHash", Func: inputGetHash, Price: 1},
|
||||
{Name: "Neo.Input.GetIndex", Func: inputGetIndex, Price: 1},
|
||||
{Name: "Neo.InvocationTransaction.GetScript", Func: invocationTxGetScript, Price: 1},
|
||||
{Name: "Neo.Iterator.Concat", Func: iterator.Concat, Price: 1},
|
||||
{Name: "Neo.Iterator.Create", Func: iterator.Create, Price: 1},
|
||||
{Name: "Neo.Iterator.Key", Func: iterator.Key, Price: 1},
|
||||
{Name: "Neo.Iterator.Keys", Func: iterator.Keys, Price: 1},
|
||||
{Name: "Neo.Iterator.Values", Func: iterator.Values, Price: 1},
|
||||
{Name: "Neo.Output.GetAssetId", Func: outputGetAssetID, Price: 1},
|
||||
{Name: "Neo.Output.GetScriptHash", Func: outputGetScriptHash, Price: 1},
|
||||
{Name: "Neo.Output.GetValue", Func: outputGetValue, Price: 1},
|
||||
{Name: "Neo.Runtime.CheckWitness", Func: runtimeCheckWitness, Price: 200},
|
||||
{Name: "Neo.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1},
|
||||
{Name: "Neo.Runtime.GetTime", Func: runtimeGetTime, Price: 1},
|
||||
{Name: "Neo.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 1},
|
||||
{Name: "Neo.Runtime.Log", Func: runtimeLog, Price: 1},
|
||||
{Name: "Neo.Runtime.Notify", Func: runtimeNotify, Price: 1},
|
||||
{Name: "Neo.Runtime.Serialize", Func: runtimeSerialize, Price: 1},
|
||||
{Name: "Neo.Storage.Delete", Func: storageDelete, Price: 100},
|
||||
{Name: "Neo.Storage.Find", Func: storageFind, Price: 1},
|
||||
{Name: "Neo.Storage.Get", Func: storageGet, Price: 100},
|
||||
{Name: "Neo.Storage.GetContext", Func: storageGetContext, Price: 1},
|
||||
{Name: "Neo.Storage.GetReadOnlyContext", Func: storageGetReadOnlyContext, Price: 1},
|
||||
{Name: "Neo.Storage.Put", Func: storagePut, Price: 0},
|
||||
{Name: "Neo.StorageContext.AsReadOnly", Func: storageContextAsReadOnly, Price: 1},
|
||||
{Name: "Neo.Transaction.GetAttributes", Func: txGetAttributes, Price: 1},
|
||||
{Name: "Neo.Transaction.GetHash", Func: txGetHash, Price: 1},
|
||||
{Name: "Neo.Transaction.GetInputs", Func: txGetInputs, Price: 1},
|
||||
{Name: "Neo.Transaction.GetOutputs", Func: txGetOutputs, Price: 1},
|
||||
{Name: "Neo.Transaction.GetReferences", Func: txGetReferences, Price: 200},
|
||||
{Name: "Neo.Transaction.GetType", Func: txGetType, Price: 1},
|
||||
{Name: "Neo.Transaction.GetUnspentCoins", Func: txGetUnspentCoins, Price: 200},
|
||||
{Name: "Neo.Transaction.GetWitnesses", Func: txGetWitnesses, Price: 200},
|
||||
{Name: "Neo.Witness.GetVerificationScript", Func: witnessGetVerificationScript, Price: 100},
|
||||
|
||||
// Aliases.
|
||||
{Name: "Neo.Iterator.Next", Func: (*interopContext).enumeratorNext, Price: 1},
|
||||
{Name: "Neo.Iterator.Value", Func: (*interopContext).enumeratorValue, Price: 1},
|
||||
{Name: "Neo.Iterator.Next", Func: enumerator.Next, Price: 1},
|
||||
{Name: "Neo.Iterator.Value", Func: enumerator.Value, Price: 1},
|
||||
|
||||
// Old compatibility APIs.
|
||||
{Name: "AntShares.Account.GetBalance", Func: (*interopContext).accountGetBalance, Price: 1},
|
||||
{Name: "AntShares.Account.GetScriptHash", Func: (*interopContext).accountGetScriptHash, Price: 1},
|
||||
{Name: "AntShares.Account.GetVotes", Func: (*interopContext).accountGetVotes, Price: 1},
|
||||
{Name: "AntShares.Asset.Create", Func: (*interopContext).assetCreate, Price: 0},
|
||||
{Name: "AntShares.Asset.GetAdmin", Func: (*interopContext).assetGetAdmin, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAmount", Func: (*interopContext).assetGetAmount, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAssetId", Func: (*interopContext).assetGetAssetID, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAssetType", Func: (*interopContext).assetGetAssetType, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAvailable", Func: (*interopContext).assetGetAvailable, Price: 1},
|
||||
{Name: "AntShares.Asset.GetIssuer", Func: (*interopContext).assetGetIssuer, Price: 1},
|
||||
{Name: "AntShares.Asset.GetOwner", Func: (*interopContext).assetGetOwner, Price: 1},
|
||||
{Name: "AntShares.Asset.GetPrecision", Func: (*interopContext).assetGetPrecision, Price: 1},
|
||||
{Name: "AntShares.Asset.Renew", Func: (*interopContext).assetRenew, Price: 0},
|
||||
{Name: "AntShares.Attribute.GetData", Func: (*interopContext).attrGetData, Price: 1},
|
||||
{Name: "AntShares.Attribute.GetUsage", Func: (*interopContext).attrGetUsage, Price: 1},
|
||||
{Name: "AntShares.Block.GetTransaction", Func: (*interopContext).blockGetTransaction, Price: 1},
|
||||
{Name: "AntShares.Block.GetTransactionCount", Func: (*interopContext).blockGetTransactionCount, Price: 1},
|
||||
{Name: "AntShares.Block.GetTransactions", Func: (*interopContext).blockGetTransactions, Price: 1},
|
||||
{Name: "AntShares.Blockchain.GetAccount", Func: (*interopContext).bcGetAccount, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetAsset", Func: (*interopContext).bcGetAsset, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetBlock", Func: (*interopContext).bcGetBlock, Price: 200},
|
||||
{Name: "AntShares.Blockchain.GetContract", Func: (*interopContext).bcGetContract, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetHeader", Func: (*interopContext).bcGetHeader, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetHeight", Func: (*interopContext).bcGetHeight, Price: 1},
|
||||
{Name: "AntShares.Blockchain.GetTransaction", Func: (*interopContext).bcGetTransaction, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetValidators", Func: (*interopContext).bcGetValidators, Price: 200},
|
||||
{Name: "AntShares.Contract.Create", Func: (*interopContext).contractCreate, Price: 0},
|
||||
{Name: "AntShares.Contract.Destroy", Func: (*interopContext).contractDestroy, Price: 1},
|
||||
{Name: "AntShares.Contract.GetScript", Func: (*interopContext).contractGetScript, Price: 1},
|
||||
{Name: "AntShares.Contract.GetStorageContext", Func: (*interopContext).contractGetStorageContext, Price: 1},
|
||||
{Name: "AntShares.Contract.Migrate", Func: (*interopContext).contractMigrate, Price: 0},
|
||||
{Name: "AntShares.Header.GetConsensusData", Func: (*interopContext).headerGetConsensusData, Price: 1},
|
||||
{Name: "AntShares.Header.GetHash", Func: (*interopContext).headerGetHash, Price: 1},
|
||||
{Name: "AntShares.Header.GetMerkleRoot", Func: (*interopContext).headerGetMerkleRoot, Price: 1},
|
||||
{Name: "AntShares.Header.GetNextConsensus", Func: (*interopContext).headerGetNextConsensus, Price: 1},
|
||||
{Name: "AntShares.Header.GetPrevHash", Func: (*interopContext).headerGetPrevHash, Price: 1},
|
||||
{Name: "AntShares.Header.GetTimestamp", Func: (*interopContext).headerGetTimestamp, Price: 1},
|
||||
{Name: "AntShares.Header.GetVersion", Func: (*interopContext).headerGetVersion, Price: 1},
|
||||
{Name: "AntShares.Input.GetHash", Func: (*interopContext).inputGetHash, Price: 1},
|
||||
{Name: "AntShares.Input.GetIndex", Func: (*interopContext).inputGetIndex, Price: 1},
|
||||
{Name: "AntShares.Output.GetAssetId", Func: (*interopContext).outputGetAssetID, Price: 1},
|
||||
{Name: "AntShares.Output.GetScriptHash", Func: (*interopContext).outputGetScriptHash, Price: 1},
|
||||
{Name: "AntShares.Output.GetValue", Func: (*interopContext).outputGetValue, Price: 1},
|
||||
{Name: "AntShares.Runtime.CheckWitness", Func: (*interopContext).runtimeCheckWitness, Price: 200},
|
||||
{Name: "AntShares.Runtime.Log", Func: (*interopContext).runtimeLog, Price: 1},
|
||||
{Name: "AntShares.Runtime.Notify", Func: (*interopContext).runtimeNotify, Price: 1},
|
||||
{Name: "AntShares.Storage.Delete", Func: (*interopContext).storageDelete, Price: 100},
|
||||
{Name: "AntShares.Storage.Get", Func: (*interopContext).storageGet, Price: 100},
|
||||
{Name: "AntShares.Storage.GetContext", Func: (*interopContext).storageGetContext, Price: 1},
|
||||
{Name: "AntShares.Storage.Put", Func: (*interopContext).storagePut, Price: 0},
|
||||
{Name: "AntShares.Transaction.GetAttributes", Func: (*interopContext).txGetAttributes, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetHash", Func: (*interopContext).txGetHash, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetInputs", Func: (*interopContext).txGetInputs, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetOutputs", Func: (*interopContext).txGetOutputs, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetReferences", Func: (*interopContext).txGetReferences, Price: 200},
|
||||
{Name: "AntShares.Transaction.GetType", Func: (*interopContext).txGetType, Price: 1},
|
||||
{Name: "AntShares.Account.GetBalance", Func: accountGetBalance, Price: 1},
|
||||
{Name: "AntShares.Account.GetScriptHash", Func: accountGetScriptHash, Price: 1},
|
||||
{Name: "AntShares.Account.GetVotes", Func: accountGetVotes, Price: 1},
|
||||
{Name: "AntShares.Asset.Create", Func: assetCreate, Price: 0},
|
||||
{Name: "AntShares.Asset.GetAdmin", Func: assetGetAdmin, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAmount", Func: assetGetAmount, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAssetId", Func: assetGetAssetID, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAssetType", Func: assetGetAssetType, Price: 1},
|
||||
{Name: "AntShares.Asset.GetAvailable", Func: assetGetAvailable, Price: 1},
|
||||
{Name: "AntShares.Asset.GetIssuer", Func: assetGetIssuer, Price: 1},
|
||||
{Name: "AntShares.Asset.GetOwner", Func: assetGetOwner, Price: 1},
|
||||
{Name: "AntShares.Asset.GetPrecision", Func: assetGetPrecision, Price: 1},
|
||||
{Name: "AntShares.Asset.Renew", Func: assetRenew, Price: 0},
|
||||
{Name: "AntShares.Attribute.GetData", Func: attrGetData, Price: 1},
|
||||
{Name: "AntShares.Attribute.GetUsage", Func: attrGetUsage, Price: 1},
|
||||
{Name: "AntShares.Block.GetTransaction", Func: blockGetTransaction, Price: 1},
|
||||
{Name: "AntShares.Block.GetTransactionCount", Func: blockGetTransactionCount, Price: 1},
|
||||
{Name: "AntShares.Block.GetTransactions", Func: blockGetTransactions, Price: 1},
|
||||
{Name: "AntShares.Blockchain.GetAccount", Func: bcGetAccount, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetAsset", Func: bcGetAsset, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetBlock", Func: bcGetBlock, Price: 200},
|
||||
{Name: "AntShares.Blockchain.GetContract", Func: bcGetContract, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetHeader", Func: bcGetHeader, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetHeight", Func: bcGetHeight, Price: 1},
|
||||
{Name: "AntShares.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 100},
|
||||
{Name: "AntShares.Blockchain.GetValidators", Func: bcGetValidators, Price: 200},
|
||||
{Name: "AntShares.Contract.Create", Func: contractCreate, Price: 0},
|
||||
{Name: "AntShares.Contract.Destroy", Func: contractDestroy, Price: 1},
|
||||
{Name: "AntShares.Contract.GetScript", Func: contractGetScript, Price: 1},
|
||||
{Name: "AntShares.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
|
||||
{Name: "AntShares.Contract.Migrate", Func: contractMigrate, Price: 0},
|
||||
{Name: "AntShares.Header.GetConsensusData", Func: headerGetConsensusData, Price: 1},
|
||||
{Name: "AntShares.Header.GetHash", Func: headerGetHash, Price: 1},
|
||||
{Name: "AntShares.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1},
|
||||
{Name: "AntShares.Header.GetNextConsensus", Func: headerGetNextConsensus, Price: 1},
|
||||
{Name: "AntShares.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1},
|
||||
{Name: "AntShares.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1},
|
||||
{Name: "AntShares.Header.GetVersion", Func: headerGetVersion, Price: 1},
|
||||
{Name: "AntShares.Input.GetHash", Func: inputGetHash, Price: 1},
|
||||
{Name: "AntShares.Input.GetIndex", Func: inputGetIndex, Price: 1},
|
||||
{Name: "AntShares.Output.GetAssetId", Func: outputGetAssetID, Price: 1},
|
||||
{Name: "AntShares.Output.GetScriptHash", Func: outputGetScriptHash, Price: 1},
|
||||
{Name: "AntShares.Output.GetValue", Func: outputGetValue, Price: 1},
|
||||
{Name: "AntShares.Runtime.CheckWitness", Func: runtimeCheckWitness, Price: 200},
|
||||
{Name: "AntShares.Runtime.Log", Func: runtimeLog, Price: 1},
|
||||
{Name: "AntShares.Runtime.Notify", Func: runtimeNotify, Price: 1},
|
||||
{Name: "AntShares.Storage.Delete", Func: storageDelete, Price: 100},
|
||||
{Name: "AntShares.Storage.Get", Func: storageGet, Price: 100},
|
||||
{Name: "AntShares.Storage.GetContext", Func: storageGetContext, Price: 1},
|
||||
{Name: "AntShares.Storage.Put", Func: storagePut, Price: 0},
|
||||
{Name: "AntShares.Transaction.GetAttributes", Func: txGetAttributes, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetHash", Func: txGetHash, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetInputs", Func: txGetInputs, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetOutputs", Func: txGetOutputs, Price: 1},
|
||||
{Name: "AntShares.Transaction.GetReferences", Func: txGetReferences, Price: 200},
|
||||
{Name: "AntShares.Transaction.GetType", Func: txGetType, Price: 1},
|
||||
}
|
||||
|
||||
// initIDinInteropsSlice initializes IDs from names in one given
|
||||
// interopedFunction slice and then sorts it.
|
||||
func initIDinInteropsSlice(iops []interopedFunction) {
|
||||
// Function slice and then sorts it.
|
||||
func initIDinInteropsSlice(iops []interop.Function) {
|
||||
for i := range iops {
|
||||
iops[i].ID = vm.InteropNameToID([]byte(iops[i].Name))
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@ import (
|
|||
"testing"
|
||||
|
||||
"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/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"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.Estack().PushVal(value)
|
||||
chain := newTestChain(t)
|
||||
|
@ -30,56 +31,56 @@ func TestUnexpectedNonInterops(t *testing.T) {
|
|||
}
|
||||
|
||||
// All of these functions expect an interop item on the stack.
|
||||
funcs := []func(*interopContext, *vm.VM) error{
|
||||
(*interopContext).accountGetBalance,
|
||||
(*interopContext).accountGetScriptHash,
|
||||
(*interopContext).accountGetVotes,
|
||||
(*interopContext).assetGetAdmin,
|
||||
(*interopContext).assetGetAmount,
|
||||
(*interopContext).assetGetAssetID,
|
||||
(*interopContext).assetGetAssetType,
|
||||
(*interopContext).assetGetAvailable,
|
||||
(*interopContext).assetGetIssuer,
|
||||
(*interopContext).assetGetOwner,
|
||||
(*interopContext).assetGetPrecision,
|
||||
(*interopContext).assetRenew,
|
||||
(*interopContext).attrGetData,
|
||||
(*interopContext).attrGetUsage,
|
||||
(*interopContext).blockGetTransaction,
|
||||
(*interopContext).blockGetTransactionCount,
|
||||
(*interopContext).blockGetTransactions,
|
||||
(*interopContext).contractGetScript,
|
||||
(*interopContext).contractGetStorageContext,
|
||||
(*interopContext).contractIsPayable,
|
||||
(*interopContext).headerGetConsensusData,
|
||||
(*interopContext).headerGetHash,
|
||||
(*interopContext).headerGetIndex,
|
||||
(*interopContext).headerGetMerkleRoot,
|
||||
(*interopContext).headerGetNextConsensus,
|
||||
(*interopContext).headerGetPrevHash,
|
||||
(*interopContext).headerGetTimestamp,
|
||||
(*interopContext).headerGetVersion,
|
||||
(*interopContext).inputGetHash,
|
||||
(*interopContext).inputGetIndex,
|
||||
(*interopContext).invocationTxGetScript,
|
||||
(*interopContext).outputGetAssetID,
|
||||
(*interopContext).outputGetScriptHash,
|
||||
(*interopContext).outputGetValue,
|
||||
(*interopContext).storageContextAsReadOnly,
|
||||
(*interopContext).storageDelete,
|
||||
(*interopContext).storageFind,
|
||||
(*interopContext).storageGet,
|
||||
(*interopContext).storagePut,
|
||||
(*interopContext).storagePutEx,
|
||||
(*interopContext).txGetAttributes,
|
||||
(*interopContext).txGetHash,
|
||||
(*interopContext).txGetInputs,
|
||||
(*interopContext).txGetOutputs,
|
||||
(*interopContext).txGetReferences,
|
||||
(*interopContext).txGetType,
|
||||
(*interopContext).txGetUnspentCoins,
|
||||
(*interopContext).txGetWitnesses,
|
||||
(*interopContext).witnessGetVerificationScript,
|
||||
funcs := []func(*interop.Context, *vm.VM) error{
|
||||
accountGetBalance,
|
||||
accountGetScriptHash,
|
||||
accountGetVotes,
|
||||
assetGetAdmin,
|
||||
assetGetAmount,
|
||||
assetGetAssetID,
|
||||
assetGetAssetType,
|
||||
assetGetAvailable,
|
||||
assetGetIssuer,
|
||||
assetGetOwner,
|
||||
assetGetPrecision,
|
||||
assetRenew,
|
||||
attrGetData,
|
||||
attrGetUsage,
|
||||
blockGetTransaction,
|
||||
blockGetTransactionCount,
|
||||
blockGetTransactions,
|
||||
contractGetScript,
|
||||
contractGetStorageContext,
|
||||
contractIsPayable,
|
||||
headerGetConsensusData,
|
||||
headerGetHash,
|
||||
headerGetIndex,
|
||||
headerGetMerkleRoot,
|
||||
headerGetNextConsensus,
|
||||
headerGetPrevHash,
|
||||
headerGetTimestamp,
|
||||
headerGetVersion,
|
||||
inputGetHash,
|
||||
inputGetIndex,
|
||||
invocationTxGetScript,
|
||||
outputGetAssetID,
|
||||
outputGetScriptHash,
|
||||
outputGetValue,
|
||||
storageContextAsReadOnly,
|
||||
storageDelete,
|
||||
storageFind,
|
||||
storageGet,
|
||||
storagePut,
|
||||
storagePutEx,
|
||||
txGetAttributes,
|
||||
txGetHash,
|
||||
txGetInputs,
|
||||
txGetOutputs,
|
||||
txGetReferences,
|
||||
txGetType,
|
||||
txGetUnspentCoins,
|
||||
txGetWitnesses,
|
||||
witnessGetVerificationScript,
|
||||
}
|
||||
for _, f := range funcs {
|
||||
for k, v := range vals {
|
||||
|
|
|
@ -2,8 +2,8 @@ package network
|
|||
|
||||
import (
|
||||
"github.com/Workiva/go-datastructures/queue"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -11,11 +11,11 @@ type blockQueue struct {
|
|||
log *zap.Logger
|
||||
queue *queue.PriorityQueue
|
||||
checkBlocks chan struct{}
|
||||
chain core.Blockchainer
|
||||
chain blockchainer.Blockchainer
|
||||
relayF func(*block.Block)
|
||||
}
|
||||
|
||||
func newBlockQueue(capacity int, bc core.Blockchainer, log *zap.Logger, relayer func(*block.Block)) *blockQueue {
|
||||
func newBlockQueue(capacity int, bc blockchainer.Blockchainer, log *zap.Logger, relayer func(*block.Block)) *blockQueue {
|
||||
if log == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/consensus"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"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/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -53,7 +54,7 @@ type (
|
|||
|
||||
transport Transporter
|
||||
discovery Discoverer
|
||||
chain core.Blockchainer
|
||||
chain blockchainer.Blockchainer
|
||||
bQueue *blockQueue
|
||||
consensus consensus.Service
|
||||
|
||||
|
@ -84,7 +85,7 @@ func randomID() uint32 {
|
|||
}
|
||||
|
||||
// NewServer returns a new Server, initialized with the given configuration.
|
||||
func NewServer(config ServerConfig, chain core.Blockchainer, log *zap.Logger) (*Server, error) {
|
||||
func NewServer(config ServerConfig, chain blockchainer.Blockchainer, log *zap.Logger) (*Server, error) {
|
||||
if log == nil {
|
||||
return nil, errors.New("logger is a required parameter")
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"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/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -50,7 +50,7 @@ type (
|
|||
)
|
||||
|
||||
// NewBlock creates a new Block wrapper.
|
||||
func NewBlock(b *block.Block, chain core.Blockchainer) Block {
|
||||
func NewBlock(b *block.Block, chain blockchainer.Blockchainer) Block {
|
||||
res := Block{
|
||||
Version: b.Version,
|
||||
Hash: b.Hash(),
|
||||
|
|
|
@ -3,8 +3,8 @@ package result
|
|||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"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/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -31,7 +31,7 @@ type (
|
|||
)
|
||||
|
||||
// NewHeader creates a new Header wrapper.
|
||||
func NewHeader(h *block.Header, chain core.Blockchainer) Header {
|
||||
func NewHeader(h *block.Header, chain blockchainer.Blockchainer) Header {
|
||||
res := Header{
|
||||
Hash: h.Hash(),
|
||||
Size: io.GetVarSize(h),
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"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/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -27,7 +27,7 @@ type TransactionMetadata struct {
|
|||
}
|
||||
|
||||
// NewTransactionOutputRaw returns a new ransactionOutputRaw object.
|
||||
func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain core.Blockchainer) TransactionOutputRaw {
|
||||
func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain blockchainer.Blockchainer) TransactionOutputRaw {
|
||||
// confirmations formula
|
||||
confirmations := int(chain.BlockHeight() - header.Base.Index + 1)
|
||||
// set index position
|
||||
|
|
|
@ -2,6 +2,7 @@ package result
|
|||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -14,7 +15,7 @@ type Unclaimed struct {
|
|||
}
|
||||
|
||||
// NewUnclaimed creates a new Unclaimed wrapper using given Blockchainer.
|
||||
func NewUnclaimed(a *state.Account, chain core.Blockchainer) (*Unclaimed, error) {
|
||||
func NewUnclaimed(a *state.Account, chain blockchainer.Blockchainer) (*Unclaimed, error) {
|
||||
var (
|
||||
available util.Fixed8
|
||||
unavailable util.Fixed8
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package result
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -29,7 +29,7 @@ var GlobalAssets = map[string]string{
|
|||
}
|
||||
|
||||
// NewUnspents creates a new Account wrapper using given Blockchainer.
|
||||
func NewUnspents(a *state.Account, chain core.Blockchainer, addr string) Unspents {
|
||||
func NewUnspents(a *state.Account, chain blockchainer.Blockchainer, addr string) Unspents {
|
||||
res := Unspents{
|
||||
Address: addr,
|
||||
Balance: make([]UnspentBalanceInfo, 0, len(a.Balances)),
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
|
@ -35,7 +36,7 @@ type (
|
|||
// Server represents the JSON-RPC 2.0 server.
|
||||
Server struct {
|
||||
*http.Server
|
||||
chain core.Blockchainer
|
||||
chain blockchainer.Blockchainer
|
||||
config rpc.Config
|
||||
coreServer *network.Server
|
||||
log *zap.Logger
|
||||
|
@ -81,7 +82,7 @@ var invalidBlockHeightError = func(index int, height int) error {
|
|||
}
|
||||
|
||||
// New creates a new Server struct.
|
||||
func New(chain core.Blockchainer, conf rpc.Config, coreServer *network.Server, log *zap.Logger) Server {
|
||||
func New(chain blockchainer.Blockchainer, conf rpc.Config, coreServer *network.Server, log *zap.Logger) Server {
|
||||
httpServer := &http.Server{
|
||||
Addr: conf.Address + ":" + strconv.FormatUint(uint64(conf.Port), 10),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue