evmcore

package
v1.0.0-rc.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2021 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNonceTooLow is returned if the nonce of a transaction is lower than the
	// one present in the local chain.
	ErrNonceTooLow = errors.New("nonce too low")

	// ErrNonceTooHigh is returned if the nonce of a transaction is higher than the
	// next one expected based on the local chain.
	ErrNonceTooHigh = errors.New("nonce too high")

	// ErrGasLimitReached is returned by the gas pool if the amount of gas required
	// by a transaction is higher than what's left in the block.
	ErrGasLimitReached = errors.New("gas limit reached")

	// ErrInsufficientFundsForTransfer is returned if the transaction sender doesn't
	// have enough funds for transfer(topmost call only).
	ErrInsufficientFundsForTransfer = errors.New("insufficient funds for transfer")

	// ErrInsufficientFunds is returned if the total cost of executing a transaction
	// is higher than the balance of the user's account.
	ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value")

	// ErrGasUintOverflow is returned when calculating gas usage.
	ErrGasUintOverflow = errors.New("gas uint64 overflow")

	// ErrIntrinsicGas is returned if the transaction is specified to use less gas
	// than required to start the invocation.
	ErrIntrinsicGas = errors.New("intrinsic gas too low")
)

List of evm-call-message pre-checking errors. All state transition messages will be pre-checked before execution. If any invalidation detected, the corresponding error should be returned which is defined here.

- If the pre-checking happens in the miner, then the transaction won't be packed. - If the pre-checking happens in the block processing procedure, then a "BAD BLOCk" error should be emitted.

View Source
var (
	// ErrAlreadyKnown is returned if the transactions is already contained
	// within the pool.
	ErrAlreadyKnown = errors.New("already known")

	// ErrInvalidSender is returned if the transaction contains an invalid signature.
	ErrInvalidSender = errors.New("invalid sender")

	// ErrUnderpriced is returned if a transaction's gas price is below the minimum
	// configured for the transaction pool.
	ErrUnderpriced = errors.New("transaction underpriced")

	// ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced
	// with a different one without the required price bump.
	ErrReplaceUnderpriced = errors.New("replacement transaction underpriced")

	// ErrGasLimit is returned if a transaction's requested gas limit exceeds the
	// maximum allowance of the current block.
	ErrGasLimit = errors.New("exceeds gas limit")

	// ErrNegativeValue is a sanity error to ensure no one is able to specify a
	// transaction with a negative value.
	ErrNegativeValue = errors.New("negative value")

	// ErrOversizedData is returned if the input data of a transaction is greater
	// than some meaningful limit a user might use. This is not a consensus error
	// making the transaction invalid, rather a DOS protection.
	ErrOversizedData = errors.New("oversized data")
)
View Source
var BadHashes = map[common.Hash]bool{}

BadHashes represent a set of manually tracked bad hashes (usually hard forks)

View Source
var (
	// ErrNoGenesis is returned when there is no Genesis Block.
	ErrNoGenesis = errors.New("genesis not found in chain")
)

Functions

func ApplyTransaction

func ApplyTransaction(
	config *params.ChainConfig,
	bc DummyChain,
	author *common.Address,
	gp *GasPool,
	statedb *state.StateDB,
	header *EvmHeader,
	tx *types.Transaction,
	usedGas *uint64,
	cfg vm.Config,
	strict bool,
) (
	*types.Receipt,
	uint64,
	*big.Int,
	bool,
	error,
)

ApplyTransaction attempts to apply a transaction to the given state database and uses the input parameters for its environment. It returns the receipt for the transaction, gas used and an error if the transaction failed, indicating the block was invalid.

func CanTransfer

func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool

CanTransfer checks whether there are enough funds in the address' account to make a transfer. This does not take the necessary gas in to account to make the transfer valid.

func GenerateChain

func GenerateChain(config *params.ChainConfig, parent *EvmBlock, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*EvmBlock, []types.Receipts, DummyChain)

GenerateChain creates a chain of n blocks. The first block's parent will be the provided parent. db is used to store intermediate states and should contain the parent's state trie.

The generator function is called with a new block generator for every block. Any transactions and uncles added to the generator become part of the block. If gen is nil, the blocks will be empty and their coinbase will be the zero address.

Blocks created by GenerateChain do not contain valid proof of work values. Inserting them into BlockChain requires use of FakePow or a similar non-validating proof of work implementation.

func GetHashFn

func GetHashFn(ref *EvmHeader, chain DummyChain) func(n uint64) common.Hash

GetHashFn returns a GetHashFunc which retrieves header hashes by number

func IntrinsicGas

func IntrinsicGas(data []byte, contractCreation bool) (uint64, error)

IntrinsicGas computes the 'intrinsic gas' for a message with the given data.

func NewEVMContext

func NewEVMContext(msg Message, header *EvmHeader, chain DummyChain, author *common.Address) vm.Context

NewEVMContext creates a new context for use in the EVM.

func TransactionPreCheck

func TransactionPreCheck(statedb *state.StateDB, msg types.Message, tx *types.Transaction) error

func Transfer

func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int)

Transfer subtracts amount from sender and adds amount to recipient using the given Db

Types

type BlockGen

type BlockGen struct {
	// contains filtered or unexported fields
}

BlockGen creates blocks for testing. See GenerateChain for a detailed explanation.

func (*BlockGen) AddTx

func (b *BlockGen) AddTx(tx *types.Transaction)

AddTx adds a transaction to the generated block. If no coinbase has been set, the block's coinbase is set to the zero address.

AddTx panics if the transaction cannot be executed. In addition to the protocol-imposed limitations (gas limit, etc.), there are some further limitations on the content of transactions that can be added. Notably, contract code relying on the BLOCKHASH instruction will panic during execution.

func (*BlockGen) AddTxWithChain

func (b *BlockGen) AddTxWithChain(bc DummyChain, tx *types.Transaction)

AddTxWithChain adds a transaction to the generated block. If no coinbase has been set, the block's coinbase is set to the zero address.

AddTxWithChain panics if the transaction cannot be executed. In addition to the protocol-imposed limitations (gas limit, etc.), there are some further limitations on the content of transactions that can be added. If contract code relies on the BLOCKHASH instruction, the block in chain will be returned.

func (*BlockGen) AddUncheckedReceipt

func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt)

AddUncheckedReceipt forcefully adds a receipts to the block without a backing transaction.

AddUncheckedReceipt will cause consensus failures when used during real chain processing. This is best used in conjunction with raw block insertion.

func (*BlockGen) AddUncheckedTx

func (b *BlockGen) AddUncheckedTx(tx *types.Transaction)

AddUncheckedTx forcefully adds a transaction to the block without any validation.

AddUncheckedTx will cause consensus failures when used during real chain processing. This is best used in conjunction with raw block insertion.

func (*BlockGen) Number

func (b *BlockGen) Number() *big.Int

Number returns the block number of the block being generated.

func (*BlockGen) OffsetTime

func (b *BlockGen) OffsetTime(seconds int64)

OffsetTime modifies the time instance of a block, implicitly changing its associated difficulty. It's useful to test scenarios where forking is not tied to chain length directly.

func (*BlockGen) PrevBlock

func (b *BlockGen) PrevBlock(index int) *EvmBlock

PrevBlock returns a previously generated block by number. It panics if num is greater or equal to the number of the block being generated. For index -1, PrevBlock returns the parent block given to GenerateChain.

func (*BlockGen) SetCoinbase

func (b *BlockGen) SetCoinbase(addr common.Address)

SetCoinbase sets the coinbase of the generated block. It can be called at most once.

func (*BlockGen) TxNonce

func (b *BlockGen) TxNonce(addr common.Address) uint64

TxNonce returns the next valid transaction nonce for the account at addr. It panics if the account does not exist.

type ChainHeadNotify

type ChainHeadNotify struct{ Block *EvmBlock }

type ChainNotify

type ChainNotify struct {
	Block *EvmBlock
	Hash  common.Hash
	Logs  []*types.Log
}

type ChainSideNotify

type ChainSideNotify struct {
	Block *EvmBlock
}

type DummyChain

type DummyChain interface {
	// GetHeader returns the hash corresponding to their hash.
	GetHeader(common.Hash, uint64) *EvmHeader
}

DummyChain supports retrieving headers and consensus parameters from the current blockchain to be used during transaction processing.

type EvmBlock

type EvmBlock struct {
	EvmHeader

	Transactions types.Transactions
}

func ApplyGenesis

