forked from TrueCloudLab/neoneo-go
core: move GetScriptContainer to runtime
It also brings ToStackItem to Block and Transaction, previously this was avoided to separate block and transaction packages from VM. But turns out `transaction` depends on `stackitem` already, so this makes little sense (but can be shuffled in another way if needed). Context.Container is still a hash.Hashable because we have a number of occasions (header or MPT root verification) where there is no ToStackItem implementation possible. Maybe they can go with `nil` Container, but I don't want to have this risk for now.
This commit is contained in:
parent
cdb55740ea
commit
d70caf1da1
6 changed files with 52 additions and 53 deletions
|
@ -4,11 +4,13 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
"math"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -211,3 +213,18 @@ func (b *Block) GetExpectedBlockSizeWithoutTransactions(txCount int) int {
|
||||||
}
|
}
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToStackItem converts Block to stackitem.Item.
|
||||||
|
func (b *Block) ToStackItem() stackitem.Item {
|
||||||
|
return stackitem.NewArray([]stackitem.Item{
|
||||||
|
stackitem.NewByteArray(b.Hash().BytesBE()),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(b.Version))),
|
||||||
|
stackitem.NewByteArray(b.PrevHash.BytesBE()),
|
||||||
|
stackitem.NewByteArray(b.MerkleRoot.BytesBE()),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(b.Timestamp))),
|
||||||
|
stackitem.NewBigInteger(new(big.Int).SetUint64(b.Nonce)),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(b.Index))),
|
||||||
|
stackitem.NewByteArray(b.NextConsensus.BytesBE()),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(len(b.Transactions)))),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@ import (
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type itemable interface {
|
||||||
|
ToStackItem() stackitem.Item
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// MaxEventNameLen is the maximum length of a name for event.
|
// MaxEventNameLen is the maximum length of a name for event.
|
||||||
MaxEventNameLen = 32
|
MaxEventNameLen = 32
|
||||||
|
@ -37,6 +41,17 @@ func GetEntryScriptHash(ic *interop.Context) error {
|
||||||
return ic.VM.PushContextScriptHash(ic.VM.Istack().Len() - 1)
|
return ic.VM.PushContextScriptHash(ic.VM.Istack().Len() - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetScriptContainer returns transaction or block that contains the script
|
||||||
|
// being run.
|
||||||
|
func GetScriptContainer(ic *interop.Context) error {
|
||||||
|
c, ok := ic.Container.(itemable)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("unknown script container")
|
||||||
|
}
|
||||||
|
ic.VM.Estack().PushItem(c.ToStackItem())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Platform returns the name of the platform.
|
// Platform returns the name of the platform.
|
||||||
func Platform(ic *interop.Context) error {
|
func Platform(ic *interop.Context) error {
|
||||||
ic.VM.Estack().PushItem(stackitem.NewByteArray([]byte("NEO")))
|
ic.VM.Estack().PushItem(stackitem.NewByteArray([]byte("NEO")))
|
||||||
|
|
|
@ -5,12 +5,9 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
|
istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,22 +23,6 @@ type StorageContext struct {
|
||||||
ReadOnly bool
|
ReadOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// engineGetScriptContainer returns transaction or block that contains the script
|
|
||||||
// being run.
|
|
||||||
func engineGetScriptContainer(ic *interop.Context) error {
|
|
||||||
var item stackitem.Item
|
|
||||||
switch t := ic.Container.(type) {
|
|
||||||
case *transaction.Transaction:
|
|
||||||
item = native.TransactionToStackItem(t)
|
|
||||||
case *block.Block:
|
|
||||||
item = native.BlockToStackItem(t)
|
|
||||||
default:
|
|
||||||
return errors.New("unknown script container")
|
|
||||||
}
|
|
||||||
ic.VM.Estack().PushItem(item)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// storageDelete deletes stored key-value pair.
|
// storageDelete deletes stored key-value pair.
|
||||||
func storageDelete(ic *interop.Context) error {
|
func storageDelete(ic *interop.Context) error {
|
||||||
stcInterface := ic.VM.Estack().Pop().Value()
|
stcInterface := ic.VM.Estack().Pop().Value()
|
||||||
|
|
|
@ -54,7 +54,7 @@ var systemInterops = []interop.Function{
|
||||||
{Name: interopnames.SystemRuntimeGetNetwork, Func: runtime.GetNetwork, Price: 1 << 3},
|
{Name: interopnames.SystemRuntimeGetNetwork, Func: runtime.GetNetwork, Price: 1 << 3},
|
||||||
{Name: interopnames.SystemRuntimeGetNotifications, Func: runtime.GetNotifications, Price: 1 << 12, ParamCount: 1},
|
{Name: interopnames.SystemRuntimeGetNotifications, Func: runtime.GetNotifications, Price: 1 << 12, ParamCount: 1},
|
||||||
{Name: interopnames.SystemRuntimeGetRandom, Func: runtime.GetRandom, Price: 0},
|
{Name: interopnames.SystemRuntimeGetRandom, Func: runtime.GetRandom, Price: 0},
|
||||||
{Name: interopnames.SystemRuntimeGetScriptContainer, Func: engineGetScriptContainer, Price: 1 << 3},
|
{Name: interopnames.SystemRuntimeGetScriptContainer, Func: runtime.GetScriptContainer, Price: 1 << 3},
|
||||||
{Name: interopnames.SystemRuntimeGetTime, Func: runtime.GetTime, Price: 1 << 3, RequiredFlags: callflag.ReadStates},
|
{Name: interopnames.SystemRuntimeGetTime, Func: runtime.GetTime, Price: 1 << 3, RequiredFlags: callflag.ReadStates},
|
||||||
{Name: interopnames.SystemRuntimeGetTrigger, Func: runtime.GetTrigger, Price: 1 << 3},
|
{Name: interopnames.SystemRuntimeGetTrigger, Func: runtime.GetTrigger, Price: 1 << 3},
|
||||||
{Name: interopnames.SystemRuntimeLog, Func: runtime.Log, Price: 1 << 15, RequiredFlags: callflag.AllowNotify,
|
{Name: interopnames.SystemRuntimeLog, Func: runtime.Log, Price: 1 << 15, RequiredFlags: callflag.AllowNotify,
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
|
@ -117,7 +116,7 @@ func (l *Ledger) getBlock(ic *interop.Context, params []stackitem.Item) stackite
|
||||||
if err != nil || !isTraceableBlock(ic, block.Index) {
|
if err != nil || !isTraceableBlock(ic, block.Index) {
|
||||||
return stackitem.Null{}
|
return stackitem.Null{}
|
||||||
}
|
}
|
||||||
return BlockToStackItem(block)
|
return block.ToStackItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTransaction returns transaction to the SC.
|
// getTransaction returns transaction to the SC.
|
||||||
|
@ -126,7 +125,7 @@ func (l *Ledger) getTransaction(ic *interop.Context, params []stackitem.Item) st
|
||||||
if err != nil || !isTraceableBlock(ic, h) {
|
if err != nil || !isTraceableBlock(ic, h) {
|
||||||
return stackitem.Null{}
|
return stackitem.Null{}
|
||||||
}
|
}
|
||||||
return TransactionToStackItem(tx)
|
return tx.ToStackItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTransactionHeight returns transaction height to the SC.
|
// getTransactionHeight returns transaction height to the SC.
|
||||||
|
@ -150,7 +149,7 @@ func (l *Ledger) getTransactionFromBlock(ic *interop.Context, params []stackitem
|
||||||
if index >= uint32(len(block.Transactions)) {
|
if index >= uint32(len(block.Transactions)) {
|
||||||
panic("wrong transaction index")
|
panic("wrong transaction index")
|
||||||
}
|
}
|
||||||
return TransactionToStackItem(block.Transactions[index])
|
return block.Transactions[index].ToStackItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTransactionSigners returns transaction signers to the SC.
|
// getTransactionSigners returns transaction signers to the SC.
|
||||||
|
@ -228,35 +227,6 @@ func getTransactionAndHeight(d *dao.Simple, item stackitem.Item) (*transaction.T
|
||||||
return d.GetTransaction(hash)
|
return d.GetTransaction(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockToStackItem converts block.Block to stackitem.Item.
|
|
||||||
func BlockToStackItem(b *block.Block) stackitem.Item {
|
|
||||||
return stackitem.NewArray([]stackitem.Item{
|
|
||||||
stackitem.NewByteArray(b.Hash().BytesBE()),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(b.Version))),
|
|
||||||
stackitem.NewByteArray(b.PrevHash.BytesBE()),
|
|
||||||
stackitem.NewByteArray(b.MerkleRoot.BytesBE()),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(b.Timestamp))),
|
|
||||||
stackitem.NewBigInteger(new(big.Int).SetUint64(b.Nonce)),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(b.Index))),
|
|
||||||
stackitem.NewByteArray(b.NextConsensus.BytesBE()),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(len(b.Transactions)))),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TransactionToStackItem converts transaction.Transaction to stackitem.Item.
|
|
||||||
func TransactionToStackItem(t *transaction.Transaction) stackitem.Item {
|
|
||||||
return stackitem.NewArray([]stackitem.Item{
|
|
||||||
stackitem.NewByteArray(t.Hash().BytesBE()),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(t.Version))),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(t.Nonce))),
|
|
||||||
stackitem.NewByteArray(t.Sender().BytesBE()),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(t.SystemFee))),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(t.NetworkFee))),
|
|
||||||
stackitem.NewBigInteger(big.NewInt(int64(t.ValidUntilBlock))),
|
|
||||||
stackitem.NewByteArray(t.Script),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignersToStackItem converts transaction.Signers to stackitem.Item.
|
// SignersToStackItem converts transaction.Signers to stackitem.Item.
|
||||||
func SignersToStackItem(signers []transaction.Signer) stackitem.Item {
|
func SignersToStackItem(signers []transaction.Signer) stackitem.Item {
|
||||||
res := make([]stackitem.Item, len(signers))
|
res := make([]stackitem.Item, len(signers))
|
||||||
|
|
|
@ -6,12 +6,14 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -451,3 +453,17 @@ func (t *Transaction) HasSigner(hash util.Uint160) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToStackItem converts Transaction to stackitem.Item.
|
||||||
|
func (t *Transaction) ToStackItem() stackitem.Item {
|
||||||
|
return stackitem.NewArray([]stackitem.Item{
|
||||||
|
stackitem.NewByteArray(t.Hash().BytesBE()),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(t.Version))),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(t.Nonce))),
|
||||||
|
stackitem.NewByteArray(t.Sender().BytesBE()),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(t.SystemFee))),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(t.NetworkFee))),
|
||||||
|
stackitem.NewBigInteger(big.NewInt(int64(t.ValidUntilBlock))),
|
||||||
|
stackitem.NewByteArray(t.Script),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue