diff --git a/pkg/core/interop/context.go b/pkg/core/interop/context.go index a22980793..93417ecc7 100644 --- a/pkg/core/interop/context.go +++ b/pkg/core/interop/context.go @@ -8,13 +8,14 @@ import ( "sort" "strings" + "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/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/dao" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames" "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/hash" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" @@ -33,9 +34,22 @@ const ( DefaultBaseExecFee = 30 ) +// Ledger is the interface to Blockchain required for Context functionality. +type Ledger interface { + BlockHeight() uint32 + CurrentBlockHash() util.Uint256 + GetBaseExecFee() int64 + GetBlock(hash util.Uint256) (*block.Block, error) + GetConfig() config.ProtocolConfiguration + GetHeaderHash(int) util.Uint256 + GetStandByCommittee() keys.PublicKeys + GetStandByValidators() keys.PublicKeys + GetStoragePrice() int64 +} + // Context represents context in which interops are executed. type Context struct { - Chain blockchainer.Blockchainer + Chain Ledger Container hash.Hashable Network uint32 Natives []Contract @@ -56,7 +70,7 @@ type Context struct { } // NewContext returns new interop context. -func NewContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO, +func NewContext(trigger trigger.Type, bc Ledger, d dao.DAO, getContract func(dao.DAO, util.Uint160) (*state.Contract, error), natives []Contract, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *Context { baseExecFee := int64(DefaultBaseExecFee) diff --git a/pkg/core/native/ledger.go b/pkg/core/native/ledger.go index 2d958d629..496ccc640 100644 --- a/pkg/core/native/ledger.go +++ b/pkg/core/native/ledger.go @@ -6,7 +6,6 @@ import ( "math/big" "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/native/nativenames" @@ -145,17 +144,17 @@ func (l *Ledger) getTransactionFromBlock(ic *interop.Context, params []stackitem // isTraceableBlock defines whether we're able to give information about // the block with index specified. -func isTraceableBlock(bc blockchainer.Blockchainer, index uint32) bool { +func isTraceableBlock(bc interop.Ledger, index uint32) bool { height := bc.BlockHeight() MaxTraceableBlocks := bc.GetConfig().MaxTraceableBlocks return index <= height && index+MaxTraceableBlocks > height } // getBlockHashFromItem converts given stackitem.Item to block hash using given -// Blockchainer if needed. Interop functions accept both block numbers and +// Ledger if needed. Interop functions accept both block numbers and // block hashes as parameters, thus this function is needed. It's supposed to // be called within VM context, so it panics if anything goes wrong. -func getBlockHashFromItem(bc blockchainer.Blockchainer, item stackitem.Item) util.Uint256 { +func getBlockHashFromItem(bc interop.Ledger, item stackitem.Item) util.Uint256 { bigindex, err := item.TryInteger() if err == nil && bigindex.IsUint64() { index := bigindex.Uint64() diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 163525080..50f61c989 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -10,7 +10,6 @@ import ( "strings" "sync/atomic" - "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/interop/runtime" @@ -244,7 +243,7 @@ func (n *NEO) Initialize(ic *interop.Context) error { // InitializeCache initializes all NEO cache with the proper values from storage. // Cache initialisation should be done apart from Initialize because Initialize is // called only when deploying native contracts. -func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error { +func (n *NEO) InitializeCache(bc interop.Ledger, d dao.DAO) error { var committee = keysWithVotes{} si := d.GetStorageItem(n.ID, prefixCommittee) if err := committee.DecodeBytes(si); err != nil { @@ -264,7 +263,7 @@ func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error { return nil } -func (n *NEO) updateCache(cvs keysWithVotes, bc blockchainer.Blockchainer) error { +func (n *NEO) updateCache(cvs keysWithVotes, bc interop.Ledger) error { n.committee.Store(cvs) var committee = n.GetCommitteeMembers() @@ -300,7 +299,7 @@ func (n *NEO) updateCommittee(ic *interop.Context) error { } // ShouldUpdateCommittee returns true if committee is updated at block h. -func ShouldUpdateCommittee(h uint32, bc blockchainer.Blockchainer) bool { +func ShouldUpdateCommittee(h uint32, bc interop.Ledger) bool { cfg := bc.GetConfig() r := len(cfg.StandbyCommittee) return h%uint32(r) == 0 @@ -925,7 +924,7 @@ func (n *NEO) getAccountState(ic *interop.Context, args []stackitem.Item) stacki } // ComputeNextBlockValidators returns an actual list of current validators. -func (n *NEO) ComputeNextBlockValidators(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) { +func (n *NEO) ComputeNextBlockValidators(bc interop.Ledger, d dao.DAO) (keys.PublicKeys, error) { if vals := n.validators.Load().(keys.PublicKeys); vals != nil { return vals.Copy(), nil } @@ -982,7 +981,7 @@ func toKeysWithVotes(pubs keys.PublicKeys) keysWithVotes { } // computeCommitteeMembers returns public keys of nodes in committee. -func (n *NEO) computeCommitteeMembers(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, keysWithVotes, error) { +func (n *NEO) computeCommitteeMembers(bc interop.Ledger, d dao.DAO) (keys.PublicKeys, keysWithVotes, error) { key := []byte{prefixVotersCount} si := d.GetStorageItem(n.ID, key) if si == nil {