func ApplyGenesis(db ethdb.Database, net *lachesis.Config) (*EvmBlock, error)

ApplyGenesis writes or updates the genesis block in db.

func MustApplyGenesis

func MustApplyGenesis(net *lachesis.Config, db ethdb.Database) *EvmBlock

MustApplyGenesis writes the genesis block and state to db, panicking on error.

func (*EvmBlock) EthBlock

func (b *EvmBlock) EthBlock() *types.Block

func (*EvmBlock) Header

func (b *EvmBlock) Header() *EvmHeader

Header is a copy of EvmBlock.EvmHeader.

func (*EvmBlock) NumberU64

func (b *EvmBlock) NumberU64() uint64

type EvmHeader

type EvmHeader struct {
	Number     *big.Int
	Hash       common.Hash
	ParentHash common.Hash
	Root       common.Hash
	TxHash     common.Hash
	Time       inter.Timestamp
	Coinbase   common.Address

	GasLimit uint64
	GasUsed  uint64
}

func ConvertFromEthHeader

func ConvertFromEthHeader(h *types.Header) *EvmHeader

ConvertFromEthHeader converts ETH-formatted header to Lachesis EVM header

func ToEvmHeader

func ToEvmHeader(block *inter.Block) *EvmHeader

ToEvmHeader converts inter.Block to EvmHeader.

func (*EvmHeader) EthHeader

func (h *EvmHeader) EthHeader() *types.Header

EthHeader returns header in ETH format

type ExecutionResult

type ExecutionResult struct {
	UsedGas    uint64 // Total used gas but include the refunded gas
	Err        error  // Any error encountered during the execution(listed in core/vm/errors.go)
	ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode)
}

ExecutionResult includes all output after executing given evm message no matter the execution itself is successful or not.

func ApplyMessage

func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) (*ExecutionResult, error)

ApplyMessage computes the new state by applying the given message against the old state within the environment.

ApplyMessage returns the bytes returned by any EVM execution (if it took place), the gas used (which includes gas refunds) and an error if it failed. An error always indicates a core error meaning that the message would always fail for that particular state and would never be accepted within a block.

func (*ExecutionResult) Failed

func (result *ExecutionResult) Failed() bool

Failed returns the indicator whether the execution is successful or not

func (*ExecutionResult) Return

func (result *ExecutionResult) Return() []byte

Return is a helper function to help caller distinguish between revert reason and function return. Return returns the data after execution if no error occurs.

func (*ExecutionResult) Revert

func (result *ExecutionResult) Revert() []byte

Revert returns the concrete revert reason if the execution is aborted by `REVERT` opcode. Note the reason can be nil if no data supplied with revert opcode.

func (*ExecutionResult) Unwrap

func (result *ExecutionResult) Unwrap() error

Unwrap returns the internal evm error which allows us for further analysis outside.

type GasPool

type GasPool uint64

GasPool tracks the amount of gas available during execution of the transactions in a block. The zero value is a pool with zero gas available.

func (*GasPool) AddGas

func (gp *GasPool) AddGas(amount uint64) *GasPool

AddGas makes gas available for execution.

func (*GasPool) Gas

func (gp *GasPool) Gas() uint64

Gas returns the amount of gas remaining in the pool.

func (*GasPool) String

func (gp *GasPool) String() string

func (*GasPool) SubGas

func (gp *GasPool) SubGas(amount uint64) error

SubGas deducts the given amount from the pool if enough gas is available and returns an error otherwise.

type Message

type Message interface {
	From() common.Address
	To() *common.Address

	GasPrice() *big.Int
	Gas() uint64
	Value() *big.Int

	Nonce() uint64
	CheckNonce() bool
	Data() []byte
}

Message represents a message sent to a contract.

type NewMinedBlockNotify

type NewMinedBlockNotify struct{ Block *EvmBlock }

NewMinedBlockNotify is posted when a block has been imported.

type NewTxsNotify

type NewTxsNotify struct{ Txs []*types.Transaction }

NewTxsNotify is posted when a batch of transactions enter the transaction pool.

type PendingLogsNotify

type PendingLogsNotify struct {
	Logs []*types.Log
}

PendingLogsNotify is posted pre mining and notifies of pending logs.

type Prefetcher

type Prefetcher interface {
	// Prefetch processes the state changes according to the Ethereum rules by running
	// the transaction messages using the statedb, but any changes are discarded. The
	// only goal is to pre-cache transaction signatures and state trie nodes.
	Prefetch(block *EvmBlock, statedb *state.StateDB, cfg vm.Config, interrupt *uint32)
}

Prefetcher is an interface for pre-caching transaction signatures and state.

type Processor

type Processor interface {
	// Process processes the state changes according to the Ethereum rules by running
	// the transaction messages using the statedb and applying any rewards to both
	// the processor (coinbase) and any included uncles.
	Process(block *EvmBlock, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error)
}

Processor is an interface for processing blocks using a given initial state.

type RemovedLogsNotify

type RemovedLogsNotify struct{ Logs []*types.Log }

RemovedLogsNotify is posted when a reorg happens

type StateProcessor

type StateProcessor struct {
	// contains filtered or unexported fields
}

StateProcessor is a basic Processor, which takes care of transitioning state from one point to another.

StateProcessor implements Processor.

func NewStateProcessor

func NewStateProcessor(config *params.ChainConfig, bc DummyChain) *StateProcessor

NewStateProcessor initialises a new StateProcessor.

func (*StateProcessor) Process

func (p *StateProcessor) Process(block *EvmBlock, statedb *state.StateDB, cfg vm.Config, strict bool) (types.Receipts, []*types.Log, uint64, *big.Int, []uint, error)

Process processes the state changes according to the Ethereum rules by running the transaction messages using the statedb and applying any rewards to both the processor (coinbase) and any included uncles.

Process returns the receipts and logs accumulated during the process and returns the amount of gas that was used in the process. If any of the transactions failed to execute due to insufficient gas it will return an error.

type StateTransition

type StateTransition struct {
	// contains filtered or unexported fields
}

The State Transitioning Model

A state transition is a change made when a transaction is applied to the current world state The state transitioning model does all the necessary work to work out a valid new state root.

1) Nonce handling 2) Pre pay gas 3) Create a new state object if the recipient is \0*32 4) Value transfer == If contract creation ==

4a) Attempt to run transaction data
4b) If valid, use result as code for the new state object

== end == 5) Run Script section 6) Derive new state root

func NewStateTransition

func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition

NewStateTransition initialises and returns a new state transition object.

func (*StateTransition) TransitionDb

func (st *StateTransition) TransitionDb() (*ExecutionResult, error)

TransitionDb will transition the state by applying the current message and returning the evm execution result with following fields.

  • used gas: total gas used (including gas being refunded)
  • returndata: the returned data from evm
  • concrete execution error: various **EVM** error which aborts the execution, e.g. ErrOutOfGas, ErrExecutionReverted

However if any consensus issue encountered, return the error directly with nil evm execution result.

type TestChain

type TestChain struct {
	// contains filtered or unexported fields
}

func (*TestChain) GetHeader

func (tc *TestChain) GetHeader(hash common.Hash, number uint64) *EvmHeader

type TxPool

type TxPool struct {
	// contains filtered or unexported fields
}

TxPool contains all currently known transactions. Transactions enter the pool when they are received from the network or submitted locally. They exit the pool when they are included in the blockchain.

The pool separates processable transactions (which can be applied to the current state) and future transactions. Transactions move between those two states over time as they are received and processed.

func NewTxPool

func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain stateReader) *TxPool

NewTxPool creates a new transaction pool to gather, sort and filter inbound transactions from the network.

func (*TxPool) AddLocal

func (pool *TxPool) AddLocal(tx *types.Transaction) error

AddLocal enqueues a single local transaction into the pool if it is valid. This is a convenience wrapper aroundd AddLocals.

func (*TxPool) AddLocals

func (pool *TxPool) AddLocals(txs []*types.Transaction) []error

AddLocals enqueues a batch of transactions into the pool if they are valid, marking the senders as a local ones, ensuring they go around the local pricing constraints.

This method is used to add transactions from the RPC API and performs synchronous pool reorganization and event propagation.

func (*TxPool) AddRemote deprecated

func (pool *TxPool) AddRemote(tx *types.Transaction) error

AddRemote enqueues a single transaction into the pool if it is valid. This is a convenience wrapper around AddRemotes.

Deprecated: use AddRemotes

func (*TxPool) AddRemotes

func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error

AddRemotes enqueues a batch of transactions into the pool if they are valid. If the senders are not among the locally tracked ones, full pricing constraints will apply.

This method is used to add transactions from the p2p network and does not wait for pool reorganization and internal event propagation.

func (*TxPool) AddRemotesSync

func (pool *TxPool) AddRemotesSync(txs []*types.Transaction) []error

This is like AddRemotes, but waits for pool reorganization. Tests use this method.

func (*TxPool) Content

func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)

Content retrieves the data content of the transaction pool, returning all the pending as well as queued transactions, grouped by account and sorted by nonce.

func (*TxPool) GasPrice

func (pool *TxPool) GasPrice() *big.Int

GasPrice returns the current gas price enforced by the transaction pool.

func (*TxPool) Get

func (pool *TxPool) Get(hash common.Hash) *types.Transaction

Get returns a transaction if it is contained in the pool and nil otherwise.

func (*TxPool) Has

func (pool *TxPool) Has(hash common.Hash) bool

Has returns an indicator whether txpool has a transaction cached with the given hash.

func (*TxPool) Locals

func (pool *TxPool) Locals() []common.Address

Locals retrieves the accounts currently considered local by the pool.

func (*TxPool) Nonce

func (pool *TxPool) Nonce(addr common.Address) uint64

Nonce returns the next nonce of an account, with all transactions executable by the pool already applied on top.

func (*TxPool) Pending

func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error)

Pending retrieves all currently processable transactions, grouped by origin account and sorted by nonce. The returned transaction set is a copy and can be freely modified by calling code.

func (*TxPool) SetGasPrice

func (pool *TxPool) SetGasPrice(price *big.Int)

SetGasPrice updates the minimum price required by the transaction pool for a new transaction, and drops all transactions below this threshold.

func (*TxPool) Stats

func (pool *TxPool) Stats() (int, int)

Stats retrieves the current pool stats, namely the number of pending and the number of queued (non-executable) transactions.

func (*TxPool) Status

func (pool *TxPool) Status(hashes []common.Hash) []TxStatus

Status returns the status (unknown/pending/queued) of a batch of transactions identified by their hashes.

func (*TxPool) Stop

func (pool *TxPool) Stop()

Stop terminates the transaction pool.

func (*TxPool) SubscribeNewTxsNotify

func (pool *TxPool) SubscribeNewTxsNotify(ch chan<- NewTxsNotify) notify.Subscription

SubscribeNewTxsNotify registers a subscription of NewTxsNotify and starts sending event to the given channel.

type TxPoolConfig

type TxPoolConfig struct {
	Locals    []common.Address // Addresses that should be treated by default as local
	NoLocals  bool             // Whether local transaction handling should be disabled
	Journal   string           // Journal of local transactions to survive node restarts
	Rejournal time.Duration    // Time interval to regenerate the local transaction journal

	PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool
	PriceBump  uint64 // Minimum price bump percentage to replace an already existing transaction (nonce)

	AccountSlots uint64 // Number of executable transaction slots guaranteed per account
	GlobalSlots  uint64 // Maximum number of executable transaction slots for all accounts
	AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account
	GlobalQueue  uint64 // Maximum number of non-executable transaction slots for all accounts

	Lifetime time.Duration // Maximum amount of time non-executable transaction are queued
}

TxPoolConfig are the configuration parameters of the transaction pool.

func DefaultTxPoolConfig

func DefaultTxPoolConfig() TxPoolConfig

DefaultTxPoolConfig contains the default configurations for the transaction pool.

func FakeTxPoolConfig

func FakeTxPoolConfig() TxPoolConfig

FakeTxPoolConfig returns the fake configurations for the transaction pool.

type TxStatus

type TxStatus uint

TxStatus is the current status of a transaction as seen by the pool.

const (
	TxStatusUnknown TxStatus = iota
	TxStatusQueued
	TxStatusPending
	TxStatusIncluded
)

type Validator

type Validator interface {
	// ValidateBody validates the given block's content.
	ValidateBody(block *EvmBlock) error

	// ValidateState validates the given statedb and optionally the receipts and
	// gas used.
	ValidateState(block *EvmBlock, state *state.StateDB, receipts types.Receipts, usedGas uint64) error
}

Validator is an interface which defines the standard for block validation. It is only responsible for validating block contents, as the header validation is done by the specific consensus engines.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL