-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Implement EIP-7702: set code tx #10812
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
Changes from all commits
9b7f69f
45ffe29
6ebae60
fb783f2
b668b57
7f6416e
05e63c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,17 +20,21 @@ | |
| package core | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "fmt" | ||
|
|
||
| "github.com/holiman/uint256" | ||
| "github.com/ledgerwatch/erigon-lib/log/v3" | ||
|
|
||
| "github.com/ledgerwatch/erigon-lib/common" | ||
| libcommon "github.com/ledgerwatch/erigon-lib/common" | ||
| "github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg" | ||
| types2 "github.com/ledgerwatch/erigon-lib/types" | ||
|
|
||
| cmath "github.com/ledgerwatch/erigon/common/math" | ||
| "github.com/ledgerwatch/erigon/common/u256" | ||
| "github.com/ledgerwatch/erigon/core/tracing" | ||
| "github.com/ledgerwatch/erigon/core/types" | ||
| "github.com/ledgerwatch/erigon/core/vm" | ||
| "github.com/ledgerwatch/erigon/core/vm/evmtypes" | ||
| "github.com/ledgerwatch/erigon/crypto" | ||
|
|
@@ -96,12 +100,14 @@ type Message interface { | |
| Data() []byte | ||
| AccessList() types2.AccessList | ||
| BlobHashes() []libcommon.Hash | ||
| Authorizations() []types.Authorization | ||
|
|
||
| IsFree() bool | ||
| } | ||
|
|
||
| // IntrinsicGas computes the 'intrinsic gas' for a message with the given data. | ||
| func IntrinsicGas(data []byte, accessList types2.AccessList, isContractCreation bool, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { | ||
| // TODO: convert the input to a struct | ||
| func IntrinsicGas(data []byte, accessList types2.AccessList, isContractCreation bool, isHomestead, isEIP2028, isEIP3860 bool, authorizationsLen uint64) (uint64, error) { | ||
| // Zero and non-zero bytes are priced differently | ||
| dataLen := uint64(len(data)) | ||
| dataNonZeroLen := uint64(0) | ||
|
|
@@ -111,7 +117,7 @@ func IntrinsicGas(data []byte, accessList types2.AccessList, isContractCreation | |
| } | ||
| } | ||
|
|
||
| gas, status := txpoolcfg.CalcIntrinsicGas(dataLen, dataNonZeroLen, accessList, isContractCreation, isHomestead, isEIP2028, isEIP3860) | ||
| gas, status := txpoolcfg.CalcIntrinsicGas(dataLen, dataNonZeroLen, authorizationsLen, accessList, isContractCreation, isHomestead, isEIP2028, isEIP3860) | ||
| if status != txpoolcfg.Success { | ||
| return 0, ErrGasUintOverflow | ||
| } | ||
|
|
@@ -339,9 +345,70 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype | |
| rules := st.evm.ChainRules() | ||
| vmConfig := st.evm.Config() | ||
| isEIP3860 := vmConfig.HasEip3860(rules) | ||
| accessTuples := make(types2.AccessList, 0) | ||
| if msg.AccessList() != nil { | ||
| accessTuples = append(accessTuples, msg.AccessList()...) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks similar to
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, will remove it
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oops. Auto-merge was on...will put this in a new pr. |
||
| } | ||
|
|
||
| // set code tx | ||
| auths := msg.Authorizations() | ||
| verifiedAuthorities := make([]common.Address, 0) | ||
| if len(auths) > 0 { | ||
| var b [33]byte | ||
| data := bytes.NewBuffer(nil) | ||
| for i, auth := range auths { | ||
| data.Reset() | ||
|
|
||
| // 1. authority recover | ||
| authorityPtr, err := auth.RecoverSigner(data, b[:]) | ||
| if err != nil { | ||
| log.Debug("authority recover failed, skipping", "err", err, "auth index", i) | ||
| continue | ||
| } | ||
| authority := *authorityPtr | ||
|
sudeepdino008 marked this conversation as resolved.
|
||
|
|
||
| // 2. chainId check | ||
| if auth.ChainID != nil && auth.ChainID.Uint64() != 0 && auth.ChainID.Uint64() != st.evm.ChainRules().ChainID.Uint64() { | ||
| log.Debug("invalid chainID, skipping", "chainId", auth.ChainID, "auth index", i) | ||
| continue | ||
| } | ||
|
|
||
| // 3. authority code should be empty | ||
| if codeHash := st.state.GetCodeHash(authority); codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) { | ||
| log.Debug("authority code is not empty, skipping", "auth index", i) | ||
| continue | ||
| } | ||
|
|
||
| // 4. nonce check | ||
| if len(auth.Nonce) > 0 && st.state.GetNonce(authority) != auth.Nonce[0] { | ||
| log.Debug("invalid nonce, skipping", "auth index", i) | ||
| continue | ||
| } | ||
|
|
||
| // 5. set code of authority to code associated with address | ||
| st.state.SetCode(authority, st.state.GetCode(auth.Address)) | ||
|
|
||
| // 6. add authority account to accesses_addresses | ||
| verifiedAuthorities = append(verifiedAuthorities, authority) | ||
| // authority is added to accessed_address in prepare step | ||
| } | ||
| } | ||
|
|
||
| if len(verifiedAuthorities) > 0 { | ||
| oldPostApplyMessage := st.evm.Context.PostApplyMessage | ||
| st.evm.Context.PostApplyMessage = func(ibs evmtypes.IntraBlockState, sender common.Address, coinbase common.Address, result *evmtypes.ExecutionResult) { | ||
| for _, authority := range verifiedAuthorities { | ||
| ibs.SetCode(authority, nil) | ||
| } | ||
|
|
||
| if oldPostApplyMessage != nil { | ||
| oldPostApplyMessage(ibs, sender, coinbase, result) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Check clauses 4-5, subtract intrinsic gas if everything is correct | ||
| gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, rules.IsHomestead, rules.IsIstanbul, isEIP3860) | ||
| gas, err := IntrinsicGas(st.data, accessTuples, contractCreation, rules.IsHomestead, rules.IsIstanbul, isEIP3860, uint64(len(auths))) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
@@ -366,7 +433,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype | |
| // Execute the preparatory steps for state transition which includes: | ||
| // - prepare accessList(post-berlin) | ||
| // - reset transient storage(eip 1153) | ||
| st.state.Prepare(rules, msg.From(), coinbase, msg.To(), vm.ActivePrecompiles(rules), msg.AccessList()) | ||
| st.state.Prepare(rules, msg.From(), coinbase, msg.To(), vm.ActivePrecompiles(rules), accessTuples, verifiedAuthorities) | ||
|
|
||
| var ( | ||
| ret []byte | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.