Skip to content

chore: backport custom changes to v1.13.15 #1

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!--
Guiding Principles:

Changelogs are for humans, not machines.
There should be an entry for every single version.
The same types of changes should be grouped.
Versions and sections should be linkable.
The latest version comes first.
The release date of each version is displayed.
Mention whether you follow Semantic Versioning.

Usage:

Change log entries are to be added to the Unreleased section under the
appropriate stanza (see below). Each entry should ideally include a tag and
the Github issue reference in the following format:

* (<tag>) \#<issue-number> message

The issue numbers will later be link-ified during the release process so you do
not have to worry about including a link manually, but you can if you wish.

Types of changes (Stanzas):

"Features" for new features.
"Improvements" for changes in existing functionality.
"Deprecated" for soon-to-be removed features.
"Bug Fixes" for any bug fixes.
"Client Breaking" for breaking CLI commands and REST routes used by end-users.
"API Breaking" for breaking exported APIs used by developers building on SDK.
"State Machine Breaking" for any changes that result in a different AppState given same genesisState and txList.

Ref: https://keepachangelog.com/en/1.0.0/
-->

# Changelog

## Unreleased

### Improvements

- [#28](https://github.com/evmos/go-ethereum/pull/28) OpCodesHooks for CREATE and CALL opcodes
- [#26](https://github.com/evmos/go-ethereum/pull/26) PreExecuteCallback for Call opcodes
- [#23](https://github.com/evmos/go-ethereum/pull/23) Remove `IsStateful` function from the `PrecompiledContract` interface, as this remains unused.
- [#8](https://github.com/evmos/go-ethereum/pull/8) Add `Address` function to `PrecompiledContract` interface.
- [#7](https://github.com/evmos/go-ethereum/pull/7) Implement custom active precompiles for the EVM.
- [#6](https://github.com/evmos/go-ethereum/pull/6) Refactor `Stack` implementation
- [#3](https://github.com/evmos/go-ethereum/pull/3) Move the `JumpTable` defaults to a separate function.
- [#2](https://github.com/evmos/go-ethereum/pull/2) Define `Interpreter` interface for the EVM.

### State Machine Breaking

- [#24](https://github.com/evmos/go-ethereum/pull/24) Set `callcode` to use `readOnly` mode for precompiled calls.
- [#10](https://github.com/evmos/go-ethereum/pull/10) Support stateful precompiled contracts.
2 changes: 1 addition & 1 deletion core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
// Execute the preparatory steps for state transition which includes:
// - prepare accessList(post-berlin)
// - reset transient storage(eip 1153)
st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList)
st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, st.evm.ActivePrecompiles(rules), msg.AccessList)

var (
ret []byte
Expand Down
6 changes: 6 additions & 0 deletions core/vm/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ import (
"github.com/holiman/uint256"
)

// CalcMemSize64 calculates the required memory size, and returns
// the size and whether the result overflowed uint64
func CalcMemSize64(off, l *uint256.Int) (uint64, bool) {
return calcMemSize64(off, l)
}

// calcMemSize64 calculates the required memory size, and returns
// the size and whether the result overflowed uint64
func calcMemSize64(off, l *uint256.Int) (uint64, bool) {
Expand Down
50 changes: 47 additions & 3 deletions core/vm/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

// ContractRef is a reference to the contract's backing object
type ContractRef interface {
// Address returns the contract's address
Address() common.Address
}

Expand Down Expand Up @@ -56,12 +57,13 @@ type Contract struct {
CodeAddr *common.Address
Input []byte

Gas uint64
value *uint256.Int
Gas uint64
value *uint256.Int
isPrecompile bool
}

// NewContract returns a new contract environment for the execution of EVM.
func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas uint64) *Contract {
func NewContract(caller, object ContractRef, value *uint256.Int, gas uint64) *Contract {
c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object}

if parent, ok := caller.(*Contract); ok {
Expand All @@ -80,7 +82,34 @@ func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas
return c
}

// NewPrecompile returns a new instance of a precompiled contract environment for the execution of EVM.
func NewPrecompile(caller, object ContractRef, value *uint256.Int, gas uint64) *Contract {
c := &Contract{
CallerAddress: caller.Address(),
caller: caller,
self: object,
isPrecompile: true,
}

// Gas should be a pointer so it can safely be reduced through the run
// This pointer will be off the state transition
c.Gas = gas
// ensures a value is set
c.value = value

return c
}

// IsPrecompile returns true if the contract is a precompiled contract environment
func (c Contract) IsPrecompile() bool {
return c.isPrecompile
}

func (c *Contract) validJumpdest(dest *uint256.Int) bool {
if c.isPrecompile {
return false
}

udest, overflow := dest.Uint64WithOverflow()
// PC cannot go beyond len(code) and certainly can't be bigger than 63bits.
// Don't bother checking for JUMPDEST in that case.
Expand All @@ -97,6 +126,10 @@ func (c *Contract) validJumpdest(dest *uint256.Int) bool {
// isCode returns true if the provided PC location is an actual opcode, as
// opposed to a data-segment following a PUSHN operation.
func (c *Contract) isCode(udest uint64) bool {
if c.isPrecompile {
return false
}

// Do we already have an analysis laying around?
if c.analysis != nil {
return c.analysis.codeSegment(udest)
Expand Down Expand Up @@ -130,6 +163,9 @@ func (c *Contract) isCode(udest uint64) bool {
// AsDelegate sets the contract to be a delegate call and returns the current
// contract (for chaining calls)
func (c *Contract) AsDelegate() *Contract {
if c.isPrecompile {
return c
}
// NOTE: caller must, at all times be a contract. It should never happen
// that caller is something other than a Contract.
parent := c.caller.(*Contract)
Expand Down Expand Up @@ -178,6 +214,10 @@ func (c *Contract) Value() *uint256.Int {
// SetCallCode sets the code of the contract and address of the backing data
// object
func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
if c.isPrecompile {
return
}

c.Code = code
c.CodeHash = hash
c.CodeAddr = addr
Expand All @@ -186,6 +226,10 @@ func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []by
// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash.
// In case hash is not provided, the jumpdest analysis will not be saved to the parent context
func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) {
if c.isPrecompile {
return
}

c.Code = codeAndHash.code
c.CodeHash = codeAndHash.hash
c.CodeAddr = addr
Expand Down
Loading