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, trie: import remaining verkle state processor tests #30672

Merged
merged 20 commits into from
Nov 4, 2024

Conversation

gballet
Copy link
Member

@gballet gballet commented Oct 25, 2024

Ahead of the rebase, I am importing these tests that are crucial to test that the verkle testnet functions properly.

Copy link
Contributor

@jwasinger jwasinger left a comment

Choose a reason for hiding this comment

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

Needs a fix: TerminalTotalDifficultyPassed was removed.

Copy link
Contributor

@jwasinger jwasinger left a comment

Choose a reason for hiding this comment

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

Nitpick for readability: ahould also reference opcodes via their mnemonics and not raw values.

gballet and others added 2 commits October 25, 2024 14:58
Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>
Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
@gballet gballet force-pushed the import-verkle-state-processor-tests branch from f01240b to 66c9bb7 Compare October 25, 2024 13:00
@gballet
Copy link
Member Author

gballet commented Oct 25, 2024

Included all the changes requested, except:

Nitpick for readability: ahould also reference opcodes via their mnemonics and not raw values.

No thank you, I would have to byte() cast every opcode, and the way it is currently done, we can highlight what in the code is important to understand what the test is trying to achieve.

trie/verkle.go Outdated Show resolved Hide resolved
@gballet gballet force-pushed the import-verkle-state-processor-tests branch from d702e36 to ce22cd7 Compare October 28, 2024 10:36
@gballet gballet changed the title core, trie: import remaining state processor tests core, trie: import remaining verkle state processor tests Oct 28, 2024
Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
@rjl493456442 rjl493456442 added this to the 1.14.12 milestone Oct 31, 2024
Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

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

LGTM, but let's drop the changes that touch stuff for no reason (whitespace).

core/chain_makers.go Outdated Show resolved Hide resolved
core/chain_makers.go Outdated Show resolved Hide resolved
core/genesis.go Outdated Show resolved Hide resolved
}

// TestProcessVerkleInvalidContractCreation checks for several modes of contract creation failures
func TestProcessVerkleInvalidContractCreation(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't it better to add all these to a file verkle_processing_test.go, or verkle_state_processor_test.go?

Comment on lines 687 to 688
// SSTORE at slot 41 and reverts
tx1payload := common.Hex2Bytes("f8d48084479c2c18830186a08080b8806000602955bda3f9600060ca55600060695523b360006039551983576000601255b0620c2fde2c592ac2600060bc55e0ac6000606455a63e22600060e655eb607e605c5360a2605d5360c7605e53601d605f5360eb606053606b606153608e60625360816063536079606453601e60655360fc60665360b7606753608b60685383021e7ca0cc20c65a97d2e526b8ec0f4266e8b01bdcde43b9aeb59d8bfb44e8eb8119c109a07a8e751813ae1b2ce734960dbc39a4f954917d7822a2c5d1dca18b06c584131f")
Copy link
Contributor

Choose a reason for hiding this comment

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

"SSTORE at slot 41 and reverts" ???
No. It starts with f8, which is the eof EXTCALL opcode, for starters. The one below, "SSTORE at slot 133 and reverts" starts with 02, a.k.a MUL, so obviously croaks on shallow stack immediately.

This kind of highlights the unmaintainability of binary blobs like this. IF you need particular code, either

  1. Use slices of vm.Opcode (for simple stuff).
  2. Use assembly programs, and feed them through some asm -> opcodes engine.

Tangential: What is the point of the payloads in all of these transactions?

Copy link
Member Author

@gballet gballet Oct 31, 2024

Choose a reason for hiding this comment

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

these payloads aren't EOF, they are the RLP of raw transactions extracted from the testnet. They are blobs because they are extracted from a real life testnet block.

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

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

Sorry, undoing that approval: those payload blobs make zero sense

Comment on lines 959 to 961
// The goal of this test is to test SELFDESTRUCT that happens in a contract
// execution which is created in **the same** transaction sending the remaining
// balance to itself.
Copy link
Contributor

Choose a reason for hiding this comment

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

This test doesn't achieve that goal. The runtime bytecode is correct, it does a selfdestruct-to-self. However, the test passes even if one uses e.g. selfDestructContract := []byte{byte(vm.NUMBER), byte(vm.SELFDESTRUCT)}

But, if I add some money to it beforehand,

	// Also add the contract-to-destroy
	gspec.Alloc[contract] = types.Account{
		Balance: big.NewInt(100),
	}

then we get a crash:

=== RUN   TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary
    verkle_witness_test.go:958: Contract: 0x3A220f351252089D385b29beca14e27F204c296A
--- FAIL: TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary (1.51s)
panic: not implemented [recovered]
	panic: not implemented

goroutine 29 [running]:
testing.tRunner.func1.2({0xebcb80, 0x1290420})
	/usr/local/go/src/testing/testing.go:1632 +0x230
testing.tRunner.func1()
	/usr/local/go/src/testing/testing.go:1635 +0x35e
panic({0xebcb80?, 0x1290420?})
	/usr/local/go/src/runtime/panic.go:785 +0x132
github.com/ethereum/go-ethereum/trie.(*VerkleTrie).NodeIterator(0xa4bd96820128063b?, {0x6539b885bc236522?, 0x1f81a32f5e61a48c?, 0xaceb1d6fa1cb7083?})
	/home/user/go/src/github.com/ethereum/go-ethereum/trie/verkle.go:255 +0x25

I'll commit the change which makes it break, so we don't forget to fix it :)

Copy link
Member Author

@gballet gballet Nov 1, 2024

Choose a reason for hiding this comment

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

This test doesn't achieve that goal. The runtime bytecode is correct, it does a selfdestruct-to-self. However, the test passes even if one uses e.g. selfDestructContract := []byte{byte(vm.NUMBER), byte(vm.SELFDESTRUCT)}

It does, the bug I'm interested in, which was fixed, is that if you self-destruct with yourself as a beneficiary, the funds don't end up in the witness - it should be nothing. If you selfdestruct to another address, the balance isn't transferred to the self address, so the "new value" will still be nil, which is normal, and the test passes.

But, if I add some money to it beforehand,

ETH is not money 😁

	// Also add the contract-to-destroy
	gspec.Alloc[contract] = types.Account{
		Balance: big.NewInt(100),
	}

This means you are no longer testing the use case, as the account already exists - which is still a valid test case, but you're changing what is being tested.

then we get a crash:

=== RUN   TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary
    verkle_witness_test.go:958: Contract: 0x3A220f351252089D385b29beca14e27F204c296A
--- FAIL: TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary (1.51s)
panic: not implemented [recovered]
	panic: not implemented

goroutine 29 [running]:
testing.tRunner.func1.2({0xebcb80, 0x1290420})
	/usr/local/go/src/testing/testing.go:1632 +0x230
testing.tRunner.func1()
	/usr/local/go/src/testing/testing.go:1635 +0x35e
panic({0xebcb80?, 0x1290420?})
	/usr/local/go/src/runtime/panic.go:785 +0x132
github.com/ethereum/go-ethereum/trie.(*VerkleTrie).NodeIterator(0xa4bd96820128063b?, {0x6539b885bc236522?, 0x1f81a32f5e61a48c?, 0xaceb1d6fa1cb7083?})
	/home/user/go/src/github.com/ethereum/go-ethereum/trie/verkle.go:255 +0x25

I'll commit the change which makes it break, so we don't forget to fix it :)

Ok yeah, interestingly that triggered a piece of code that shouldn't be called. I have to look into it, thanks.

tx, _ = types.SignTx(types.NewContractCreation(6, big.NewInt(16), 3000000, big.NewInt(875000000), code), signer, testKey)
gen.AddTx(tx)

tx, _ = types.SignTx(types.NewContractCreation(7, big.NewInt(0), 3000000, big.NewInt(875000000), codeWithExtCodeCopy), signer, testKey)
Copy link
Contributor

Choose a reason for hiding this comment

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

you use NewContractCreation a lot. It's deprecated

Copy link
Member Author

Choose a reason for hiding this comment

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

no surprise here, I'm trying to merge changes to a fork from 4 years ago.

What should this be replaced with though? I still see it used all over the codebase. nvm found it.

@holiman
Copy link
Contributor

holiman commented Nov 1, 2024

You have a lot of tests surrounding selfdestruct, however, the scenario around "selfdestruct in the same tx" seems a bit under-explored. You do

  • Send create-tx. During evaluation of initcode, instead of deploying code, invoke SELFDESTRUCT.

A more complicated scenario that might be worth including is:

  • Have a contract (factory) A, already existing in state.
  • Send tx to A. This triggers
    • A does CREATE2 and spawns B.
    • A calls B
      • B performs SELFDESTRUCT.
    • A returns ok (as opposed error-exit)

Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
@@ -665,7 +689,12 @@ func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) {

if i == 0 {
// Create selfdestruct contract, sending 42 wei.
tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(42), 100_000, big.NewInt(875000000), selfDestructContract), signer, testKey)
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: 0,
Copy link

Choose a reason for hiding this comment

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

Tip, types.SignTx(types.NewTx( can be replaced by types.SignNewTx

Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

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

LGTM

@holiman holiman merged commit 06cbc80 into ethereum:master Nov 4, 2024
3 checks passed
holiman added a commit that referenced this pull request Nov 19, 2024
Tests that are crucial to for verifying the verkle testnet functions properly.

---------

Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Martin HS <martin@swende.se>
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.

5 participants