Skip to content
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

core/vm: implement EIP-3860: Limit and meter initcode #23847

Merged
merged 16 commits into from Jan 11, 2023

Conversation

gumb0
Copy link
Member

@gumb0 gumb0 commented Nov 2, 2021

@gumb0 gumb0 force-pushed the eip-3860 branch 2 times, most recently from d96f2af to 91542cc Compare November 2, 2021 15:08
core/vm/gas_table.go Outdated Show resolved Hide resolved
if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow {
lenWords := toWordSize(len)

hashingWordGas, overflow := math.SafeMul(lenWords, params.Sha3WordGas)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is moved to be the last step, then the size-related check can be deduplicated between gasCreate and gasCreate2. I think we also mentioned this in the EIP.

Not sure if this is a concern in geth, but thought to mention it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be a bit tricky without having to repeat len, overflow := stack.Back(2).Uint64WithOverflow() and lenWords := toWordSize(len) calls, so I decided that maybe it's simpler to leave duplication.

core/vm/gas_table.go Outdated Show resolved Hide resolved
Comment on lines 310 to 316
eip3860 := false
for _, eip := range st.evm.Config.ExtraEips {
if eip == 3860 {
eip3860 = true
break
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this iteration should happen in here. IIRC we already do this somewhere else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes in a private function in vm currently

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made HasEip3860() a public method of evm.Config, this iteration is not repeated now.

@gumb0 gumb0 force-pushed the eip-3860 branch 4 times, most recently from cb25f4d to 7c6961f Compare November 15, 2021 11:59
core/tx_pool.go Outdated
@@ -636,7 +636,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
return ErrInsufficientFunds
}
// Ensure the transaction has more gas than the basic tx fee.
intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul)
intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, true)
Copy link
Member Author

@gumb0 gumb0 Nov 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here TxPool is being conservative and always expects creation transactions to have enough gas to cover initcode charge.

Not sure yet how would we check here for extra EIP being activated and whether it's worth it.

Copy link
Member Author

@gumb0 gumb0 Nov 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to change it to always assume EIP-3860 is not activated, then nothing changes for the tx pool right now, but with EIP activated it will not drop some txs that don't have enough gas to pay for initcode.

Which would be easier to solve when EIP is accepted to the fork, and not is an "extra EIP".

Suggested change
intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, true)
intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, false)

core/vm/eips.go Outdated
@@ -174,3 +175,13 @@ func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
scope.Stack.push(baseFee)
return nil, nil
}

func enable3860(jt *JumpTable) {
createOp := *jt[CREATE]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I clone operation struct here, because doing just jt[CREATE].dynamicCost = ... would modify existing operation in underlying global londonInstructionSet, and that would influence unit tests that switch between enabling / disabling EIP3860.

Not sure if this is also a problem for other enable... functions above (enable2200, enable3529)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be an issue -- NewXXInstructionSet uses a brand new instructionset.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But newLondonInstructionSet() is called only once when global is initialized

londonInstructionSet = newLondonInstructionSet()

NewEVMInterpreter then creates a new JumpTable instance, but it contains the pointers to the same opertations of londonInstructionSet global.

jt = londonInstructionSet

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better fix for this is in #23977

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this code needs any changes after #23977?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better fix for this is in #23977

Actually this hack is still needed, because JumpTable contains pointers to operations, so modification like jt[CREATE].dynamicGas = gasCreateEip3860 would change the operation for londonInstructionSet, too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now not needed, I think, we changed it so ops are deep-copied.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the latest commit I removed it anyway, because the new initcode charge is applied inside create implementation and not in dynamicGas calculation, so new cost functions are not needed.

@gumb0 gumb0 force-pushed the eip-3860 branch 2 times, most recently from aab6c14 to d986fb2 Compare November 23, 2021 10:12
@gumb0 gumb0 requested a review from holiman November 24, 2021 12:18
@gumb0
Copy link
Member Author

gumb0 commented Nov 24, 2021

@holiman Please take a look. Suggestions how to improve this are appreciated.

core/vm/gas_table_test.go Outdated Show resolved Hide resolved
@MariusVanDerWijden
Copy link
Member

commit ff8a9aa49073bd033278b5ceed65e673d441b88e (HEAD -> eip-3860)
Author: Marius van der Wijden <m.vanderwijden@live.de>
Date:   Tue Jan 10 12:24:14 2023 +0100

    core/txpool: set shanghai by time correctly

diff --git a/core/state_processor_test.go b/core/state_processor_test.go
index 473a09f27..400ccd318 100644
--- a/core/state_processor_test.go
+++ b/core/state_processor_test.go
@@ -327,7 +327,7 @@ func TestStateProcessorErrors(t *testing.T) {
                                        ArrowGlacierBlock:   big.NewInt(0),
                                        GrayGlacierBlock:    big.NewInt(0),
                                        MergeNetsplitBlock:  big.NewInt(0),
-                                       ShanghaiBlock:       big.NewInt(0),
+                                       ShanghaiTime:        big.NewInt(0),
                                },
                                Alloc: GenesisAlloc{
                                        common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go
index 4c7e73c39..dc6a71f07 100644
--- a/core/txpool/txpool.go
+++ b/core/txpool/txpool.go
@@ -1307,7 +1307,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
        pool.istanbul = pool.chainconfig.IsIstanbul(next)
        pool.eip2718 = pool.chainconfig.IsBerlin(next)
        pool.eip1559 = pool.chainconfig.IsLondon(next)
-       pool.shanghai = pool.chainconfig.IsShanghai(next)
+       pool.shanghai = pool.chainconfig.IsShanghai(big.NewInt(time.Now().Unix()))
 }
 
 // promoteExecutables moves transactions that have become processable from the
diff --git a/light/txpool.go b/light/txpool.go
index 798ef1708..e12f6ef94 100644
--- a/light/txpool.go
+++ b/light/txpool.go
@@ -318,7 +318,7 @@ func (pool *TxPool) setNewHead(head *types.Header) {
        next := new(big.Int).Add(head.Number, big.NewInt(1))
        pool.istanbul = pool.config.IsIstanbul(next)
        pool.eip2718 = pool.config.IsBerlin(next)
-       pool.shanghai = pool.config.IsShanghai(next)
+       pool.shanghai = pool.config.IsShanghai(big.NewInt(time.Now().Unix()))
 }
 
 // Stop stops the light transaction pool

I can't push to this repo, @chfast could you add this diff pls

@@ -120,16 +120,17 @@ func (result *ExecutionResult) Revert() []byte {
}

// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028 bool) (uint64, error) {
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028 bool, isEIP3860 bool) (uint64, error) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isEIP2028 bool seems not used anymore

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is, afaict:

nonZeroGas := params.TxDataNonZeroGasFrontier
if isEIP2028 {
	nonZeroGas = params.TxDataNonZeroGasEIP2028
}
		```

NazariiDenha pushed a commit to scroll-tech/go-ethereum that referenced this pull request May 9, 2023
Implementation of https://eips.ethereum.org/EIPS/eip-3860, limit and meter initcode. This PR enables EIP-3860 as part of the Shanghai fork.

Co-authored-by: lightclient@protonmail.com <lightclient@protonmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
NazariiDenha added a commit to scroll-tech/go-ethereum that referenced this pull request May 18, 2023
#318)

* core/vm: implement EIP-3860: Limit and meter initcode (ethereum#23847)

Implementation of https://eips.ethereum.org/EIPS/eip-3860, limit and meter initcode. This PR enables EIP-3860 as part of the Shanghai fork.

Co-authored-by: lightclient@protonmail.com <lightclient@protonmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>

* add ishanghai

* fix test

* fix

---------

Co-authored-by: Andrei Maiboroda <andrei@ethereum.org>
Co-authored-by: lightclient@protonmail.com <lightclient@protonmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
shekhirin pushed a commit to shekhirin/go-ethereum that referenced this pull request Jun 6, 2023
Implementation of https://eips.ethereum.org/EIPS/eip-3860, limit and meter initcode. This PR enables EIP-3860 as part of the Shanghai fork. 


Co-authored-by: lightclient@protonmail.com <lightclient@protonmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
MoonShiesty pushed a commit to MoonShiesty/go-ethereum that referenced this pull request Aug 30, 2023
Implementation of https://eips.ethereum.org/EIPS/eip-3860, limit and meter initcode. This PR enables EIP-3860 as part of the Shanghai fork. 


Co-authored-by: lightclient@protonmail.com <lightclient@protonmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants