-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FVM] beyond EVM part 2.2 - adding EVM emulator #4927
Merged
Merged
Changes from 19 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
01bc52e
add emulator code
ramtinms c5ec8b2
go mod tidy
ramtinms 0306c55
.
ramtinms 14f56a1
fix test
ramtinms 3ea815d
Merge branch 'ramtin/evm-adding-emulator-database' into ramtin/evm-ad…
ramtinms a21ecbe
update commit
ramtinms 76686d3
minor improvements
ramtinms 7395887
simplify direct calls
ramtinms e205b2a
add EVM validation error type
ramtinms 5ee4bc4
Merge branch 'ramtin/evm-adding-emulator-database' into ramtin/evm-ad…
ramtinms d0328c4
typo
ramtinms 6a9fee2
fix error handling
ramtinms f3d9a25
.
ramtinms 57d342b
.
ramtinms b98e919
add more tests on tx validation
ramtinms c0c6844
doc
ramtinms 948fd28
update docs
ramtinms 1a8e3dd
doc update
ramtinms 3ed4ea2
improve error handling
ramtinms eb152e1
apply PR comments
ramtinms 26480ec
apply PR comments
ramtinms ae39807
Merge branch 'master' into ramtin/evm-adding-emulator
ramtinms 3594345
fix err override issue
ramtinms 03a064e
Merge branch 'master' into ramtin/evm-adding-emulator
ramtinms 81e7c4d
Merge branch 'master' into ramtin/evm-adding-emulator
ramtinms c848b92
apply PR feedback
ramtinms 48be317
remove WithBaseFee config
ramtinms cda7ba4
Merge branch 'master' into ramtin/evm-adding-emulator
ramtinms File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
package emulator | ||
|
||
import ( | ||
"math" | ||
"math/big" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core" | ||
"github.com/ethereum/go-ethereum/core/vm" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/ethereum/go-ethereum/params" | ||
) | ||
|
||
var ( | ||
FlowEVMTestnetChainID = big.NewInt(666) | ||
FlowEVMMainnetChainID = big.NewInt(777) | ||
BlockLevelGasLimit = uint64(math.MaxUint64) | ||
zero = uint64(0) | ||
) | ||
|
||
// Config sets the required parameters | ||
type Config struct { | ||
// Chain Config | ||
ChainConfig *params.ChainConfig | ||
// EVM config | ||
EVMConfig vm.Config | ||
// block context | ||
BlockContext *vm.BlockContext | ||
// transaction context | ||
TxContext *vm.TxContext | ||
// base unit of gas for direct calls | ||
DirectCallBaseGasUsage uint64 | ||
} | ||
|
||
// DefaultChainConfig is the default chain config which | ||
// considers majority of EVM upgrades (e.g. Shanghai update) already been applied | ||
// this has done through setting the height of these changes | ||
// to zero nad setting the time for some other changes to zero | ||
// For the future changes of EVM, we need to update the EVM go mod version | ||
// and set a proper height for the specific release based on the Flow EVM heights | ||
// so it could gets activated at a desired time. | ||
var DefaultChainConfig = ¶ms.ChainConfig{ | ||
ChainID: FlowEVMTestnetChainID, // default is testnet | ||
|
||
// Fork scheduling based on block heights | ||
HomesteadBlock: big.NewInt(0), | ||
DAOForkBlock: big.NewInt(0), | ||
DAOForkSupport: false, | ||
EIP150Block: big.NewInt(0), | ||
EIP155Block: big.NewInt(0), | ||
EIP158Block: big.NewInt(0), | ||
ByzantiumBlock: big.NewInt(0), // already on Byzantium | ||
ConstantinopleBlock: big.NewInt(0), // already on Constantinople | ||
PetersburgBlock: big.NewInt(0), // already on Petersburg | ||
IstanbulBlock: big.NewInt(0), // already on Istanbul | ||
BerlinBlock: big.NewInt(0), // already on Berlin | ||
LondonBlock: big.NewInt(0), // already on London | ||
MuirGlacierBlock: big.NewInt(0), // already on MuirGlacier | ||
|
||
// Fork scheduling based on timestamps | ||
ShanghaiTime: &zero, // already on Shanghai | ||
CancunTime: &zero, // already on Cancun | ||
PragueTime: &zero, // already on Prague | ||
} | ||
|
||
func defaultConfig() *Config { | ||
return &Config{ | ||
ChainConfig: DefaultChainConfig, | ||
EVMConfig: vm.Config{ | ||
NoBaseFee: true, | ||
}, | ||
TxContext: &vm.TxContext{}, | ||
BlockContext: &vm.BlockContext{ | ||
CanTransfer: core.CanTransfer, | ||
Transfer: core.Transfer, | ||
GasLimit: BlockLevelGasLimit, // block gas limit | ||
BaseFee: big.NewInt(0), // | ||
GetHash: func(n uint64) common.Hash { // default returns some random hash values | ||
return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String()))) | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
// NewConfig initializes a new config | ||
func NewConfig(opts ...Option) *Config { | ||
ctx := defaultConfig() | ||
for _, applyOption := range opts { | ||
ctx = applyOption(ctx) | ||
} | ||
return ctx | ||
} | ||
|
||
type Option func(*Config) *Config | ||
|
||
// WithMainnetChainID sets the chain ID to flow evm testnet | ||
func WithTestnetChainID() Option { | ||
return func(c *Config) *Config { | ||
c.ChainConfig.ChainID = FlowEVMTestnetChainID | ||
return c | ||
} | ||
} | ||
|
||
// WithMainnetChainID sets the chain ID to flow evm mainnet | ||
func WithMainnetChainID() Option { | ||
return func(c *Config) *Config { | ||
c.ChainConfig.ChainID = FlowEVMMainnetChainID | ||
return c | ||
} | ||
|
||
} | ||
|
||
// WithOrigin sets the origin of the transaction (signer) | ||
func WithOrigin(origin common.Address) Option { | ||
return func(c *Config) *Config { | ||
c.TxContext.Origin = origin | ||
return c | ||
} | ||
} | ||
|
||
// WithGasPrice sets the gas price for the transaction (usually the one sets by the sender) | ||
func WithGasPrice(gasPrice *big.Int) Option { | ||
return func(c *Config) *Config { | ||
c.TxContext.GasPrice = gasPrice | ||
return c | ||
} | ||
} | ||
|
||
// WithBaseFee sets the the base fee for each transaction | ||
func WithBaseFee(baseFee *big.Int) Option { | ||
return func(c *Config) *Config { | ||
c.BlockContext.BaseFee = baseFee | ||
return c | ||
} | ||
} | ||
|
||
// WithGasLimit sets the gas limit of the transaction | ||
func WithGasLimit(gasLimit uint64) Option { | ||
return func(c *Config) *Config { | ||
c.BlockContext.GasLimit = gasLimit | ||
return c | ||
} | ||
} | ||
|
||
// WithCoinbase sets the coinbase of the block where the fees are collected in | ||
func WithCoinbase(coinbase common.Address) Option { | ||
return func(c *Config) *Config { | ||
c.BlockContext.Coinbase = coinbase | ||
return c | ||
} | ||
} | ||
|
||
// WithBlockNumber sets the block height in the block context | ||
func WithBlockNumber(blockNumber *big.Int) Option { | ||
return func(c *Config) *Config { | ||
c.BlockContext.BlockNumber = blockNumber | ||
return c | ||
} | ||
} | ||
|
||
// WithBlockTime sets the block time in the block context | ||
func WithBlockTime(time uint64) Option { | ||
return func(c *Config) *Config { | ||
c.BlockContext.Time = time | ||
return c | ||
} | ||
} | ||
|
||
// WithGetBlockHashFunction sets the functionality to look up block hash by height | ||
func WithGetBlockHashFunction(getHash vm.GetHashFunc) Option { | ||
return func(c *Config) *Config { | ||
c.BlockContext.GetHash = getHash | ||
return c | ||
} | ||
} | ||
|
||
// WithDirectCallBaseGasUsage sets the base direct call gas usage | ||
func WithDirectCallBaseGasUsage(gas uint64) Option { | ||
return func(c *Config) *Config { | ||
c.DirectCallBaseGasUsage = gas | ||
return c | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.