Compare commits

..

1483 Commits

Author SHA1 Message Date
Martin HS
f3c696fa1d all: release go-ethereum v1.13.8
Release 1.14.11
2024-10-01 15:17:59 +02:00
Martin Holst Swende
f14f13bac7 params: go-ethereum v1.14.11 stable 2024-10-01 15:14:30 +02:00
Sina M
40fd887df6 internal/ethapi: remove td field from block (#30386)
implement https://github.com/ethereum/execution-apis/pull/570
2024-10-01 11:36:56 +02:00
Ng Wei Han
db6ae7fa12 cmd/geth: remove deprecated lightchaindata db (#30527)
This PR removes the dependencies on `lightchaindata` db as the light
protocol has been deprecated and removed from the codebase.
2024-09-30 19:32:39 +03:00
Martin HS
e67d5f8c44 eth/catalyst: use setcanonical instead of sethead in simulated fork (#30465)
Fixes https://github.com/ethereum/go-ethereum/issues/30448
2024-09-30 14:46:39 +02:00
Martin HS
cfe25c7a3b build: use buildx to build multi-platform docker images (#30530) 2024-09-30 15:39:53 +03:00
minh-bq
0a21cb4d21 core/txpool/blobpool: use types.Sender instead of signer.Sender (#30473)
Use types.Sender(signer, tx) to utilize the transaction's sender cache
and avoid repeated address recover.
2024-09-30 12:06:10 +03:00
Felix Lange
6b61b54dc7 p2p/discover: add config option for disabling FINDNODE liveness check (#30512)
This is for fixing Prysm integration tests.
2024-09-30 10:56:14 +02:00
Péter Szilágyi
283be23817 params: begin v1.14.11 release cycle 2024-09-27 14:13:45 +03:00
Péter Szilágyi
1015a42d90 Merge pull request #30522 from ethereum/master
Release Geth v1.14.10
2024-09-27 14:12:54 +03:00
Péter Szilágyi
269551876e params: release Geth v1.14.10 2024-09-27 14:09:42 +03:00
Péter Szilágyi
1df75dbe36 Revert "core/txpool, eth/catalyst: ensure gas tip retains current value upon rollback" (#30521)
Reverts ethereum/go-ethereum#30495

You are free to create a proper Clear method if that's the best way. But
one that does a proper cleanup, not some hacky call to set gas which
screws up logs, metrics and everything along the way. Also doesn't work
for legacy pool local transactions.

The current code had a hack in the simulated code, now we have a hack in
live txpooling code. No, that's not acceptable. I want the live code to
be proper, meaningful API, meaningful comments, meaningful
implementation.
2024-09-27 13:56:25 +03:00
Péter Szilágyi
52a9d89655 Merge pull request #30518 from holiman/blobpool_fix
core/txpool/blobpool: return all reinject-addresses
2024-09-27 13:05:35 +03:00
Péter Szilágyi
abbd3d9d21 core/txpool/blobpool: add test to check internal shuffling 2024-09-27 12:20:12 +03:00
Martin Holst Swende
9274f28210 core/txpool/blobpool: revert part of #30437, return all reinject-addresses 2024-09-27 08:24:23 +02:00
jwasinger
bb9897f11b core/txpool, eth/catalyst: ensure gas tip retains current value upon rollback (#30495)
Here we move the method that drops all transactions by temporarily increasing the fee
into the TxPool itself. It's better to have it there because we can set it back to the
configured value afterwards. This resolves a TODO in the simulated backend.
2024-09-26 11:08:36 +02:00
Martin HS
93675d1da7 deps: update supranational/blst (#30504)
This update should only affect the fuzzers, as far as I know. But it
seems like it might also fix some arm/macos compilation issue in
https://github.com/ethereum/go-ethereum/issues/30494

Closes #30494 (I think)
2024-09-26 10:28:40 +03:00
Martin HS
b5a88dafae p2p/discover: fix flaky tests writing to test.log after completion (#30506)
This PR fixes two tests, which had a tendency to sometimes write to the `*testing.T` `log` facility after the test function had completed, which is not allowed. This PR fixes it by using waitgroups to ensure that the handler/logwriter terminates before the test exits.

closes #30505
2024-09-26 08:12:12 +02:00
jwasinger
80b529ea71 core/vm: more benchmarks for bls g1/g2-multiexp precompiles (#30459)
This change adds more comprehensive benchmarks with a wider-variety of input sizes for g1 and g2 multi exponentiation.
2024-09-24 13:53:46 +02:00
Karol Chojnowski
55ed8fef0b core/tracing, core/vm: add ContractCode to the OpContext (#30466)
Extends the opcontext interface to include accessor for code being executed in current context. While it is possible to get the code via `statedb.GetCode`, that approach doesn't work for initcode.
2024-09-24 13:18:36 +02:00
Sina M
f2e13c7e33 internal/ethapi: fix gascap 0 for eth_simulateV1 (#30496)
Similar to #30474.
2024-09-24 13:14:38 +02:00
maskpp
2278647ef2 core/rawdb: make sure specified state scheme is valid (#30499)
This change exits with error if user provided a `--state.scheme` which is neither `hash` nor `path`
2024-09-24 09:26:29 +02:00
jwasinger
564b616163 internal/ethapi/api: for simulated calls, set gaspool to max value if global gascap is 0 (#30474)
In #27720, we introduced RPC global gas cap. A value of `0` means an unlimited gas cap. However, this was not the case for simulated calls. This PR fixes the behaviour.
2024-09-23 13:31:56 +02:00
rjl493456442
b805772cb4 core/state: commit snapshot only if the base layer exists (#30493)
This pull request skips the state snapshot update if the base layer is
not existent, eliminating the numerous warning logs after an unclean
shutdown.

Specifically, Geth will rewind its chain head to a historical block
after unclean shutdown and state snapshot will be remained as unchanged
waiting for recovery. During this period of time, the snapshot is unusable
and all state updates should be ignored/skipped for state snapshot update.
2024-09-23 19:27:29 +08:00
zhiqiangxu
956d32d3e4 core/state: fix comment of mode (#30490) 2024-09-23 09:29:07 +02:00
zhiqiangxu
118c84af57 cmd/utils: fix setEtherbase (#30488)
Make `setEtherbase` fall thorugh and handle `miner.pending.feeRecipient` after showing deprecation-warning for `miner.etherbase`-flag.
2024-09-23 09:17:18 +02:00
Martin HS
f4c6c033c8 travis: work around travis/osx/go1.23 setup bug (#30491)
This is a work-around for a strange issue with travis, specifically,
`os=osx, go: 1.23.1`. When this is used, the actual go that ends up
being used is `go1.19.4 darwin/amd64 `.

Using `which go`, it told me that the `go` in the path was a softlink at
`/Users/travis/gopath/bin/go1.23.1 `. However, this was not true: using
`command -v go`, it told me that the actual `go` that was used is a
softlink at `/usr/local/bin/go`.

This change rewrites the `/usr/local/bin/go` softlink to point to the
binary at `/Users/travis/gopath/bin/go1.23.1`, so we get the right
go-version.
2024-09-22 10:12:47 +02:00
Péter Szilágyi
9326a118c7 beacon, core, eth, miner: integrate witnesses into production Geth (#30069)
This PR integrates witness-enabled block production, witness-creating
payload execution and stateless cross-validation into the `engine` API.
The purpose of the PR is to enable the following use-cases (for API
details, please see next section):

- Cross validating locally created blocks:
- Call `forkchoiceUpdatedWithWitness` instead of `forkchoiceUpdated` to
trigger witness creation too.
- Call `getPayload` as before to retrieve the new block and also the
above created witness.
- Call `executeStatelessPayload` against another client to
cross-validate the block.

- Cross validating locally processed blocks:
- Call `newPayloadWithWitness` instead of `newPayload` to trigger
witness creation too.
- Call `executeStatelessPayload` against another client to
cross-validate the block.

- Block production for stateless clients (local or MEV builders):
- Call `forkchoiceUpdatedWithWitness` instead of `forkchoiceUpdated` to
trigger witness creation too.
- Call `getPayload` as before to retrieve the new block and also the
above created witness.
- Propagate witnesses across the consensus libp2p network for stateless
Ethereum.

- Stateless validator validation:
- Call `executeStatelessPayload` with the propagated witness to
statelessly validate the block.

*Note, the various `WithWitness` methods could also *just be* an
additional boolean flag on the base methods, but this PR wanted to keep
the methods separate until a final consensus is reached on how to
integrate in production.*

---

The following `engine` API types are introduced:

```go
// StatelessPayloadStatusV1 is the result of a stateless payload execution.
type StatelessPayloadStatusV1 struct {
	Status          string      `json:"status"`
	StateRoot       common.Hash `json:"stateRoot"`
	ReceiptsRoot    common.Hash `json:"receiptsRoot"`
	ValidationError *string     `json:"validationError"`
}
```

- Add `forkchoiceUpdatedWithWitnessV1,2,3` with same params and returns
as `forkchoiceUpdatedV1,2,3`, but triggering a stateless witness
building if block production is requested.
- Extend `getPayloadV2,3` to return `executionPayloadEnvelope` with an
additional `witness` field of type `bytes` iff created via
`forkchoiceUpdatedWithWitnessV2,3`.
- Add `newPayloadWithWitnessV1,2,3,4` with same params and returns as
`newPayloadV1,2,3,4`, but triggering a stateless witness creation during
payload execution to allow cross validating it.
- Extend `payloadStatusV1` with a `witness` field of type `bytes` if
returned by `newPayloadWithWitnessV1,2,3,4`.
- Add `executeStatelessPayloadV1,2,3,4` with same base params as
`newPayloadV1,2,3,4` and one more additional param (`witness`) of type
`bytes`. The method returns `statelessPayloadStatusV1`, which mirrors
`payloadStatusV1` but replaces `latestValidHash` with `stateRoot` and
`receiptRoot`.
2024-09-20 16:43:42 +03:00
Martin HS
b018da9d02 build: fix macos builds by working around travis osx flaw (#30479)
This should fix https://github.com/ethereum/go-ethereum/issues/30471.
See investigation in https://github.com/ethereum/go-ethereum/pull/30478
for more background.
2024-09-20 14:06:12 +02:00
Guillaume Ballet
deb5c087c4 .github: add release maintainers to params/ CODEOWNERS (#30458) 2024-09-19 10:23:13 +02:00
maskpp
7513966d6e ethdb/pebble: handle errors (#30367) 2024-09-19 09:41:10 +02:00
Szupingwang
c4c2c4fb14 core: minor fix for the log wrapper with debug purpose (#30454)
After this PR, https://github.com/ethereum/go-ethereum/pull/28187, the
way to set the default logger is different. This PR only updates the way
to set logger in some test cases' comments that existed in the codebase
(since this commit
https://github.com/ethereum/go-ethereum/commit/b63e3c37a6). Although I
am not sure if it a good way to leave the code in the comment, it truly
makes me more efficiently to debug and fix the failing test cases.
2024-09-19 14:38:06 +08:00
Sina M
868d53c2f2 genesis: fix dev mode alloc (#30460)
Balance being null causes `getGenesisState` to fail as the balance field
is required in json marshaling of an account.
2024-09-19 14:35:14 +08:00
Guillaume Ballet
af794ef682 params: begin v1.14.10 release cycle (#30457) 2024-09-18 15:48:47 +03:00
Péter Szilágyi
c350d3acd5 Merge pull request #30456 from ethereum/master
Merge branch 'master' into release/1.14
2024-09-18 15:32:56 +03:00
Guillaume Ballet
f321dfa827 params: release go-ethereum v1.14.9 stable (#30455) 2024-09-18 15:27:03 +03:00
Guillaume Ballet
d09600fdf9 Revert "core/rawdb: remove unused transition status state accessors" (#30449)
Reverts ethereum/go-ethereum#30433
2024-09-18 11:53:50 +03:00
Sina M
8032b63f16 core/tracing: add verkle gas change reasons to changelog (#30444)
Add changes from #30409 and #29338 to changelog.

---------

Co-authored-by: Martin HS <martin@swende.se>
Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
2024-09-17 16:10:59 +02:00
Ikko Eltociear Ashimine
8dd296201d core/tracing: fix typo in comment (#30443)
minor fix
2024-09-16 19:57:31 +02:00
maskpp
ec596e06a5 core, trie: prealloc capacity for maps (#30437)
- preallocate capacity for map
- avoid `reinject` adding empty value
- use `maps.Copy`
2024-09-16 10:56:02 +02:00
piersy
03424962f1 core/types: more easily extensible tx signing (#30372)
This change makes the code slightly easier for downstream-projects to extend with more signer-types, but if functionalily equivalent to the previous code.
2024-09-16 08:51:03 +02:00
Håvard Anda Estensen
4c4f21293e internal: run tests in parallel (#30381)
Continuation of https://github.com/ethereum/go-ethereum/pull/28546
2024-09-16 08:44:47 +02:00
steven
ae707445f5 core/rawdb: remove unused transition status state accessors (#30433) 2024-09-15 08:55:53 +08:00
maskpp
0dd7e82c0a core/txpool/blobpool: avoid possible zero index panic (#30430)
This situation(`len(txs) == 0`) rarely occurs, but if it does, it will
panic.

---------

Co-authored-by: Martin HS <martin@swende.se>
2024-09-14 15:45:52 +02:00
Guillaume Ballet
07b5a04bd6 core/tracing: fix copy/paste error+comments in reason listing (#30431)
Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
2024-09-14 15:44:42 +02:00
Guillaume Michel
f544fc3b46 p2p/enode: add quic ENR entry (#30283)
Add `quic` entry to the ENR as proposed in
https://github.com/ethereum/consensus-specs/pull/3644

---------

Co-authored-by: lightclient <lightclient@protonmail.com>
2024-09-13 23:47:18 +02:00
Guillaume Ballet
9be2e010c1 core/state, core/vm: Nyota contract create init simplification (#30409)
Implementation of [this EIP-4762
update](https://github.com/ethereum/EIPs/pull/8867).

---------

Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Co-authored-by: Tanishq Jasoria <jasoriatanishq@gmail.com>
2024-09-13 15:37:30 +02:00
rjl493456442
c0b5d428a9 core/rawdb: more accurate description of freezer in docs (#30393)
fixes https://github.com/ethereum/go-ethereum/issues/29793
2024-09-13 11:17:40 +02:00
Darioush Jalali
7c6b3f9f14 eth/filters: prevent concurrent access in test (#30401)
use a mutex to prevent concurrent access to the api.filters map during `TestPendingTxFilterDeadlock` test
2024-09-13 11:16:47 +02:00
Felföldi Zsolt
a01e9742d9 beacon/light/api: fixed blsync update query (#30421)
This PR fixes what https://github.com/ethereum/go-ethereum/pull/30306/
broke. Escaping the `?` in the event sub query was fixed in that PR but
it was still escaped in the `updates` request. This PR adds a URL params
argument to `httpGet` and fixes `updates` query formatting.
2024-09-12 16:08:29 +02:00
Dylan Vassallo
ec69830b6f core/vm: remove panic when address is not present (#30414)
Remove redundant address presence check in `makeGasSStoreFunc`.

This PR simplifies the `makeGasSStoreFunc` function by removing the
redundant check for address presence in the access list. The updated
code now only checks for slot presence, streamlining the logic and
eliminating unnecessary panic conditions.

This change removes the unnecessary address presence check, simplifying
the code and improving maintainability without affecting functionality.
The previous panic condition was intended as a canary during the testing
phases (i.e. _YOLOv2_) and is no longer needed.
2024-09-11 16:11:08 +03:00
lightclient
c70b0a9138 beacon/engine/types: remove PayloadV4 (#30415)
h/t @MariusVanDerWijden for finding and fixing this on devnet 3.

I made the mistake of thinking `PayloadVersion` was correlated with the
`GetPayloadVX` method, but it actually tracks which version of
`PayloadAttributes` were passed to `forkchoiceUpdated`. So far, Prague
does not necessitate a new version of fcu, so there is no need for
`PayloadV4`.

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2024-09-10 21:52:20 +03:00
rjl493456442
d71831255d core/state/snapshot: port changes from 29995 (#30040)
#29995 has been reverted due to an unexpected flaw in the state snapshot
process.

Specifically, it attempts to stop the state snapshot generation, which
could potentially
cause the system to halt if the generation is not currently running.

This pull request ports the changes made in #29995 and fixes the flaw.
2024-09-06 18:02:34 +03:00
Roberto Bayardo
88c8459005 eth/fetcher: fix blob transaction propagation (#30125)
This PR fixes an issue with blob transaction propagation due to the blob
transation txpool rejecting transactions with gapped nonces. The
specific changes are:

- fetch transactions from a peer in the order they were announced to
minimize nonce-gaps (which cause blob txs to be rejected

- don't wait on fetching blob transactions after announcement is
received, since they are not broadcast

Testing:
- unit tests updated to reflect that fetch order should always match tx
announcement order
- unit test added to confirm blob transactions are scheduled immediately
for fetching
  - running the PR on an eth mainnet full node without incident so far

---------

Signed-off-by: Roberto Bayardo <bayardo@alum.mit.edu>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-09-06 13:32:01 +03:00
Sina M
8f4fac7b86 internal/ethapi: eth_multicall (#27720)
This is a successor PR to #25743. This PR is based on a new iteration of
the spec: https://github.com/ethereum/execution-apis/pull/484.

`eth_multicall` takes in a list of blocks, each optionally overriding
fields like number, timestamp, etc. of a base block. Each block can
include calls. At each block users can override the state. There are
extra features, such as:

- Include ether transfers as part of the logs
- Overriding precompile codes with evm bytecode
- Redirecting accounts to another address

## Breaking changes

This PR includes the following breaking changes:

- Block override fields of eth_call and debug_traceCall have had the
following fields renamed
  - `coinbase` -> `feeRecipient`
  - `random` -> `prevRandao`
  - `baseFee` -> `baseFeePerGas`

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-09-06 11:31:00 +02:00
Marius Kjærstad
83775b1dc7 build: upgrade -dlgo version to Go 1.23.1 (#30404)
New security fix:
https://groups.google.com/g/golang-announce/c/K-cEzDeCtpc
2024-09-06 11:11:14 +03:00
rjl493456442
5035f99bce core/state: get rid of field pointer in journal (#30361)
This pull request replaces the field pointer in journal entry with the
field itself, specifically the address of mutated account.

While it will introduce the extra allocation cost, but it's easier for
code reading. Let's measure the overhead overall to see if the change is
acceptable or not.
2024-09-06 15:42:59 +08:00
rjl493456442
623b17ba20 core/state: state reader abstraction (#29761)
This pull request introduces a state.Reader interface for state
accessing.

The interface could be implemented in various ways. It can be pure trie
only reader, or the combination of trie and state snapshot. What's more,
this interface allows us to have more flexibility in the future, e.g.
the
archive reader (for accessing archive state).

Additionally, this pull request removes the following metrics

- `chain/snapshot/account/reads`
- `chain/snapshot/storage/reads`
2024-09-05 13:10:47 +03:00
Marius van der Wijden
23973bd3a0 build: increase go test timeout (#30398)
This increases the timeout for the go tests on ci, this should prevent
travis from erroring.

see:
https://app.travis-ci.com/github/ethereum/go-ethereum/jobs/625803693
2024-09-05 10:50:34 +02:00
Martin HS
c3f13b2a1c node: fix flaky jwt-test (#30388)
This PR fixes a flaky jwt-test. 

The test is a jwt "from one second in the future". The test passes; the
reason for this is that the CI-system is slow, and by the time the jwt
is actually evaluated, that second has passed, and it's no longer
future.

Alternative to #30380
2024-09-04 16:15:41 +02:00
lightclient
7ef49e350b all: remove funding verifier (#30391)
Now that verification is done, we can remove the funding information.
2024-09-04 15:19:18 +02:00
Martin HS
fdb84993d8 core: fix compilation error (#30394)
un-borks a compilation error from a recent merge to master
2024-09-04 15:13:20 +02:00
Marius van der Wijden
b0b67be0a2 all: remove forkchoicer and reorgNeeded (#29179)
This PR changes how sidechains are handled. 

Before the merge, it was possible to import a chain with lower td and not set it as canonical. After the merge, we expect every chain that we get via InsertChain to be canonical. Non-canonical blocks can still be inserted
with InsertBlockWIthoutSetHead.

If during the InsertChain, the existing chain is not canonical anymore, we mark it as a sidechain and send the SideChainEvents normally.
2024-09-04 15:03:06 +02:00
lightclient
dfd33c7792 all: implement EIP-6110, execution layer triggered deposits (#29431)
This PR implements EIP-6110: Supply validator deposits on chain. It also sketches
out the base for Prague in the engine API types.
2024-09-04 14:33:51 +02:00
lightclient
de597af9c5 funding.json: add funding information file (#30385)
Adds a list of funding identifiers.
2024-09-03 16:22:32 +02:00
rjl493456442
922eb033d3 core/state: pull the verkle trie from prefetcher for empty storage root (#30369)
This pull request fixes a flaw in prefetcher.

In verkle tree world, both accounts and storage slots are committed into
a single tree instance for state hashing. If the prefetcher is activated, we will
try to pull the trie for the prefetcher for performance speedup. 

However, we had a special logic to skip pulling storage trie if the
storage root is empty. While it's true for merkle as we have nothing to
do with an empty storage trie, it's totally wrong for verkle. The consequences
for skipping pulling is the storage changes are committed into trie A, while the
account changes are committed into trie B (pulled from the prefetcher), boom.
2024-09-02 10:41:44 +02:00
Karl Bartel
36a7134367 Include tracerConfig in created tracing test (#30364)
Fixes the tracer test filler for when there is tracerConfig.
2024-09-02 10:30:33 +02:00
Ignacio Hagopian
ab3ee99ca9 trie, core/state: Nyota EIP-6800 & EIP-4762 spec updates (#30357)
This PR implements changes related to
[EIP-6800](https://eips.ethereum.org/EIPS/eip-6800) and
[EIP-4762](https://eips.ethereum.org/EIPS/eip-4762) spec updates.

A TL;DR of the changes is that `Version`, `Balance`, `Nonce` and
`CodeSize` are encoded in a single leaf named `BasicData`. For more
details, see the [_Header Values_ table in
EIP-6800](https://eips.ethereum.org/EIPS/eip-6800#header-values).

The motivation for this was simplifying access event patterns, reducing
code complexity, and, as a side effect, saving gas since fewer leaf
nodes must be accessed.

---------

Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-08-30 14:13:02 +02:00
Guillaume Ballet
e9467eec1c consensus/beacon, core/types: add verkle witness builder (#30129)
This PR adds the bulk verkle witness+proof production at the end of block
production. It reads all data from the tree in one swoop and produces
a verkle proof.

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-08-29 14:50:27 +02:00
markus
ea3b5095f4 signer/core/apitypes: support fixed size arrays for EIP-712 typed data (#30175)
When attempting to hash a typed data struct that includes a type
reference with a fixed-size array, the validation process fails.
According to EIP-712, arrays can be either fixed-size or dynamic,
denoted by `Type[n]` or `Type[]` respectively, although it appears this
currently isn't supported.

This change modifies  the validation logic to accommodate types
containing fixed-size arrays.
2024-08-28 14:12:09 +02:00
Martin HS
0e5546f032 core/state: semantic journalling (part 1) (#28880)
This is a follow-up to #29520, and a preparatory PR to a more thorough
change in the journalling system.

### API methods instead of `append` operations

This PR hides the journal-implementation details away, so that the
statedb invokes methods like `JournalCreate`, instead of explicitly
appending journal-events in a list. This means that it's up to the
journal whether to implement it as a sequence of events or
aggregate/merge events.

### Snapshot-management inside the journal 

This PR also makes it so that management of valid snapshots is moved
inside the journal, exposed via the methods `Snapshot() int` and
`RevertToSnapshot(revid int, s *StateDB)`.


### SetCode

JournalSetCode journals the setting of code: it is implicit that the
previous values were "no code" and emptyCodeHash. Therefore, we can
simplify the setCode journal.

### Selfdestruct

The self-destruct journalling is a bit strange: we allow the
selfdestruct operation to be journalled several times. This makes it so
that we also are forced to store whether the account was already
destructed.

What we can do instead, is to only journal the first destruction, and
after that only journal balance-changes, but not journal the
selfdestruct itself.

This simplifies the journalling, so that internals about state
management does not leak into the journal-API.

### Preimages

Preimages were, for some reason, integrated into the journal management,
despite not being a consensus-critical data structure. This PR undoes
that.

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-08-28 08:18:23 +02:00
Ceyhun Onur
9eb91542de accounts/abi/bind, ethclient/simulated: check SendTransaction error in tests (#30349)
In few tests the returned error from `SendTransaction` is not being
checked. This PR checks the returned err in tests.

Returning errors also revealed tx in `TestCommitReturnValue` is not
actually being sent, and returns err ` only replay-protected (EIP-155)
transactions allowed over RPC`. Fixed the transaction by using the
`testTx` function.
2024-08-27 17:11:50 +02:00
Nicolas Gotchac
87377c58bc p2p/discover: fix Write method in metered connection (#30355)
`WriteToUDP` was never called, since `meteredUdpConn` exposed directly
all the methods from the underlying `UDPConn` interface.

This fixes the `discover/egress` metric never being updated.
2024-08-27 14:10:32 +02:00
rjl493456442
9b5d1412cc core/state: fix trie prefetcher for verkle (#30354)
This pull request fixes the panic issue in prefetcher once the verkle is
activated.
2024-08-26 22:18:47 +08:00
rjl493456442
bfda8ae0c6 core: add metrics for state access (#30353)
This pull request adds a few more performance metrics, specifically:

- The average time cost of an account read
- The average time cost of a storage read
- The rate of account reads
- The rate of storage reads
2024-08-26 20:02:10 +08:00
Sina M
a223efcf39 core: implement EIP-2935 (#29465)
https://eips.ethereum.org/EIPS/eip-2935

---------

Co-authored-by: Guillaume Ballet <gballet@gmail.com>
Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Martin HS <martin@swende.se>
2024-08-26 10:39:35 +02:00
Oksana
4e17f28740 doc: update 2021-08-22-split-postmortem (#30351)
Update 2021-08-22-split-postmortem
2024-08-26 09:29:24 +08:00
Martin HS
1d006bd5bf gitignore: ignore build signatures (#30346)
Ignore files are generated during signing of download-binaries, which 'dirty' the vcs for subsequent builds.
2024-08-23 16:48:20 +02:00
Martin HS
0378dc8367 build: debug travis build (#30344)
debugging travis build pipeline
2024-08-23 16:30:30 +02:00
Gealber Morales
eaf4285f0a beacon/light/sync: basic tests for rangeLock (#30269)
adds simple tests for lock and firstUnlocked method from rangeLock
type

---------

Co-authored-by: lightclient <lightclient@protonmail.com>
2024-08-23 12:31:24 +02:00
Karl Bartel
c12a1c9bcf beacon/blsync: better error information in test (#30336)
this change reports the error instead of ignoring it
2024-08-23 12:29:02 +02:00
rjl493456442
020f026616 trie: avoid un-needed map copy (#30343)
This change avoids the an unnecessary map copy if the preimage recording is not enabled.
2024-08-23 12:27:06 +02:00
Martin HS
ada20c09dc build: make go buildid static (#30342)
The previous clearing of buildid did fully work, turns out we need to
set it in `ldflags`

The go buildid is the only remaining hurdle for reproducible builds, see
https://github.com/ethereum/go-ethereum/issues/28987#issuecomment-2306412590

This PR changes the go build id application note to say literally `none`

https://github.com/golang/go/issues/33772#issuecomment-528176001:

> This difference is due to the .note.go.buildid section added by the
linker. It can be set to something static e.g. -ldflags=-buildid= (empty
string) to gain reproducibility.
2024-08-23 09:48:24 +02:00
Marius Kjærstad
941ae33d7e build: fix hash for go1.23.0.linux-riscv64.tar.gz (#30335)
build: fix hash for go1.23.0.linux-riscv64.tar.gz
2024-08-22 13:29:40 +02:00
Martin HS
30824faf90 eth/tracers: avoid panic in state test runner (#30332)
Make tracers more robust by handling `nil` receipt as input. 
Also pass in a receipt with gas used in the state test runner.
Closes https://github.com/ethereum/go-ethereum/issues/30117.

---------

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-08-21 15:16:08 +02:00
Martin HS
733fcbbc65 eth/protocols/eth: handle zero-count header requests (#30305)
Proper fix for handling `count=0` get header requests. 

https://en.wikipedia.org/wiki/Count_Zero
2024-08-21 09:22:33 +02:00
Guillaume Ballet
df645e77b7 trie: use go-verkle helper for speedier (*VerkleTrie).RollBackAccount (#30242)
This is a performance improvement on the account-creation rollback code
required for the archive node to support verkle. It uses the utility
function `DeleteAtStem` to remove code and account data per-group
instead of doing it leaf by leaf.

It also fixes an index bug, as code is chunked in 31-byte chunks, so
comparing with the code size should use 31 as its stride.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-08-21 10:00:31 +08:00
Martin HS
2a534ee133 travis.yml: use focal for builds (#30319) 2024-08-20 17:34:03 +02:00
lightclient
00294e9d28 cmd/utils,p2p: enable discv5 by default (#30327) 2024-08-20 16:02:54 +02:00
stevemilk
3c37db7989 all: clean up goerli flag and config (#30289)
Co-authored-by: lightclient <lightclient@protonmail.com>
2024-08-20 15:59:48 +02:00
John Hilliard
0fde5067c3 cmd/devp2p: require dns:read, dns:edit permissions for cloudflare deploy (#30326)
This PR adds the `dns:read` and `dns:edit` permissions to the required
set of permissions checked before deploying an ENR tree to Cloudflare.
These permissions are necessary for a successful publish.

**Background**:
The current logic for `devp2p dns to-cloudflare` checks for `zone:edit`
and `zone:read` permissions. However, when running the command with only
these two permissions, the following error occurs:
```
wrong permissions on zone REMOVED-ZONE: map[#zone:edit:false #zone:read:true]
```

Adding `zone:read` and `zone:edit` to the API token led to a different
error:
```
INFO [08-19|14:06:16.782] Retrieving existing TXT records on pos-nodes.hardfork.dev
Authentication error (10000)
```

This suggested that additional permissions were required. I added
`dns:read`, but encountered another error:
```
INFO [08-19|14:11:42.342] Retrieving existing TXT records on pos-nodes.hardfork.dev
INFO [08-19|14:11:42.851] Updating DNS entries
failed to publish REMOVED.pos-nodes.hardfork.dev: Authentication error (10000)
```

Finally, after adding both `dns:read` and `dns:edit` permissions, the
command executed successfully with the following output:
```
INFO [08-19|14:13:07.677] Checking Permissions on zone REMOVED-ZONE
INFO [08-19|14:13:08.014] Retrieving existing TXT records on pos-nodes.hardfork.dev
INFO [08-19|14:13:08.440] Updating DNS entries
INFO [08-19|14:13:08.440] "Updating pos-nodes.hardfork.dev from \"enrtree-root:v1 e=FSED3EDKEKRDDFMCLP746QY6CY l=FDXN3SN67NA5DKA4J2GOK7BVQI seq=1 sig=Glja2c9RviRqOpaaHR0MnHsQwU76nJXadJwFeiXpp8MRTVIhvL0LIireT0yE3ETZArGEmY5Ywz3FVHZ3LR5JTAE\" to \"enrtree-root:v1 e=AB66M4ULYD5OYN4XFFCPVZRLUM l=FDXN3SN67NA5DKA4J2GOK7BVQI seq=1 sig=H8cqDzu0FAzBplK4g3yudhSaNtszIebc2aj4oDm5a5ZE5PAg-xpCnQgVE_53CsgsqQpalD9byafx_FrUT61sagA\""
INFO [08-19|14:13:16.932] Updated DNS entries                      new=32 updated=1 untouched=100
INFO [08-19|14:13:16.932] Deleting stale DNS entries
INFO [08-19|14:13:24.663] Deleted stale DNS entries                count=31
```

With this PR, the required permissions for deploying an ENR tree to
Cloudflare now include `zone:read`, `zone:edit`, `dns:read`, and
`dns:edit`. The initial check now includes all of the necessary
permissions and indicates in the error message which permissions are
missing:
```
INFO [08-19|14:17:20.339] Checking Permissions on zone REMOVED-ZONE
wrong permissions on zone REMOVED-ZONE: map[#dns_records:edit:false #dns_records:read:false #zone:edit:false #zone:read:true]
```
2024-08-20 15:59:16 +02:00
lightclient
15fb0dcc67 rpc: add timeout to rpc client Unsubscribe (#30318)
Fixes #30156

This adds a repro of the linked issue. I fixed it by adding a timeout
when issuing the call to unsubscribe.
2024-08-20 15:54:28 +02:00
Martin HS
d0fd1331f1 all: update to go version 1.23.0 (#30323)
This PR updates the version of go used in builds and docker to
1.23.0. Release notes: https://go.dev/doc/go1.23

More importantly, following our policy of maintaining the last two
versions (which now becomes 1.23 and 1.22), we can now make use of
the things that were introduced in 1.22: https://go.dev/doc/go1.22

Go 1.22 makes two changes to “for” loops.
- each iteration creates new variables, 
- for loops may range over integers

Other than that, some interesting library changes and other stuff.
2024-08-20 15:50:07 +02:00
Martin HS
693e40a495 build: attempt at reproducible builds (#30321)
This PR implements the conclusions from
https://github.com/ethereum/go-ethereum/issues/28987#issuecomment-2296075028,
that is:

Building with `--strip-all` as a ld-flag to the cgo linker, to remove
symbols. Without that, some spurious reference to a temporary file is
included into the kzg-related library.

Building with `--build-id=none`, to avoid putting a `build id` into the file.
2024-08-20 15:33:28 +02:00
lmittmann
fc88cea648 core/vm: reuse Memory instances (#30137)
This PR adds a sync.Pool to reuse instances of Memory in EVMInterpreter.
2024-08-20 14:31:06 +02:00
Sina M
3b48b16290 core/rawdb: drop MigrateTable (#30331)
These are the leftovers from #24028.
2024-08-20 14:06:00 +02:00
chen4903
65aaf52f4c accounts/abi: handle ABIs with contract type parameter (#30315)
convert parameter of type contract to the basic `address` type
---------

Co-authored-by: Martin HS <martin@swende.se>
2024-08-20 12:26:35 +02:00
lightclient
84565dc899 eth/catalyst: ensure period zero mode leaves no pending txs in pool (#30264)
closes #29475, replaces #29657, #30104 

Fixes two issues. First is a deadlock where the txpool attempts to reorg, but can't complete because there are no readers left for the new txs subscription. Second, resolves a problem with on demand mode where txs may be left pending when there are more pending txs than block space.

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-08-19 15:32:15 -06:00
Martin HS
41b3b30863 gitignore: ignore upload-artefacts (#30325)
Our `WriteArchive`, used by ci builder, creates files in the repo root,in order to upload. After we've built the amd64-builds, we create the uploads, and cause the repo to be flagged as dirty for the remaining builds.

This change fixes it by adding the artefacts to gitignore. Closes #30324
2024-08-19 20:06:57 +02:00
Martin HS
8486722dcb build: remove mantic from ppa builds (#30322)
removes ppa-build for ubuntu `mantic`
2024-08-19 13:35:41 +02:00
Martin HS
60db6a7b42 internal/build: include git-date on detached head (#30320)
When we are building in detached head, we cannot easily obtain the same information as we can if we're in non-detached head.

However, one thing we _can_ obtain is the git-hash and git-date. Currently, we omit to include the git-date into the build-info, which causes problem for reproducable builds which are on a detached head.

This change fixes it to include the date-info always.
2024-08-19 13:35:04 +02:00
Arran Schlosberg
710c3f32ac vm: simplify error handling in vm.EVM.create() (#30292)
To allow all error paths in `vm.EVM.create()` to consume the necessary
gas, there is currently a pattern of gating code on `if err == nil`
instead of returning as soon as the error occurs. The same behaviour can
be achieved by abstracting the gated code into a method that returns
immediately on error, improving readability and thus making it easier to
understand and maintain.
2024-08-16 08:41:44 -06:00
Shude Li
09d889d2e3 core: remove withdrawal length check for state processor (#30286)
The withdrawal length is already verified by the beacon consensus package, so the check in the state processor is a duplicate.
2024-08-16 08:33:41 -06:00
Sina M
43640f12d8 beacon/light: handle endpoint URL more gracefully (#30306)
blsync was failing if the light endpoint it was provided ended with a
`/`. This change should handle the joining more gracefully.
2024-08-16 14:39:57 +02:00
Felix Lange
6eb42a6b4f eth: dial nodes from discv5 (#30302)
Here I am adding a discv5 nodes source into the p2p dial iterator. It's
an improved version of #29533.

Unlike discv4, the discv5 random nodes iterator will always provide full
ENRs. This means we can apply filtering to the results and will only try
dialing nodes which explictly opt into the eth protocol with a matching
chain.

I have also removed the dial iterator from snap. We don't have an
official DNS list for snap anymore, and I doubt anyone else is running
one. While we could potentially filter for snap on discv5, there will be
very few nodes announcing it, and the extra iterator would just stall
the dialer.

---------

Co-authored-by: lightclient <lightclient@protonmail.com>
2024-08-15 22:14:42 +02:00
Dylan Vassallo
7a149a159a eth/tracers/js: add coinbase addr to ctx (#30231)
Add coinbase address to javascript tracer context.

This PR adds the `coinbase` address to `jsTracer.ctx`, allowing access
to the coinbase address (fee receipient) in custom JavaScript tracers.

Example usage:

```javascript
result: function(ctx) {
  return toAddress(ctx.coinbase);
}
```

This change enables custom tracers to access coinbase address,
previously unavailable, enhancing their capabilities to match built-in
tracers.
2024-08-15 16:36:35 +02:00
Felix Lange
c35684709c eth/ethconfig: remove LES server config (#30298) 2024-08-15 11:42:39 +02:00
rjl493456442
c4b01d80b9 eth/fetcher: always expect transaction metadata in announcement (#30288)
This pull request drops the legacy transaction retrieval support from before
eth68, adding the restrictions that transaction metadata must be provided
along with the transaction announment.
2024-08-15 11:35:16 +02:00
Felix Lange
2f2e5b088a .golangci.yml: remove lint warning for TxLookupLimit 2024-08-15 10:11:03 +02:00
Marius van der Wijden
c686485a06 core: only compute state root once (#30299)
This PR refactors the genesis initialization a bit, s.th. we only
compute the blockhash once instead of twice as before (during hashAlloc
and flushAlloc)

This will significantly reduce the amount of memory allocated during
genesis init

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-08-15 15:16:23 +08:00
Adrian Sutton
2b9d198706 go.mod: upgrade to pebble v1.1.2 (#30297)
Includes a fix for MIPS32 support.

Pebble release:
https://github.com/cockroachdb/pebble/releases/tag/v1.1.2
Key fix for mips32:
9f3904a705
(also the only change from v1.1.1.
2024-08-14 11:45:51 +02:00
Zoo
bd57f35f8d core/txpool/blobpool: fix error message (#30247)
the validation process only checks for 'less than', which is
inconsistent with the error output
2024-08-13 19:49:31 +08:00
jwasinger
bc95452e02 build: run 'go mod tidy' check as part of lint (#30291) 2024-08-12 20:46:15 +02:00
Shude Li
ab03c5746c go.mod: remove github.com/julienschmidt/httprouter (#30290) 2024-08-12 20:42:36 +02:00
Felix Lange
1cf3b5d38a params: begin v1.14.9 release cycle 2024-08-12 14:19:35 +02:00
Felix Lange
a9523b6428 Merge branch 'master' into release/1.14 2024-08-12 14:16:16 +02:00
Felix Lange
880511dc39 params: release go-ethereum v1.14.8 stable 2024-08-12 14:15:30 +02:00
rjl493456442
5adf4adc8e eth/protocols/snap: cleanup dangling account trie nodes due to incomplete storage (#30258)
This pull request fixes #30229.
 
During snap sync, large storage will be split into several pieces and
synchronized concurrently. Unfortunately, the tradeoff is that the respective
merkle trie of each storage chunk will be incomplete due to the incomplete
boundaries. The trie nodes on these boundaries will be discarded, and any
dangling nodes on disk will also be removed if they fall on these paths,
ensuring the state healer won't be blocked.

However, the dangling account trie nodes on the path from the root to the
associated account are left untouched. This means the dangling account trie
nodes could potentially stop the state healing and break the assumption that the
entire subtrie should exist if the subtrie root exists. We should consider the
account trie node as the ancestor of the corresponding storage trie node.

In the scenarios described in the above ticket, the state corruption could occur
if there is a dangling account trie node while some storage trie nodes are
removed due to synchronization redo.

The fixing idea is pretty straightforward, the trie nodes on the path from root
to account should all be explicitly removed if an incomplete storage trie
occurs. Therefore, a `delete` operation has been added into `gentrie` to
explicitly clear the account along with all nodes on this path. The special
thing is that it's a cross-trie clearing. In theory, there may be a dangling
node at any position on this account key and we have to clear all of them.
2024-08-12 10:43:54 +02:00
lightclient
33a13b6f21 p2p/simulations: remove packages (#30250)
Looking at the history of these packages over the past several years, there
haven't been any meaningful contributions or usages:
https://github.com/ethereum/go-ethereum/commits/master/p2p/simulations?before=de6d5976794a9ed3b626d4eba57bf7f0806fb970+35

Almost all of the commits are part of larger refactors or low-hanging-fruit contributions.
Seems like it's not providing much value and taking up team + contributor time.
2024-08-12 10:36:48 +02:00
Artyom Aminov
32a1e0643c beacon/engine, consensus/beacon: use params.MaximumExtraDataSize instead of hard-coded value (#29721)
Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
Co-authored-by: lightclient <lightclient@protonmail.com>
2024-08-10 12:44:31 +02:00
Martin HS
811a69cd3c go.mod: update uint256 to 1.3.1 (#30280)
Release notes: https://github.com/holiman/uint256/releases/tag/v1.3.1
2024-08-09 23:11:22 +03:00
Martin HS
83e70aa3d0 cmd/evm: fix evm basefee (#30281)
fixes #30279 -- previously we did not use the basefee from the genesis, and instead the defaults were used from `runtime.go/setDefaults`-function
2024-08-08 18:58:08 +02:00
psogv0308
ebe31dfd5c eth/downloader, core/types: take withdrawals-size into account in downloader queue (#30276)
Fixes a slight miscalculation in the downloader queue, which was not accurately taking block withdrawals into account when calculating the size of the items in the queue
2024-08-08 15:14:00 +02:00
taiking
d3dae66e59 tests: fix TransactionTest to actually run (#30272)
Due to https://github.com/ethereum/tests/releases/tag/v10.1, the format
of the TransactionTest changed, but it was not properly addressed, causing the test
to pass unexpectedly.

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-08-08 13:50:00 +02:00
Marius Kjærstad
9ea766d6e9 build: upgrade -dlgo version to Go 1.22.6 (#30273) 2024-08-08 13:47:43 +02:00
lmittmann
4a3aed380e core/vm: use uint64 in memory for indices everywhere (#30252)
Consistently use `uint64` for indices in `Memory` and drop lots of type
conversions from `uint64` to `int64`.

---------

Co-authored-by: lmittmann <lmittmann@users.noreply.github.com>
2024-08-08 11:27:38 +03:00
llkhacquan
978041feea signer/core: improve performance of isPrimitiveTypeValid function (#30274) (#30277)
Precomputes valid primitive types into a map to use for validation, thus removing sprintf.
2024-08-08 09:13:18 +02:00
lmittmann
b37ac5c102 core/vm: improved stack swap performance (#30249)
This PR adds the methods `Stack.swap1..16()` that faster than `Stack.swap(1..16)`. 

Co-authored-by: lmittmann <lmittmann@users.noreply.github.com>
2024-08-06 14:38:47 +02:00
Zhihao Lin
e9981bc6f7 ethclient: support networkID in hex format (#30263)
Some chains’ network IDs use hexadecimal such as Optimism ("0xa" instead
of "10"), so when converting the string to big.Int, we cannot specify
base 10; otherwise, it will encounter errors with hexadecimal network
IDs.
2024-08-06 15:14:37 +03:00
lightclient
dbc1d04f5e core/vm/runtime: ensure tracer benchmark calls OnTxStart (#30257)
The struct-based tracing added in #29189 seems to have caused an issue
with the benchmark `BenchmarkTracerStepVsCallFrame`. On master we see
the following panic:

```console
BenchmarkTracerStepVsCallFrame
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x40 pc=0x1019782f0]

goroutine 37 [running]:
github.com/ethereum/go-ethereum/eth/tracers/js.(*jsTracer).OnOpcode(0x140004c4000, 0x0, 0x10?, 0x989680, 0x1, {0x101ea2298, 0x1400000e258}, {0x1400000e258?, 0x14000155928?, 0x10173020c?}, ...)
        /Users/matt/dev/go-ethereum/eth/tracers/js/goja.go:328 +0x140
github.com/ethereum/go-ethereum/core/vm.(*EVMInterpreter).Run(0x14000307da0, 0x140003cc0d0, {0x0, 0x0, 0x0}, 0x0)
 ...
FAIL    github.com/ethereum/go-ethereum/core/vm/runtime 0.420s
FAIL
```

The issue seems to be that `OnOpcode` expects that `OnTxStart` has
already been called to initialize the `env` value in the tracer. The JS
tracer uses it in `OnOpcode` for the `GetRefund()` method.

This patch resolves the issue by reusing the `Call` method already
defined in `runtime_test.go` which correctly calls `OnTxStart`.
2024-08-06 19:51:48 +08:00
stevemilk
cf8aa31e3e params: remove unused les parameters (#30268) 2024-08-06 19:49:48 +08:00
Delweng
10586952df eth/catalyst: get params.ExcessBlobGas but check with params.BlobGasUsed (#30267)
Seems it is checked with the wrong argument

Signed-off-by: jsvisa <delweng@gmail.com>
2024-08-05 11:14:22 -06:00
lightclient
142c94d628 cmd/evm: don't overwrite sender account (#30259)
Fixes #30254 

It seems like the removed CreateAccount call is very old and not needed anymore.
After removing it, setting a sender that does not exist in the state doesn't seem to cause
an issue.
2024-08-02 17:49:01 +02:00
Felix Lange
16cf5c5fed eth/downloader: gofmt (#30261)
Fixes a regression introduced in
https://github.com/ethereum/go-ethereum/pull/30219
2024-08-02 17:36:28 +02:00
Felix Lange
e4675771ed internal/debug: remove memsize (#30253)
Removing because memsize will very likely be broken by Go 1.23. See
https://github.com/fjl/memsize/issues/4
2024-08-02 06:44:03 +02:00
ysh0566
67b8137100 accounts/abi/bind: add accessList support to base bond contract (#30195)
Adding the correct accessList parameter when calling a contract can
reduce gas consumption. However, the current version only allows adding
the accessList manually when constructing the transaction. This PR can
provide convenience for saving gas.
2024-08-01 12:09:04 -06:00
Icarus Wu
b635089c7c all: remove deprecated protobuf dependencies (#30232)
The package `github.com/golang/protobuf/proto` is deprecated in favor
`google.golang.org/protobuf/proto`. We should update the codes to
recommended package.

Signed-off-by: Icarus Wu <icaruswu66@qq.com>
2024-08-01 16:25:55 +02:00
Seungmin Kim
dad8f237ff eth/downloader: correct sync mode logging to show old mode (#30219)
This PR fixes an issue in the setMode method of beaconBackfiller where the
log message was not displaying the previous mode correctly. The log message
now shows both the old and new sync modes.
2024-08-01 16:10:43 +02:00
Darioush Jalali
ff6e43e8c4 miner: remove outdated comment (#30248) 2024-08-01 16:06:43 +02:00
Daniel Knopik
de6d597679 p2p/discover: schedule revalidation also when all nodes are excluded (#30239)
## Issue

If `nextTime` has passed, but all nodes are excluded, `get` would return
`nil` and `run` would therefore not invoke `schedule`. Then, we schedule
a timer for the past, as neither `nextTime` value has been updated. This
creates a busy loop, as the timer immediately returns.

## Fix

With this PR, revalidation will be also rescheduled when all nodes are
excluded.

---------

Co-authored-by: lightclient <lightclient@protonmail.com>
2024-07-31 21:38:23 +02:00
Marius G
6e33dbf96a p2p: fix flaky test TestServerPortMapping (#30241)
The test specifies `ListenAddr: ":0"`, which means a random ephemeral
port will be chosen for the TCP listener by the OS. Additionally, since
no `DiscAddr` was specified, the same port that is chosen automatically
by the OS will also be used for the UDP listener in the discovery UDP
setup. This sometimes leads to test failures if the TCP listener picks a
free TCP port that is already taken for UDP. By specifying `DiscAddr:
":0"`, the UDP port will be chosen independently from the TCP port,
fixing the random failure.

See issue #29830.

Verified using
```
cd p2p
go test -c -race
stress ./p2p.test -test.run=TestServerPortMapping
...
5m0s: 4556 runs so far, 0 failures
```

The issue described above can technically lead to sporadic failures on
systems that specify a listen address via the `--port` flag of 0 while
not setting `--discovery.port`. Since the default is using port `30303`
and using a random ephemeral port is likely not used much to begin with,
not addressing the root cause might be acceptable.
2024-07-30 07:31:27 -06:00
dknopik
b0f66e34ca p2p/nat: return correct port for ExtIP NAT (#30234)
Return the actually requested external port instead of 0 in the
AddMapping implementation for `--nat extip:<IP>`.
2024-07-27 10:18:05 +02:00
lightclient
f94baab238 internal/ethapi: fix state override test (#30228)
Looks like #30094 became a bit stale after #30185 was merged and now we
have a stale ref to a state override object causing CI to fail on
master.
2024-07-26 11:02:37 +08:00
caseylove
ac0f220040 eth/tracers, internal/ethapi: remove unnecessary map pointer in state override (#30094) 2024-07-25 01:01:59 +02:00
yukionfire
4dfc75deef beacon/types, cmd/devp2p, p2p/enr: clean up uses of fmt.Errorf (#30182) 2024-07-25 00:32:58 +02:00
rjl493456442
4ad88e9463 triedb/pathdb: print out all trie owner and hash information (#30200)
This pull request explicitly prints out the full hash for debugging
purpose.
2024-07-24 20:32:28 +08:00
rjl493456442
766ce23032 core/state: fix SetStorage override behavior (#30185)
This pull request fixes the broken feature where the entire storage set is overridden.

Originally, the storage set override was achieved by marking the associated account
as deleted, preventing access to the storage slot on disk. However, since #29520, this
flag is also checked when accessing the account, rendering the account unreachable.

A fix has been applied in this pull request, which re-creates a new state object with all
account metadata inherited.
2024-07-23 14:54:35 +02:00
minh-bq
35b4183caa cmd/utils: allow configurating blob pool from flags (#30203)
Currently, we have 3 flags to configure blob pool. However, we don't
read these flags and set the blob pool configuration in eth config
accordingly. This commit adds a function to check if these flags are
provided and set blob pool configuration based on them.
2024-07-23 14:44:01 +02:00
rjl493456442
1939813ece core/state: check db error after intermediate call (#30171)
This pull request adds an additional error check after statedb.IntermediateRoot,
ensuring that no errors occur during this call. This step is essential, as the call might
encounter database errors.
2024-07-23 14:40:12 +02:00
minh-bq
6693fe1be2 core/txpool: use the cached address in ValidateTransactionWithState (#30208)
The address recover is executed and cached in ValidateTransaction already. It's
expected that the cached one is returned in ValidateTransaction. However,
currently, we use the wrong function signer.Sender instead of types.Sender which
will do all the address recover again.
2024-07-23 14:07:06 +02:00
Sina M
7026bae17c core/tracing: update latest release version (#30211) 2024-07-23 14:05:46 +02:00
zhiqiangxu
57e6627932 rpc: show more error detail for invalidMessageError (#30191)
Here we add distinct error messages for network timeouts and JSON parsing errors.
Note this specifically applies to HTTP connections serving a single RPC request.

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-07-23 11:55:56 +02:00
rjl493456442
ef583e9d18 core/state: remove useless metrics (#30184)
Originally, these metrics were added to track the largest storage wiping.
Since account self-destruction was deprecated with the Cancun fork,
these metrics have become meaningless.
2024-07-22 23:44:31 +02:00
lightclient
7abe84c8d7 rpc: use stable object in notifier test (#30193)
This makes the test resilient to changes of types.Header -- otherwise the test needs to be
updated each time the header structure is modified.
2024-07-22 23:38:04 +02:00
Marius van der Wijden
380688c636 eth/gasprice: remove default from config (#30080)
* eth/gasprice: remove default from config

* eth/gasprice: sanitize startPrice
2024-07-22 15:58:53 +08:00
Sina M
944718bf16 ethdb: remove snapshot (#30189) 2024-07-22 11:40:14 +08:00
Alexander Mint
df3f0a81a7 go.mod: upgrade to btcsuite/btcd/btcec v2.3.4 (#30181) 2024-07-18 12:38:42 +02:00
Felix Lange
ad49c708f5 p2p/discover: remove type encPubkey (#30172)
The pubkey type was moved to package v4wire a long time ago. Remaining uses of
encPubkey were probably left in due to laziness.
2024-07-18 11:09:02 +02:00
rjl493456442
f59d013e40 core/rawdb, triedb, cmd: create an isolated disk namespace for verkle (#30105)
* core, triedb/pathdb, cmd: define verkle state ancient store

* core/rawdb, triedb: add verkle namespace in pathdb
2024-07-16 16:17:58 +03:00
Guillaume Ballet
c54294bd41 core/state: don't compute verkle storage tree roots (#30130) 2024-07-16 16:06:22 +03:00
maskpp
15936c64a2 core/txpool/legacypool: use maps.Keys and maps.Copy (#30091) 2024-07-16 13:42:30 +02:00
rjl493456442
b530d8e455 trie, triedb: remove unnecessary child resolver interface (#30167) 2024-07-16 18:52:19 +08:00
Jordan Krage
0d38b0cd34 eth/catalyst: fix (*SimulatedBeacon).AdjustTime() conversion (#30138) 2024-07-16 11:47:11 +02:00
zhiqiangxu
71210b0630 all: simplify tests using t.TempDir() (#30150) 2024-07-15 15:26:58 +02:00
JeukHwang
8adce57b41 SECURITY.md: correct PGP key block formatting (#30123) 2024-07-15 14:29:13 +02:00
Danyal Prout
a0d2613ef0 core/types: don't modify signature V when reading large chainID (#30157) 2024-07-15 12:09:32 +02:00
Jeremy Schlatter
169aa91449 cmd/utils: fix typo in flag description (#30127) 2024-07-15 11:36:21 +02:00
Nathan Jo
4bbe993252 p2p: fix ip change log parameter (#30158) 2024-07-15 10:15:35 +02:00
Guillaume Ballet
79d2327771 trie: add RollBackAccount function to verkle trees (#30135) 2024-07-15 15:05:59 +08:00
minh-bq
a0631f3ebd core/txpool/blobpool: use nonce from argument instead of tx.Nonce() (#30148)
This does not change the behavior here as the nonce in the argument is
tx.Nonce(). This commit helps to make the function easier to read and avoid
capturing the tx in the function.
2024-07-15 10:28:06 +08:00
rjl493456442
cf0378499f core/state: fix prefetcher for verkle (#29760) 2024-07-11 22:09:24 +08:00
Felix Lange
aa55f5ea20 Merge branch 'master' into release/1.14 2024-07-11 14:34:03 +02:00
Felix Lange
bcaf3747f8 params: begin v1.14.8 release cycle 2024-07-11 14:24:09 +02:00
Felix Lange
0aafbb31ab params: go-ethereum v1.14.7 stable 2024-07-11 14:23:27 +02:00
Marius van der Wijden
803dc6b664 core/txpool/blobpool: revert #29989, WLock on Nonce (#30142) 2024-07-11 10:28:27 +03:00
Aayush Rajasekaran
37590b2c55 eth/catalyst: fix params in failure log (#30131) 2024-07-09 15:19:55 +03:00
Martin HS
10467acc71 go.mod: update uint256 to 1.3.0 (#30134) 2024-07-09 15:17:43 +03:00
zhiqiangxu
c4b4d05e69 crypto: remove hardcoded value for secp256k1.N (#30126) 2024-07-09 13:19:25 +02:00
Marius Kjærstad
2d9d423764 build: upgrade -dlgo version to Go 1.22.5 (#30112) 2024-07-03 12:11:43 +02:00
Felix Lange
c6cae0f300 Merge remote-tracking branch 'gballet/release-1.14.6' 2024-07-02 17:45:10 +02:00
Guillaume Ballet
aadddf3a6e params: release Geth v1.14.6 2024-07-02 15:19:57 +02:00
Guillaume Ballet
640e0f15fd params: begin v1.14.7 release cycle 2024-07-02 14:59:41 +02:00
Guillaume Ballet
6f2e1cff47 params: release Geth v1.14.6 2024-07-02 14:58:42 +02:00
winniehere
de366fd2e2 accounts/abi: embed Go template instead of string literal (#30098)
refactor(accounts/abi): use embed pkg to split default template to file
2024-07-02 15:58:15 +03:00
Hteev Oli
09056601d8 core/state: fix inconsistent verkle test error messages (#29753) 2024-07-01 21:57:04 +02:00
jwasinger
41abab9e39 build: add check for stale generated files (#30037)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-07-01 17:16:15 +02:00
jwasinger
a4e338f05e accounts/usbwallet/trezor: upgrade to generate with protoc 27.1 (#30058) 2024-07-01 16:18:38 +02:00
Ceyhun Onur
7cfff30ba3 rpc: truncate call error data logs (#30028)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-06-28 20:37:58 +02:00
gitglorythegreat
06f1d077d3 all: replace division with right shift if possible (#29911) 2024-06-28 18:08:31 +02:00
maskpp
4939c25341 cmd/evm/internal/t8ntool: log writeTraceResult error message (#30038) 2024-06-28 18:05:57 +02:00
maskpp
36d67be41b core/txpool/blobpool: improve newPriceHeap function (#30050)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-06-28 15:51:27 +02:00
lilasxie
19c3c1e205 triedb/pathdb: fix flaky test in pathdb (#29901) 2024-06-28 21:15:54 +08:00
rjl493456442
045b9718d5 trie: relocate state execution logic into pathdb package (#29861) 2024-06-27 20:30:39 +08:00
Halimao
269e80b07e eth/tracers,trie: remove unnecessary check (#30071) 2024-06-27 11:29:50 +02:00
maskpp
9298d2db88 trie/trienode: remove unnecessary check in Summary (#30047) 2024-06-25 15:45:33 +02:00
maskpp
98b5930d2d core/txpool/blobpool: avoid use *map as parameter. (#30048) 2024-06-25 14:19:04 +02:00
jwasinger
ed8fd0ac09 all: stateless witness builder and (self-)cross validator (#29719)
* all: add stateless verifications

* all: simplify witness and integrate it into live geth

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-06-25 14:48:08 +03:00
AMIR
73f7e7c087 internal/debug: remove unnecessary log level assignment (#30044)
Log level is specified in L259 so it's unnecessary to specify it for handlers (L234, L236).
2024-06-25 11:30:58 +02:00
Halimao
fe0c0b04fe accounts/keystore: use t.TempDir in test (#30052) 2024-06-25 11:24:33 +02:00
lightclient
0a651f8972 .github: add lightclient as codeowner to relevant packages (#30062) 2024-06-25 11:16:27 +02:00
lightclient
d8ea7ac2b0 cmd/blsync: use debug.Setup for logging configuration (#30065) 2024-06-25 11:14:12 +02:00
Halimao
a71f6f91fd p2p/discover: improve flaky revalidation tests (#30023) 2024-06-21 15:29:07 +02:00
rjl493456442
c10ac4f48f Revert "core/state/snapshot: tiny fixes" (#30039)
Revert "core/state/snapshot: tiny fixes (#29995)"

This reverts commit e0e45dbc32.
2024-06-21 10:42:43 +03:00
rjl493456442
e0e45dbc32 core/state/snapshot: tiny fixes (#29995) 2024-06-21 09:51:03 +08:00
David Theodore
27654d3022 p2p/rlpx: 2KB maximum size for handshake messages (#30029)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-06-20 14:08:54 +02:00
maskpp
00675c5876 trie/trienode: avoid unnecessary copy (#30019)
* avoid unnecessary copy

* delete the never used function ProofList

* eth/protocols/snap, trie/trienode: polish the code

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-06-20 11:47:29 +08:00
psogv0308
27008408a5 core/txpool/blobpool: change rw-lock to r-lock (#29989) 2024-06-19 14:46:57 +02:00
Halimao
c11aac249d common: using ParseUint instead of ParseInt (#30020)
Since Decimal is defined as unsiged `uint64`, we should use `strconv.ParseUint` instead of `strconv.ParseInt` during unmarshalling.

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-06-19 11:06:52 +02:00
jwasinger
0e3a0a693c trie: don't reset tracer at the end of Commit (#30024)
* trie: don't reset tracer at the end of Commit

* Update trie.go

---------

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
2024-06-19 10:58:22 +03:00
Ha DANG
67a862db9d cmd/geth, ethdb/pebble: improve database statistic (#29948)
* cmd/geth, ethdb/pebble: polish method naming and code comment

* implement db stat for pebble

* cmd, core, ethdb, internal, trie: remove db property selector

* cmd, core, ethdb: fix function description

---------

Co-authored-by: prpeh <prpeh@proton.me>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-06-19 14:47:17 +08:00
Marius van der Wijden
7cf6a63687 core/state/snapshot: acquire the lock on Release (#30011)
* core/state/snapshot: acquire the lock on release

* core/state/snapshot: only acquire read-lock when iterating
2024-06-18 10:52:49 +08:00
Dean Eigenmann
d8664490da common/math: fix out of bounds access in json unmarshalling (#30014)
Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-06-17 21:53:00 +02:00
maskpp
c736b04d9b triedb/pathdb: use maps.Clone and maps.Keys (#29985) 2024-06-17 17:09:29 +02:00
maskpp
115d154392 trie, triedb/pathdb: prealloc capacity for map and slice (#29986) 2024-06-17 11:42:41 +02:00
Zoro
b78d2352ef log: fix some functions comments (#29907)
updates some docstrings
---------

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
2024-06-17 11:03:27 +02:00
Péter Szilágyi
a58e4f0674 go.mod: update Pebble to sort out a deleted upstream dependency (#30010) 2024-06-17 11:15:27 +03:00
maskpp
34b46a2f75 core/state/snapshot: add a missing lock (#30001)
* upgrade lock usage

* revert unnecessary change
2024-06-17 10:42:39 +03:00
Darioush Jalali
fd5078c779 trie/triedb: add Reader to backend interface (#29988) 2024-06-14 14:52:46 +08:00
Felföldi Zsolt
86150af2e5 beacon/light: fix shutdown issues (#29946)
* beacon/light/request: add server test for event after unsubscribe

* beacon/light/api: fixed double stream.Close()

* beacon/light/request: add checks for nil event callback function

* beacon/light/request: unlock server mutex while unsubscribing from parent
2024-06-12 16:38:19 +02:00
jwasinger
69351e8b0f core/state, eth/protocols, trie, triedb/pathdb: remove unused error from trie Commit (#29869)
* core/state, eth/protocols, trie, triedb/pathdb:  remove unused error return from trie Commit

* move set back to account-trie-update block scoping for easier readability

* address review

* undo tests submodule change

* trie:  panic if BatchSerialize returns an error in Verkle trie Commit

* trie: verkle comment nitpicks

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-06-12 12:23:16 +03:00
jackyin
3687c34cfc accounts: avoid duplicate regex compilation (#29943)
* fix: Optimize regular initialization

* modify var name

* variable change to private types
2024-06-12 10:46:36 +03:00
Felix Lange
1e97148249 all: fix inconsistent receiver name and add lint rule for it (#29974)
* .golangci.yml: enable check for consistent receiver name

* beacon/light/sync: fix receiver name

* core/txpool/blobpool: fix receiver name

* core/types: fix receiver name

* internal/ethapi: use consistent receiver name 'api' for handler object

* signer/core/apitypes: fix receiver name

* signer/core: use consistent receiver name 'api' for handler object

* log: fix receiver name
2024-06-12 10:45:42 +03:00
bugmaker9371
b6f2bbd417 p2p/simulations: update doc of HTTP endpoints (#29894) 2024-06-11 19:41:17 +02:00
Guillaume Ballet
c732039a34 .github: disable cache in actions run (#29926) 2024-06-11 15:57:41 +02:00
bugmaker9371
caa066dcb0 cmd/devp2p: fix log output (#29972) 2024-06-11 16:27:35 +03:00
ucwong
ffb29be7d4 ethconfig: regenerate config (#29970) 2024-06-11 20:34:56 +08:00
maskpp
3aa874bed2 core/state: rename all the AccessList receivers to 'al' (#29921)
rename all the receivers to 'al'
2024-06-11 11:24:44 +03:00
jwasinger
85587d5ef2 cmd, core: prefetch reads too from tries if requested (#29807)
* cmd/utils, consensus/beacon, core/state: when configured via stub  flag: prefetch all reads from account/storage tries, terminate prefetcher synchronously.

* cmd, core/state: fix nil panic, fix error handling, prefetch nosnap too

* core/state: expand prefetcher metrics for reads and writes separately

* cmd/utils, eth: fix noop collect witness flag

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-06-11 11:10:07 +03:00
TinyFoxy
2eb185c92b core, rlp: remove duplicated words (#29964) 2024-06-10 20:55:47 +08:00
jwasinger
db273c8733 core: initialize developer genesis beacon root contract with 0 balance (#29963) 2024-06-10 13:58:50 +08:00
Gealber Morales
8bda642963 p2p: use package slices to sort in PeersInfo (#29957) 2024-06-09 22:50:22 +02:00
Gealber Morales
349fcdd22d p2p/discover: add missing lock when calling tab.handleAddNode (#29960) 2024-06-09 22:47:51 +02:00
Ha DANG
1098d148a5 cmd/geth: remove unused param (#29952) 2024-06-08 13:04:16 +02:00
kukuru909
deaf10982c cmd/clef, cmd/evm: fix markdown issues in README (#29954) 2024-06-08 13:00:53 +02:00
ucwong
6a49d13c13 go.mod : tidy 2024-06-07 15:57:46 +02:00
Gealber Morales
4405f18519 cmd/evm/internal/t8ntool: remove unused parameter (#29930) 2024-06-07 20:04:18 +08:00
Gary Rong
4461c1fc17 params: begin v1.14.6 release cycle 2024-06-06 21:23:44 +08:00
Gary Rong
0dd173a727 params: release Geth v1.14.5 2024-06-06 21:17:53 +08:00
Felix Lange
85459e1439 p2p/discover: unwrap 4-in-6 UDP source addresses (#29944)
Fixes an issue where discovery responses were not recognized.
2024-06-06 16:15:22 +03:00
Hteev Oli
0750cb0c8f p2p/netutil: fix comments (#29942) 2024-06-06 10:56:41 +03:00
Marquis Shanahan
cbbfa3eac0 rlp: no need to repeat called len method (#29936)
rlp: no need to repeat calling len
2024-06-06 10:55:38 +03:00
Marius Kjærstad
6c518fe606 build: upgrade -dlgo version to Go 1.22.4 (#29938) 2024-06-06 10:52:57 +03:00
Felix Lange
bc6569462d p2p: use netip.Addr where possible (#29891)
enode.Node was recently changed to store a cache of endpoint information. The IP address in the cache is a netip.Addr. I chose that type over net.IP because it is just better. netip.Addr is meant to be used as a value type. Copying it does not allocate, it can be compared with ==, and can be used as a map key.

This PR changes most uses of Node.IP() into Node.IPAddr(), which returns the cached value directly without allocating.
While there are still some public APIs left where net.IP is used, I have converted all code used internally by p2p/discover to the new types. So this does change some public Go API, but hopefully not APIs any external code actually uses.

There weren't supposed to be any semantic differences resulting from this refactoring, however it does introduce one: In package p2p/netutil we treated the 0.0.0.0/8 network (addresses 0.x.y.z) as LAN, but netip.Addr.IsPrivate() doesn't. The treatment of this particular IP address range is controversial, with some software supporting it and others not. IANA lists it as special-purpose and invalid as a destination for a long time, so I don't know why I put it into the LAN list. It has now been marked as special in p2p/netutil as well.
2024-06-05 19:31:04 +02:00
Marquis Shanahan
d09ddac399 core/rawdb: remove unused deriveLogFields (#29913)
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Martin HS <martin@swende.se>
2024-06-05 21:05:00 +08:00
Hteev Oli
e85e21c932 core/state, eth/tracers: fix typos (#29932) 2024-06-05 11:07:37 +02:00
Péter Szilágyi
fc40d68e5b params: begin v1.14.5 release cycle 2024-06-05 11:20:35 +03:00
Péter Szilágyi
5550d8399f params: release Geth v1.14.4 2024-06-05 11:06:37 +03:00
rjl493456442
125fb1ff58 core/state: avoid data race (#29924) 2024-06-04 15:51:34 +03:00
SangIlMo
682ae838b2 internal/ethapi: recap higher args.Gas with block GasLimit in DoEstimateGas (#29738)
* internal/ethapi: recap higher args.Gas with block GasLimit in DoEstimateGas

* internal/ethapi: fix gas estimator capping code

* internal/ethapi: fix test

* fix goimports lint (remove space)

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-06-04 10:59:41 +03:00
Roy Crihfield
68c0ec0815 trie: iterate values pre-order and fix seek behavior (#27838)
This pull request fixes the pre-order trie traversal by defining 
a more accurate iterator order and path comparison rule.

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-06-04 11:17:26 +08:00
Steven Wang
adbbd8cd7b core/state: prefetch account trie while starting a prefetcher (#29919)
Always prefetch the account trie while starting the prefetcher.

Co-authored-by: steven <steven@stevendeMacBook-Pro.local>
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
2024-06-04 11:12:24 +08:00
tianyeyouyou
a6751d6fc8 core/rawdb,eth/protocols,p2p: prealloc slice size (#29893)
chore: prealloc slice size
2024-06-03 15:51:04 +03:00
miles
7270cba25c log: fix a typo (#29883)
logger
2024-06-03 15:50:24 +03:00
maskpp
b36c73813c beacon/engine: prealloc capacity for map and slice (#29903)
* prealloc capacity for map and slice

* revert unnecessary change
2024-06-03 15:38:08 +03:00
HAOYUatHZ
50405e29b7 cmd/evm/internal/t8ntool: fix a typo (#29887)
* i8ntool: fix a typo

* cmd/evm/internal/t8ntool: fix typo typo

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-06-03 15:31:23 +03:00
rjl493456442
d38b88a5a1 core/state: introduce stateupdate structure (#29530)
* core/state: introduce stateUpate structure

* core/state: remove outdated function description

* core/state: address comments
2024-06-03 14:17:12 +03:00
Chris Ziogas
c9e0b3105b Supply delta live tracer (#29347)
Introduces the first built-in live tracer. The supply tracer tracks ETH supply changes across blocks
and writes the output to disk. This will need to be enabled through CLI using the `--vmtrace supply` flag.

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-06-03 12:30:27 +02:00
Sina M
d4b81f0e08 CODEOWNERS: @s1na owns core/tracing (#29899)
Update CODEOWNERS
2024-05-31 18:40:09 +02:00
Péter Szilágyi
2613523cb5 miner: lower default min miner tip from 1 gwei to 0.001 gwei (#29895) 2024-05-31 10:39:40 +03:00
tianyeyouyou
bdc62f9beb common/math: rename variable name int to n (#29890)
* chore: rename variable name `int` to `in`

* chore: rename variable name `int` to `n`
2024-05-31 10:25:49 +03:00
yujinpark
5d7d48fc3e eth/gasprice: add comment to constant (#29892)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-05-30 18:22:23 +02:00
SuiYuan
2262bf3415 crypto/secp256k1: change receiver variable name to lowercase (#29889) 2024-05-30 16:24:16 +02:00
SuiYuan
e015c1116f ethdb: remove unnecessary function wrapper (#29888) 2024-05-30 21:23:04 +08:00
Felix Lange
6bb13e8e2b eth/catalyst: ensure TxPool is synced in Fork (#29876)
This should fix an occasional test failure in ethclient/simulated.TestForkResendTx.
Inspection of logs revealed the cause of the failure to be that the txpool was not done
reorganizing by the time Fork is called.
2024-05-29 15:56:52 +02:00
hattizai
2f06c1e854 cmd/devp2p: fix node.TCP -> node.UDP (#29879) 2024-05-29 15:55:51 +02:00
Felix Lange
3fef53447f build: upgrade to golangci-lint v1.59.0 (#29875) 2024-05-29 16:31:27 +03:00
Felix Lange
94a8b296e4 p2p/discover: refactor node and endpoint representation (#29844)
Here we clean up internal uses of type discover.node, converting most code to use
enode.Node instead. The discover.node type used to be the canonical representation of
network hosts before ENR was introduced. Most code worked with *node to avoid conversions
when interacting with Table methods. Since *node also contains internal state of Table and
is a mutable type, using *node outside of Table code is prone to data races. It's also
cleaner not having to wrap/unwrap *enode.Node all the time.

discover.node has been renamed to tableNode to clarify its purpose.

While here, we also change most uses of net.UDPAddr into netip.AddrPort. While this is
technically a separate refactoring from the *node -> *enode.Node change, it is more
convenient because *enode.Node handles IP addresses as netip.Addr. The switch to package
netip in discovery would've happened very soon anyway.

The change to netip.AddrPort stops at certain interface points. For example, since package
p2p/netutil has not been converted to use netip.Addr yet, we still have to convert to
net.IP/net.UDPAddr in a few places.
2024-05-29 15:02:26 +02:00
牛晓婕
e26fa9e40e core/state: fix typo in comment (#29639) 2024-05-29 14:44:14 +02:00
trillo
2f0e63e5ac eth/downloader, eth/tracer: fix typos in comments (#29707) 2024-05-29 14:43:07 +02:00
PolyMa
06263b1b35 all: fix typos in comments (#29873)
fix using `a` & `the` simutaneously
2024-05-29 12:24:10 +02:00
Steven Wang
b8cf1636d4 accounts: fix TestUpdateKeyfileContents (#29867)
Create the directory before NewKeyStore. This ensures the watcher successfully starts on
the first attempt, and waitWatcherStart functions as intended.
2024-05-29 12:12:57 +02:00
lilasxie
153f8da887 p2p/nodestate: remove unused package (#29872) 2024-05-29 12:11:18 +02:00
bugmaker9371
daf4f72077 p2p/simulations: remove stale information about docker adapter (#29874) 2024-05-29 12:09:58 +02:00
Martin HS
5534c849b6 go.mod: update a number of dependencies (#29763)
* deps: update go-winio

* deps: update fastcache

* deps: update golang-set

* update fatih/color

* update natefinch/lumberjack.v2
2024-05-29 11:30:25 +03:00
lightclient
cc22e0cdf0 p2p/discover: fix update logic in handleAddNode (#29836)
It seems the semantic differences between addFoundNode and addInboundNode were lost in
#29572. My understanding is addFoundNode is for a node you have not contacted directly
(and are unsure if is available) whereas addInboundNode is for adding nodes that have
contacted the local node and we can verify they are active.

handleAddNode seems to be the consolidation of those two methods, yet it bumps the node in
the bucket (updating it's IP addr) even if the node was not an inbound. This PR fixes
this. It wasn't originally caught in tests like TestTable_addSeenNode because the
manipulation of the node object actually modified the node value used by the test.

New logic is added to reject non-inbound updates unless the sequence number of the
(signed) ENR increases. Inbound updates, which are published by the updated node itself,
are always accepted. If an inbound update changes the endpoint, the node will be
revalidated on an expedited schedule.

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-05-28 21:30:17 +02:00
jwasinger
171430c3f5 core/state: remove unused error from prefetcher trie method (#29768)
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-05-28 19:54:55 +02:00
jwasinger
e517183719 eth, eth/downloader: remove references to LightChain, LightSync (#29711)
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-05-28 19:52:08 +02:00
Felix Lange
af0a3274be p2p/discover: fix crash when revalidated node is removed (#29864)
In #29572, I assumed the revalidation list that the node is contained in could only ever
be changed by the outcome of a revalidation request. But turns out that's not true: if the
node gets removed due to FINDNODE failure, it will also be removed from the list it is in.
This causes a crash.

The invariant is: while node is in table, it is always in exactly one of the two lists. So
it seems best to store a pointer to the current list within the node itself.
2024-05-28 18:13:03 +02:00
rjl493456442
b88051ec83 core/rawdb, triedb/pathdb: fix freezer read-only option (#29823) 2024-05-28 14:41:11 +02:00
Martin HS
61932e4710 cmd/geth: update testdata (vulncheck) (#29714) 2024-05-28 14:16:45 +02:00
gitglorythegreat
871e55d93e core/state: fix typos in comments (#29767) 2024-05-28 14:10:27 +02:00
Martin HS
42471d7a3e core/vm/runtime: set random to enable merge-opcodes (#29799) 2024-05-28 13:45:16 +02:00
trillo
caafa93598 all: improve some error strings (#29842) 2024-05-28 13:44:40 +02:00
Sina M
ea6c16007c eth/tracers: clear error for non-reverting pre-homestead fail (#29824) 2024-05-28 13:12:46 +02:00
rjl493456442
513276864b eth/downloader: fix flaky test (#29852)
This pull request fixes the flay test TestSkeletonSyncRetrievals. In this test, we first
trigger a sync cycle and wait for it to meet certain expectations. We then inject a new
head and potentially also a new peer, then perform another final sync. The test now
performs the newPeer addition before launching the final sync, and waits a bit for that
peer to get registered. This fixes the logic race that made the test fail sometimes.

Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
2024-05-27 16:26:55 +02:00
Steven Wang
1a4e4a4fe1 miner: fix TestBuildPayload sporadic failure (#29853)
miner: fix TestBuildPayload sporadic failure

Co-authored-by: steven <steven@stevendeMacBook-Pro.local>
2024-05-27 19:42:07 +08:00
Mobin Mohanan
7224576fba core, eth/protocols/snap, internal/ethapi: remove redundant types (#29841) 2024-05-27 14:39:39 +08:00
Wukingbow
7f5cc02a99 metrics: fix function comment (#29843) 2024-05-27 14:34:53 +08:00
winterjihwan
d1d9f34e51 core/types: clarify set inclusion in comments (#29839) 2024-05-26 11:54:37 +02:00
levisyin
b6474e9f90 metrics: add test for SampleSnapshot.Sum (#29831) 2024-05-24 11:34:30 +02:00
gitglorythegreat
64b1cd8aaf p2p: fix typos (#29828) 2024-05-24 11:33:19 +02:00
Halimao
08fe6a8614 metrics: fix flaky testTestExpDecaySampleNanosecondRegression (#29832) 2024-05-24 15:20:05 +08:00
Aaron Chen
61b3d93bb0 p2p/enode: fix TCPEndpoint (#29827) 2024-05-23 23:17:51 +02:00
Felix Lange
cc9e2bd9dd p2p/enode: fix endpoint determination for IPv6 (#29801)
enode.Node has separate accessor functions for getting the IP, UDP port and TCP port.
These methods performed separate checks for attributes set in the ENR.

With this PR, the accessor methods will now return cached information, and the endpoint is
determined when the node is created. The logic to determine the preferred endpoint is now
more correct, and considers how 'global' each address is when both IPv4 and IPv6 addresses
are present in the ENR.
2024-05-23 14:27:03 +02:00
Felix Lange
6a9158bb1b p2p/discover: improved node revalidation (#29572)
Node discovery periodically revalidates the nodes in its table by sending PING, checking
if they are still alive. I recently noticed some issues with the implementation of this
process, which can cause strange results such as nodes dropping unexpectedly, certain
nodes not getting revalidated often enough, and bad results being returned to incoming
FINDNODE queries.

In this change, the revalidation process is improved with the following logic:

- We maintain two 'revalidation lists' containing the table nodes, named 'fast' and 'slow'.
- The process chooses random nodes from each list on a randomized interval, the interval being
  faster for the 'fast' list, and performs revalidation for the chosen node.
- Whenever a node is newly inserted into the table, it goes into the 'fast' list.
  Once validation passes, it transfers to the 'slow' list. If a request fails, or the
  node changes endpoint, it transfers back into 'fast'.
- livenessChecks is incremented by one for successful checks. Unlike the old implementation,
  we will not drop the node on the first failing check. We instead quickly decay the
  livenessChecks give it another chance.
- Order of nodes in bucket doesn't matter anymore.

I am also adding a debug API endpoint to dump the node table content.

Co-authored-by: Martin HS <martin@swende.se>
2024-05-23 14:26:09 +02:00
Halimao
70bee977d6 metrics: fix out of range error message (#29821) 2024-05-23 12:34:34 +02:00
Mobin Mohanan
b779e469da Makefile: add fmt, update help (#29777) 2024-05-23 11:56:32 +02:00
Sina M
fa581766f5 eth/tracers: fix json logger for evm blocktest (#29795) 2024-05-23 10:55:54 +02:00
Karl Bartel
0d4cdb3dbe internal/ethapi: fix typos (#29784)
Fix typos in api.go
2024-05-23 10:41:51 +02:00
Martin HS
7fd7c1f7dd eth/tracers: fix basefee context for traceBlock (#29811)
This fixes an issue for `debug_traceBlock*` methods where the BASEFEE opcode was returning always 0. This caused the method return invalid results.

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-05-21 18:27:36 +02:00
cocoyeal
be5df74ed5 trie: update the valid function comments (#29809) 2024-05-21 19:53:34 +08:00
rjl493456442
473ee8fc07 trie, eth/protocols/snap: sanitize the committed node data (#29485) 2024-05-16 17:58:35 +08:00
zhiqiangxu
7ed52c949e core: move balanceCheck addition in buyGas (#29762)
It's a bit confusing to add msg.value into the balanceCheck within the conditional.
No impact on block validation since GasFeeCap is always set when processing transactions.
2024-05-15 14:23:24 +02:00
cario-dev
d2f00cb54e .github: upgrade to action versions with node20 (#29776)
* github: upgrade checkout action to version with node20

* Update go.yml

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-05-14 15:46:11 +02:00
0xbeny
8919c5c0fc core: deploy EIP-4788 contract in dev mode genesis (#29655)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-05-14 15:04:32 +02:00
rjl493456442
be3284373f core/state: remove useless operation (#29769) 2024-05-14 14:54:49 +02:00
rjl493456442
5b3e3cd2be tests: update tests (#29730) 2024-05-13 21:34:29 +08:00
Péter Szilágyi
2ac83e197b core/state: blocking prefetcher on term signal, parallel updates (#29519)
* core/state: trie prefetcher change: calling trie() doesn't stop the associated subfetcher

Co-authored-by: Martin HS <martin@swende.se>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>

* core/state: improve prefetcher

* core/state: restore async prefetcher stask scheduling

* core/state: finish prefetching async and process storage updates async

* core/state: don't use the prefetcher for missing snapshot items

* core/state: remove update concurrency for Verkle tries

* core/state: add some termination checks to prefetcher async shutdowns

* core/state: differentiate db tries and prefetched tries

* core/state: teh teh teh

---------

Co-authored-by: Jared Wasinger <j-wasinger@hotmail.com>
Co-authored-by: Martin HS <martin@swende.se>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-05-13 15:47:45 +03:00
Guillaume Ballet
44a50c9f96 cmd, core, params, trie: add verkle access witness gas charging (#29338)
Implements some of the changes required to charge and do gas accounting in verkle testnet.
2024-05-10 20:13:11 +02:00
Hteev Oli
47af69c2bc core, beacon, ethdb: fix typos (#29748)
* core, beacon, ethdb: fix typos

* revert file that can't be changed
2024-05-10 19:48:14 +02:00
cocoyeal
603fd898d4 event: fix typo (#29749)
typo: of -> or
2024-05-10 19:44:07 +02:00
rjl493456442
e5f5eaebc4 core/state: remove slot dirtyness if it's set back to origin value (#29731)
* core/state: remove slot dirtiness if it's set back to origin value

* core/state: suggestion from martin
2024-05-10 10:57:38 +03:00
Felix Lange
74edc93864 params: gofmt 2024-05-09 16:07:32 +02:00
Felix Lange
0e456d9eeb .travis.yml: disable normal unit tests in cron job (#29746) 2024-05-09 16:05:42 +02:00
Felix Lange
6d51c1f5f4 params: begin v1.14.4 release cycle 2024-05-09 12:40:37 +02:00
Felix Lange
ab48ba42f4 params: release go-ethereum v1.14.3 stable 2024-05-09 12:34:54 +02:00
Felix Lange
804afb8faa .travis.yml: restore PPA condition and bump timeouts (#29742) 2024-05-08 20:46:54 +02:00
Felix Lange
faff03c403 .travis.yml: enable PPA upload on push and fix apt-get command (#29741) 2024-05-08 20:28:05 +02:00
Felix Lange
1a79f8fe58 params: begin v1.14.3 release cycle 2024-05-08 16:31:14 +02:00
Felix Lange
35b2d07f4b params: release go-ethereum v1.14.2 stable 2024-05-08 16:26:01 +02:00
Felix Lange
eeb22089fd .travis.yml: fix package install on PPA builder 2024-05-08 14:34:58 +02:00
Felix Lange
14f4228472 params: begin v1.14.2 release cycle 2024-05-08 14:30:18 +02:00
Felix Lange
dd09f7e3fa params: release go-ethereum v1.14.1 stable 2024-05-08 14:28:40 +02:00
Felix Lange
6154f87c33 .travis.yml: fix apt-get options (#29734) 2024-05-08 11:33:07 +02:00
Felix Lange
dd4afb9fec .travis.yml: fix install of gcc-multilib (#29733) 2024-05-08 11:08:55 +02:00
rjl493456442
9ec50080eb core: use in-memory freezer for tests (#29720)
* core: simplify chain tests

* core, eth, cmd: use in-memory freezer for tests

* core: restore tests
2024-05-08 09:43:33 +03:00
Felix Lange
e96de6489c build: upgrade to go 1.22.3 (#29725) 2024-05-07 22:08:29 +02:00
Martin HS
71aa15c98f travis: use ubuntu noble (24.04) instead of bionic (18.04) (#29723) 2024-05-07 21:24:58 +02:00
nand2
d6e91e2e05 eth/gasestimator: include blobs in virtual balance computation (#29703)
Fixes #29702

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-05-07 14:27:14 +02:00
Nathan
e4b8058d5a eth/gasprice: add query limit for FeeHistory to defend DDOS attack (#29644)
* eth/gasprice: add query limit for FeeHistory to defend DDOS attack

* fix return values after cherry-pick

---------

Co-authored-by: Eric <45141191+zlacfzy@users.noreply.github.com>
2024-05-07 10:25:15 +03:00
Maciej Kulawik
3e896c875a ethdb/pebble: fix pebble metrics registration (#29699)
ethdb/pebble: use GetOrRegister instead of NewRegistered when creating metrics
2024-05-06 14:42:22 +03:00
Guillaume Ballet
43cbcd78ea core, core/state: move TriesInMemory to state package (#29701) 2024-05-06 13:28:53 +02:00
Matthieu Vachon
a09a610384 core/tracing: add system call callback when performing ProcessBeaconBlockRoot (#29355)
Added a start/end system where tracer can be notified that processing of some Ethereum system calls is starting processing and also notifies it when the processing has completed.

Doing a start/end for system call will enable tracers to "route" incoming next tracing events to go to a separate bucket than other EVM calls. Those not interested by this fact can simply avoid registering the hooks.

The EVM call is going to be traced normally afterward between the signals provided by those 2 new hooks but outside of a transaction context OnTxStart/End. That something implementors of live tracers will need to be aware of (since only "trx tracers" are not concerned by ProcessBeaconRoot).

---------

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-05-06 13:21:55 +02:00
Kiarash Hajian
905e325cd8 p2p/discover/v5wire: add tests for invalid handshake and auth data size (#29708) 2024-05-06 13:17:19 +02:00
rjl493456442
86a1f0c394 core/rawdb: fix ancient root folder (#29697) 2024-05-02 13:26:07 +03:00
maskpp
2c67fab0d7 trie/pathdb: preallocate map capacity (#29690)
* preallocated capacity for map's certain usege of memory

* preallocated capacity for map's certain usege of memory
2024-05-02 12:35:45 +03:00
Nathan
fbf6238ae9 params: fix misleading comments (#29684) 2024-05-02 11:21:11 +03:00
Aaron Chen
bc609e852a core/vm: remove redundant error checks (#29692) 2024-05-02 11:18:59 +03:00
Péter Szilágyi
682ee820fa core/state: parallelise parts of state commit (#29681)
* core/state, internal/workerpool: parallelize parts of state commit

* core, internal: move workerpool into syncx

* core/state: use errgroups, commit accounts concurrently

* core: resurrect detailed commit timers to almost-accuracy
2024-05-02 11:18:27 +03:00
rjl493456442
9f96e07c1c core/rawdb, trie: improve db APIs for accessing trie nodes (#29362)
* core/rawdb, trie: improve db APIs for accessing trie nodes

* triedb/pathdb: fix
2024-04-30 16:25:35 +02:00
Bin
f8820f170c accounts, cmd/geth, core: close opened files (#29598)
* fix: open file used up but not closed

* feat: more same case

* feat: accept conversation
2024-04-30 15:47:21 +02:00
jwasinger
45baf21111 eth/downloader: purge pre-merge sync code (#29281)
This PR removes pre-merge sync logic from the downloader. Now-irrelevant tests are removed and others have been updated.
2024-04-30 15:46:53 +02:00
lightclient
2e8e35f2ad all: refactor so NewBlock, WithBody take types.Body (#29482)
* all: refactor so NewBlock(..) and WithBody(..) take a types.Body

* core: fixup comments, remove txs != receipts panic

* core/types: add empty withdrawls to body if len == 0
2024-04-30 14:55:08 +02:00
Martin HS
5e07054589 internal/ethapi: listen to ctx cancellation in access list (#29686) 2024-04-30 14:48:54 +02:00
Marius van der Wijden
bd6bc37eec core/vm: add subgroup checks for mul/mulexp for G1/G2 (#29637) 2024-04-30 14:35:48 +02:00
Dragan Milic
7c7e3a77fc eth/tracers/native: fix flatCallTracer Stop() bug (#29623)
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-04-30 14:33:22 +02:00
Aaron Chen
ea89f9adf0 core/vm: remove a redundant zero check in opAddmod (#29672) 2024-04-30 14:08:13 +02:00
Martin HS
242b24af9f trie/trienode: minor speedup in nodeset merging (#29683) 2024-04-30 19:51:04 +08:00
rjl493456442
f46c878441 core/rawdb: implement in-memory freezer (#29135) 2024-04-30 11:33:22 +02:00
felipe
c04b8e6d74 cmd/utils: require TTD and difficulty to be zero at genesis for dev mode (#29579) 2024-04-30 11:22:57 +02:00
Nathan
69f815f6f5 params: print time value instead of pointer in ConfigCompatError (#29514) 2024-04-30 11:22:02 +02:00
maskpp
fecc8a0f4a cmd/evm/internal/t8ntool, core: prealloc map sizes where possible (#29620)
set cap for map in a certain scenario
2024-04-30 11:19:59 +02:00
Aaron Chen
8c3fc56d7f p2p/simulations/adapters: use maps.Clone (#29626) 2024-04-29 19:44:41 +02:00
Roy Crihfield
4bdbaab471 params: clarify consensus engine config Strings (#29643)
Define these on a value receiever so that nil is shown differently.
2024-04-28 13:03:03 +02:00
Péter Szilágyi
4253030ef6 core/state: move metrics out of state objects (#29665) 2024-04-26 18:35:52 +03:00
Péter Szilágyi
8d42e115b1 core/state: revert pending storage updates if they revert to original (#29661) 2024-04-26 15:24:40 +03:00
Péter Szilágyi
ad4fb2c729 build: drop trusty from PPA builds, EOL and incompatible (#29651)
* build: drop trusty from PPA builds, EOL and incompatible

* build: add Ubuntu Noble PPA build target
2024-04-25 14:07:39 +03:00
Péter Szilágyi
634d037937 travis: revert the PPA fix hot-build, it works (#29649) 2024-04-25 12:27:36 +03:00
Péter Szilágyi
a0282fc94f travis: temporarilly enable PPA builds for testing (#29648) 2024-04-25 12:00:59 +03:00
Péter Szilágyi
1f628d842c build: build all the builders to build all the builders (#29647)
* build: build all the builders to build all the builders

* build: tweak the indexes a bit to make them consistent
2024-04-25 11:50:25 +03:00
Martin HS
243cde0f54 core/state: better randomized testing (postcheck) on journalling (#29627)
This PR fixes some flaws with the existing tests.

The randomized testing (TestSnapshotRandom) executes a series of steps which modify the state and create journal-events. Later on, we compare the forward-going-states against the backwards-unrolling-journal-states, and check that they are identical.

The "identical" check is performed using various accessors. It turned out that we failed to check some things: 
- the accesslist contents
- the transient storage contents
- the 'newContract' flag
- the dirty storage map

This change adds these new checks
2024-04-25 09:56:25 +02:00
Undefinedor
a13b92524d eth/protocols/eth,p2p/discover: remove unnecessary checks (#29590)
fix useless condition
2024-04-25 08:40:29 +02:00
yujinpark
2f6ff492ae internal/ethapi: typo (#29636) 2024-04-25 13:47:29 +08:00
Péter Szilágyi
4f4f9d88d3 core/state: storage journal entry should revert dirtyness too (#29641)
Currently our state journal tracks each storage update to a contract, having the ability to revert those changes to the previously set value.

For the very first modification however, it behaves a bit wonky. Reverting the update doesn't actually remove the dirty-ness of the slot, rather leaves it as "change this slot to it's original value". This can cause issues down the line with for example write witnesses needing to gather an unneeded proof.

This PR modifies the storageChange journal entry to not only track the previous value of a slot, but also whether there was any previous value at all set in the current execution context. In essence, the PR changes the semantic of storageChange so it does not simply track storage changes, rather it tracks dirty storage changes, an important distinction for being able to cleanly revert the journal item.
2024-04-24 17:45:24 +02:00
Aaron Chen
7362691479 trie, consensus/clique: use maps.Clone (#29616) 2024-04-24 14:27:58 +02:00
qcrao
ac21f9bfb5 trie: preallocate capacity for fields slice (#29614)
trie: Preallocate capacity for fields slice
2024-04-24 14:04:20 +02:00
Martin HS
0d4c38865e core/state: remove account reset operation v2 (#29520)
* core/state, tests: remove account reset operation

* core/state, core/vm: implement createcontract journal event

* core/state: make createcontract not emit dirtied account, unskip tests

* core/state: add createcontract to journal fuzzing

* core/state: fix journal

* core/state: address comments

* core/state: remove useless code

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-04-24 12:59:06 +03:00
Péter Szilágyi
938734be3c params: begin 1.14.1 release cycle 2024-04-24 11:05:10 +03:00
Péter Szilágyi
87246f3cba params: release Geth v1.14.0 2024-04-24 11:02:49 +03:00
jwasinger
5f3c58f1de eth/downloader: fix case where skeleton reorgs below the filled block (#29358)
This change adds a testcase and fixes a corner-case in the skeleton sync.

With this change, when doing the skeleton cleanup, we check if the filled header is acually within the range of what we were meant to backfill. If not, it means the backfill was a noop (possibly because we started and stopped it so quickly that it didn't have time to do any meaningful work). In that case, just don't clean up anything.

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-04-24 09:07:39 +02:00
Matthieu Vachon
ade7515c81 eth, eth/tracers: process beacon root before transactions (#29402)
The beacon root when applied in `state_processor.go` is performed right before executing transaction. That means that contract reliying on this value would query the same value found in the block header.

In that spirit, it means that any tracing/operation relying on state data which touches transaction must have updated the beacon root before any transaction processing.
2024-04-24 07:58:05 +02:00
Chris Ziogas
fb08fd334a core/tracing: Add OnClose Trace Hook (#29629)
The OnClose trace hook is being triggered on blockchain Stop, so as tracers can release any resources.
2024-04-24 07:54:59 +02:00
Chris Ziogas
882d1e22f6 cmd/geth, cmd/utils: rename config and flag to VMTraceJsonConfig (#29573)
renames the yaml config field VMTraceConfig to VMTraceJsonConfig, in order to be consistent with the renaming of the CLI flag.
2024-04-24 07:53:16 +02:00
Mario Vega
94579932b1 core/vm: fix Prague contracts (#29612)
core/vm: fix prague contracts
2024-04-23 15:10:24 +02:00
Felföldi Zsolt
256d4b099c beacon/light: request finality update explicitly when necessary (#29567)
This PR adds an extra mechanism to sync.HeadSync that tries to retrieve the latest finality update from every server each time it sends an optimistic update in a new epoch (unless we already have a validated finality update attested in the same epoch). 

Note that this is not necessary and does not happen if the new finality update is delivered before the optimistic update. The spec only mandates light_client_finality_update events when a new epoch is finalized. If the chain does not finalize for a while then we might need an explicit request that returns a finality proof that proves the same finality epoch from the latest attested epoch.
2024-04-23 13:31:32 +02:00
haoran
b2b0e1da8c all: fix various typos (#29600)
* core: fix typo

* rpc: fix typo

* snap: fix typo

* trie: fix typo

* main: fix typo

* abi: fix typo

* main: fix field comment for basicOp
2024-04-23 13:09:42 +03:00
Aaron Chen
709e0b3997 metrics: remove librato (#29624) 2024-04-23 13:08:02 +03:00
HAOYUatHZ
0e380ddaf7 miner: fix typos (#29625) 2024-04-23 13:06:25 +03:00
Martin HS
853e0c23f3 eth/catalyst, trie/pathdb: fix flaky tests (#29571)
This change fixes three flaky tests `TestEth2AssembleBlock`,`TestEth2NewBlock`, `TestEth2PrepareAndGetPayload` and `TestDisable`.

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-04-23 10:33:36 +02:00
rjl493456442
acd1eaae2c core: remove bad block checks (#29609) 2024-04-22 20:00:42 +03:00
Felföldi Zsolt
e6689fe090 beacon/light/sync: print error log if checkpoint retrieval fails (#29532)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-04-22 13:19:42 +02:00
Ryan Schneider
1ec7af2612 eth: Add eth_blobBaseFee RPC and blob fields to eth_feeHistory (#29140)
Co-authored-by: lightclient <lightclient@protonmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-04-22 12:17:06 +02:00
Péter Szilágyi
c2dfe7a0c7 go.mod: update golang/x repos (#29604) 2024-04-22 12:56:54 +03:00
Felix Lange
82b0dec713 eth/filters: remove support for pending logs (#29574)
This change removes support for subscribing to pending logs. 

"Pending logs" were always an odd feature, because it can never be fully reliable. When support for it was added many years ago, the intention was for this to be used by wallet apps to show the 'potential future token balance' of accounts, i.e. as a way of notifying the user of incoming transfers before they were mined. In order to generate the pending logs, the node must pick a subset of all public mempool transactions, execute them in the EVM, and then dispatch the resulting logs to API consumers.
2024-04-22 10:31:17 +02:00
xiaodong
ad3d8cb12a cmd/geth: remove unused parameter (#29602) 2024-04-22 16:13:03 +08:00
Aaron Chen
28ccb2bbf8 build: fix string compare for SortFunc (#29595) 2024-04-21 11:14:13 +02:00
bugmaker9371
98f504f69f p2p/discover: fix test error messages (#29592) 2024-04-21 11:13:36 +02:00
Marius van der Wijden
2e06fbd409 core/vm: add KZG benchmark (#29583) 2024-04-19 13:46:43 +02:00
Mario Vega
cce879b71b tests: define cancun-to-prague at 15K chainconig (#29557)
tests: add cancun->prague config
2024-04-19 10:07:52 +02:00
ids
81349ff6e5 eth/catalyst: fix typo (#29580) 2024-04-19 09:58:14 +02:00
Martin HS
823719b9e1 core/vm: enable bls-precompiles for Prague (#29552)
enables the bls-contracts on the "Prague" config, so that the testing-team can activate them to make tests.
2024-04-18 09:08:25 +02:00
rjl493456442
b5902cf595 core: remove unused fields (#29569) 2024-04-18 14:48:50 +08:00
ucwong
5f95145308 eth/ethconfig: regenerate autogen files (#29559)
eth/ethconfig/gen_config.go : go generate fix
2024-04-18 08:21:23 +02:00
Felföldi Zsolt
0da69e84c0 beacon/blsync: proceed with empty finalized hash if proof is not expected soon (#29449)
* beacon/blsync: proceed with empty finalized hash if proof is not expected soon

* Update beacon/blsync/block_sync.go

Co-authored-by: Felix Lange <fjl@twurst.com>

* beacon/blsync: fixed linter warning

* Update beacon/blsync/block_sync.go

Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
2024-04-17 17:07:28 +02:00
Aaron Chen
1e9bf2a09e core/state: fix bug in statedb.Copy and remove unnecessary preallocation (#29563)
This change removes an unnecessary preallocation and fixes a flaw with no-op copies of some parts of the statedb
2024-04-17 13:55:31 +02:00
Aaron Chen
74e8d2da97 trie/utils: simplify codeChunkIndex (#29480)
minor simplification to the code
2024-04-17 08:24:30 +02:00
rjl493456442
27de7dec65 ethdb/pebble: print warning log if pebble performance degrades (#29478) 2024-04-17 13:52:08 +08:00
Devon Bear
92da96b7d5 core/vm: refactor push-functions to use min builtin (#29515)
* optimize-push

* revert push1 change

* Update instructions.go

* core/vm: go format

* core/vm: fix nit

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-04-16 15:57:57 +03:00
persmor
0a51028819 all: fix various typos (#29542)
* core/rawdb: fix typos

* accounts/abi: fix typos

* metrics: fix typo

* beacon: fix typo

* crypto: fix typo

* rpc: fix typo

* rpc: fix typo
2024-04-16 15:44:00 +03:00
ucwong
5ffd940b7e core: go fmt (#29544) 2024-04-16 15:42:16 +03:00
ucwong
65e32d47ea go.mod: clean up indirection (#29553) 2024-04-16 15:32:50 +03:00
Chris Ziogas
72f69366de c.d/utils: rename vmtrace.config to vmtrace.jsonconfig (#29554)
rename vmtrace.config to vmtrace.jsonconfig

for consinstency with t8ntool trace.jsonconfig
2024-04-16 15:31:19 +03:00
law wang
fadd9d8b81 eth/catalyst: fix log (#29549)
log:output the correct variable

Co-authored-by: steven <steven@stevendeMacBook-Pro.local>
2024-04-16 11:21:20 +02:00
Marius van der Wijden
f437307877 core/vm: update gascosts for BLS12-381 + use gnark instead of kilic (#29441)
This PR updates the bls contracts from our internal implementation which is an unmaintained fork of the kilic library to the gnark-crypto library that is actively maintained by consensys.

It also updates the gas-costs according to the EIP
2024-04-16 10:53:43 +02:00
Darioush Jalali
71c78bf56d rpc: close Clients in tests (#29512) 2024-04-16 10:38:25 +02:00
Marcus Baldassarre
e4ecaf89cf rpc: implement Unwrap() for wsHandshakeError (#29522) 2024-04-16 10:37:18 +02:00
rjl493456442
d3c4466edd core, eth/protocols/snap, trie: fix cause for snap-sync corruption, implement gentrie (#29313)
This pull request defines a gentrie for snap sync purpose.

The stackTrie is used to generate the merkle tree nodes upon receiving a state batch. Several additional options have been added into stackTrie to handle incomplete states (either missing states before or after).

In this pull request, these options have been relocated from stackTrie to genTrie, which serves as a wrapper for stackTrie specifically for snap sync purposes.

Further, the logic for managing incomplete state has been enhanced in this change. Originally, there are two cases handled:

-    boundary node filtering
-    internal (covered by extension node) node clearing

This changes adds one more:
 
- Clearing leftover nodes on the boundaries.

This feature is necessary if there are leftover trie nodes in database, otherwise node inconsistency may break the state healing.
2024-04-16 09:05:36 +02:00
Martin HS
ef5ac3fb7a eth/filters: enforce topic-limit early on filter criterias (#29535)
This PR adds a limit of 1000 to the "inner" topics in a filter-criteria
2024-04-15 17:35:35 +02:00
Seungbae Yu
67422e2a56 p2p/nat: fix typos in comments (#29536) 2024-04-15 14:58:17 +02:00
Martin HS
84b12df09e core/rawdb: add sanity-limit to header accessor (#29534) 2024-04-15 14:54:51 +02:00
yudrywet
3705acd1a9 cmd/utils: fix typo in comment (#29528) 2024-04-15 08:40:42 +02:00
Abirdcfly
b179b7b8e7 all: remove duplicate word in comments (#29531)
This change removes some duplicate words in in comments
2024-04-15 08:34:31 +02:00
forestkeeperio.eth
bd91810462 cmd: fix some typos in readmes (#29405)
* Update README.md

updated for readability

* Update rules.md

Updated for readability and typos
2024-04-11 14:06:49 +03:00
Newt6611
b9010f3e87 rpc: fix comment grammar (#29507) 2024-04-11 11:30:15 +03:00
rjl493456442
9dcf8aae47 eth/protocols/snap: skip retrieval for completed storages (#29378)
* eth/protocols/snap: skip retrieval for completed storages

* eth/protocols/snap: address comments from peter

* eth/protocols/snap: add comments
2024-04-10 12:02:45 +03:00
Aaron Chen
34aac1d756 all: use big.Sign to compare with zero (#29490) 2024-04-09 12:14:30 +02:00
Sina M
f202dfdd47 core/tracing: add changelog (#29388)
Co-authored-by: Matthieu Vachon <matthieu.o.vachon@gmail.com>
2024-04-09 12:12:02 +02:00
Bin
0bbd88bda0 all: use timer instead of time.After in loops, to avoid memleaks (#29241)
time.After is equivalent to NewTimer(d).C, and does not call Stop if the timer is no longer needed. This can cause memory leaks. This change changes many such occations to use NewTimer instead, and calling Stop once the timer is no longer needed.
2024-04-09 08:51:54 +02:00
rjl493456442
1126c6d8a5 core: add txlookup lock (#29343)
This change adds a lock to the transaction lookup cache, to avoid the case where reorgs make the lookup return inconsistent results.
2024-04-09 08:37:18 +02:00
cui
3caf617dcd core/vm: move bls precompiles to correct addresses (#29445)
core: make bls precompiled contract use the correct address as in eip
2024-04-09 08:33:36 +02:00
Mohanson
f447de936c rlp: replace reflect.PtrTo with reflect.PointerTo (#29488)
reflect.PtrTo has been deprecated and superseded by reflect.PointerTo
2024-04-09 08:27:13 +02:00
Aaron Chen
70bf94c34e internal, signer/core: replace path.Join with filepath.Join (#29489) 2024-04-09 08:22:53 +02:00
rjl493456442
c170cc0ab0 core/vm: reject contract creation if the storage is non-empty (#28912)
This change implements EIP-7610, which rejects the contract deployment if the destination has non-empty storage.
2024-04-08 15:48:37 +02:00
seayyyy
3c75c64e6b core: fix typo (#29438) 2024-04-08 13:02:56 +02:00
Sina M
c3465cb5ba core: fix dev mode genesis difficulty (#29469)
The dev mode is nowadays in Merge-mode from genesis, hence the difficulty of the first block should be zero.
2024-04-08 13:01:22 +02:00
Aaron Chen
ed4bc7f27b all: replace fmt.Errorf() with errors.New() if no param required (#29472) 2024-04-08 12:59:17 +02:00
Aaron Chen
cfc7d06cc9 signer/core/apitypes: use slices.Contains (#29474) 2024-04-08 12:58:37 +02:00
imalasong
0dc09da7db all: replace path.Join with filepath.Join (#29479)
* core/rawdb: replace file.Join with filepath.Join

Signed-off-by: xiaochangbai <704566072@qq.com>

* internal/build: replace file.Join with filepath.Join

Signed-off-by: xiaochangbai <704566072@qq.com>

---------

Signed-off-by: xiaochangbai <704566072@qq.com>
2024-04-08 12:29:49 +03:00
Martin HS
7aafad2233 core/vm: better error-info for vm errors (#29354) 2024-04-06 12:22:55 +02:00
Roberto Bayardo
8876868bb8 log: default JSON log handler should log all verbosity levels (#29471)
Co-authored-by: lightclient <lightclient@protonmail.com>
2024-04-06 12:17:41 +02:00
Aaron Chen
ccb76c01d7 eth/tracers: use slices.Contains (#29461) 2024-04-06 12:16:25 +02:00
Aaron Chen
74995bf8a1 all: use slices.Contains (#29459)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-04-06 12:05:06 +02:00
georgehao
cc348a601e common/prque: fix godoc comments (#29460)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-04-06 11:09:30 +02:00
Martin HS
4458905f26 signer/core/apitypes: fix apitypes breakage due to bitrotted PR (#29470) 2024-04-05 21:01:39 +02:00
Martin HS
7ee9a6e89f signer: implement blob txs sendtxargs, enable blobtx-signing (#28976)
This change makes it possible to sign blob transactions
2024-04-05 19:29:44 +02:00
Felföldi Zsolt
35fcf9c52b beacon/types: enforce fork order based on known forks list (#29380)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-04-04 16:30:27 +02:00
Aaron Chen
15ff066a24 trie/utils: change Div+Mod to DivMod (#29413)
* trie/utils: change Div+Mod to DivMod

* trie/utils: gofmt
2024-04-04 16:52:38 +03:00
Péter Szilágyi
e3bdd84e98 core/txpool: repair the limbo Billy too on unclean shutdowns (#29451) 2024-04-04 16:51:10 +03:00
lmittmann
a851e39cbe core/types: use new atomic types in caches (#29411)
* use generic atomic types in tx caches

* use generic atomic types in block caches

* eth/catalyst: avoid copying tx in test

---------

Co-authored-by: lmittmann <lmittmann@users.noreply.github.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-04-04 16:50:31 +03:00
lightclient
9cb8de8703 internal/debug: convert legacy log level value in debug_verbosity (#29356) 2024-04-04 12:26:10 +02:00
cui
9dfe728909 p2p/discover: using slices.Contains (#29395) 2024-04-04 12:24:49 +02:00
guangwu
8bd0334168 crypto/signify: close tmp key file in test (#29444) 2024-04-04 12:20:54 +02:00
cui
2e0c5e05ba p2p/dnsdisc: using clear builtin func (#29418)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-04-04 12:19:48 +02:00
cui
eea0acc549 log: using maps.Clone (#29392) 2024-04-04 11:59:54 +02:00
cui
6b39e9236c beacon/engine: using slices.Contains (#29396) 2024-04-04 11:58:44 +02:00
Marius Kjærstad
1f8f1377e6 build: upgrade -dlgo version to Go 1.22.2 (#29448) 2024-04-04 12:00:27 +03:00
cui
7bb3fb1481 eth: simplify peer counting logic (#29420) 2024-04-03 14:08:52 +08:00
Ng Wei Han
dfb3d46098 p2p: add inbound and outbound peers metric (#29424) 2024-04-02 21:18:28 +02:00
cui
a83e57666d eth/fetcher: using slices.Contains (#29383) 2024-04-02 21:17:34 +02:00
cui
12dcc162d0 common/lru: use clear builtin (#29399) 2024-04-02 15:45:25 +02:00
cui
ab6419ccd8 core/state: use maps.Clone (#29365)
core: using maps.Clone
2024-04-02 15:56:12 +03:00
rjl493456442
fe0bf325a6 cmd/evm: reopen the statedb for dumping (#29437) 2024-04-02 20:25:06 +08:00
cui
0bd03dbc55 eth/filter: using atomic.Pointer instead of atomic.Value (#29435) 2024-04-02 11:25:57 +02:00
Miles Chen
e63f992fed rpc: fix ipc max path size (#29385) 2024-04-02 11:25:19 +02:00
cui
31e63fcf66 rlp: using maps.Clone (#29434) 2024-04-02 10:47:15 +02:00
carehabit
fde90443a4 log: replace the outdated link (#29412) 2024-04-02 15:05:53 +08:00
Delweng
8c5576b1ac eth/tracers: fix base fee and set blob fee in tests (#29376)
Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-04-01 14:53:56 +02:00
cui
6c9f702982 core/types: using maps.Clone (#29398) 2024-04-01 11:45:56 +08:00
cui
c39d00e316 trie: using maps.Clone (#29419) 2024-04-01 11:42:50 +08:00
Brandon Liu
a3829178af eth/tracers/js: consistent name for method receivers (#29375) 2024-03-28 17:35:40 +01:00
cui
0183c7ad82 eth/tracers/logger: using maps.Equal (#29384)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-03-28 14:09:21 +01:00
cui
7481398a24 core/state: using slices.Clone (#29366) 2024-03-28 12:13:41 +01:00
cui
3754a6cc92 p2p/dnsdisc: using maps.Copy (#29377) 2024-03-28 12:07:38 +01:00
rjl493456442
3b77e0ff4b core: remove unused code (#29381) 2024-03-28 12:06:57 +01:00
cui
7aba6511b0 ethdb/dbtest: replace reflect.DeepEqual with slices.Equal (#29382) 2024-03-28 12:06:44 +01:00
Sina M
767b00b0b5 t8ntool: add optional call frames to json logger (#29353)
Adds a flag `--trace.callframes` to t8n which will log info when entering or exiting a call frame in addition to the execution steps.

---------

Co-authored-by: Mario Vega <marioevz@gmail.com>
2024-03-27 16:12:57 +01:00
crazeteam
fa5019de19 accounts/keystore: fix typos in comments (#29336) 2024-03-27 13:16:29 +01:00
Pawan Dhananjay
8bb8f23bb2 beacon/engine: Fix json param name in GetClientVersionV1 (#29351)
Fix json param name
2024-03-27 13:15:57 +01:00
rjl493456442
304879da20 eth/protocols/snap: check storage root existence for hash scheme (#29341) 2024-03-27 09:35:33 +08:00
Guillaume Ballet
da7469e5c4 core: add an end-to-end verkle test (#29262)
core: add a simple verkle test

triedb, core: skip hash comparison in verkle

core: remove legacy daoFork logic in verkle chain maker

fix: nil pointer in tests

triedb/pathdb: add blob hex

core: less defensive

Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Martin HS <martin@swende.se>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-03-26 21:25:41 +01:00
Aaron Chen
723b1e36ad all: fix mismatched names in comments (#29348)
* all: fix mismatched names in comments

* metrics: fix mismatched name in UpdateIfGt
2024-03-26 21:01:28 +01:00
jwasinger
58a3e2f180 core/state: perform updates before deletions when mutating tries (#29201)
This addresses an edge-case (detailed in the code comment) where the computation of the intermediate trie root would force the unnecessary resolution of a hash node. The change makes it so that when we process changes from a block, we first process trie-updates and afterwards process trie-deletions.
2024-03-26 15:21:39 +01:00
Martin HS
1dd898c24e tests: fix panic via state test runner using json logger (#29349)
* tests: fix panic via state test runner using json logger

* tests: also invoke OnTxEnd
2024-03-26 15:04:15 +01:00
Aaron Chen
f2a6ac17b2 eth/catalyst: fix flaw in withdrawal-gathering in simulated beacon (#29344)
return after reaching maxCount
2024-03-26 12:26:44 +01:00
Matthieu Vachon
738b5a586e Removes some leftover err check (#29339)
Before, `ToMessage` was returning both the resulting `Message` and an error while no error is returned now.

Those error checks were probably leftover from the past.
2024-03-26 12:01:13 +08:00
Felföldi Zsolt
100c0f47de beacon/blsync: fixed blsync command line params (#29335) 2024-03-25 20:28:55 +01:00
Felix Lange
eda9cb7b36 beacon/light/api: improve handling of event stream setup failures (#29308)
The StartHeadListener method will only be called once. So it can't just make one attempt
to connect to the eventsource endpoint, it has to keep trying. Note that once the stream
is established, the eventsource implementation itself will keep retrying.
2024-03-25 20:27:50 +01:00
Roberto Bayardo
5cea7a6230 ethclient/simulated: clean up Node resources when simulated backend is closed (#29316) 2024-03-25 18:03:44 +01:00
Martin HS
14cc967d19 all: remove dependency on golang.org/exp (#29314)
This change includes a leftovers from https://github.com/ethereum/go-ethereum/pull/29307
- using the [new `slices` package](https://go.dev/doc/go1.21#slices) and
- using the [new `cmp.Ordered`](https://go.dev/doc/go1.21#cmp) instead of exp `constraints.Ordered`
2024-03-25 07:50:18 +01:00
deterclosed
ae47004487 eth: fix typo (#29320) 2024-03-25 10:16:44 +08:00
Nathan
6f1fb0c29f metrics/influxdb: skip float64-precision-dependent tests on arm64 (#29047)
metrics/influxdb: fix failed cases caused by float64 precision on arm64
2024-03-24 13:51:34 +01:00
Sina M
064f37d6f6 eth/tracers: live chain tracing with hooks (#29189)
Here we add a Go API for running tracing plugins within the main block import process. 

As an advanced user of geth, you can now create a Go file in eth/tracers/live/, and within
that file register your custom tracer implementation. Then recompile geth and select your tracer
on the command line. Hooks defined in the tracer will run whenever a block is processed.

The hook system is defined in package core/tracing. It uses a struct with callbacks, instead of 
requiring an interface, for several reasons:

- We plan to keep this API stable long-term. The core/tracing hook API does not depend on
  on deep geth internals.
- There are a lot of hooks, and tracers will only need some of them. Using a struct allows you
   to implement only the hooks you want to actually use.

All existing tracers in eth/tracers/native have been rewritten to use the new hook system.

This change breaks compatibility with the vm.EVMLogger interface that we used to have.
If you are a user of vm.EVMLogger, please migrate to core/tracing, and sorry for breaking
your stuff. But we just couldn't have both the old and new tracing APIs coexist in the EVM.

---------

Co-authored-by: Matthieu Vachon <matthieu.o.vachon@gmail.com>
Co-authored-by: Delweng <delweng@gmail.com>
Co-authored-by: Martin HS <martin@swende.se>
2024-03-22 18:53:53 +01:00
George Ma
38eb8b3e20 all: fix docstrings (#29311) 2024-03-22 20:29:12 +08:00
Martin HS
d9bde37ac3 log: use native log/slog instead of golang/exp (#29302) 2024-03-22 13:17:59 +01:00
rjl493456442
6490d9897a cmd, triedb: implement history inspection (#29267)
This pull request introduces a database tool for inspecting the state history. 
It can be used for either account history or storage slot history, within a 
specific block range.

The state output format can be chosen either with

- the "rlp-encoded" values (those inserted into the merkle trie)
- the "rlp-decoded" value (the raw state value)

The latter one needs --raw flag.
2024-03-22 20:12:10 +08:00
Darioush Jalali
f46fe62c5d triedb/hashdb: Avoid setting db.cleans on Close (#29309) 2024-03-22 19:38:24 +08:00
Martin HS
14eb8967be all: use min/max/clear from go1.21 (#29307) 2024-03-21 13:50:13 +01:00
Felix Lange
bca6c40709 beacon/blsync: support for deneb fork (#29180)
This adds support for the Deneb beacon chain fork, and fork handling
in general, to the beacon chain light client implementation.

Co-authored-by: Zsolt Felfoldi <zsfelfoldi@gmail.com>
2024-03-20 19:22:44 +01:00
Martin HS
04bf1c802f eth/protocols/snap, internal/testlog: fix dataraces (#29301) 2024-03-20 15:22:52 +01:00
Marius van der Wijden
8f7fbdfedc core: refactor consensus interface (#29283)
This PR modifies the consensus interface to wrap the body fields.
2024-03-20 14:58:47 +01:00
Aaron Chen
0444388c74 core/txpool/blobpool: calculate log1.125 faster (#29300) 2024-03-20 14:51:05 +01:00
rjl493456442
78c102dec5 core: skip the check the statefulness of head block in repair (#29245) 2024-03-20 13:11:30 +01:00
imalasong
22ac46cbdb Makefile: update PHONY directive (#29296) 2024-03-20 13:09:46 +01:00
Martin HS
9a7e6ce6f5 cmd/evm: fix flag-mismatch from #29290 (#29298) 2024-03-20 10:38:30 +01:00
Martin HS
de08f3d625 cmd/evm: make staterunner always output stateroot to stderr (#29290)
This changes makes it so that when `evm statetest` executes, regardless of whether `--json` is specified or not, the stateroot is printed on `stderr` as a `jsonl` line. This enables speedier execution of testcases in goevmlab, in cases where full execution op-by-op is not required.
2024-03-20 09:12:58 +01:00
georgehao
0ceac8d00e metrics: fix docstrings (#29279) 2024-03-20 08:51:45 +01:00
miles
45b88abbde all: fix typos (#29288) 2024-03-20 08:49:38 +01:00
zgfzgf
6f929a0762 core/asm: minor code-clarification (#29293) 2024-03-20 08:46:50 +01:00
buddho
4c1b57856f miner: modify header before checking time-based fields (#29242)
The Prepare-method of consensus engine might modify the time-field in a header, so it should be called prior to checks that rely on it
2024-03-19 15:23:55 +01:00
Tien Nguyen
eda9c7e36f accounts/abi/bind: check invalid chainID first (#29275) 2024-03-19 14:05:31 +01:00
bitcoin-lightning
6b3d4d068a beacon/light/sync: fix typo in comment (#29256) 2024-03-19 14:05:06 +01:00
Aaron Chen
ac6060a4c6 log: replace tmp with bytes.Buffer.AvailableBuffer (#29287) 2024-03-19 11:25:30 +01:00
rjl493456442
15eb9773f9 triedb/pathdb: improve tests (#29278) 2024-03-19 10:50:08 +08:00
Martin HS
ab49f228ad all: update to go version 1.22.1 (#28946)
Since Go 1.22 has deprecated certain elliptic curve operations, this PR removes 
references to the affected functions and replaces them with a custom implementation
in package crypto. This causes backwards-incompatible changes in some places.

---------

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-03-18 17:36:50 +01:00
Martin HS
c611924727 go.mod: update protobuf (#29270) 2024-03-18 08:13:55 +01:00
SanYe
ba2dd9385c accounts/abi/bind: remove unused err set and check (#29269)
accounts/abi: remove unused err set and check
2024-03-15 10:46:22 +01:00
Martin HS
40cac1d0e2 eth/catalyst: prettier output on bad new payloads (#29259)
When we receive a bad NewPayload, we currently emit a lot of data to the logging facilities. This PR makes it so we print less data.
2024-03-15 10:44:41 +01:00
shivhg
95715fdb03 eth/downloader, graphql: fix typos (#29243) 2024-03-15 10:07:47 +01:00
Haotian
cffb7c8604 params: use the same variable name as EIP-4788 (#29195)
In https://eips.ethereum.org/EIPS/eip-4788 the name `BEACON_ROOTS_ADDRESS` is used. This change makes geth use the same variable name to avoid confusion.
2024-03-15 09:14:31 +01:00
John Xu
d28adb61bf cmd/emv/internal/t8ntool: fix shadowing of excessBlobGas (#29263)
fix(t8n): unexpected `excessBlobGas` shadowed
2024-03-14 14:38:11 +01:00
Ng Wei Han
20d3e0ac06 cmd/devp2p: fix decoding of raw RLP ENR attributes (#29257) 2024-03-14 10:32:49 +01:00
Haotian
3c26ffeb29 eth/catalyst: remove error return in delayPayloadImport (#29043)
Co-authored-by: tmelhao <tmelhao@gmail.com>
2024-03-14 00:26:46 +01:00
Bin
57308beecf go.mod: update golang.org/x/crypto from v0.17.0 to v0.21.0 (#29228) 2024-03-14 00:25:42 +01:00
Martin HS
f3d18d64bf tests, appveyor: only execute one in four permutations on CI (#29220)
tests, appveyor: only execute one in four permutations when flag -short is used

Also enable -short flag on all appveyor builds (also ubuntu)
2024-03-13 18:12:23 +01:00
rjl493456442
c170fa277c core: improve chain rewinding mechanism (#29196)
* core: improve chain rewinding mechanism

* core: address comment

* core: periodically print progress log

* core: address comments

* core: fix comment

* core: fix rewinding in path

* core: fix beyondRoot condition

* core: polish code

* core: polish code

* core: extend code comment

* core: stop rewinding if chain is gapped or genesis is reached

* core: fix broken tests
2024-03-13 13:39:30 +02:00
Justin Dhillon
b80643b737 accounts/usbwallet, common/bitutil: fix broken links in docs (#29078)
fixes some links in documentation
2024-03-13 07:54:40 +01:00
Martin HS
d5bacfa4de crypto/kz4844: pass blobs by ref (#29050)
This change makes use of the following underlying changes to the kzg-libraries in order to avoid passing large things on the stack:

- c-kzg: https://github.com/ethereum/c-kzg-4844/pull/393 and
- go-kzg: https://github.com/crate-crypto/go-kzg-4844/pull/63
2024-03-13 07:51:46 +01:00
Sina M
eff424cc30 eth/tracers: fix concurrency issue for JS-tracing a block (#29238)
This change fixes a concurrency-issue where JS-tracers were accessing the block-ctx GetHash function in a in parallel, which is not safe.
2024-03-13 07:40:02 +01:00
Felix Lange
758fce71fa p2p: fix race in dialScheduler (#29235)
Co-authored-by: Stefan <stefan@starflinger.eu>
2024-03-12 19:23:24 +01:00
Marius van der Wijden
6c76b813df miner: add additional log (#29193)
Adds a debug level log if the payload building failed for whatever reason
2024-03-12 14:29:35 +01:00
Aaron Chen
4bd55a064c common/math: copy result in Exp (#29233)
common/math: does not change base parameter
2024-03-12 13:05:31 +01:00
Shiming Zhang
99bbbc0277 internal/build, rpc: add missing HTTP response body Close() calls (#29223)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-03-12 12:12:37 +01:00
Bin
89cefe240f cmd: use package filepath over path for file system operations (#29227)
Package filepath implements utility routines for manipulating filename paths in a way compatible with the target operating system-defined file paths.

Package path implements utility routines for manipulating slash-separated paths.

The path package should only be used for paths separated by forward slashes, such as the paths in URLs
2024-03-12 10:00:34 +01:00
San Ye
4e1116f9c5 crypto/bn256/cloudflare: fix noescape-directive (#29222) 2024-03-12 09:49:53 +01:00
guangwu
ebf9e11af2 beacon/light/request: fix typos (#29216) 2024-03-11 11:17:16 +01:00
Sina Mahmoodi
fa4ade8ecb core: fix deprecation comment for GenesisAccount (#29218)
core: fix deprecation comment
2024-03-11 12:05:48 +02:00
Lee Bousfield
00c21128ef core/txpool/blobpool: return ErrAlreadyKnown for duplicate txs (#29210)
Signed-off-by: Lee Bousfield <ljbousfield@gmail.com>
2024-03-11 12:05:17 +02:00
Péter Szilágyi
b393ad8d29 cmd, core, metrics: always report expensive metrics (#29191)
* cmd, core, metrics: always report expensive metrics

* core, metrics: report block processing metrics as resetting timer

* metrics: update reporter tests
2024-03-11 10:06:57 +02:00
Kero
3dc549b3d7 p2p/simulations/adapters: fix error messages in TestTCPPipeBidirections (#29207) 2024-03-10 20:01:26 +01:00
Haotian
e31709db65 console: fix the wrong error msg of datadir testcase (#29183) 2024-03-08 12:15:52 +01:00
colin
d35c8f0c25 ethclient/gethclient: add blob transaction fields in toCallArg (#29198) 2024-03-08 12:13:46 +01:00
Sebastian Stammler
c41105ce80 log: add Handler getter to Logger interface (#28793)
log: Add Handler getter to Logger interface
2024-03-08 00:01:31 +01:00
hyhnet
cd490608e3 all: fix typos in comments (#29186) 2024-03-07 22:56:19 +01:00
cuinix
3bebabbd03 accounts: remove redundant string conversion (#29184) 2024-03-07 22:25:08 +01:00
Felföldi Zsolt
aadcb88675 cmd/blsync, beacon/light: beacon chain light client (#28822)
Here we add a beacon chain light client for use by geth.

Geth can now be configured to run against a beacon chain API endpoint,
without pointing a CL to it. To set this up, use the `--beacon.api` flag. Information
provided by the beacon chain is verified, i.e. geth does not blindly trust the beacon
API endpoint in this mode. The root of trust are the beacon chain 'sync committees'.

The configured beacon API endpoint must provide light client data. At this time, only
Lodestar and Nimbus provide the necessary APIs.

There is also a standalone tool, cmd/blsync, which uses the beacon chain light client
to drive any EL implementation via its engine API.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-03-06 17:50:22 +01:00
Marius van der Wijden
d8e0807da2 miner: refactor the miner, make the pending block on demand (#28623)
* miner: untangle miner

* miner: use common.hash instead of *types.header

* cmd/geth: deprecate --mine

* eth: get rid of most miner api

* console: get rid of coinbase in welcome message

* miner/stress: get rid of the miner stress test

* eth: get rid of miner.setEtherbase

* ethstats: remove miner and hashrate flags

* ethstats: remove miner and hashrate flags

* cmd: rename pendingBlockProducer to miner.pending.feeRecipient flag

* miner: use pendingFeeRecipient instead of etherbase

* miner: add mutex to protect the pending block

* miner: add mutex to protect the pending block

* eth: get rid of etherbase mentions

* miner: no need to lock the coinbase

* eth, miner: fix linter

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-03-06 14:45:03 +02:00
Delweng
6e379b6fc7 eth/tracers: prestate tracer add blob fee (#29168)
* eth/tracers: prestate balance add blob fee

Signed-off-by: jsvisa <delweng@gmail.com>

* eth/tracers: prestate test support blob tx

Signed-off-by: jsvisa <delweng@gmail.com>

* eth/tracers: add prestate blob tx test

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2024-03-06 14:36:12 +02:00
Undefinedor
a90fe84971 accounts: remove deprecated function NewPlaintextKeyStore (#29171) 2024-03-06 11:55:44 +01:00
Martin HS
e73f55365c accounts/usbwallet: update hid library (#29176) 2024-03-06 12:31:50 +02:00
Andrei Kostakov
a000acb611 rpc: add more test cases for arg types (#29006) 2024-03-06 10:53:12 +01:00
Martin HS
899bb88a4b accounts/usbwallet: revert #28945 (#29175) 2024-03-06 11:32:17 +02:00
Tom
588c5480fd internal/ethapi: delete needless error check (#29127) 2024-03-06 13:23:35 +08:00
Devon Bear
66e1a6ef49 go.mod: bump pebble db to official release (#29038)
bump pebble
2024-03-05 16:15:02 +02:00
Péter Szilágyi
f4d53133f6 consensus, cmd, core, eth: remove support for non-merge mode of operation (#29169)
* eth: drop support for forward sync triggers and head block packets

* consensus, eth: enforce always merged network

* eth: fix tx looper startup and shutdown

* cmd, core: fix some tests

* core: remove notion of future blocks

* core, eth: drop unused methods and types
2024-03-05 16:13:28 +02:00
Marius van der Wijden
9a0fa8093c node: remove test which doesn't do a lot (#29159)
* node: fix test if directory already exists

* node: remove test
2024-03-05 14:52:44 +01:00
zhiqiangxu
9e129efd7b core: remove useless assignments (#29065) 2024-03-05 14:48:27 +01:00
cui
a970295956 rlp: using unsafe.Slice instead of SliceHeader (#29067)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-03-05 14:45:17 +01:00
Undefinedor
a6d6e8ac41 rpc: remove deprecated method "Notifier.Closed" (#29162) 2024-03-05 14:44:23 +01:00
Delweng
dfa6c5e9c8 internal/jsre: format blob fields from hexdecimal to int (#29166)
* internal/jsre: format receipt.{blobGasPrice,blobGasUsed} to int

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/jsre: format tx.maxFeePerBlobGas to int

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/jsre: format blob* in block

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2024-03-05 15:37:26 +02:00
Martin HS
96bf23f1ea accounts/usbwallet: use updated hid (only) library (#28945)
* accounts/usbwallet: use updated hid (only) library

* deps: update karalabe/hid
2024-03-05 14:32:47 +01:00
rjl493456442
7b81cf6362 core/state, trie/triedb/pathdb: remove storage incomplete flag (#28940)
As SELF-DESTRUCT opcode is disabled in the cancun fork(unless the
account is created within the same transaction, nothing to delete
in this case). The account will only be deleted in the following
cases:

- The account is created within the same transaction. In this case
the original storage was empty.

- The account is empty(zero nonce, zero balance, zero code) and
is touched within the transaction. Fortunately this kind of accounts
are not-existent on ethereum-mainnet.

All in all, after cancun, we are pretty sure there is no large contract
deletion and we don't need this mechanism for oom protection.
2024-03-05 14:31:55 +01:00
buddho
e199319fd6 rlp: remove a moot todo (#29154) 2024-03-05 10:47:56 +01:00
zhiqiangxu
d89d7ebdec core: initialize gasRemaining with = instead of += (#29149)
initialize gasRemaining with = instead of +=
2024-03-05 09:47:58 +01:00
Vie
9b3ceb2137 core/types: reuse signtx (#29152)
* core/types: reuse signtx

* core/types: inline signtx
2024-03-05 09:33:52 +02:00
Domino Valdano
5d5b384efd .mailmap: remove invalid email address (#29163) 2024-03-04 21:58:25 +01:00
Andrei Silviu Dragnea
19607d1a10 eth/tracers: Fix prestateTracer pre nonce on contract creation (#29099)
The prestateTracer was reporting an inaccurate nonce for the contract being created in
post EIP-158 transactions. Correct nonce is 0, due to the issue nonce was being reported as 1.
2024-03-04 20:21:43 +01:00
rjl493456442
ca473b81cb core: use finalized block as the chain freeze indicator (#28683)
* core: use finalized block as the chain freeze indicator

* core/rawdb: use max(finality, head-90k) as chain freezing threshold

* core/rawdb: fix tests

* core/rawdb: fix lint

* core/rawdb: address comments from peter

* core/rawdb: fix typo
2024-03-04 16:25:53 +02:00
Felix Lange
a97d622588 cmd/devp2p: fix commandHasFlag (#29091)
It got broken in some update of the cli library, and thus bootnodes weren't 
being configured automatically for some of the discovery commands.
2024-03-04 14:07:41 +01:00
psogv0308
35cebc1687 triedb/pathdb: changed the test code to check for verifying state (#29150)
Co-authored-by: this-is-iron <iron@superblock.co>
2024-03-04 11:03:53 +01:00
buddho
679a27a2b3 all: use EmptyUncleHash, EmptyCodeHash instead of raw value (#29134) 2024-03-04 10:31:18 +01:00
cui
5a1e8a6547 core: delete unused ErrMaxInitCodeSizeExceeded (#29062) 2024-03-04 10:30:15 +01:00
yzb
b408b3e5fe accounts/abi: delete duplicate error check (#29136) 2024-03-04 10:24:24 +01:00
yzb
a732ad0364 p2p: remove unused argument 'flags' (#29132) 2024-03-04 10:16:05 +01:00
Undefinedor
00905f7dc4 all: remove redundant import aliases (#29144) 2024-03-02 22:42:50 +02:00
Péter Szilágyi
0b1438c3df eth: make transaction propagation paths in the network deterministic (#29034)
* eth: make transaction propagation paths in the network deterministic

* eth: avoid potential division by 0

* eth: make tx propagation dependent on local node id too

* eth: fix review comments
2024-03-02 22:39:22 +02:00
Sina Mahmoodi
0a2f33946b eth/catalyst: update simulated beacon for cancun (#28829)
* eth/catalyst: update simulated beacon for cancun

* validate blob hashes

* compute hashes from commitment

* fix beacon root and payload version

* check commitment conversion

* fix random attr

* flip dev to cancun
2024-02-29 14:17:32 +02:00
Péter Szilágyi
865e1e9f57 cmd/utils, core/rawdb, triedb/pathdb: flip hash to path scheme (#29108)
* cmd/utils, core/rawdb, triedb/pathdb: flip hash to path scheme

* graphql: run tests in hash mode as the chain maker needs it
2024-02-29 12:40:59 +02:00
yzb
db4cf69166 all: replace fmt.Errorf() with errors.New() if no param required (#29126)
replace-fmt-errorf

Co-authored-by: yzb@example.cn <yzb@example.cn>
2024-02-29 11:56:46 +02:00
Ng Wei Han
28d55218f7 cmd/geth: parseDumpConfig should not return closed db (#29100)
* cmd: parseDumpConfig should not return closed db

* fix lint
2024-02-29 11:56:17 +02:00
cui fliter
dbc27a199f all: fix function names in docs (#29128)
Signed-off-by: cui fliter <imcusg@gmail.com>
2024-02-29 11:29:06 +02:00
lightclient
1883438964 eth/catalyst: return invalid payload attributes instead of invalid parms for bad fcu payload (#29115) 2024-02-28 19:59:16 +01:00
buddho
9986a69c25 internal/ethapi: pass in accesslist in test (#29089)
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2024-02-28 18:38:21 +01:00
rjl493456442
5bae14f9df triedb/pathdb: fix panic in recoverable (#29107)
* triedb/pathdb: fix panic in recoverable

* triedb/pathdb: add todo

* triedb/pathdb: rename

* triedb/pathdb: rename
2024-02-28 14:40:28 +02:00
rjl493456442
49623bd469 core, triedb/pathdb: calculate the size for batch pre-allocation (#29106)
* core, triedb/pathdb: calculate the size for batch pre-allocation

* triedb/pathdb: address comment
2024-02-28 14:23:52 +02:00
Péter Szilágyi
170fcd80c6 params: being major version bump cycle 2024-02-28 10:01:52 +02:00
cui
02d77c98f9 core: using math.MaxUint64 instead of 0xffffffffffffffff (#29094) 2024-02-28 15:25:12 +08:00
Péter Szilágyi
57d2b552c7 params: begin v1.13.15 cycle 2024-02-27 13:53:30 +02:00
Péter Szilágyi
9038ba6942 params: release Geth v1.13.14 2024-02-27 13:50:30 +02:00
Roberto Bayardo
51b479e564 core/txpool: elevate the 'already reserved' error into a constant (#29095)
declare the 'already reserved' error in errors.go
2024-02-27 13:27:50 +02:00
Andrei Silviu Dragnea
5a0f468f8c eth/tracers: Fix callTracer logs on onlyTopCall == true (#29068) 2024-02-27 10:29:12 +01:00
Delweng
45a272c7b9 core/txpool: no need to log loud rotate if no local txs (#29083)
* core/txpool: no need to run rotate if no local txs

Signed-off-by: jsvisa <delweng@gmail.com>

* Revert "core/txpool: no need to run rotate if no local txs"

This reverts commit 17fab17388.

Signed-off-by: jsvisa <delweng@gmail.com>

* use Debug if todo is empty

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2024-02-26 18:34:45 +02:00
Péter Szilágyi
63aaac8100 core/txpool/blobpool: reduce default database cap for rollout (#29090)
xcore/txpool/blobpool: reduce default database cap for rollout
2024-02-26 14:27:56 +02:00
cui
c1f59b98f6 eth/catalyst: remove variable in tx conversion loop (#29076) 2024-02-26 13:22:13 +01:00
Justin Dhillon
821d70240d cmd/clef: add spaces in README.md table (#29077)
Add space after links in so they are clickable in vscode.
2024-02-26 11:03:59 +01:00
maskpp
8bca93e82c internal/ethapi: pass blob hashes to gas estimation (#29085) 2024-02-26 11:02:18 +01:00
cui
edffacca8f eth/catalyst: enable some commented-out testcases   (#29073) 2024-02-26 10:59:03 +01:00
Qt
26724fc2aa p2p, log, rpc: use errors.New to replace fmt.Errorf with no parameters (#29074) 2024-02-26 11:25:35 +02:00
Roberto Bayardo
32d4d6e616 core/txpool: reject blob txs with blob fee cap below the minimum (#29081)
* make blobpool reject blob transactions with fee below the minimum

* core/txpool: some minot nitpick polishes and unified error formats

* core/txpool: do less big.Int constructions with the min blob cap

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2024-02-26 11:06:52 +02:00
Haotian
93c541ad56 eth/catalyst: fix wrong error message of payloadV2 after cancun (#29049)
* eth/catalyst: the same error format

Signed-off-by: tmelhao <tmelhao@gmail.com>

* eth/catalyst: wrong error message for payloadV2 post-cancun

Signed-off-by: tmelhao <tmelhao@gmail.com>

* eth/catalyst: parentBeaconBlockRoot -> parentBlockBeaconRoot

Signed-off-by: tmelhao <tmelhao@gmail.com>

* apply commit review

Signed-off-by: tmelhao <tmelhao@gmail.com>

---------

Signed-off-by: tmelhao <tmelhao@gmail.com>
Co-authored-by: tmelhao <tmelhao@gmail.com>
2024-02-23 10:57:47 +02:00
colin
b87b9b4533 internal/ethapi:fix zero rpc gas cap in eth_createAccessList (#28846)
This PR enhances eth_createAccessList RPC call to support scenarios where the node is launched with an unlimited gas cap (--rpc.gascap 0). The eth_createAccessList RPC call returns failure if user doesn't explicitly set a gas limit.
2024-02-22 16:35:23 +01:00
ArtificialPB
e47a7c22c4 internal/ethapi: use overriden baseFee for gasPrice (#29051)
eth_call and debug_traceCall allow users to override various block fields, among them base fee. However the overriden base fee was not considered for computing the effective gas price of that message, and instead base fee of the base block was used. This has been fixed in this commit.
2024-02-22 14:39:22 +01:00
Felix Lange
b590cae892 params: begin v1.13.14 release cycle 2024-02-21 15:49:50 +01:00
Felix Lange
3b4ede7444 params: release go-ethereum v1.13.13 stable 2024-02-21 15:44:02 +01:00
Sina Mahmoodi
b47cf8fe1d internal/ethapi: fix defaults for blob fields (#29037)
Co-authored-by: Martin HS <martin@swende.se>
2024-02-21 12:46:32 +01:00
colin
b9ca38b735 core/txpool: fix typo (#29036)
* fix typos

* address comments
2024-02-21 10:00:01 +02:00
Haotian
79e340fb12 params: add cancun upgrade banner (#29042)
params: add cancun banner

Signed-off-by: tmelhao <tmelhao@gmail.com>
Co-authored-by: tmelhao <tmelhao@gmail.com>
2024-02-21 09:59:21 +02:00
buddho
bba3fa9af9 core,eth,internal: fix typo (#29024) 2024-02-20 19:42:48 +08:00
buddho
7f5e96dc6c core/txpool: fix typo (#29031) 2024-02-20 12:08:56 +02:00
Péter Szilágyi
f4852b8ddc core/txpool, eth, miner: retrieve plain and blob txs separately (#29026)
* core/txpool, eth, miner: retrieve plain and blob txs separately

* core/txpool: fix typo, no farming

* miner: farm all the typos

Co-authored-by: Martin HS <martin@swende.se>

---------

Co-authored-by: Martin HS <martin@swende.se>
2024-02-20 11:37:23 +02:00
Martin HS
ac0ff04460 core/vm, params: ensure order of forks, prevent overflow (#29023)
This PR fixes an overflow which can could happen if inconsistent blockchain rules were configured. Additionally, it tries to prevent such inconsistencies from occurring by making sure that merge cannot be enabled unless previous fork(s) are also enabled.
2024-02-19 16:29:59 +01:00
Péter Szilágyi
6fb0d0992b core/txpool, miner: speed up blob pool pending retrievals (#29008)
* core/txpool, miner: speed up blob pool pending retrievals

* miner: fix test merge issue

* eth: same same

* core/txpool/blobpool: speed up blobtx creation in benchmark a bit

* core/txpool/blobpool: fix linter

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-02-19 15:59:40 +02:00
cui
5d984796af core: using math.MaxUint64 instead of 0xffffffffffffffff (#29022) 2024-02-19 13:03:58 +01:00
rjl493456442
034bc4669f ethstats: prevent panic if head block is not available (#29020)
This pull request fixes a flaw in ethstats which can lead to node crash

A panic could happens when the local blockchain is reorging which causes the original head block not to be  reachable (since number->hash canonical mapping is deleted). In order to prevent the panic, the block nilness is now checked in ethstats.
2024-02-19 07:25:53 +01:00
Péter Szilágyi
593e303485 core/txpool, eth, miner: pre-filter dynamic fees during pending tx retrieval (#29005)
* core/txpool, eth, miner: pre-filter dynamic fees during pending tx retrieval

* miner: fix typo

* core/txpool: handle init-error in blobpool without panicing

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-02-17 13:37:14 +02:00
Sina Mahmoodi
95741b1844 core: move genesis alloc types to core/types (#29003)
We want to use these types in public user-facing APIs, so they shouldn't be in core.

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-02-16 19:05:33 +01:00
Péter Szilágyi
3c30de219f core/txpool/blobpool: update the blob db with corruption handling (#29001)
Updates billy to a more recent version which is more robust in the face of corrupt data (e.g. after a hard crash)
2024-02-16 16:33:14 +01:00
colin
a193bb0c73 core/txpool/legacypool: remove a redundant heap.Init (#28910)
Co-authored-by: Martin HS <martin@swende.se>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-02-15 19:50:17 +01:00
Felix Lange
1bdf8b9b2d cmd/devp2p/internal/ethtest: some fixes for the eth test suite (#28996)
Improving two things here:

On hive, where we look at these tests, the Go code comment above the test
is not visible. When there is a failure, it's not obvious what the test is actually
expecting. I have converted the comments in to printed log messages to
explain the test more.

Second, I noticed that besu is failing some tests because it happens to request
a header when we want it to send transactions. Trying the minimal fix here to
serve the headers.

Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
2024-02-15 19:43:37 +01:00
alex
0c412dcd1f cmd/evm: fix typo in test script (#28995) 2024-02-15 15:54:40 +01:00
Marius van der Wijden
286090689a eth/catalyst: add getClientVersion to capabilities (#28994) 2024-02-15 14:43:45 +01:00
Martin HS
886f0e72e5 tests: update execution spec tests + split statetest exec (#28993) 2024-02-15 13:30:11 +01:00
lightclient
9e3e46671e eth/catalyst,beacon/engine: implement GetClientVersionV1 (#28915) 2024-02-15 12:01:30 +01:00
colin
2a1d94bd1d cmd/devp2p: fix modulo in makeBlobTxs (#28970) 2024-02-15 10:22:03 +01:00
bk
efddedc16c core/txpool/blobpool: rename variables in comments (#28981)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-02-15 10:20:10 +01:00
maskpp
9d537f5439 ethereum, ethclient: add blob transaction fields in CallMsg (#28989)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-02-15 10:08:46 +01:00
Martin HS
8321fe2fda tests: fix goroutine leak related to state snapshot generation (#28974)
---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2024-02-14 17:02:56 +01:00
Martin HS
55a46c3b10 cmd/utils: fix merge-breakage in test (#28985) 2024-02-14 09:26:53 +01:00
rjl493456442
fe91d476ba all: remove the dependency from trie to triedb (#28824)
This change removes the dependency from trie package to triedb package.
2024-02-13 14:49:53 +01:00
Lindlof
4c15d58007 internal/ethapi, signer/core: fix documentation-links (#28979)
fix: management api links
2024-02-13 10:14:18 +01:00
Ng Wei Han
beb2954fa4 core/txpool/legacypool: use uint256.Int instead of big.Int (#28606)
This change makes the legacy transaction pool use of `uint256.Int` instead of `big.Int`. The changes are made primarily only on the internal functions of legacypool. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-02-13 10:10:11 +01:00
maskpp
f1c27c286e internal/ethapi: fix gas estimation bug in eth_fillTransaction for blob tx (#28929) 2024-02-09 20:53:04 +01:00
Peter Straus
1a79089193 fix: update outdated link to trezor docs (#28966)
fix: update link to trezor
2024-02-09 19:30:56 +01:00
Martin HS
f0c5b6765d build: remove ubuntu 'lunar' build (#28962) 2024-02-09 13:15:11 +01:00
Martin Holst Swende
89575aeb4b params: begin v1.13.13 release cycle 2024-02-09 08:39:15 +01:00
Martin Holst Swende
8facf44109 params: go-ethereum v1.13.12 stable 2024-02-09 07:51:43 +01:00
lightclient
85938dda09 internal/era: update block index format to be based on record offset (#28959)
As mentioned in #26621, the block index format for era1 is not in line with the regular era block index. This change modifies the index so all relative offsets are based against the beginning of the block index record.
2024-02-09 07:42:50 +01:00
Sina Mahmoodi
ac5aa672d3 internal/ethapi: add support for blobs in eth_fillTransaction (#28839)
This change adds support for blob-transaction in certain API-endpoints, e.g. eth_fillTransaction. A follow-up PR will add support for signing such transactions.
2024-02-08 19:53:32 +01:00
lightclient
2732fb10d2 params, core/forkid: add mainnet timestamp for Cancun (#28958)
* params: add cancun timestamp for mainnet

* core/forkid: add test for mainnet cancun forkid

* core/forkid: update todo tests for cancun
2024-02-08 19:36:38 +01:00
Péter Szilágyi
8a76a814a2 cmd/devp2p, eth: drop support for eth/67 (#28956) 2024-02-08 15:49:19 +02:00
Felix Lange
ae3b7a0b65 eth/gasprice: fix percentile validation in eth_feeHistory (#28954) 2024-02-08 13:34:38 +01:00
alex
2dc33d46b8 ethclient/simulated: fix typo (#28952)
(ethclient/simulated):fix typo
2024-02-08 12:25:13 +02:00
zoereco
2ab365f6d8 all: fix docstring names (#28923)
* fix wrong comment

* reviewers input

* Update log/handler_glog.go

---------

Co-authored-by: Martin HS <martin@swende.se>
2024-02-07 21:10:49 +01:00
Felix Lange
69f5d5ba1f node, rpc: add configurable HTTP request limit (#28948)
Adds a configurable HTTP request limit, and bumps the engine default
2024-02-07 21:06:38 +01:00
lightclient
449d3f0d87 core,params: add holesky to default genesis function (#28903) 2024-02-07 17:19:14 +01:00
lightclient
1f50aa7631 cmd,internal/era: implement export-history subcommand (#26621)
* all: implement era format, add history importer/export

* internal/era/e2store: refactor e2store to provide ReadAt interface

* internal/era/e2store: export HeaderSize

* internal/era: refactor era to use ReadAt interface

* internal/era: elevate anonymous func to named

* cmd/utils: don't store entire era file in-memory during import / export

* internal/era: better abstraction between era and e2store

* cmd/era: properly close era files

* cmd/era: don't let defers stack

* cmd/geth: add description for import-history

* cmd/utils: better bytes buffer

* internal/era: error if accumulator has more records than max allowed

* internal/era: better doc comment

* internal/era/e2store: rm superfluous reader, rm superfluous testcases, add fuzzer

* internal/era: avoid some repetition

* internal/era: simplify clauses

* internal/era: unexport things

* internal/era,cmd/utils,cmd/era: change to iterator interface for reading era entries

* cmd/utils: better defer handling in history test

* internal/era,cmd: add number method to era iterator to get the current block number

* internal/era/e2store: avoid double allocation during write

* internal/era,cmd/utils: fix lint issues

* internal/era: add ReaderAt func so entry value can be read lazily

Co-authored-by: lightclient <lightclient@protonmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>

* internal/era: improve iterator interface

* internal/era: fix rlp decode of header and correctly read total difficulty

* cmd/era: fix rebase errors

* cmd/era: clearer comments

* cmd,internal: fix comment typos

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2024-02-07 09:18:27 -07:00
lmittmann
199e0c9ff5 core/state, core/vm: minor uint256 related perf improvements (#28944) 2024-02-07 17:01:38 +01:00
Péter Szilágyi
16ce7bf50f eth, miner: fix enforcing the minimum miner tip (#28933)
* eth, miner: fix enforcing the minimum miner tip

* ethclient/simulated: fix failing test due the min tip change

* accounts/abi/bind: fix simulater gas tip issue
2024-02-06 10:59:24 +02:00
rjl493456442
0b5d8d2b58 core: cache transaction indexing tail in memory (#28908) 2024-02-06 10:44:42 +08:00
Halimao
99e9c0702b Makefile: add help target to display available targets (#28845)
Co-authored-by: Martin HS <martin@swende.se>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-02-05 22:48:19 +01:00
Dimitris Apostolou
8fd43c8013 all: fix typos in comments (#28881) 2024-02-05 22:16:32 +01:00
Péter Szilágyi
8ec638dc5e internal/flags: fix --miner.gasprice default listing (#28932) 2024-02-05 22:01:56 +01:00
Chris Ziogas
19af9008f1 p2p: fix accidental termination of portMappingLoop (#28911) 2024-02-05 22:00:46 +01:00
zoereco
253447a4f5 core/types: fix typo (#28922) 2024-02-04 13:55:30 +08:00
Péter Szilágyi
47d76c5f95 core/txpool: don't inject lazy resolved transactions into the container (#28917)
* core/txpool: don't inject lazy resolved transactions into the container

* core/txpool: minor typo fixes
2024-02-02 20:39:12 +02:00
Péter Szilágyi
62affdc9c5 core/txpool/blobpool: post-crash cleanup and addition/removal metrics (#28914)
* core/txpool/blobpool: clean up resurrected junk after a crash

* core/txpool/blobpool: track transaction insertions and rejections

* core/txpool/blobpool: linnnnnnnt
2024-02-02 18:26:35 +02:00
Martin HS
06a871136e deps: update memsize (#28916) 2024-02-02 18:26:13 +02:00
rjl493456442
5c67066a05 eth/downloader: fix skeleton cleanup (#28581)
* eth/downloader: fix skeleton cleanup

* eth/downloader: short circuit if nothing to delete

* eth/downloader: polish the logic in cleanup

* eth/downloader: address comments
2024-01-31 10:57:33 +02:00
Martin HS
3adf1cecf2 build: fix problem with windows line-endings in CI download (#28900)
fixes #28890
2024-01-31 10:45:20 +02:00
rjl493456442
eaac53ec38 core: reset tx lookup cache if necessary (#28865)
This pull request resets the txlookup cache if chain reorg happens, 
preventing them from remaining reachable. It addresses failures in
the hive tests.
2024-01-30 09:34:14 +08:00
KeienWang
fc380f52ef docs/postmortems: fix outdated link (#28893) 2024-01-29 16:40:57 +01:00
lightclient
e2778cd59f eth/catalyst: allow payload attributes v1 in fcu v2 (#28882)
At some point, `ForkchoiceUpdatedV2` stopped working for `PayloadAttributesV1` while `paris` was active. This was causing a few failures in hive. This PR fixes that, and also adds a gate in `ForkchoiceUpdatedV1` to disallow `PayloadAttributesV3`.
2024-01-29 11:53:25 +01:00
KeienWang
db98cc485e README.md: fix travis badge (#28889)
The hyperlink in the README file that directs to the Travis CI build was broken.
This commit updates the link to point to the corrent build page.
2024-01-29 10:58:43 +01:00
protolambda
2e947b7a00 core/types: fix and test handling of faulty nil-returning signer (#28879)
This adds an error if the signer returns a nil value for one of the signature value fields.
2024-01-27 21:16:20 +01:00
alex
bc0b87ca19 internal/flags: fix typo (#28876) 2024-01-26 08:57:04 +01:00
Martin Holst Swende
cd0770ea68 params: begin v.1.13.12 release cycle 2024-01-24 11:55:40 +01:00
Martin Holst Swende
99dc3fe118 params: go-ethereum v1.13.11 stable 2024-01-24 11:45:29 +01:00
rjl493456442
765f2904d8 ethclient: fix flaky test (#28864)
Fix flaky test due to incomplete transaction indexing
2024-01-24 09:07:20 +01:00
lightclient
a8a87586c1 eth/catalyst: prefix payload id with version (#28246)
GetPayloadVX should only return payloads which match its version. GetPayloadV2 is a special snowflake that supports v1 and v2 payloads. This change uses a a version-specific prefix within in the payload id, basically a namespace for the version number.
2024-01-24 08:39:12 +01:00
rjl493456442
6b0de79935 core: move tx indexer to its own file (#28857)
This change moves all the transaction indexing functions to a separate txindexer.go file and defines a txIndexer structure as a refactoring.
2024-01-23 21:00:50 +01:00
Péter Szilágyi
542c861b4f core/txpool, eth/catalyst: fix racy simulator due to txpool background reset (#28837)
This PR fixes an issues in the new simulated backend. The root cause is the fact that the transaction pool has an internal reset operation that runs on a background thread.

When a new transaction is added to the pool via the RPC, the transaction is added to a non-executable queue and will be moved to its final location on a background thread. If the machine is overloaded (or simply due to timing issues), it can happen that the simulated backend will try to produce the next block, whilst the pool has not yet marked the newly added transaction executable. This will cause the block to not contain the transaction. This is an issue because we want determinism from the simulator: add a tx, mine a block. It should be in there.

The PR fixes it by adding a Sync function to the txpool, which waits for the current reset operation (if any) to finish, and then runs an entire round of reset on top. The new round is needed because resets are only triggered by new head events, so newly added transactions will not trigger the outer resets that we can wait on. The transaction pool would eventually internally do a reset even on transaction addition, but there's no easy way to wait on that and there's no meaningful reason to bubble that across everything. A clean outer reset will at worse be a small noop goroutine.
2024-01-23 20:59:38 +01:00
lightclient
98eaa57e6f eth/catalyst: add timestamp checks to fcu and new payload and improve param checks (#28230)
This PR introduces a few changes with respect to payload verification in fcu and new payload requests:

* First of all, it undoes the `verifyPayloadAttributes(..)` simplification I attempted in #27872. 
* Adds timestamp validation to fcu payload attributes [as required](https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#specification-1) (section 2) by the Engine API spec. 
* For the new payload methods, I also update the verification of the executable data. For `newPayloadV2`, it does not currently ensure that cancun values are `nil`. Which could make it possible to submit cancun payloads through it. 
* On `newPayloadV3` the same types of checks are added. All shanghai and cancun related fields in the executable data must be non-nil, with the addition that the timestamp is _only_ with cancun.
* Finally it updates a newly failing catalyst test to call the correct fcu and new payload methods depending on the fork.
2024-01-23 16:02:08 +01:00
trocher
2dc74770a7 core/vm: fix misleading comment (#28860)
fix misleading comment
2024-01-23 15:17:42 +01:00
Marius van der Wijden
c89a3da7d9 core/state/snapshot: use AddHash/ContainHash instead of Hasher interface (#28849)
This change switches from using the `Hasher` interface to add/query the bloomfilter to implementing it as methods.
This significantly reduces the allocations for Search and Rebloom.
2024-01-23 15:15:48 +01:00
Marius Kjærstad
4c8d92d303 build: upgrade -dlgo version to Go 1.21.6 (#28836) 2024-01-23 15:02:58 +01:00
Martin HS
a5a4fa7032 all: use uint256 in state (#28598)
This change makes use of uin256 to represent balance in state. It touches primarily upon statedb, stateobject and state processing, trying to avoid changes in transaction pools, core types, rpc and tracers.
2024-01-23 14:51:58 +01:00
Darioush Jalali
819a4977e8 core: fix genesis setup in benchReadChain (#28856) 2024-01-23 21:46:34 +08:00
Guillaume Ballet
19d9977641 go.{mod,sum}: upgrade go-ole to support arm64 (#28859)
go.{mod,sum}: upgrade go-ole
2024-01-23 11:40:01 +01:00
Martin HS
6a724b94db docs: remove reference to being official (#28858) 2024-01-23 09:26:00 +01:00
rjl493456442
78a3c32ef4 core, core/rawdb, eth/sync: no tx indexing during snap sync (#28703)
This change simplifies the logic for indexing transactions and enhances the UX when transaction is not found by returning more information to users.

Transaction indexing is now considered as a part of the initial sync, and `eth.syncing` will thus be `true` if transaction indexing is not yet finished. API consumers can use the syncing status to determine if the node is ready to serve users.
2024-01-22 21:05:18 +01:00
Marius van der Wijden
f55a10b64d params, core/forkid: enable cancun on sepolia and holesky (#28834)
This change enables Cancun 

- Sepolia at 1706655072 (Jan 31st, 2024)
- Holesky at 1707305664 (Feb 7th, 2024)

Specification: https://github.com/ethereum/execution-specs/pull/860
2024-01-20 16:03:14 +01:00
colin
1c488298c8 ethclient: apply accessList field in toCallArg (#28832)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-01-19 16:43:02 +01:00
Felix Lange
0e93da3197 crypto/kzg4844: add helpers for versioned blob hashes (#28827)
The code to compute a versioned hash was duplicated a couple times, and also had a small
issue: if we ever change params.BlobTxHashVersion, it will most likely also cause changes
to the actual hash computation. So it's a bit useless to have this constant in params.
2024-01-19 11:41:17 +01:00
Darioush Jalali
830f3c764c eth/filters: reset filter.begin in BenchmarkFilters (#28830) 2024-01-18 13:08:13 +01:00
Sina Mahmoodi
e5d5e09faa internal/ethapi: handle blobs in API methods (#28786)
EIP-4844 adds a new transaction type for blobs. Users can submit such transactions via `eth_sendRawTransaction`. In this PR we refrain from adding support to `eth_sendTransaction` and in fact it will fail if the user passes in a blob hash.

However since the chain can handle such transactions it makes sense to allow simulating them. E.g. an L2 operator should be able to simulate submitting a rollup blob and updating the L2 state. Most methods that take in a transaction object should recognize blobs. The change boils down to adding `blobVersionedHashes` and `maxFeePerBlobGas` to `TransactionArgs`. In summary:

- `eth_sendTransaction`: will fail for blob txes
- `eth_signTransaction`: will fail for blob txes

The methods that sign txes does not, as of this PR, add support the for new EIP-4844 transaction types. Resuming the summary:

- `eth_sendRawTransaction`: can send blob txes
- `eth_fillTransaction`: will fill in a blob tx. Note: here we simply fill in normal transaction fields + possibly `maxFeePerBlobGas` when blobs are present. One can imagine a more elaborate set-up where users can submit blobs themselves and we fill in proofs and commitments and such. Left for future PRs if desired.
- `eth_call`: can simulate blob messages
- `eth_estimateGas`: blobs have no effect here. They have a separate unit of gas which is not tunable in the transaction.
2024-01-17 15:06:14 +01:00
Thabokani
2e2e89c2fb miner: fix typo in payload_building_test.go (#28825) 2024-01-17 12:44:01 +02:00
Paul Lange
c66ca8bf7a tracer: use proper base fee in tests (#28775)
In the tracing tests, the base fee was generally set to nil. This commit changes this to pass the proper base instead, and fixes the few tests which become broken by the change.
2024-01-16 12:20:26 +01:00
Martin HS
d4f25b4dcf tests: more verbosity if block decoding fails (#28814) 2024-01-16 12:08:49 +01:00
alex
566754c74a acounts/usbwallet: fix typo (#28815)
acounts:fix typo
2024-01-15 21:45:50 +02:00
Alfie John
9ee6809ff4 core/txpool/blobpool: fix typos 2024-01-15 21:45:14 +02:00
牛晓婕
18e154eaa2 eth: fix potential hang in waitSnapExtension (#28744)
This should fix a rare hang in waitSnapExtension during shutdown.
2024-01-15 15:32:03 +01:00
hyunchel
7596db5f48 ethclient: add tests for TransactionInBlock (#28283)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-01-15 11:10:26 +01:00
Martin HS
89ccc680da tests: update reference tests (#28778)
Updates the reference tests to the latest version
2024-01-15 09:15:40 +01:00
Felix Lange
1485814f89 cmd/rlpdump: add -pos flag, displaying byte positions (#28785) 2024-01-14 12:32:48 +01:00
Darioush Jalali
29b73555ae core/state: unexport GetOrNewStateObject (#28804) 2024-01-14 12:32:23 +01:00
Sina Mahmoodi
407f779c8e internal/ethapi: avoid using pending for defaults (#28784)
Given the discussions around deprecating pending (see #28623 or ethereum/execution-apis#495), we can move away from using the pending block internally, and use latest instead
2024-01-12 19:59:36 +01:00
ddl
1335ba5f28 p2p/dnsdisc: use strings.Cut over strings.IndexByte (#28787) 2024-01-12 19:57:47 +01:00
Sina Mahmoodi
a608c0ac84 cmd/devp2p/internal/ethtest: skip large tx test on github build (#28794)
This test was failling consistently on the github 32-bit build probably due to slow IO. Skipping it for that green check.
2024-01-12 15:14:03 +01:00
Péter Szilágyi
43ba7d65a8 cmd/geth, internal/debug: get rid of by-default log config (#28801) 2024-01-12 15:59:03 +02:00
Péter Szilágyi
065f82a8cc accounts, ethclient: minor tweaks on the new simulated backend (#28799)
* accounts, ethclient: minor tweaks on the new simulated backend

* ethclient/simulated: add an initial batch of gas options

* accounts, ethclient: remove mandatory gasLimit constructor param

* accounts, ethclient: minor option naming tweaks
2024-01-12 15:58:49 +02:00
drstevenbrule
7280a5b31a build: fix typo in comment (#28800) 2024-01-12 14:22:45 +01:00
vuittont60
ae4ea047e3 cmd: fix typos (#28798) 2024-01-12 10:40:00 +02:00
HAOYUatHZ
6e235c0833 eth: minor change of config-accessor (#28782)
eth: refactor `GetVM`
2024-01-12 08:06:22 +01:00
drstevenbrule
5c2de7fcbe docs: fix badge in README (#28796)
* Fix broken badge in README.md

Replaced broken Github link with IPFS link for long-term storage.

* update go badge

Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>

---------

Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
2024-01-12 07:43:52 +01:00
Péter Szilágyi
2e8b1187aa params: begin v1.13.11 release cycle 2024-01-11 19:24:36 +02:00
Péter Szilágyi
a162091e8f version: release v1.13.10 to fix bad tag 2024-01-11 19:17:54 +02:00
Felix Lange
daa2e5d6a6 params: begin v1.13.10 release cycle 2024-01-10 17:32:41 +01:00
Felix Lange
4f825318ea params: go-ethereum v1.13.9 stable 2024-01-10 17:29:05 +01:00
Marius van der Wijden
2d08c99009 ethclient/simulated: implement new sim backend (#28202)
This is a rewrite of the 'simulated backend', an implementation of the ethclient interfaces
which is backed by a simulated blockchain. It was getting annoying to maintain the old
version of the simulated backend feature because there was a lot of code duplication with
the main client. 

The new version is built using parts that we already have: an in-memory geth node instance
running in developer mode provides the chain, while the Go API is provided by ethclient.
A backwards-compatibility wrapper is provided, but the simulated backend has also moved to
a more sensible import path: github.com/ethereum/go-ethereum/ethclient/simulated

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2024-01-10 16:45:08 +01:00
jwasinger
9e018ce3a5 cmd/geth: update log test data (#28780)
update logger test data
2024-01-09 15:35:49 +01:00
rjl493456442
d0edc5af4a accounts/abi: fix bigInt topic encoding (#28764) 2024-01-09 14:55:09 +01:00
Martin HS
1010a79c7c cmd/geth: make it possible to autopilot removedb (#28725)
When managing geth, it is sometimes desirable to do a partial wipe; deleting state but retaining freezer data. A partial wipe can be somewhat tricky to accomplish. 

This change implements the ability to perform partial wipe by making it possible to run geth removedb non-interactive, using command line options instead.
2024-01-09 08:56:01 +01:00
Marius van der Wijden
cfff3cbbf1 params, core/forkid: schedule cancun fork on goerli (#28719)
This PR schedules the cancun fork for the goerli testnet as discussed on ACD.
Spec: ethereum/execution-specs#860

We schedule:
  goerli at 1705473120
2024-01-08 20:33:32 +01:00
vuittont60
f29520ffdf cmd/devp2p/internal/ethtest: fix typos in comments (#28772) 2024-01-08 20:31:22 +01:00
ucwong
e7fa158086 eth/filters: fix early Unsubscribe of log events (#28769) 2024-01-08 20:18:30 +01:00
jwasinger
07b17f991b log: emit error level string as "error", not "eror" (#28774) 2024-01-08 15:27:33 +01:00
ucwong
877d09443d eth/downloader, eth/filters: use defer to call Unsubscribe (#28762) 2024-01-05 13:49:31 +01:00
Rossen Krastev
e3eeb64c94 ethclient: simplify error handling in TransactionReceipt (#28748)
Co-authored-by: Martin HS <martin@swende.se>
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-01-04 16:32:23 +01:00
Marius Kjærstad
99eb49e601 internal/flags: update copyright year to 2024 (#28760)
Co-authored-by: Felix Lange <fjl@twurst.com>
2024-01-04 15:03:58 +01:00
Mario Vega
0b471c312a cmd/evm: Fix blob-gas-used on invalid transactions in t8n (#28734)
cmd/evm: fixes the blob gas calculation if a transaction is invalid
2024-01-03 16:12:20 +01:00
Darioush Jalali
2365d77968 core/vm: update comments to match eip number (#28743) 2024-01-02 11:39:53 +01:00
ddl
33c94ef083 cmd/evm: fix link in README.md (#28755) 2024-01-02 11:37:22 +01:00
Felix Lange
c053eb71b6 log: avoid setting default slog logger in init (#28747)
slog.SetDefault has undesirable side effects. It also sets the default logger destination,
for example. So we should not call it by default in init.
2023-12-30 21:16:02 +01:00
Martin HS
76a5474b32 build: add support for ubuntu 23.10 (mantic minotaur) (#28728) 2023-12-30 17:02:48 +01:00
Taeguk Kwon
09e0208029 accounts,signer: fix typos in comments (#28730) 2023-12-28 11:46:51 +01:00
Mario Vega
b5b70033e2 tests: add currentExcessBlobGas to state tests (#28735) 2023-12-28 11:39:28 +01:00
cygaar
d2e3cb894b core/state: logic equivalence for GetCodeHash (#28733) 2023-12-26 16:38:11 +08:00
Martin Holst Swende
8d0391806f params: begin v1.13.9 release cycle 2023-12-22 13:46:27 +01:00
Martin Holst Swende
904a278054 params: go-ethereum v1.13.8 stable 2023-12-22 13:37:16 +01:00
rjl493456442
f469470aff core/rawdb: improve state scheme checking (#28724)
This pull request improves the condition to check if path state scheme is in use. 

Originally, root node presence was used as the indicator if path scheme is used or not. However due to fact that root node will be deleted during the initial snap sync, this condition is no longer useful.

If PersistentStateID is present, it shows that we've already configured for path scheme.
2023-12-22 07:50:41 +01:00
rjl493456442
cca94792a4 core, cmd, trie: fix the condition of pathdb initialization (#28718)
Original problem was caused by #28595, where we made it so that as soon as we start to sync, the root of the disk layer is deleted. That is not wrong per se, but another part of the code uses the "presence of the root" as an init-check for the pathdb. And, since the init-check now failed, the code tried to re-initialize it which failed since a sync was already ongoing.

The total impact being: after a state-sync has begun, if the node for some reason is is shut down, it will refuse to start up again, with the error message: `Fatal: Failed to register the Ethereum service: waiting for sync.`. 

This change also modifies how `geth removedb` works, so that the user is prompted for two things: `state data` and `ancient chain`. The former includes both the chaindb aswell as any state history stored in ancients. 

---------

Co-authored-by: Martin HS <martin@swende.se>
2023-12-21 20:28:32 +01:00
lightclient
577be37e0e cmd/devp2p: update eth/snap protocol test suites for PoS (#28340)
Here we update the eth and snap protocol test suites with a new test chain,
created by the hivechain tool. The new test chain uses proof-of-stake. As such,
tests using PoW block propagation in the eth protocol are removed. The test suite
now connects to the node under test using the engine API in order to make it
accept transactions. 

The snap protocol test suite has been rewritten to output test descriptions and
log requests more verbosely.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-12-20 17:23:48 +01:00
Felix Lange
8c2d455ccd build: upgrade to golangci-lint v1.55.2 (#28712)
This is primarily to make lint work again on macOS 14. The older version of golangci-lint kept crashing. 

Also included is a fix for a goroutine leak in the recently-introduced function MustRunCommandWithOutput.
2023-12-20 15:36:10 +01:00
Martin HS
d3452a22cc accounts: properly close managed wallets when closing manager (#28710) 2023-12-20 13:41:40 +01:00
Felix Lange
7124057bad internal/build: fix crash in MustRunCommandWithOutput (#28709) 2023-12-20 07:56:41 +01:00
Felix Lange
9258a44b8f params: begin go-ethereum v1.13.8 release cycle 2023-12-19 13:32:25 +01:00
Felix Lange
3fd568855f params: go-ethereum v1.13.7 stable 2023-12-19 13:25:03 +01:00
dependabot[bot]
0cc192bd3a build(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 (#28702)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.15.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.15.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-19 10:50:02 +01:00
Martin HS
435bed5da0 ci: disable lint on travis (#28706) 2023-12-19 10:35:02 +01:00
Martin HS
5a9dda64ce .travis: set lower GOGC value (#28705)
As documented on https://golangci-lint.run/usage/performance/ , a lower
GOGC value causes less peak mem consumption when running the linter.

Exceeding 3Gb is a common cause for build failures, according to
https://docs.travis-ci.com/user/common-build-problems/#my-build-script-is-killed-without-any-error
2023-12-19 09:24:23 +01:00
Martin HS
952b343cb3 build: make linter emit output (#28704) 2023-12-19 08:55:04 +01:00
wangyifan
cd58897f18 core/rawdb: implement size reporting for live items in freezer_table (#28525)
This is the fix to issue #27483. A new hiddenBytes() is introduced to calculate the byte size of hidden items in the freezer table. When reporting the size of the freezer table, size of the hidden items will be subtracted from the total size.

---------

Co-authored-by: Yifan <Yifan Wang>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-12-18 20:10:54 +01:00
Delweng
54a400ee71 internal/ethapi: ethSendTransaction check baseFee (#27834)
If the EIP-1559 is activated, reject 0-priced transactions in the rpc level
2023-12-18 20:09:41 +01:00
Felix Lange
4410c1416a params: begin v1.13.7 release cycle 2023-12-18 19:10:11 +01:00
Felix Lange
a18b845ecd params: release go-ethereum v1.13.6 stable 2023-12-18 18:53:47 +01:00
Delweng
c18c5c3d92 cmd/evm: t8n support custom tracers (#28557)
This change implements ability for the `evm t8n` tool to use custom tracers; either 'native' golang tracers or javascript tracers.
2023-12-18 15:16:25 +01:00
Martin HS
553bafc127 cmd/evm, cmd/clef, cmd/bootnode: fix / unify logging (#28696)
This change fixes a problem with our non-core binaries: evm, clef, bootnode.

First of all, they failed to convert from legacy loglevels 1 to 5, to the new slog loglevels -4 to 4.

Secondly, the logging was actually setup in the init phase, and then overridden in the main. This is not needed for evm, since it used the same flag name as the main geth verbosity. Better to let the flags/internal handle the logging init.
2023-12-18 14:11:27 +01:00
jwasinger
05bbc56677 cmd/evm: default to mirror mainnet forks enabled (#28691)
cmd/evm:  default to using dev chain config (all mainnet HFs activated at block/timestamp 0
2023-12-18 13:56:27 +01:00
Sebastian Stammler
02766d349a internal/flags: add missing flag types for auto-env-var generation (#28692)
Certain flags, such as `--rpc.txfeecap` currently do not have an env-var auto-generated for them. This change adds three missing cli flag types to the auto env-var helper function to fix this.
2023-12-18 13:28:41 +01:00
Felix Lange
5b22a472d6 p2p/discover: add liveness check in collectTableNodes (#28686)
* p2p/discover: add liveness check in collectTableNodes

* p2p/discover: fix test

* p2p/discover: rename to appendLiveNodes

* p2p/discover: add dedup logic back

* p2p/discover: simplify

* p2p/discover: fix issue found by test
2023-12-18 10:47:21 +01:00
alex
edc864f9ba all: fix typos in comments (#28682)
chore(core,eth):fix a couple of typos
2023-12-18 09:35:12 +01:00
FletcherMan
f1794ba278 miner: eliminate the dead loop possibility for newWorkLoop and mainLoop (#28677)
discard the intervalAdjust message if the channel is full
2023-12-15 11:48:55 +08:00
Elias Rad
0f74aad641 all: fix typos in comments (#28662)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-12-13 23:33:46 +01:00
Ursulafe
b2ced97ac4 eth/fetcher, eth/gasestimator: fix typos in comments (#28675) 2023-12-13 23:32:17 +01:00
ucwong
81fd1b3cf9 core/txpool : small cleanup refactors (#28654) 2023-12-12 17:23:36 +02:00
Ford
17c2b3c194 eth/protocols/eth: fix typos in comments (#28652) 2023-12-12 14:47:59 +01:00
Ng Wei Han
a3ca1b2818 cmd/utils: fix HTTPHost, WSHost flag priority (#28669)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-12-12 14:40:50 +01:00
rjl493456442
e206d3f897 trie: remove inconsistent trie nodes during sync in path mode (#28595)
This fixes a database corruption issue that could occur during state healing.
When sync is aborted while certain modifications were already committed, and a
reorg occurs, the database would contain incorrect trie nodes stored by path.
These nodes need to detected/deleted in order to obtain a complete and fully correct state
after state healing.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-12-08 14:28:23 +01:00
Péter Szilágyi
d98d70f670 cmd/utils, eth: disallow invalid snap sync / snapshot flag combos (#28657)
* eth: prevent startup in snap mode without snapshots

* cmd/utils: try to fix bad flag combos wrt snap sync and snapshot generation
2023-12-08 15:16:04 +02:00
Felföldi Zsolt
fff843cfaf beacon/light: add CommitteeChain (#27766)
This change implements CommitteeChain which is a key component of the beacon light client. It is a passive data structure that can validate, hold and update a chain of beacon light sync committees and updates, starting from a checkpoint that proves the starting committee through a beacon block hash, header and corresponding state. Once synced to the current sync period, CommitteeChain can also validate signed beacon headers.
2023-12-08 13:38:00 +01:00
Martin HS
1048e2d6a3 cmd/evm: fix dump after state-test exec (#28650)
The dump after state-test didn't work, the problem was an error, "Already committed", which was silently ignored. 

This change re-initialises the state, so the dumping works again.
2023-12-08 11:06:01 +01:00
Martin HS
5a45e7a631 rpc: fix ns/µs mismatch in metrics (#28649)
The rpc/duration/all meter was in nanoseconds, the individual meter in microseconds.
This PR changes it so both of them use nanoseconds.
2023-12-08 09:40:50 +01:00
Marius Kjærstad
77c4bbcaa5 build: upgrade -dlgo version to Go 1.21.5 (#28648) 2023-12-07 12:45:09 +02:00
Guillaume Ballet
a113497dd7 tests/fuzzers/bls12381: deactivate BLS fuzzer when CGO_ENABLED=0 (#28653)
tests/fuzzers/bls12381: deactivate fuzzer when CGO_ENABLED=0
2023-12-07 10:07:20 +01:00
Marius van der Wijden
55b483d82a ethdb/pebble: remove a dependency (#28627)
The dependency was not really used anyway, so we can get rid of it.

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-12-06 11:41:04 +01:00
Guillaume Ballet
69576df254 .github: use github actions to run 32-bit linux tests (#28549)
use github actions to run 32-bit linux tests
2023-12-05 14:45:40 +01:00
Martin Holst Swende
b8d44ed98b log: remove lazy, remove unused interfaces, unexport methods (#28622)
This change 

- Removes interface `log.Format`, 
- Removes method `log.FormatFunc`, 
- unexports `TerminalHandler.TerminalFormat` formatting methods (renamed to `TerminalHandler.format`)
- removes the notion of `log.Lazy` values


The lazy handler was useful in the old log package, since it
could defer the evaluation of costly attributes until later in the
log pipeline: thus, if the logging was done at 'Trace', we could
skip evaluation if logging only was set to 'Info'.

With the move to slog, this way of deferring evaluation is no longer
needed, since slog introduced 'Enabled': the caller can thus do
the evaluate-or-not decision at the callsite, which is much more
straight-forward than dealing with lazy reflect-based evaluation.

Also, lazy evaluation would not work with 'native' slog, as in, these
two statements would be evaluated differently:

```golang
  log.Info("foo", "my lazy", lazyObj)
  slog.Info("foo", "my lazy", lazyObj)
```
2023-12-05 11:54:44 +01:00
Martin Holst Swende
3dc071e036 eth/tracers/logger: make structlog/json-log stack hex again (#28628)
* common/hexutil: define hex wrappers for uint256.Int

* eth/tracers/logger: make structlog/json-log stack hex again

* common/hexutil: goimports
2023-12-05 09:37:48 +01:00
Håvard Anda Estensen
2e13b01046 accounts: run tests in parallel (#28544) 2023-12-04 14:55:06 +01:00
Manav Darji
70fd0b635e eth/fetcher: fix invalid tracking of received at time for block (#28637)
eth/fetcher: fix invalid tracking of received at time
2023-12-04 14:25:17 +02:00
BorkBorked
f04e5bde74 accounts/abi/bind: fixed typos (#28634)
* Update auth.go

* Update backend.go

* Update bind.go

* Update bind_test.go
2023-12-04 11:53:42 +02:00
ddl
6e488c2449 cmd/evm: fix Env struct json tag (#28635) 2023-12-04 11:52:55 +02:00
Delweng
5fb8ebc9ec eth/tracers: tx-level state in debug_traceCall (#28460) 2023-12-01 16:38:52 +03:30
Martin Holst Swende
dd0d0a2522 slog: faster and less memory-consumption (#28621)
These changes improves the performance of the non-coloured terminal formatting, _quite a lot_. 

```
name               old time/op    new time/op    delta
TerminalHandler-8    10.2µs ±15%     5.4µs ± 9%  -47.02%  (p=0.008 n=5+5)

name               old alloc/op   new alloc/op   delta
TerminalHandler-8    2.17kB ± 0%    0.40kB ± 0%  -81.46%  (p=0.008 n=5+5)

name               old allocs/op  new allocs/op  delta
TerminalHandler-8      33.0 ± 0%       5.0 ± 0%  -84.85%  (p=0.008 n=5+5)
```

I tried to _somewhat_ organize the commits, but the it might still be a bit chaotic. Some core insights: 

- The function `terminalHandler.Handl` uses a mutex, and writes all output immediately to 'upstream'. Thus, it can reuse a scratch-buffer every time. 
- This buffer can be propagated internally, making all the internal formatters either write directly to it,
- OR, make  use of the `tmp := buf.AvailableBuffer()` in some cases, where a byte buffer "extra capacity" can be temporarily used. 
- The `slog` package  uses `Attr` by value. It makes sense to minimize operating on them, since iterating / collecting into a new slice, iterating again etc causes copy-on-heap. Better to operate on them only once. 
- If we want to do padding, it's better to copy from a constant `space`-buffer than to invoke `bytes.Repeat` every single time.
2023-12-01 13:28:20 +01:00
BorkBorked
f2b509d8a1 accounts/abi/bind: fix typo (#28630) 2023-12-01 09:51:50 +01:00
Maciej Kulawik
fa0df76f3c trie/triedb/hashdb: take lock around access to dirties cache (#28542)
Add read locking of db lock around access to dirties cache in hashdb.Database to prevent
data race versus hashdb.Database.dereference which can modify the dirities map by deleting
an item.

Fixes #28541

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-11-30 10:50:48 +01:00
rjl493456442
ab0eb46a84 core/state: make stateobject.create selfcontain (#28459) 2023-11-29 16:07:51 +08:00
jwasinger
28e7371701 all: replace log15 with slog (#28187)
This PR replaces Geth's logger package (a fork of [log15](https://github.com/inconshreveable/log15)) with an implementation using slog, a logging library included as part of the Go standard library as of Go1.21.

Main changes are as follows:
* removes any log handlers that were unused in the Geth codebase.
* Json, logfmt, and terminal formatters are now slog handlers.
* Verbosity level constants are changed to match slog constant values.  Internal translation is done to make this opaque to the user and backwards compatible with existing `--verbosity` and `--vmodule` options.
* `--log.backtraceat` and `--log.debug` are removed.

The external-facing API is largely the same as the existing Geth logger.  Logger method signatures remain unchanged.

A small semantic difference is that a `Handler` can only be set once per `Logger` and not changed dynamically.  This just means that a new logger must be instantiated every time the handler of the root logger is changed.

----
For users of the `go-ethereum/log` module. If you were using this module for your own project, you will need to change the initialization. If you previously did 
```golang
log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
```
You now instead need to do 
```golang
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true)))
```
See more about reasoning here: https://github.com/ethereum/go-ethereum/issues/28558#issuecomment-1820606613
2023-11-29 08:33:50 +01:00
Péter Szilágyi
61b844f2b2 eth/gasestimator: allow slight estimation error in favor of less iterations (#28618)
* eth/gasestimator: early exit for plain transfer and error allowance

* core, eth/gasestimator: hard guess at a possible required gas

* internal/ethapi: update estimation tests with the error ratio

* eth/gasestimator: I hate you linter

* graphql: fix gas estimation test

---------

Co-authored-by: Oren <orenyomtov@users.noreply.github.com>
2023-11-28 22:31:47 +02:00
Jakub Freebit
e0c7ad01ab consensus: verify the nonexistence of shanghai- and cancun-specific header fields (#28605) 2023-11-28 21:29:00 +01:00
Guillaume Ballet
34dcd74935 crypto/secp256k1: fix 32-bit tests when CGO_ENABLED=0 (#28602) 2023-11-28 19:16:50 +01:00
Sina Mahmoodi
bbc5db8405 eth/tracers/js: fix type inconsistencies (#28488)
This change fixes two type-inconsistencies in the JS tracer:

- In most places we return byte arrays as a `Uint8Array` to the tracer. However it seems we missed doing the conversion for `ctx` fields which are passed to the tracer during `result`. They are passed as simple arrays. I think Uint8Arrays are more suitable and we should change this inconsistency. Note: this will be a breaking-change. But I believe the effect is small. If we look at our tracers we see that these fields (`ctx.from`, `ctx.to`, etc.) are used in 2 ways. Passed to `toHex` which takes both array or buffer. Or the length was measured which is the same for both types.
- The `slice` taking in `int, int` params versus `memory.slice` taking `int64, int64` params. I suggest changing `slice` types to `int64`. This should have no effect almost in any case.
2023-11-28 15:00:35 +01:00
Shivam Sandbhor
248dc50ee8 ethereum: remove TODO comment about subscription (#28609) 2023-11-28 14:49:08 +01:00
Martin Holst Swende
63979bc9cc cmd/evm, core/state: fix post-exec dump of state (statetests, blockchaintests) (#28504)
There were several problems related to dumping state. 

- If a preimage was missing, even if we had set the `OnlyWithAddresses` to `false`, to export them anyway, the way the mapping was constructed (using `common.Address` as key) made the entries get lost anyway. Concerns both state- and blockchain tests. 
- Blockchain test execution was not configured to store preimages.

This changes makes it so that the block test executor takes a callback, just like the state test executor already does. This callback can be used to examine the post-execution state, e.g. to aid debugging of test failures.
2023-11-28 13:54:17 +01:00
lightclient
58297e339b light: remove package light(#28614)
This changes removes the package 'light', which is currently unused.
2023-11-28 09:01:23 +01:00
rjl493456442
71817f318e eth/catalyst, eth/downloader: expose more sync information (#28584)
This change exposes more information from sync module internally
2023-11-28 08:38:30 +01:00
Martin Holst Swende
5b57727d6d go.mod: update uint256 to v1.2.4 (#28612) 2023-11-27 16:39:28 +02:00
Péter Szilágyi
1e28e0bb03 eth/gasestimator, internal/ethapi: move gas estimator out of rpc (#28600) 2023-11-27 16:20:09 +02:00
Ng Wei Han
333dd956bf trie: fix random test generator early terminate (#28590)
This change fixes a minor bug in the `randTest.Generate` function, which caused the `quick.Check` to be a no-op.
2023-11-25 14:56:22 +01:00
Péter Szilágyi
2a2013014c eth, internal/ethapi: drop some weird indirection (#28597) 2023-11-24 13:26:42 +02:00
Marius van der Wijden
bdf5e388ca cmd, les, tests: remove light client code (#28586)
* cmd, les, tests: remove light client code

This commit removes the light client (LES) code.
Since the merge the light client has been broken and
it is hard to maintain it alongside the normal client.
We decided it would be best to remove it for now and
maybe rework and reintroduce it in the future.

* cmd, eth: remove some more mentions of light mode

* cmd: re-add flags and mark as deprecated

* cmd: warn the user about deprecated flags

* eth: better error message
2023-11-23 16:28:26 +02:00
Mikel Cortes
d76efbb9be params: update discV5 bootnodes (#28562)
update discV5 bootnodes from https://github.com/eth-clients/eth2-networks/blob/master/shared/mainnet/bootstrap_nodes.txt
2023-11-23 11:14:10 +01:00
Martin Holst Swende
eec37e3b71 cmd/devp2p/internal/ethtest: undo debug-hack (#28588)
cmd/devp2p/internal/ethtest: remove a debug-hack flaw which prevented certain tests from running
2023-11-23 09:22:09 +01:00
Felix Lange
63127f5443 cmd/geth: fix build error (#28585) 2023-11-22 16:32:43 +01:00
Guillaume Ballet
d468c333a7 cmd/{geth,utils}: add cmd to export preimages in snap enumeration order (#28256)
Adds a subcommand: `geth snapshot export-preimages`, to export preimages of every hash found during a snapshot enumeration: that is, it exports _only the active state_, and not _all_ preimages that have been used but are no longer part of the state. 

This tool is needed for the verkle transition, in order to distribute the preimages needed for the conversion. Since only the 'active' preimages are exported, the output is shrunk from ~70GB to ~4GB.

The order of the output is the order used by the snapshot enumeration, which avoids database thrashing. However, it also means that storage-slot preimages are not deduplicated.
2023-11-22 14:48:25 +01:00
Håvard Anda Estensen
5ff929c22f les/vflux: run tests in parallel (#28524) 2023-11-22 14:00:30 +01:00
jwasinger
3cfcd252db cmd/geth: add support for --dev flag in dumpgenesis (#28463)
Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: lightclient <lightclient@protonmail.com>
2023-11-22 12:08:39 +01:00
jwasinger
104dbf7821 cmd/utils: validate pre-existing genesis in --dev mode (#28468)
geth --dev can be used with an existing data directory and genesis block. Since
dev mode only works with PoS, we need to verify that the merge has happened.

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-11-22 12:01:38 +01:00
Delweng
d6cea4832a rpc: improve performance of subscription notification encoding (#28328)
It turns out that encoding json.RawMessage is slow because
package json basically parses the message again to ensure it is valid.
We can avoid the slowdown by encoding the entire RPC notification once,
which yields a 30% speedup.
2023-11-22 11:24:54 +01:00
Mario Vega
347fecd881 core/types: make 'v' optional for DynamicFeeTx and BlobTx (#28564)
This fixes an issue where transactions would not be accepted when they have only
'yParity' and not 'v'.
2023-11-22 11:00:44 +01:00
ucwong
e9f59b5d5e eth/filters: reuse error msg for invalid block range (#28479) 2023-11-21 15:28:44 +01:00
Maciej Kulawik
6489a0dd1f ethdb/pebble: don't double-close iterator inside pebbleIterator (#28566)
Adds 'released' flag to pebbleIterator to avoid double closing cockroachdb/pebble.Iterator as it is an invalid operation.

Fixes #28565
2023-11-21 15:22:22 +01:00
Marius van der Wijden
146e8d999c core, trie, rpc: speed up tests (#28461)
* rpc: make subscription test faster

reduces time for TestClientSubscriptionChannelClose
from 25 sec to < 1 sec.

* trie: cache trie nodes for faster sanity check

This reduces the time spent on TestIncompleteSyncHash
from ~25s to ~16s.

* core/forkid: speed up validation test

This takes the validation test from > 5s to sub 1 sec

* core/state: improve snapshot test run
brings the time for TestSnapshotRandom from 13s down to 6s

* accounts/keystore: improve keyfile test

This removes some unnecessary waits and reduces the
runtime of TestUpdatedKeyfileContents from 5 to 3 seconds

* trie: remove resolver
* trie: only check ~5% of all trie nodes
2023-11-21 12:19:28 +01:00
levisyin
525db7b2c5 accounts/abi: context info on unpack-errors (#28529)
adds contextual information to errors returned by unpack
2023-11-21 09:16:57 +01:00
Haotian
ad16f11f84 cmd/evm: capitalize evm commands (#28569)
* standard:fix for a unified standard

* standard:fix more as a complements

---------

Co-authored-by: haotian <haotian@haotiandeMacBook-Air.local>
2023-11-21 09:56:23 +02:00
rjl493456442
661bd45188 core/state/snapshot: print correct error from trie iterator (#28560) 2023-11-21 10:47:37 +08:00
Håvard Anda Estensen
460cc1673e cmd: run tests in parallel (#28546) 2023-11-20 10:52:14 +01:00
jp-imx
14a1e96b68 core/txpool/legacypool: respect nolocals-setting (#28435)
This change adds a check to ensure that transactions added to the legacy pool are not treated as 'locals' if the global locals-management has been disabled. 

This change makes the pool enforce the --txpool.pricelimit setting.
2023-11-20 09:05:20 +01:00
levisyin
a73748258f accounts, cmd: fix typos (#28526) 2023-11-20 08:44:05 +01:00
Håvard Anda Estensen
77cb21da2c signer: run tests in parallel (#28536)
marks tests as parallel-safe in package signer
2023-11-20 08:20:59 +01:00
danceratopz
c8a2202028 cmd/evm: validate blockchain tests poststate account storage (#28443)
This PR verifies the accounts' storage as specified in a blockchain test's postState field

The expect-section, it does really only check that the test works. It's meant for the test-author to verify that "If the test does what it's supposed to, then the nonce of X should be 2, and the slot Y at Z should be 0x123.

    This expect-section is not exhaustive (not full post-state)
    It is also not auto-generated, but put there manually by the author.

We can still check it, as a test-sanity-check, in geth
2023-11-17 15:56:21 +01:00
Håvard Anda Estensen
8b78d6a7a0 Dockerfile: update Go to 1.21 (#28538) 2023-11-17 16:48:06 +02:00
Martin Holst Swende
5bf8769fb0 ethdb/memorydb, trie: reduced allocations (#28473)
* trie: use pooling of iterator states in iterator

The node iterator burns through a lot of memory while iterating a trie, and a lot of
that can be avoided by using a fairly small pool (max 40 items).

name        old time/op    new time/op    delta
Iterator-8    6.22ms ± 3%    5.40ms ± 6%  -13.18%  (p=0.008 n=5+5)

name        old alloc/op   new alloc/op   delta
Iterator-8    2.36MB ± 0%    1.67MB ± 0%  -29.23%  (p=0.008 n=5+5)

name        old allocs/op  new allocs/op  delta
Iterator-8     37.0k ± 0%     29.8k ± 0%     ~     (p=0.079 n=4+5)

* ethdb/memorydb: avoid one copying of key

By making the transformation from []byte to string at an earlier point,
we save an allocation which otherwise happens later on.

name           old time/op    new time/op    delta
BatchAllocs-8     412µs ± 6%     382µs ± 2%   -7.18%  (p=0.016 n=5+4)

name           old alloc/op   new alloc/op   delta
BatchAllocs-8     480kB ± 0%     490kB ± 0%   +1.93%  (p=0.008 n=5+5)

name           old allocs/op  new allocs/op  delta
BatchAllocs-8     3.03k ± 0%     2.03k ± 0%  -32.98%  (p=0.008 n=5+5)
2023-11-15 16:20:34 +01:00
Håvard Anda Estensen
a75a2d6db6 all: replace some cases of strings.SplitN with strings.Cut (#28446) 2023-11-15 14:42:33 +01:00
Halimao
db7895d3b6 accounts/abi: improve readability of method-to-string conversion (#28530)
refactor: improve readability of NewMethod print
2023-11-15 14:30:35 +01:00
aliening
fcc7ae162d internal/jsre/deps: fix typo in jsdoc (#28511)
minor typo fix
2023-11-15 13:55:56 +01:00
Håvard Anda Estensen
b9504e4966 miner: run tests in parallel (#28506)
Changes many of the tests in the miner package to run in parallel
2023-11-15 13:46:32 +01:00
Zoro
2814ee0547 accounts,cmd,console,les,metrics: refactor some errors checked by (ST1005) go-staticcheck (#28532)
fix: fix some (ST1005)go-staticcheck
2023-11-15 14:36:57 +02:00
jwasinger
984f82629c cmd/geth: more special cases logging tests (#28527)
adds logging tests for errors and custom fmt.Stringer-types which output strings that needs to be quoted/escaped.
2023-11-15 09:54:35 +01:00
Martin Holst Swende
c5b7cfa9c3 tests: skip tests on windows 32bit CI (#28521)
tests: skip half the blockchain- and state-tests on windows 32bit CI-tests
2023-11-14 18:40:16 +01:00
Martin Holst Swende
2391fbc676 tests/fuzzers: move fuzzers into native packages (#28467)
This PR moves our fuzzers from tests/fuzzers into whatever their respective 'native' package is.

The historical reason why they were placed in an external location, is that when they were based on go-fuzz, they could not be "hidden" via the _test.go prefix. So in order to shove them away from the go-ethereum "production code", they were put aside.

But now we've rewritten them to be based on golang testing, and thus can be brought back. I've left (in tests/) the ones that are not production (bls128381), require non-standard imports (secp requires btcec, bn256 requires gnark/google/cloudflare deps).

This PR also adds a fuzzer for precompiled contracts, because why not.

This PR utilizes a newly rewritten replacement for go-118-fuzz-build, namely gofuzz-shim, which utilises the inputs from the fuzzing engine better.
2023-11-14 14:34:29 +01:00
VM
24d46224c1 trie: spelling - fix comments in hasher (#28507)
Co-authored-by: VM <arimas@foxmail.com>
2023-11-14 14:27:07 +01:00
Sina Mahmoodi
e803ef09ad eth/tracers/js: fix isPush for push0 (#28520)
Fixes so that `push0` opcode is correctly reported as `true` by the `IsPush` function

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-11-14 13:14:38 +01:00
Guillaume Ballet
fa8d39807d cmd, core, trie: verkle-capable geth init (#28270)
This change allows the creation of a genesis block for verkle testnets. This makes for a chunk of code that is easier to review and still touches many discussion points.
2023-11-14 13:09:40 +01:00
Delweng
f265cc24b4 cmd/geth: remove some whitespace in code and comments (#28148)
This changes just removes some whitespace
2023-11-10 13:26:13 +01:00
Marius Kjærstad
49b2c5f43c build: upgrade -dlgo version to Go 1.21.4 (#28505) 2023-11-10 13:15:06 +01:00
Delweng
ce5a4809fd ethclient: add empty/nonexist account testcase for eth_getProof RPC (#28482)
Adds testcases for eth_getProof endpoint for the following cases: 

- the account/contract does not exist
- the account/contract exists but is empty.
2023-11-10 12:23:09 +01:00
Wei Tang
2f4833b828 cmd/evm: allow state dump regardless if test passes in statetest (#28484)
This change makes it so that when executing state tess, state is always dumped out if the corresponding flag is set.
2023-11-10 12:21:51 +01:00
rjl493456442
326fa00759 core/rawdb: fsync the index file after each freezer write (#28483)
* core/rawdb: fsync the index and data file after each freezer write

* core/rawdb: fsync the data file in freezer after write
2023-11-10 12:56:39 +02:00
Delweng
e38b9f1830 eth/filters: exit early if topics-filter has more than 4 topics (#28494)
Currently, geth's will return `[]` for any `len(topics) > 4` log filter. The EVM only supports up to four logs, via LOG4 opcode, so larger criterias fail. This change makes the filter query exit early in those cases.
2023-11-10 08:10:03 +01:00
Jim McDonald
f7dde2a96c ethdb/pebble: add Errorf function to panicLogger (#28491)
cockroachdb/pebble@422dce9 added Errorf to the Logger interface, this change makes it possible to compile geth with that version of pebble by adding the corresponding method to panicLogger.
2023-11-09 15:15:22 +01:00
Martin Holst Swende
b77a9b127c cmd/geth: more testcases for logging (#28501)
* cmd/geth: more testcases for logging

This adds more edgecases around logging, particularly around handling of different types of nil-values
as concrete types and within interfaces.

Also adds tests with 'reserved' values which breaks json/logfmt formats. The json output is checked in,
but not actively used by any testcase at the moment.

* cmd/geth/testdata: remove timestamps
2023-11-09 10:46:48 +01:00
Delweng
7ea860d665 graphql: type of yParity from Long to BigInt (#28456)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-11-09 11:36:27 +03:00
Péter Szilágyi
470dba8fc1 core/vm: set basefee to 0 internally on eth_call (#28470)
* core/vm: set basefee to 0 internally on eth_call

* core: nicer 0-basefee, make it work for blob fees too

* internal/ethapi: make tests a bit more complex

* core: fix blob fee checker

* core: make code a bit more readable

* core: fix some test error strings

* core/vm: Get rid of weird comment

* core: dict wrong typo
2023-11-08 11:22:08 +02:00
Marius van der Wijden
4d9f3cd5d7 eth: set networkID to chainID by default (#28250)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-11-07 14:21:46 +01:00
Delweng
f20b334f21 eth/filters: eth_getLogs fast exit for invalid block range (#28386) 2023-11-07 12:41:19 +01:00
Péter Szilágyi
97ae32441e travis: use newer builder image (#28475) 2023-11-07 13:00:31 +02:00
Péter Szilágyi
51b5ad3da3 .travis: enable cross building to macos arm64 (#28474)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-11-07 11:35:03 +01:00
Péter Szilágyi
e91cdb49be ethclient: fix forwarding 1559 gas fields (#28462) 2023-11-03 19:40:37 +02:00
Alvaro Sevilla
b1cec853be eth/tracers: add position field for callTracer logs (#28389)
Currently, one can use the "withLogs" parameter to include logs in the
callTracer results, which allows the user to see at which trace level
was each log emitted.
This commit adds a position field to the logs which determine
the exact ordering of a call's logs and its subcalls. This would
be useful e.g. for explorers wishing to display the flow of execution.

Co-authored-by: jsvisa <delweng@gmail.com>
2023-11-03 10:28:27 +01:00
lmittmann
a3be38127c core/vm: performance tweak of OpCode.String() (#28453)
make `opCodeToString` a `[256]string` array

Co-authored-by: lmittmann <lmittmann@users.noreply.github.com>
2023-11-02 08:54:28 +02:00
rjl493456442
f4ac548619 ethdb/pebble: cap memory table size as maxMemTableSize-1 (#28444) 2023-10-31 18:19:31 +02:00
Mario Vega
285202aae2 cmd/evm: add --run option to blocktest command (#28421)
Co-authored-by: lightclient <lightclient@protonmail.com>
2023-10-31 15:23:51 +01:00
Felix Lange
bc42e88415 core: add basic chain history support in GenerateChain (#28428)
This change improves GenerateChain to support internal chain history access (ChainReader)
for the consensus engine and EVM.

GenerateChain takes a `parent` block and the number of blocks to create. With my changes,
the consensus engine and EVM can now access blocks from `parent` up to the block currently
being generated. This is required to make the BLOCKHASH instruction work, and also needed
to create real clique chains.  Clique uses chain history to figure out if the current signer is in-turn,
for example.

I've also added some more accessors to BlockGen. These are helpful when creating transactions:

- g.Signer returns a signer instance for the current block
- g.Difficulty returns the current block difficulty
- g.Gas returns the remaining gas amount

Another fix in this commit concerns the receipts returned by GenerateChain. The receipts now
have properly derived fields (BlockHash, etc.) and should generally match what would be
returned by the RPC API.
2023-10-31 12:39:25 +01:00
Jakub Freebit
447945e438 core/rawdb: add logging and fix comments around AncientRange function. (#28379)
This adds warning logs when the read does not match the expected count.
We can also remove the size limit since the function documentation explicitly states
that callers should limit the count.
2023-10-31 12:04:45 +01:00
rjl493456442
ea2e66a58e trie/triedb/pathdb: improve dirty node flushing trigger (#28426)
* trie/triedb/pathdb: improve dirty node flushing trigger

* trie/triedb/pathdb: add tests

* trie/triedb/pathdb: address comment
2023-10-31 11:39:55 +02:00
Martin Holst Swende
233db64cc1 all: make vendored copy of reexec (#28382)
a little copying is better than a little dependency

-- go proverb

We have this dependency on docker, a.k.a moby: a gigantic library, and we only need ~70 LOC,
so here I tried moving it inline instead.

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-10-28 00:14:43 +02:00
Delweng
2d7dba024d graphql: always set content-type to application/json (#28417)
---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-10-27 16:50:59 +02:00
Guillaume Ballet
4cbca5178a core, cmd/geth: add --override.* flags to geth init (#28407)
* core, cmd/geth: add --override.* flags to geth init

* also apply overrides before genesis commit with new block

* review feedback
2023-10-27 10:15:14 +08:00
Delweng
abe3fca1de graphql: fix an issue of nil pointer panic (#28416)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-10-26 13:48:51 +02:00
Martin Holst Swende
58ae1df684 cmd/geth: test for logging-output (#28373)
This PR is a bit in preparation for the slog work in #28187 .

Our current test re logging mostly test the internals, but we have no real end-to-end test of the logging output. This PR introduces a simple reexec-based log tester. This also relies upon a special mode in geth, which can be made to eject a set of predefined log messages (only available if the build-tag `integrationtests` is used

e.g. go run --tags=integrationtests ./cmd/geth --log.format terminal logtest

While working on this, I also noticed a quirk in the setup: when geth was configured to use a file output, then two separate handlers were used (one handler for the file, one handler for the console). Using two separate handlers means that two formatters are used, thus the formatting of any/all records happened twice. This PR changes the mechanism to use two separate io.Writers instead, which is both more optimal and fixes a bug which occurs due to a global statefulness in the formatter.
2023-10-25 17:57:12 +02:00
Adrian Sutton
d8c6ae054c rpc: use correct stringer-method for serializing BlockNumberOrHash (#28358)
The String() version of BlockNumberOrHash uses decimal for all block numbers, including negative ones used to indicate labels. Switch to using BlockNumber.String() which encodes it correctly for use in the JSON-RPC API.
2023-10-25 15:52:42 +02:00
Delweng
f7b62e5506 graphql: logs return error if from block > to (#28412)
As per discussion in ethereum/execution-apis#475

Signed-off-by: jsvisa <delweng@gmail.com>
2023-10-25 15:20:23 +02:00
Martin Holst Swende
96b75033c0 trie: use explicit errors in stacktrie (instead of panic) (#28361)
This PR removes panics from stacktrie (mostly), and makes the Update return errors instead. While adding tests for this, I also found that one case of possible corruption was not caught, which is now fixed.
2023-10-25 14:53:50 +02:00
Martin Holst Swende
300df874d7 cmd/evm: make t8ntool handle transaction decoding errors better (#28397)
This change closes https://github.com/ethereum/go-ethereum/issues/27730 . By using an iterator instead of a slice of transactions, we can better handle the case when an individual transaction (within an otherwise well-formed RLP-list) cannot be decoded.
2023-10-25 14:08:52 +02:00
moomin
a8617c6d4d txpool/legacypool: remove already known error in legacypool (#28400) 2023-10-23 18:36:11 +03:00
rjl493456442
ab04aeb855 core, eth, trie: filter out boundary nodes and remove dangling nodes in stacktrie (#28327)
* core, eth, trie: filter out boundary nodes in stacktrie

* eth/protocol/snap: add comments

* Update trie/stacktrie.go

Co-authored-by: Martin Holst Swende <martin@swende.se>

* eth, trie: remove onBoundary callback

* eth/protocols/snap: keep complete boundary nodes

* eth/protocols/snap: skip healing if the storage trie is already complete

* eth, trie: add more metrics

* eth, trie: address comment

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-10-23 18:31:56 +03:00
Delweng
43e6a3c196 graphql: return error if block from>to (#28393)
As per discussion in ethereum/execution-apis#475
2023-10-23 17:25:26 +02:00
rjl493456442
3853f50082 trie/triedb/pathdb, core/rawdb: enhance error message in freezer (#28198)
This PR adds more error message for debugging purpose.
2023-10-23 15:46:39 +02:00
hyunchel
062598bb40 core/blockchain: fix typos and grammar (#28295) 2023-10-23 15:23:41 +02:00
kaliubuntu0206
54f35c68be ethstats: fix bug in block reporting (#28398)
Fixes a bug where the ethstats omits to report full block contents. This bug was a side-effect of https://github.com/ethereum/go-ethereum/pull/26777,  where `CurrentBlock` was changed to return a header instead of a block, leading to a failed type assertion.
2023-10-23 15:06:05 +02:00
aaronbuchwald
6c6982163b core/state/pruner: track number of skipped items during state pruning (#28368) 2023-10-23 13:24:32 +08:00
Inphi
ffc6a0f36e event: fix Resubscribe deadlock when unsubscribing after inner sub ends (#28359)
A goroutine is used to manage the lifetime of subscriptions managed by
resubscriptions. When the subscription ends with no error, the resub
goroutine ends as well. However, the resub goroutine needs to live
long enough to read from the unsub channel. Otheriwse, an Unsubscribe
call deadlocks when writing to the unsub channel.

This is fixed by adding a buffer to the unsub channel.
2023-10-22 17:37:56 +02:00
kevaundray
a6a0ae45b6 crypto/kzg4844: use the new trusted setup file and format (#28383)
Changes the trusted_setup to the one created during the kzg-ceremony. The trusted setup file can be found in the consensus specs: https://github.com/ethereum/consensus-specs/blob/dev/presets/mainnet/trusted_setups/trusted_setup_4096.json
---------

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2023-10-22 16:05:04 +02:00
Martin Holst Swende
c1d5a012ea core/state, tests: fix memory leak via fastcache (#28387)
This change fixes a memory leak, when running either state-tests or blockchain-tests, we allocate a `1MB` fastcache during snapshot generation. `fastcache` is a bit special, and requires a `Reset()` (it has it's own memory allocator). 

The `1MB` was hidden [here](https://github.com/ethereum/go-ethereum/blob/master/tests/state_test_util.go#L333) and [here](https://github.com/ethereum/go-ethereum/blob/master/tests/block_test_util.go#L146) respectively.
2023-10-20 13:35:49 +02:00
Marius van der Wijden
cd29535672 crypto/blake2b: put architecture-dependent features behind build-tag (#28381)
This change to fixes a compilation-flaw on master, by putting architecture-specific functions behind corresponding build tags.
2023-10-19 14:04:26 +02:00
Sina Mahmoodi
4d3c0d41f4 eth/filters: fix flaky test TestPendingTxFilterDeadlock (#28376) 2023-10-19 10:30:55 +02:00
Brandon Liu
ec1a0502bf rpc: increase timeout in TestClientWebsocketPing (#28371) 2023-10-19 10:08:36 +02:00
Marius van der Wijden
d10a2f6ab7 tests/fuzzers: update fuzzers to be based on go-native fuzzing (#28352)
This change modifies the fuzzers to use the native golang fuzzing framework instead of go-fuzz
2023-10-18 15:01:16 +02:00
lightclient
da55b23d21 eth/fetcher: downgrade stale txs log from warn to debug (#28364) 2023-10-17 19:52:53 +03:00
Marius van der Wijden
d782dc2341 tests/fuzzers/les: fix crash in fuzzer (#28362) 2023-10-17 15:20:22 +02:00
lightclient
20d5256e40 core/chain_makers: add SetParentBeaconRoot(..) to chain makers (#28252) 2023-10-17 14:43:46 +02:00
Adrian Sutton
b85c86022e api/bind: add CallOpts.BlockHash to allow calling contracts at a specific block hash (#28084)
* api/bind: Add CallOpts.BlockHash to allow calling contracts at a specific block hash.

* ethclient: Add BalanceAtHash, NonceAtHash and StorageAtHash functions
2023-10-17 15:34:01 +03:00
Brandon Liu
f62502e123 internal/ethapi, accounts/abi/bind: use errors.Is for error comparison (#28348)
Co-authored-by: lightclient <lightclient@protonmail.com>
2023-10-17 14:11:04 +02:00
Kero
1f11d2d340 ethclient: ensure the close of canceled context (#28349) 2023-10-17 14:09:48 +02:00
rjl493456442
1b1611b8d0 core, trie, eth: refactor stacktrie constructor (#28350)
This change enhances the stacktrie constructor by introducing an option struct. It also simplifies the `Hash` and `Commit` operations, getting rid of the special handling round root node.
2023-10-17 14:09:25 +02:00
Péter Szilágyi
aeb0abf80a params: begin v1.13.5 release cycle 2023-10-17 14:18:45 +03:00
Péter Szilágyi
3f907d6a6f params: release Geth v1.13.4 2023-10-17 14:17:27 +03:00
Marius van der Wijden
667966c5c1 eth/fetcher: fix fetcher timeout (#28220)
This changes fixes a bug in the fetcher, where the timeout for how long to remember underpriced transaction was erroneously compared, and the timeout never hit.
---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-10-17 10:38:00 +02:00
xiaolou86
00c63830e4 cmd: fix typos (#28323) 2023-10-17 15:53:10 +08:00
Martin Holst Swende
8b99ad4602 internal/ethapi: fix codehash lookup in eth_getProof (#28357)
This change fixes #28355, where eth_getProof failed to return the correct codehash under certain conditions. This PR changes the logic to unconditionally look up the codehash, and also adds some more tests.
2023-10-17 09:25:16 +02:00
phenix3443
a5544d35f6 fix: broken url link (#28342) 2023-10-17 14:32:35 +08:00
Péter Szilágyi
2e478aab98 eth/fetcher: only make noise big mismatches (#28356) 2023-10-16 23:40:25 +03:00
Martin Holst Swende
4632b7b31e tests: update execution-spec-tests to 1.0.5 (#28337)
Updates execution-spec-tests to 1.0.5: https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.5, switching to develop which contains Cancun tests (which are also enabled in this change).
2023-10-16 20:10:05 +02:00
Péter Szilágyi
509a64ffb9 cmd, core, ethdb: enable Pebble on 32 bits and OpenBSD too (#28335)
* cmd, core, ethdb: enable Pebble on 32 bits and OpenBSD too

* ethdb/pebble: use Pebble's internal constant calculation
2023-10-13 22:50:20 +03:00
Péter Szilágyi
425cb6f65d go.mod: pull in the latest cloudflare API libs (#28336) 2023-10-13 17:08:38 +03:00
Martin Holst Swende
f62c58f8de trie: make rhs-proof align with last key in range proofs (#28311)
During snap-sync, we request ranges of values: either a range of accounts or a range of storage values. For any large trie, e.g. the main account trie or a large storage trie, we cannot fetch everything at once.

Short version; we split it up and request in multiple stages. To do so, we use an origin field, to say "Give me all storage key/values where key > 0x20000000000000000". When the server fulfils this, the server provides the first key after origin, let's say 0x2e030000000000000 -- never providing the exact origin. However, the client-side needs to be able to verify that the 0x2e03.. indeed is the first one after 0x2000.., and therefore the attached proof concerns the origin, not the first key.

So, short-short version: the left-hand side of the proof relates to the origin, and is free-standing from the first leaf.

On the other hand, (pun intended), the right-hand side, there's no such 'gap' between "along what path does the proof walk" and the last provided leaf. The proof must prove the last element (unless there are no elements).

Therefore, we can simplify the semantics for trie.VerifyRangeProof by removing an argument. This doesn't make much difference in practice, but makes it so that we can remove some tests. The reason I am raising this is that the upcoming stacktrie-based verifier does not support such fancy features as standalone right-hand borders.
2023-10-13 16:05:29 +02:00
Péter Szilágyi
31b566f7a8 go.mod: update AWS APIs to latest heads (#28332) 2023-10-13 15:19:03 +03:00
Martin Holst Swende
ed5da55149 build: move version-info into checksum file (#28324)
* build: upgrade to golang 1.21.2

* build: verify checksums via tool

* deps: upgrade go to 1.21.3

* build: move more build metadata into checksum file

* build: move gobootsrc to checksums
2023-10-13 15:14:48 +03:00
Péter Szilágyi
660cbe4117 go.mod: update fastcache to latest (#28334) 2023-10-13 15:13:34 +03:00
Péter Szilágyi
78c8e1060c go.mod: update gnark lib to fix a malleability issue (#28333) 2023-10-13 13:49:40 +03:00
Péter Szilágyi
1f30cae4ad go.mod, internal/build: update Azure dependencies (#28329) 2023-10-13 12:58:07 +03:00
rjl493456442
1cb3b6aee4 eth/protocols/snap: fix snap sync failure on empty storage range (#28306)
This change addresses an issue in snap sync, specifically when the entire sync process can be halted due to an encountered empty storage range.

Currently, on the snap sync client side, the response to an empty (partial) storage range is discarded as a non-delivery. However, this response can be a valid response, when the particular range requested does not contain any slots.

For instance, consider a large contract where the entire key space is divided into 16 chunks, and there are no available slots in the last chunk [0xf] -> [end]. When the node receives a request for this particular range, the response includes:

    The proof with origin [0xf]
    A nil storage slot set

If we simply discard this response, the finalization of the last range will be skipped, halting the entire sync process indefinitely. The test case TestSyncWithUnevenStorage can reproduce the scenario described above.

In addition, this change also defines the common variables MaxAddress and MaxHash.
2023-10-13 09:08:26 +02:00
Péter Szilágyi
2f66d7c47c params: begin v1.13.4 release cycle 2023-10-12 14:39:10 +03:00
Péter Szilágyi
0d45d72d70 params: release Geth v.1.13.3 2023-10-12 14:36:49 +03:00
Martin Holst Swende
d2c0bed9d5 cmd/geth: fix failing test (#28322) 2023-10-12 09:54:00 +02:00
vuittont60
0004c6b229 accounts, cmd: fix typos (#28300) 2023-10-11 11:29:10 +03:00
rjl493456442
eeb5dc3ccf cmd, core: resolve scheme from a read-write database (#28313)
* cmd, core: resolve scheme from a read-write database

* cmd, core, eth: move the scheme check in the ethereum constructor

* cmd/geth: dump should in ro mode

* cmd: reverts
2023-10-11 11:27:44 +03:00
Péter Szilágyi
13d1d425ac eth/fetcher: fix typo 2023-10-11 11:23:57 +03:00
Péter Szilágyi
a6deb2d994 eth/fetcher: throttle tx fetches to 128KB responses (#28304)
* eth/fetcher: throttle tx fetches to 128KB responses

* eth/fetcher: unindent a clause per review request
2023-10-11 10:50:09 +03:00
rjl493456442
7776a3214a ethdb/pebble: add level file metrics (#28271) 2023-10-11 09:18:18 +02:00
Martin Holst Swende
8976a0c97a trie: remove owner and binary marshaling from stacktrie (#28291)
This change
  - Removes the owner-notion from a stacktrie; the owner is only ever needed for comitting to the database, but the commit-function, the `writeFn` is provided by the caller, so the caller can just set the owner into the `writeFn` instead of having it passed through the stacktrie.
  - Removes the `encoding.BinaryMarshaler`/`encoding.BinaryUnmarshaler` interface from stacktrie. We're not using it, and it is doubtful whether anyone downstream is either.
2023-10-11 06:12:45 +02:00
Péter Szilágyi
2c007cfed7 accounts/abi/bind/backend: use requested header for gas prices and gas limits (#28280) 2023-10-10 15:53:01 +03:00
lightclient
5e43ed0d72 git: ignore tests/spec-tests folder (#28254) 2023-10-10 10:56:50 +02:00
Péter Szilágyi
8afbcf4713 eth: enforce announcement metadatas and drop peers violating the protocol (#28261)
* eth: enforce announcement metadatas and drop peers violating the protocol

* eth/fetcher: relax eth/68 validation a bit for flakey clients

* tests/fuzzers/txfetcher: pull in suggestion from Marius

* eth/fetcher: add tests for peer dropping

* eth/fetcher: linter linter linter linter linter
2023-10-10 11:35:51 +03:00
Brandon Liu
6505297456 trie: fix a typo, use correct docstrings (#28302)
* fix a typo

* trie: additional fixes to docstrings

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-10-10 10:32:14 +02:00
Martin Holst Swende
6b1e4f4211 all: move light.NodeSet to trienode.ProofSet (#28287)
This is a minor refactor in preparation of changes to range verifier. This PR contains no intentional functional changes but moves (and renames) the light.NodeSet
2023-10-10 10:30:47 +02:00
hyunchel
db9afae2ea eth, params: fix typos (#28286)
* eth/ethconfig: fix typo on comment

* params/config: fix typo on comment

* eth/ethconfig: fix typo on comment
2023-10-10 10:22:45 +02:00
0xbstn
fa6107c85e core: fix typos (#28255)
fixes various typos in core
2023-10-10 10:22:03 +02:00
Martin Holst Swende
08326794e8 trie: refactor stacktrie (#28233)
This change refactors stacktrie to separate the stacktrie itself from the
internal representation of nodes: a stacktrie is not a recursive structure
of stacktries, rather, a framework for representing and operating upon a set of nodes.

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-10-10 08:28:56 +02:00
hyunchel
4e1e37323d core/txpool/legacypool: fix typo (#28258) 2023-10-07 10:57:12 +08:00
tactical_retreat
052355f5e2 cmd/evm/internal/t8ntoo: tiny bugfix for difficulty field (#28245) 2023-10-04 12:38:25 +03:00
Péter Szilágyi
95b0555c84 eth: when snap is complaining for missing eth, be verbose about the details (#28249)
* eth: when snap is complaining for missing eth, be verbost about the details

* eth: lower snapshot registration error verbosity
2023-10-04 12:37:04 +03:00
Péter Szilágyi
a8a9c8e4b0 core, eth, miner: start propagating and consuming blob txs (#28243)
* core, eth, miner: start propagating and consuming blob txs

* eth/protocols/eth: disable eth/67 if Cancun is enabled

* core/txpool, eth, miner: pass gas limit infos in lazy tx for mienr filtering

* core/txpool, miner: add lazy resolver for pending txs too

* core, eth: fix review noticed bugs

* eth, miner: minor polishes in the mining and announcing logs

* core/expool: unsubscribe the event scope
2023-10-04 12:36:36 +03:00
Péter Szilágyi
bc6d184872 cmd/devp2p, eth: drop eth/66 (#28239)
* cmd/devp2p, eth: drop eth/66

* eth/protocols/eth: yes sir, linter
2023-10-03 15:03:19 +03:00
hyunchel
7963c4e808 rpc: fix erroneous error-message in test (#28227) 2023-10-03 07:48:36 -04:00
Chirag Garg
2091ebdf5e trie: fix benchmark by ensuring key immutability (#28221)
This change fixes the bug in a benchmark, where the input to the trie is reused in a way which is not correct. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-10-03 07:46:22 -04:00
0xbstn
339a4cf056 core: fix typos (#28238) 2023-10-03 07:44:01 -04:00
lightclient
07dec7a11c cmd/evm: cancun-updates for b11r and t8n -tools (#28195)
This change updates `evm b11r` (blockbuilder) and `evm t8n` (transition) tools to contain cancun updates (e.g. new header fields)
---------

Co-authored-by: Mario Vega <marioevz@gmail.com>
2023-10-03 03:26:33 -04:00
tylerni7
705a51e566 eth, rpc: add configurable option for wsMessageSizeLimit (#27801)
This change adds a configurable limit to websocket message. 
---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-10-03 03:23:19 -04:00
Marius van der Wijden
c39cbc1a78 core: implement BLOBBASEFEE opcode (0x4a) (#28098)
Implements "EIP-7516: BLOBBASEFEE opcode" for cancun, as per spec: https://eips.ethereum.org/EIPS/eip-7516
2023-10-02 05:49:29 -04:00
Péter Szilágyi
7b6ff527d5 cmd, eth: switch the dev synctarget to hash from block (#28209)
* cmd, eth: switch the dev synctarget to hash from block

* cmd/utils, eth/catalyst: terminate node wyen synctarget reached
2023-09-29 22:11:15 +03:00
lightclient
a408e37fa1 eth/catalyst: add validation error in new paylaod hash mismatch (#28226)
* eth/catalyst: add validation error in new paylaod hash mismatch

* eth/catalyst/api: refactor api.invalid(..) to return nil latest valid hash if none provided
2023-09-29 21:27:30 +03:00
Péter Szilágyi
966e50bddb ethdb/pebble: luv you linter 2023-09-29 20:52:55 +03:00
rjl493456442
22dcb7a77b ethdb/pebble: upgrade pebble to master (aa077af62593) (#28070)
* ethdb/pebble: upgrade pebble

* ethdb/pebble, go.mod: update pebble to master (aa077af62593)

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2023-09-29 20:45:38 +03:00
Péter Szilágyi
1f9d672df1 common: remove address.Hash footgun (#28228) 2023-09-29 18:14:26 +03:00
aaronbuchwald
c5ff839fb2 core/state: small trie prefetcher nits (#28183)
Small trie prefetcher nits
2023-09-29 17:46:23 +03:00
Sina Mahmoodi
0ded110b80 core: infer blobGasUsed in chain maker (#28212)
Same way that the gasUsed in header is updated when a tx 
is added we should update blob gas used instead of requiring caller
to set it manually.
2023-09-29 10:44:28 +02:00
0xbstn
1f6e63900d core: fix typos (#28218)
* fix(core/txpool): fix typos

* core/asm: fix typos

* core/bloombits: fix typos

* core/rawdb: fix typos
2023-09-29 10:52:22 +03:00
Péter Szilágyi
f988b2332e ethdb, internal/ethapi: support exposing Pebble stats too, beside LevelDB (#28224)
ethdb, internal/ethapi: support exposing Pebble stats too, besinde LevelDB
2023-09-28 22:27:21 +03:00
phenix3443
b9450bfcca core, eth: typos and some code formatting (#28201)
* fix: typo

* feat: revert symbol name
2023-09-28 13:15:50 +03:00
Delweng
46c850a941 internal/ethapi: compact db missing key starts with 0xff (#28207)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-09-28 12:04:45 +03:00
lightclient
37a2d919b0 params: update 4788 beacon roots contract addr (#28205)
This change contains the final (?) address for 4788 beacon root contract. The update to the EIP is being tracked here: https://github.com/ethereum/EIPs/pull/7672

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-09-28 03:52:27 -04:00
Péter Szilágyi
3dc45a3e1d params: begin v1.13.3 release cycle 2023-09-28 10:23:25 +03:00
Péter Szilágyi
dc34fe8291 params: release Geth v1.13.2 2023-09-28 10:22:09 +03:00
rjl493456442
73f5bcb75b core, accounts, eth, trie: handle genesis state missing (#28171)
* core, accounts, eth, trie: handle genesis state missing

* core, eth, trie: polish

* core: manage txpool subscription in mainpool

* eth/backend: fix test

* cmd, eth: fix test

* core/rawdb, trie/triedb/pathdb: address comments

* eth, trie: address comments

* eth: inline the function

* eth: use synced flag

* core/txpool: revert changes in txpool

* core, eth, trie: rename functions
2023-09-28 10:00:53 +03:00
0xbstn
a081130081 core/txpool: fix typos (#28213)
fix(core/txpool): fix typos
2023-09-28 09:48:14 +08:00
bnovil
614804b33c core/txpool: fix typos (#28208)
core/txpool:fix typos
2023-09-27 11:08:53 +08:00
rjl493456442
b85c183ea7 eth/downloader: remove header rollback mechanism (#28147)
* eth/downloader: remove rollback mechanism in downloader

* eth/downloader: remove the tests
2023-09-26 16:29:13 +03:00
Sina Mahmoodi
adb9b319c9 internal/ethapi: eth_call block parameter is optional (#28165)
So apparently in the spec the base block parameter of eth_call is optional.
I agree that "latest" is a sane default for this that most people would use.
2023-09-26 14:22:11 +02:00
Marius van der Wijden
2b7bc2c36b eth/fetcher: allow underpriced transactions in after timeout (#28097)
This PR will allow a previously underpriced transaction back in after a timeout
of 5 minutes. This will block most transaction spam but allow for transactions to
be re-broadcasted on networks with less transaction flow.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-09-26 13:12:44 +02:00
phenix3443
40219109b0 eth/downloader: typo in comment (#28196) 2023-09-26 11:59:41 +03:00
hzysvilla
4de89e92e4 core/vm: minor code formatting (#28199)
Adding a space beween function opOrigin() and opcCaller() in instruciton.go.
Adding a space beween function opkeccak256()  and opAddress() in instruciton.go.
2023-09-26 11:58:01 +03:00
Andryanau Kanstantsin
4985d83b8f ethclient: fix BlockReceipts parameter encoding (#28087)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-09-25 23:24:20 +02:00
buddho
f6f64cc43d cmd/utils: fix bootnodes config priority (#28095)
This fixes an issue where the --bootnodes flag was overridden by the config file.

---------

Co-authored-by: NathanBSC <Nathan.l@nodereal.io>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-09-25 19:17:39 +02:00
Delweng
3d297fc2d7 cmd/geth: ensure db is closed before exit (#28150) 2023-09-25 18:28:20 +02:00
Felix Lange
c3742a9ae0 internal/debug: add --log.rotate to the logging category (#28190) 2023-09-25 17:02:44 +03:00
Marius van der Wijden
1fa3362ea7 core/forkid: add forkid test for holesky (#28193) 2023-09-25 17:02:19 +03:00
tokikuch
c2cfe35f12 core/bloombits: fix deadlock when matcher session hits an error (#28184)
When MatcherSession encounters an error, it attempts to close the session.
Closing waits for all goroutines to finish, including the 'distributor'. However, the
distributor will not exit until all requests have returned.

This patch fixes the issue by delivering the (empty) result to the distributor
before calling Close().
2023-09-25 15:35:24 +02:00
Péter Szilágyi
d051ea5e89 params: update hash for Holesky relaunch (#28192) 2023-09-25 16:13:56 +03:00
Péter Szilágyi
323542af50 core, params: update Holesky testnet to relaunched spec (#28191) 2023-09-25 16:10:23 +03:00
Péter Szilágyi
82ec555d70 cmd: add state.scheme to the database flag group for local flag handling (#28107) 2023-09-22 14:56:48 +03:00
Delweng
f1b2ec0833 core/rawdb: use readonly file lock in readonly mode (#28180)
This allows using the freezer from multiple processes at once
in read-only mode.

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-09-22 12:10:50 +02:00
Péter Szilágyi
d135bafdcb cmd/geth: print progress logs when iterating large contracts too (#28179) 2023-09-22 11:07:20 +03:00
Péter Szilágyi
83f3fc2e80 core/state/snapshot: be very noisy if the generator hits a trie error (#28178) 2023-09-22 10:27:58 +03:00
rjl493456442
03c2176a1d trie/triedb/pathdb: improve error log (#28177) 2023-09-22 09:33:17 +03:00
rjl493456442
4773dcbc81 trie: remove internal nodes between shortNode and child in path mode (#28163)
* trie: remove internal nodes between shortNode and child in path mode

* trie: address comments

* core/rawdb, trie: address comments

* core/rawdb: delete unused func

* trie: change comments

* trie: add missing tests

* trie: fix lint
2023-09-22 09:31:10 +03:00
Delweng
545f4c5547 core/rawdb: no need to run truncateFile for readonly mode (#28145)
Avoid truncating files, if ancients are opened in readonly mode. With this change, we return error instead of trying (and failing)  to repair
2023-09-21 04:05:55 -04:00
Delweng
5b9cbe30f8 cmd/clef: suppress fsnotify error if keydir not exists (#28160)
As the keydir will be automatically created after an account is created, no error message if the watcher is failed.
2023-09-20 06:39:46 -04:00
phenix3443
5c6f4b9f0d cmd/utils: fix typo in comment (#28159) 2023-09-19 21:20:18 +02:00
Guillaume Ballet
7ed5bc021a trie: add getter for preimage store in trie.Database (#28155) 2023-09-19 08:47:24 -04:00
Martin Holst Swende
30d5d7c1b3 go.mod: use existing version of karalabe/usb (#28127)
There is no 0.0.3 release of karalabe/usb.
2023-09-19 14:20:06 +02:00
Delweng
41a0ad9f03 cmd/devp2p: use bootnodes as crawl input (#28139)
This PR makes the tool use the --bootnodes list as the input to devp2p crawl.
The flag will take effect if the input/output.json file is missing or empty.
2023-09-19 14:18:29 +02:00
bnovil
4b748b7a27 eth: fix typo in comment (#28146) 2023-09-19 14:14:36 +02:00
Delweng
ef76afad35 core/rawdb: fix typo in comment (#28140) 2023-09-19 13:43:37 +02:00
Felix Lange
e9f78db79d cmd/evm: fix some issues with the evm run command (#28109)
* cmd/evm: improve flags handling

This fixes some issues with flags in cmd/evm. The supported flags did not
actually show up in help output because they weren't categorized. I'm also
adding the VM-related flags to the run command here so they can be given
after the subcommand name. So it can be run like this now:

   ./evm run --code 6001 --debug

* cmd/evm: enable all forks by default in run command

The default genesis was just empty with no forks at all, which is annoying because
contracts will be relying on opcodes introduced in a fork. So this changes the default to
have all forks enabled.

* core/asm: fix some issues in the assembler

This fixes minor bugs in the old assembler:

- It is now possible to have comments on the same line as an instruction.
- Errors for invalid numbers in the jump instruction are reported better
- Line numbers in errors were off by one
2023-09-19 13:41:16 +02:00
Péter Szilágyi
90d5bd85bc params: begin Geth v1.13.2 release cycle 2023-09-17 17:55:46 +03:00
Péter Szilágyi
3f40e65c48 params: release Geth v1.13.1 2023-09-17 17:54:33 +03:00
rjl493456442
c53b0fef2a core, eth/downloader: fix genesis state missing due to state sync (#28124)
* core: fix chain repair corner case in path-based scheme

* eth/downloader: disable trie database whenever state sync is launched
2023-09-17 17:35:09 +03:00
phenix3443
d8a351b58f params: fix typo in comment (#28129)
fix: typo
2023-09-17 17:02:48 +03:00
phenix3443
52234eb172 internal/flags: fix typo (#28133)
fix(flag): one typo
2023-09-17 17:02:11 +03:00
cam-schultz
217719347d internal/ethapi: correctly calculate effective gas price (#28130)
correctly calculate effective gas price
2023-09-17 17:00:04 +03:00
rjl493456442
9a9db3d265 eth/catalyst: fix engine API (#28135) 2023-09-17 16:50:18 +03:00
Péter Szilágyi
16cd1a7561 cmd/geth, internal/flags: print envvar config source and bad names (#28119) 2023-09-15 15:52:53 +03:00
Péter Szilágyi
4fa3db49a1 eth/downloader: prevent pivot moves after state commit (#28126) 2023-09-15 15:06:25 +03:00
Darioush Jalali
48fdb79de5 core/state: check err for iter.Error in fastDeleteStorage (#28122)
core/state: check err for iter.Error
2023-09-15 14:09:07 +08:00
Péter Szilágyi
65a17c00c7 metrics: add support for enabling metrics from env vars (#28118) 2023-09-14 13:56:06 +03:00
Felix Lange
909dd4a109 rlp/rlpgen: remove build tag (#28106)
* rlp/rlpgen: remove build tag

This tag was supposed to prevent unstable output when types reference each other. Imagine
there are two struct types A and B, where a reference to type B is in A. If I run rlpgen
on type B first, and then on type A, the generator will see the B.EncodeRLP method and
call it. However, if I run rlpgen on type A first, it will inline the encoding of B.

The solution I chose for the initial release of rlpgen was to just ignore methods
generated by rlpgen using a build tag. But there is a problem with this: if any code in
the package calls EncodeRLP explicitly, the package can't be loaded without errors anymore
in rlpgen, because the loader ignores it. Would be nice if there was a way to just make it
ignore invalid functions during type checking (they're not necessary for rlpgen), but
golang.org/x/tools/go/packages does not provide a way of ignoring them.

Luckily, the types we use rlpgen with do not reference each other right now, so we can
just remove the build tags for now.
2023-09-14 12:28:40 +02:00
Péter Szilágyi
ee654626ad internal/flags: fix loading env vars for custom flags (#28117) 2023-09-14 12:43:58 +03:00
Delweng
8514d665ee graphql: add 4844 blob fields (#27963)
This adds block and receipt fields for EIP-4844.

---------

Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-09-14 10:23:16 +02:00
Péter Szilágyi
86bc2cdf33 internal/flags: fix linter 2023-09-14 10:58:13 +03:00
Marius Kjærstad
636c64caa9 build: upgrade -dlgo version to Go 1.21.1 (#28113) 2023-09-14 10:34:52 +03:00
Péter Szilágyi
d9fbb71d63 cmd/geth, internal/flags, go.mod: colorize cli help, support env vars (#28103)
* cmd/geth, internal/flags, go.mod: colorize cli help, support env vars

* internal/flags: use stdout, not stderr for terminal detection
2023-09-14 10:33:59 +03:00
Sina Mahmoodi
b9b99a12e5 eth: abort on api operations not available in pbss-mode (#28104)
eth: abort on api calls not supporting pbss
2023-09-14 03:10:37 -04:00
Péter Szilágyi
eb7438997b cmd/geth: rename the protocols field in the metrics gague (#28102) 2023-09-13 13:17:55 -04:00
Martin Holst Swende
8b6cf128af metrics: refactor metrics (#28035)
This change includes a lot of things, listed below. 

### Split up interfaces, write vs read

The interfaces have been split up into one write-interface and one read-interface, with `Snapshot` being the gateway from write to read. This simplifies the semantics _a lot_. 

Example of splitting up an interface into one readonly 'snapshot' part, and one updatable writeonly part: 

```golang
type MeterSnapshot interface {
	Count() int64
	Rate1() float64
	Rate5() float64
	Rate15() float64
	RateMean() float64
}

// Meters count events to produce exponentially-weighted moving average rates
// at one-, five-, and fifteen-minutes and a mean rate.
type Meter interface {
	Mark(int64)
	Snapshot() MeterSnapshot
	Stop()
}
```

### A note about concurrency

This PR makes the concurrency model clearer. We have actual meters and snapshot of meters. The `meter` is the thing which can be accessed from the registry, and updates can be made to it. 

- For all `meters`, (`Gauge`, `Timer` etc), it is assumed that they are accessed by different threads, making updates. Therefore, all `meters` update-methods (`Inc`, `Add`, `Update`, `Clear` etc) need to be concurrency-safe. 
- All `meters` have a `Snapshot()` method. This method is _usually_ called from one thread, a backend-exporter. But it's fully possible to have several exporters simultaneously: therefore this method should also be concurrency-safe. 

TLDR: `meter`s are accessible via registry, all their methods must be concurrency-safe. 

For all `Snapshot`s, it is assumed that an individual exporter-thread has obtained a `meter` from the registry, and called the `Snapshot` method to obtain a readonly snapshot. This snapshot is _not_ guaranteed to be concurrency-safe. There's no need for a snapshot to be concurrency-safe, since exporters should not share snapshots. 

Note, though: that by happenstance a lot of the snapshots _are_ concurrency-safe, being unmutable minimal representations of a value. Only the more complex ones are _not_ threadsafe, those that lazily calculate things like `Variance()`, `Mean()`.

Example of how a background exporter typically works, obtaining the snapshot and sequentially accessing the non-threadsafe methods in it: 
```golang
		ms := metric.Snapshot()
                ...
		fields := map[string]interface{}{
			"count":    ms.Count(),
			"max":      ms.Max(),
			"mean":     ms.Mean(),
			"min":      ms.Min(),
			"stddev":   ms.StdDev(),
			"variance": ms.Variance(),
```

TLDR: `snapshots` are not guaranteed to be concurrency-safe (but often are).

### Sample changes

I also changed the `Sample` type: previously, it iterated the samples fully every time `Mean()`,`Sum()`, `Min()` or `Max()` was invoked. Since we now have readonly base data, we can just iterate it once, in the constructor, and set all four values at once. 

The same thing has been done for runtimehistogram. 

### ResettingTimer API

Back when ResettingTImer was implemented, as part of https://github.com/ethereum/go-ethereum/pull/15910, Anton implemented a `Percentiles` on the new type. However, the method did not conform to the other existing types which also had a `Percentiles`. 

1. The existing ones, on input, took `0.5` to mean `50%`. Anton used `50` to mean `50%`. 
2. The existing ones returned `float64` outputs, thus interpolating between values. A value-set of `0, 10`, at `50%` would return `5`, whereas Anton's would return either `0` or `10`. 

This PR removes the 'new' version, and uses only the 'legacy' percentiles, also for the ResettingTimer type. 

The resetting timer snapshot was also defined so that it would expose the internal values. This has been removed, and getters for `Max, Min, Mean` have been added instead. 

### Unexport types

A lot of types were exported, but do not need to be. This PR unexports quite a lot of them.
2023-09-13 13:13:47 -04:00
Péter Szilágyi
8d38b1fe62 core/rawdb: skip pathdb state inspection in hashdb mode (#28108) 2023-09-13 15:13:10 +03:00
Martin Holst Swende
43df612268 internal, log: remove code for old unsupported go-versions (#28090) 2023-09-13 01:42:32 -04:00
Péter Szilágyi
766272ff8c params: begin v1.13.1 release cycle 2023-09-12 14:03:50 +03:00
Péter Szilágyi
7371b38171 params: release Geth v1.13.0 2023-09-12 13:57:10 +03:00
Bala Murali Krishna Komatireddy
12ef276a7d consensus/misc: fix min gas limit error message (#28085) 2023-09-11 04:57:22 -04:00
lightclient
1efd12f695 core: fix calculation of blob gasprice in tx receipt (#28082)
This fixes the derived value BlobGasPrice on the receipt of EIP-4844 transactions, which was previously erroneously set to the price cap.
2023-09-11 02:14:20 -04:00
Martin Holst Swende
5cf53f51ac ethclient: use 'input', not 'data' as field for transaction input (#28078) 2023-09-08 18:33:36 +02:00
Péter Szilágyi
83886e40b6 go.mod: pull in a fix from pebble crl-release-23.1 (#28081) 2023-09-08 17:23:57 +03:00
rjl493456442
a7842c9cae core, trie: cleanup trie database (#28062) 2023-09-07 21:17:14 +08:00
Martin Holst Swende
a8d7201ec5 log: avoid stack lookups when not needed/used (#28069)
Avoids the somewhat expensive stack.Caller invocation by checking if it is needed
2023-09-07 08:48:49 -04:00
Martin Holst Swende
c60f7dd08d deps: update minisign (#28066)
This updates minisign to the latest version. One new thing is that minisign (not go-minisign) has started to prehash the file, and in order to make geth pass the version-check, we need to sign the file in legacy-mode.
2023-09-07 04:18:46 -04:00
Delweng
2e02c1ffd9 core/rawdb: don't warn for missing "unclean shutdown markers" (#28014)
This changes removes the warn-printout about not finding unclean shutdown markers, which always happens on fresh installs / wiped databases.
2023-09-06 06:29:51 -04:00
ucwong
2f77299136 go.mod: goupnp 1.3.0 (#28053) 2023-09-06 11:17:36 +03:00
lightclient
25733a4aad params: update 4844 parameters (#28026)
On ACD 163, it was agreed to bump the target and max blob values from `2/4` to `3/6` for future devnets until we could decide on final mainnet number. This change contains said update, making master pass all the hive tests. The final decision for mainnet cancun is still to be made.
---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-09-05 04:49:51 -04:00
lightclient
eff7c3bda0 core/forkid: skip genesis forks by time (#28034)
* core/forkid: skip genesis forks by time

* core/forkid: add comment about skipping non-zero fork times

* core/forkid: skip all time based forks in genesis using loop

* core/forkid: simplify logic for dropping time-based forks
2023-09-04 09:32:14 -04:00
lightclient
f260a9edb9 beacon/engine: add shouldOverrideBuilder to payload envelope (#28029)
beacon/engine: add shouldOverrideBuilder to payload envelope
2023-09-04 09:26:13 -04:00
Marius van der Wijden
28857080d7 eth/catalyst: set random value in dev mode (#27940)
* eth/catalyst: set random

* Apply suggestions from code review

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-31 14:37:16 -04:00
rjl493456442
0acc0a1f86 core/state: simplify storage trie update and commit (#28030)
This change improves function description and simplifies logic in statedb update and commit operations.
2023-08-31 14:33:18 -04:00
Jorge
53f3c2ae65 metrics, cmd/geth: informational metrics (prometheus, influxdb, opentsb) (#24877)
This chang creates a GaugeInfo metrics type for registering informational (textual) metrics, e.g. geth version number. It also improves the testing for backend-exporters, and uses a shared subpackage in 'internal' to provide sample datasets and ordered registry. 

Implements #21783

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-31 13:37:17 -04:00
Péter Szilágyi
5b159498bb go.mod: regenerate all indirect dependencies to clean up the junk (#28037) 2023-08-31 16:00:31 +03:00
lightclient
41ee96fdfe core/txpool/blobpool: fix rlp decoding flaw during offload (#28027) 2023-08-30 03:28:03 -04:00
Martin Holst Swende
b8adb4cb0c tests: use 'sender' in state tests if present (#28023)
A while back, statetests started coming with sender baked in, which at least 
evmone makes use of. Let's make use of that too, and save some cycles.
2023-08-29 04:36:10 +02:00
CrashOverride
fe24d22a62 miner/stress/clique: fix typo (#28016)
fix typo
2023-08-28 02:36:11 -04:00
Marius van der Wijden
f174ddba7a build, tests: add execution-spec-tests (#26985)
This makes it possible to run the execution-spec-tests (a.k.a. pyspec) in CI.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-26 15:42:27 +02:00
Martin Holst Swende
d4e345c7d4 core/state: fix missing import (#28010) 2023-08-26 04:43:36 -04:00
lightclient
3a662d4735 eth: remove check for tdd reached on pos api block tags (#27799)
This change defers to the blockchain for in what circumstances to return error, instead of handling many error-cases in the api backend.
2023-08-26 04:19:01 -04:00
rjl493456442
3ff6b3c31e core/state: implement fast storage deletion (#27955)
This changes implements faster post-selfdestruct iteration of storage slots for deletion, by using snapshot-storage+stacktrie to recover the trienodes to be deleted. This mechanism is only implemented for path-based schema. 

For hash-based schema, the entire post-selfdestruct storage iteration is skipped, with this change, since hash-based does not actually perform deletion anyway. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-26 04:13:22 -04:00
Shude Li
5ca7fb82d6 account/abi: handle solidity panic revert (#27868)
See  https://docs.soliditylang.org/en/v0.8.21/control-structures.html#panic-via-assert-and-error-via-require
2023-08-26 04:10:48 -04:00
Martin Holst Swende
6aa88ccdd2 beacon/engine, eth/catalyst, miner: EIP-4788 CL/EL protocol updates (#27872)
This PR makes EIP-4788 work in the engine API and miner. It also fixes some bugs related to 
EIP-4844 block processing and mining. Changes in detail:

- Header.BeaconRoot has been renamed to ParentBeaconRoot.
- The engine API now implements forkchoiceUpdatedV3
- newPayloadV3 method has been updated with the parentBeaconBlockRoot parameter
- beacon root is now applied to new blocks in miner
- For EIP-4844, block creation now updates the blobGasUsed field of the header
2023-08-26 04:52:12 +02:00
Delweng
cde462c6bf eth/catalyst: reset to current header if chain is rewound (in dev mode) (#27992)
Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Jared Wasinger <j-wasinger@hotmail.com>
2023-08-25 15:38:27 -04:00
Felix Lange
9bbb9df185 core/types: transaction and receipt encoding/decoding optimizations (#27976)
Just some minor optimizations I figured out a while ago. By using ReadBytes instead of
Bytes on the rlp stream, we can save the allocation of a temporary buffer for the typed tx
payload.

If kind == rlp.Byte, the size reported by Stream.Kind will be zero, but we need a buffer
of size 1 for ReadBytes. Since typed txs always have to be longer than 1 byte, we can just
return an error for kind == rlp.Byte.

There is a also a small change for Log: since the first three fields of Log are the ones that 
should appear in the canon encoding, we can simply ignore the remaining fields via 
struct tag. Doing this removes an indirection through the rlpLog type.

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-25 20:03:41 +02:00
Péter Szilágyi
6b98d18789 cmd, core, params: add support for the Holesky testnet (#28007)
* cmd, core, params: add support for the Holesky testnet

* cmd/devp2p: add support for holesky for the dns crawler
2023-08-25 18:11:40 +03:00
Péter Szilágyi
5e0eb62a8e eth/protocols/eth: stop advertising eth/66 for pathdb nodes (#28006) 2023-08-25 18:10:30 +03:00
Felix Lange
6dc9cdf15b core: support null balance in genesis (#28005) 2023-08-25 15:59:40 +02:00
aaronbuchwald
56d2366699 core/state/snapshot: replace diffToDisk ideal batch size with 64MB (#27977) 2023-08-25 15:48:10 +03:00
Guido Vranken
0ba2d3cfa4 core/vm/runtime: Add Random field to config (#28001) 2023-08-25 04:05:33 -04:00
rjl493456442
1a2135044c eth/catalyst: use block as finalization (#28000) 2023-08-24 11:49:13 +03:00
Delweng
45b198dd3a eth/catalyst: disable heartbeat for simulated beacon node (#27979)
* eth/catalyst: disable heartbeat for simulated beacon node

Signed-off-by: jsvisa <delweng@gmail.com>

* eth/catalyst: update

* eth/catalyst: disable heartbeat for tester

---------

Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-08-24 11:48:09 +03:00
Felix Lange
9b46986edc all: use rlp.DecodeBytes instead of rlp.Decode where possible (#27994) 2023-08-24 11:47:42 +03:00
Marius van der Wijden
60ec41ce73 miner: refactor getSealingBlock method (#27993) 2023-08-24 00:28:38 +02:00
lightclient
feb8f416ac miner: add to build block with EIP-4844 blobs (#27875)
---------

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-23 23:16:14 +02:00
Felix Lange
d1f6735171 core/rawdb: fix 32bit build (#27995) 2023-08-23 23:14:36 +02:00
Martin Holst Swende
eb6cbe37e1 core/state: remove public method ForEachStorage (#27986)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-23 21:53:31 +02:00
Marius van der Wijden
2f4dbb4f90 core/rawdb: allocate database keys with explicit size to avoid slice growth (#27772) 2023-08-23 21:41:56 +02:00
cui
4abc412348 crypto/bn256: eliminate dead store (#27944) 2023-08-23 21:26:30 +02:00
ucwong
e3f3e01504 les: use new atomic types (#27856)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-23 21:19:04 +02:00
Martin Holst Swende
f0f8703bf2 core/rawdb, ethdb/pebble: avoid fsync db in tests (#27836)
Adds an option to disable fsync for database operations.
This is to make tests faster.
2023-08-23 20:43:55 +02:00
Felix Lange
5c7136adb4 rlp: remove allocation of bytes.Reader in DecodeBytes (#27987) 2023-08-23 20:31:05 +02:00
Péter Szilágyi
52219ced8b travis: get rid of old useless GO111MODULE directives (#27991) 2023-08-23 18:54:30 +03:00
Shude Li
76d4ac1acb account/abi: convert if-else-if chain to tagged switch (#27869)
account/abi: conver if-else-if chain to tagged switch
2023-08-23 09:53:38 -04:00
Martin Holst Swende
4af98d4ee6 travis: increase travis wait time (#27975) 2023-08-23 16:49:36 +03:00
Péter Szilágyi
00fead91c4 cmd/utils: fix a startup issue on deleted chaindata but dangling ancients (#27989) 2023-08-23 16:42:37 +03:00
rjl493456442
bce5c46739 eth/catalyst: disable full payload when not in dev mode (#27921)
eth/catalyst: only enable full payload in dev mode
2023-08-23 15:14:04 +03:00
Péter Szilágyi
0c6bbeb423 core, eth, trie: expose more detailed dirty ram tracking for diff layers (#27971) 2023-08-23 14:08:39 +03:00
Péter Szilágyi
ab3762b2d9 go.mod: update pebble to crl-release-23.1 (#27967) 2023-08-23 10:50:28 +03:00
Delweng
c31f9cf23a graphql: fix nil deref on a timer (#27978)
graphql: fix the panic of nil timer.Stop

Signed-off-by: jsvisa <delweng@gmail.com>
2023-08-23 03:47:42 -04:00
Martin Holst Swende
16946d218a rpc: use go-winio for named pipes (#27972)
We're trying a new named pipe library, which should hopefully fix some occasional failures in CI.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-23 04:39:01 +02:00
Felix Lange
4c7053baf1 core: add BeaconRoot to header in GenerateChain (#27974)
Fixes an error in tests of internal/ethapi.
2023-08-22 18:29:17 +02:00
Martin Holst Swende
8d2492982b cmd/evm: add back stateroot to jsonl-output (#27968)
The PR #26274 broke the evm statetest command a bit, in that it stopped spitting out the stateroot following a non-successful statetest-execution. 

This PR changes it back, so the stateroot is unconditionally output on stderr, and makes it so fuzzing works again.
2023-08-22 09:37:04 -04:00
Martin Holst Swende
b8d38e76ef core, params, beacon/engine: implement EIP 4788 BeaconRoot (#27849)
This change implements "EIP 4788 : Beacon block root in the EVM". It implements version-2 of EPI-4788, main difference being that the contract is an actual contract rather than a precompile, as in #27289.
2023-08-22 08:33:39 -04:00
Marius van der Wijden
0b4b299099 go.mod: update docker (#27970) 2023-08-22 14:11:25 +03:00
Martin Holst Swende
55c5f5964d travis, build: update Go to 1.21.0 (#27958)
build: update to go 1.21
2023-08-22 11:00:01 +03:00
shuo
bbee0e7e50 miner: fix reply -> replay typo (#27961)
* typo: reply -> replay

* rebuild
2023-08-22 10:59:38 +03:00
Delweng
7c0d90c8c9 core: ensure txindex will be triggered at least once (#27847)
Currently, we trigger the logic to (un)index transactions when the node receives a new
block. However, in some cases the node may not receive new blocks (eg, when the Geth node
is configured without peer discovery, or when it acts as an RPC node for historical-only
data).

In these situations, the Geth node user may not have previously configured txlookuplimit
(i.e. the default of around one year), but later realizes they need to index all
historical blocks. However, adding txlookuplimit=0 and restarting geth has no effect. This
change makes it check for required indexing work once, on startup, to fix the issue.

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-22 02:58:20 +02:00
Delweng
9f4a528793 internal/ethapi: add testcases for blobTx (#27818)
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-22 02:53:29 +02:00
jwasinger
f56ee7d9c5 eth/catalyst: set finalized block hash properly in dev mode (#27886)
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-21 13:33:37 -04:00
Marius van der Wijden
b3024e8fe6 eth: ignore genesis block on importChain (#27956) 2023-08-21 13:32:34 -04:00
Marius van der Wijden
5976e58415 trie: reduce allocs in recHash (#27770) 2023-08-18 22:41:19 +02:00
Marius van der Wijden
7dea9c10cd internal/ethapi: eth API changes needed for 4844 (#27928)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-18 14:22:35 +02:00
Roberto Bayardo
950ccddfc8 internal/ethapi: optimize & clean up EstimateGas (#27710)
Optimizations:

- Previously, if a transaction was reverting, EstimateGas would exhibit worst-case behavior and binary search up to the max gas limit (~40 state-clone + tx executions). This change allows EstimateGas to return after only a single unconstrained execution in this scenario.
- Uses the gas used from the unconstrained execution to bias the remaining binary search towards the likely solution in a simple way that doesn't impact the worst case. For a typical contract-invoking transaction, this reduces the median number of state-clone+executions from 25 to 18 (28% reduction).

Cleanup:

- added & improved function + code comments
- correct the EstimateGas documentation to clarify the gas limit determination is at latest block, not pending, if the blockNr is unspecified.
2023-08-18 03:03:14 -04:00
Delweng
649deb69f3 eth/downloader: fix rare crash when parent header missing in db (#27945)
ReadSkeletonHeader can return nil if the header is missing, so we should
not access fields on it. Note that calling .Hash() on a nil header is fine, so there 
is no need to actually check for nil.

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-17 23:15:29 +02:00
Martin Holst Swende
1aa5520d75 core/txpool/legacypool: protect cache with mutex (#27898)
This change fixes the a potential race by using mutexes when the m.cache is read or modified.
2023-08-17 05:22:18 -04:00
lightclient
32fde3f838 core/forkid: correctly compute forkid when timestamp fork is activated in genesis (#27895)
This changes the forkID calculation to ignore time-based forks that occurred before the
genesis block. It's supposed to be done this way because the spec says:

> If a chain is configured to start with a non-Frontier ruleset already in its genesis, that is NOT considered a fork.
2023-08-16 23:31:02 +02:00
lightclient
a3e35414b7 core/types: fix unmarshalling of BlobTx values (#27939)
FromBig returns true *when overflow occurs*
2023-08-16 23:22:15 +02:00
Delweng
386cba15b5 node: increase batch limits for auth rpc API (#27924)
This raises the JSON-RPC batch request limits significantly for the engine API endpoint.
The limits are now also hard-coded, so users won't get them wrong. I have chosen these limits:

    maximum batch items: 2000
    maximum batch response size: 250MB

While it would also be possible to disable batch limits completely for the engine API, 
I think having some limits is a good safety net against misbehaving CLs. Since this
 isn't configurable, we really want to ensure this limit will never become an issue in the
 CL/EL communication, so I set them quite high.

---------

Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-16 15:26:49 +02:00
Martin Holst Swende
a16d757cd4 build: remove ubuntu kinetic (deprecated) (#27933) 2023-08-16 12:11:22 +02:00
Joe Netti
e0b119884c eth/tracers/js: use t.toBig on ctx.GasPrice for js tracing (#27903)
This change fixes a bug in js tracer, where `ctx.GasPrice.toString(16)` returns a number string in base `10`.
2023-08-15 14:19:37 -04:00
Paweł Bylica
ab28680e66 trie: add tests for "short" nodes in StackTrie (#27932) 2023-08-15 14:16:00 -04:00
lonika
05a8b887a9 crypto/bls12381: fix typo in comment (#27930) 2023-08-15 14:37:34 +02:00
Delweng
f1801a9fed internal/ethapi: implement eth_getBlockReceipts (#27702) 2023-08-15 14:35:48 +02:00
ucwong
509cd428e9 go.mod: upgrade goja (#27899) 2023-08-14 14:59:05 +02:00
Delweng
68855216c9 cmd/utils: restore support for txlookuplimit flag (#27917)
This fixes a regression where -txlookuplimit was not applied anymore.
2023-08-14 14:58:01 +02:00
Felix Lange
2a6beb6a39 core/types: support for optional blob sidecar in BlobTx (#27841)
This PR removes the newly added txpool.Transaction wrapper type, and instead adds a way
of keeping the blob sidecar within types.Transaction. It's better this way because most
code in go-ethereum does not care about blob transactions, and probably never will. This
will start mattering especially on the client side of RPC, where all APIs are based on
types.Transaction. Users need to be able to use the same signing flows they already
have.

However, since blobs are only allowed in some places but not others, we will now need to
add checks to avoid creating invalid blocks. I'm still trying to figure out the best place
to do some of these. The way I have it currently is as follows:

- In block validation (import), txs are verified not to have a blob sidecar.
- In miner, we strip off the sidecar when committing the transaction into the block.
- In TxPool validation, txs must have a sidecar to be added into the blobpool.
  - Note there is a special case here: when transactions are re-added because of a chain
    reorg, we cannot use the transactions gathered from the old chain blocks as-is,
    because they will be missing their blobs. This was previously handled by storing the
    blobs into the 'blobpool limbo'. The code has now changed to store the full
    transaction in the limbo instead, but it might be confusing for code readers why we're
    not simply adding the types.Transaction we already have.

Code changes summary:

- txpool.Transaction removed and all uses replaced by types.Transaction again
- blobpool now stores types.Transaction instead of defining its own blobTx format for storage
- the blobpool limbo now stores types.Transaction instead of storing only the blobs
- checks to validate the presence/absence of the blob sidecar added in certain critical places
2023-08-14 10:13:34 +02:00
Felix Lange
68860063fb internal/build: apply -ubuntu to env (#27910) 2023-08-12 10:32:50 +02:00
Felix Lange
e91b21ce2b go.mod, build: upgrade c-kzg-4844 (#27907)
This upgrades to the latest release of ckzg, and also attempts to fix some blst-related
build errors that occur on launchpad.net.
2023-08-12 00:21:46 +02:00
Péter Szilágyi
be65b47645 all: update golang/x/ext and fix slice sorting fallout (#27909)
The Go authors updated golang/x/ext to change the function signature of the slices sort method. 
It's an entire shitshow now because x/ext is not tagged, so everyone's codebase just 
picked a new version that some other dep depends on, causing our code to fail building.

This PR updates the dep on our code too and does all the refactorings to follow upstream...
2023-08-12 00:04:12 +02:00
Péter Szilágyi
0ce331f56a trie/triedb/pathdb: make shutdown journal log friendlier (#27905) 2023-08-11 17:05:35 +03:00
DongXi Huang
80b76a9527 core/types: remove duplication in eip2930 signer (#27860)
Remove duplication in signer
---------

Co-authored-by: GDdark <huangdongxi@minijoy.work>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-11 09:50:57 -04:00
Felix Lange
8f8ef2bc0c rpc: attempt to fix ping/pong logic race (#27733)
This should fix #27726. With enough load, it might happen that the SetPongHandler 
callback gets invoked before the call to SetReadDeadline is made in pingLoop. When 
this occurs, the socket will end up with a 30s read deadline even though it got the pong,
which will lead to a timeout.

The fix here is processing the pong on pingLoop, synchronizing with the code that 
sends the ping.
2023-08-11 15:16:45 +02:00
Delweng
35f7f3d015 ethdb/leveldb: support more than 7 levels in metrics (#27904) 2023-08-11 15:15:49 +02:00
imulmat4
6ddb92cac3 core/txpool/blobpool: fix metrics name for prometheus export (#27901) 2023-08-11 10:12:26 +03:00
Péter Szilágyi
e2507a17e8 params: switch release family to 1.13 to prep for PBSS 2023-08-10 22:22:17 +03:00
rjl493456442
503f1f7ada all: activate pbss as experimental feature (#26274)
* all: activate pbss

* core/rawdb: fix compilation error

* cma, core, eth, les, trie: address comments

* cmd, core, eth, trie: polish code

* core, cmd, eth: address comments

* cmd, core, eth, les, light, tests: address comment

* cmd/utils: shorten log message

* trie/triedb/pathdb: limit node buffer size to 1gb

* cmd/utils: fix opening non-existing db

* cmd/utils: rename flag name

* cmd, core: group chain history flags and fix tests

* core, eth, trie: fix memory leak in snapshot generation

* cmd, eth, internal: deprecate flags

* all: enable state tests for pathdb, fixes

* cmd, core: polish code

* trie/triedb/pathdb: limit the node buffer size to 256mb

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2023-08-10 22:21:36 +03:00
Sina Mahmoodi
5e89ff4d6b graphql: validate block params (#27876)
Block takes a number and a hash. The spec is unclear on what should happen in this case, leaving it an implemenation detail. With this change, we return an error in case both number and hash are passed in.
2023-08-10 07:00:52 -04:00
dependabot[bot]
86d7f5aeee deps: update supranational/blst to 0.3.11 (#27890)
build(deps): bump github.com/supranational/blst

Bumps [github.com/supranational/blst](https://github.com/supranational/blst) from 0.3.11-0.20230406105308-e9dfc5ee724b to 0.3.11.
- [Release notes](https://github.com/supranational/blst/releases)
- [Commits](https://github.com/supranational/blst/commits/v0.3.11)

---
updated-dependencies:
- dependency-name: github.com/supranational/blst
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-10 06:50:09 -04:00
Martin Holst Swende
8d1db1601d eth/filters, core/rawdb: remove unused param, refactor filtering-loop (#27891)
This change removes a chainconfig parameter passed into rawdb.ReadLogs, which is not used nor needed.
It also modifies the filter loop slightly, avoiding a labeled break and instead using a method.

This change does not modify any behaviour.
2023-08-10 06:49:05 -04:00
Felix Lange
d9a8b0ff71 params: begin v1.12.2 release cycle 2023-08-10 12:13:15 +02:00
Felix Lange
9c216bd6cb params: release go-ethereum v1.12.1 2023-08-10 12:10:33 +02:00
Guillaume Ballet
67979022aa core/state: move UpdateContractCode before the trie hash is computed (#27853)
Context: The UpdateContractCode method was introduced for the state storage commitment
schemes that include the whole code for their commitment computation. It must therefore be called
before the root hash is computed at the end of IntermediateRoot.

This should have no impact on the MPT since, in this context, the method is a no-op.
2023-08-09 18:02:45 +02:00
Delweng
10d9f9377b graphql: add yParity field for transactions (#27882)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-09 17:57:57 +02:00
Felix Lange
7ec60d5f0c p2p: move ping handling into pingLoop goroutine (#27887)
Moving the response sending there allows tracking all peer goroutines
in the peer WaitGroup.
2023-08-09 16:00:31 +02:00
Martin Holst Swende
e13fa32cea core/vm: update 4844 - point evaluation precompile address (#27874) 2023-08-08 15:54:19 +03:00
Martin Holst Swende
0d772b9f09 graphql: avoid greedy allocation (#27873)
Fixes a graphql-dos

---------

Co-authored-by: Sina Mahmoodi <1591639+s1na@users.noreply.github.com>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-08-08 07:35:58 -04:00
ucwong
6d2bcb911a p2p/simulations/examples: use atomic.Int64 (#27861) 2023-08-07 18:30:05 +02:00
Amin Talebi
eeebb07c73 internal/ethapi: add state override to estimateGas (#27845) 2023-08-07 16:03:57 +02:00
ucwong
d14c07d91e accounts: use atomic type (#27857) 2023-08-07 03:11:50 -04:00
ucwong
857476753d internal: use atomic type (#27858) 2023-08-07 03:11:06 -04:00
Christopher Harrison
60070fe5c6 internal/ethapi, graphql: correct comments about gas price logic (#27752) 2023-08-05 01:08:53 +02:00
ucwong
5c30541c2a log: use atomic types (#27763)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-05 00:58:53 +02:00
Felix Lange
bb148dd342 core/types: support yParity field in JSON transactions (#27744)
This adds support for the "yParity" field in transaction objects returned by RPC
APIs. We somehow forgot to add this field even though it has been in the spec for
a long time.
2023-08-05 00:54:55 +02:00
Darioush Jalali
57cdbaef30 all: remove trailing whitespace (#27741) 2023-08-05 00:24:32 +02:00
Felix Lange
df544350bc core/types: fix immutability guarantees in Block (#27844)
This change rearranges the accessor methods in block.go and fixes some minor issues with
the copy-on-write logic of block data. Fixed issues:

- Block.WithWithdrawals did not create a shallow copy of the block.

- Block.WithBody copied the header unnecessarily, and did not preserve withdrawals.

However, the bugs did not affect any code in go-ethereum because blocks are *always*
created using NewBlockWithHeader().WithBody().WithWithdrawals()
2023-08-04 14:16:23 +02:00
Péter Szilágyi
6e934f40f9 eth/protocols/snap: fix batch writer when resuming an aborted sync (#27842) 2023-08-03 14:51:02 +03:00
Marius Kjærstad
8224bb9218 build: upgrade -dlgo version to Go 1.20.7 (#27835) 2023-08-02 12:53:05 +03:00
ucwong
d04bde0a20 p2p: use atomic types (#27764)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-01 23:20:52 +02:00
Delweng
ff97b4cc6a cmd/geth: disable automaxprocs log (#27814)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-08-01 18:02:36 +02:00
rjl493456442
7de748d3f6 all: implement path-based state scheme (#25963)
* all: implement path-based state scheme

* all: edits from review

* core/rawdb, trie/triedb/pathdb: review changes

* core, light, trie, eth, tests: reimplement pbss history

* core, trie/triedb/pathdb: track block number in state history

* trie/triedb/pathdb: add history documentation

* core, trie/triedb/pathdb: address comments from Peter's review

Important changes to list:

- Cache trie nodes by path in clean cache
- Remove root->id mappings when history is truncated

* trie/triedb/pathdb: fallback to disk if unexpect node in clean cache

* core/rawdb: fix tests

* trie/triedb/pathdb: rename metrics, change clean cache key

* trie/triedb: manage the clean cache inside of disk layer

* trie/triedb/pathdb: move journal function

* trie/triedb/path: fix tests

* trie/triedb/pathdb: fix journal

* trie/triedb/pathdb: fix history

* trie/triedb/pathdb: try to fix tests on windows

* core, trie: address comments

* trie/triedb/pathdb: fix test issues

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-01 15:17:32 +03:00
ucwong
9d744f0ca8 cmd/bootnode: fix timer leak (#27754) 2023-08-01 14:12:11 +02:00
Delweng
f404a2d0f1 cmd/evm: set ExcessBlobGas from env (#27796)
Sets the `currentExcessBlobGas` from env, alternatively calculates it based on `parentExcessBlobGas` and `parentBlobGasUsed`. It then emits the `currentExcessBlobGas` and `currentBlobGasUsed` into the output, to be used as parent-values for a future iteration. 

Closes #27785
Closes #27783

---------

Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-08-01 07:58:26 -04:00
Delweng
7c95ebd63d consensus/misc: move eip1559 into a package (#27828)
* consensus/misc: move eip1559 as a sub directory

Signed-off-by: jsvisa <delweng@gmail.com>

* consensus/misc: package name

Signed-off-by: jsvisa <delweng@gmail.com>

* all: eip1559

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-08-01 12:58:45 +03:00
rjl493456442
2fd77a6a7e core/txpool/blobpool: remove error log when finalized block is nil (#27822)
* core/txpool/blobpool: remove error log when finalized block is nil

* core/txpool/blobpool: take peter's suggestion
2023-08-01 10:09:20 +03:00
Martin Holst Swende
852be575e1 tests: make tests pass on windows/386 (#27821)
* tests: split up state test execution

* Revert "tests: split up state test execution"

This reverts commit 96017c248c.

* build: bump test timeout to 20 minutes
2023-08-01 10:08:19 +03:00
Delweng
3ca92f70e5 all: replace data gas to blob gas in comments (#27825)
* eth: excessDataGas -> excessBlobGas

* consensus: data gas -> blob gas

* core: data gas -> blob gas

* params: data gas -> blob gas
2023-08-01 10:07:25 +03:00
Zig Blathazar
4e9775668e cmd/bootnode: defer udp connection close (#27787) 2023-07-31 13:15:13 -04:00
rjl493456442
817553cc28 core, trie: track state change set with account address (#27815) 2023-07-31 15:07:51 +03:00
Delweng
43a1a48ee2 core: remove pointless check for excessBlobGas nilness (#27797)
* core: check excessBlobGas in front

Signed-off-by: jsvisa <delweng@gmail.com>

* core: no need to manual panic

Signed-off-by: jsvisa <delweng@gmail.com>

* core: no comment

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-07-31 10:54:26 +03:00
Shude Li
5a4eba6886 eth: conver if-else-if chain to tagged switch (#27816) 2023-07-31 10:22:36 +03:00
Shude Li
95cc7bf4f8 cmd/geth: import package catalyst once (#27803) 2023-07-31 08:18:13 +03:00
Mario Vega
8f2ae29b8f core/types: fix receipt blob fields marshaling (#27793) 2023-07-28 10:08:38 +03:00
Marius van der Wijden
d9556533c3 core/types: put header fields in correct order (#27791) 2023-07-27 17:15:08 +03:00
Péter Szilágyi
57268f7e6c all: rename dataGas to blobGas (#27789) 2023-07-27 16:53:28 +03:00
Péter Szilágyi
0f4b21feac core/txpool/blobpool: fix a merge conflict from a package rename (#27790) 2023-07-27 14:53:05 +03:00
Felix Lange
393d4db18c core/types: add 4844 data gas fields in Receipt (#27743)
* core/types: add data gas fields in Receipt

* core/types: use BlobGas method of tx

* core: fix test

* core/types: fix receipt tests, add data gas used field test

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2023-07-27 14:11:09 +03:00
Péter Szilágyi
1662228ac6 core/txpool/blobpool: 4844 blob transaction pool (#26940)
* core/blobpool: implement txpool for blob txs

* core/txpool: track address reservations to notice any weird bugs

* core/txpool/blobpool: add support for in-memory operation for tests

* core/txpool/blobpool: fix heap updating after SetGasTip if account is evicted

* core/txpool/blobpool: fix eviction order if cheap leading txs are included

* core/txpool/blobpool: add note as to why the eviction fields are not inited in reinject

* go.mod: pull in inmem billy form upstream

* core/txpool/blobpool: fix review commens

* core/txpool/blobpool: make heap and heap test deterministic

* core/txpool/blobpool: luv u linter

* core/txpool: limit blob transactions to 16 per account

* core/txpool/blobpool: fix rebase errors

* core/txpool/blobpool: luv you linter

* go.mod: revert some strange crypto package dep updates
2023-07-27 13:45:35 +03:00
Darioush Jalali
37b952a4a2 core/types: deepcopy ExcessDataGas, DataGasUsed (#27767) 2023-07-27 11:32:15 +03:00
Justin Traglia
2274a03e33 crypto/kzg4844: do lazy init in all ckzg funcs (#27679)
* crypto/kzg4844: remove unnecessary init call & fix typo

* Fix kzg4844 tests/benchmarks

* Make init lazy & revert changes to tests
2023-07-24 19:13:34 +03:00
ucwong
a196f3e8a2 cmd/devp2p: atomic types used (#27755) 2023-07-24 13:23:38 +03:00
ucwong
7a1fba1a02 cmd/geth: atomic types used (#27756) 2023-07-24 13:22:54 +03:00
rjl493456442
88f3d61468 all: expose block number information to statedb (#27753)
* core/state: clean up

* all: add block number infomration to statedb

* core, trie: rename blockNumber to block
2023-07-24 13:22:09 +03:00
Marius van der Wijden
a46f4173cd ethclient/gethclient: gofmt -s (#27762) 2023-07-24 13:21:26 +03:00
Pierre Grimaud
7f756dc118 cmd/evm/testdata: fix typos in docs (#27742) 2023-07-18 14:07:25 +02:00
Felix Lange
e86ad52640 beacon/engine, eth/catalyst: EIP-4844 updates for the engine API (#27736)
This is a spin-out from the EIP-4844 devnet branch, containing just the Engine API modifications
and nothing else. The newPayloadV3 endpoint won't really work in this version, but we need the
data structures for testing so I'd like to get this in early.

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2023-07-18 09:44:16 +02:00
Felföldi Zsolt
d4d88f9bce les: remove obsolete code related to PoW header syncing (#27737)
This change removes PoW header syncing related code from LES and also deletes 
duplicated packages les/catalyst, les/downloader and les/fetcher. These package copies
were created because people wanted to make changes in their eth/ counterparts, but weren't
able to adapt LES code to the API changes.
2023-07-17 20:48:11 +02:00
jwasinger
988d84aa7c core/state, core/vm: implement EIP 6780 (#27189)
EIP-6780: SELFDESTRUCT only in same transaction

>     SELFDESTRUCT will recover all funds to the caller but not delete the account, except when called in the same transaction as creation

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-07-17 13:02:18 -04:00
Martin Holst Swende
b058cf454b core, tests: EIP-4844 transaction processing logic (#27721)
This updates the reference tests to the latest version and also adds logic
to process EIP-4844 blob transactions into the state transition. We are now
passing most Cancun fork tests.

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-07-15 23:27:36 +02:00
ucwong
99e000cb13 core/vm: use types.EmptyCodeHash (#27729) 2023-07-15 17:45:57 +02:00
jwasinger
d233b6b23a core: replace instances of 'suicide' with 'selfdestruct' to improve code consistency. (#27716)
---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
2023-07-15 10:35:30 -04:00
Yurie
00408f7479 accounts/abi/bind/backends: fix goroutine leak in unit test (#27705) 2023-07-15 10:33:46 -04:00
Ömer Faruk Irmak
34d5072159 metrics: NilResettingTimer.Time should execute the timed function (#27724) 2023-07-14 19:19:03 +02:00
Delweng
47b9f1b4ae cmd/geth: use automaxprocs to apply cpu quota correctly (#27506)
It is usually best to set GOMAXPROCS to the number of available CPU cores. However, setting
it like that does not work well when the process is quota-limited to a certain number of CPUs.
The automaxprocs library configures GOMAXPROCS, taking such limits into account.
2023-07-14 19:14:47 +02:00
Ömer Faruk Irmak
13c0305106 metrics: NilTimer should still run the function to be timed (#27723) 2023-07-14 18:10:16 +02:00
Seungbae Yu
60ecf48dd4 cmd/bootnode, p2p: support for alternate mapped ports (#26359)
This changes the port mapping procedure such that, when the requested port is unavailable
an alternative port suggested by the router is used instead.

We now also repeatedly request the external IP from the router in order to catch any IP changes.

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-07-14 14:58:27 +02:00
ucwong
c40ab6af72 core/blockchain: fast to snap in comments (#27722) 2023-07-14 15:06:51 +03:00
ucwong
e1fe6bc846 go.sum: go mod tidy (#27717) 2023-07-13 16:34:29 +02:00
Ryan Schneider
517ac886d4 eth/tracers/native: panic on memory read in prestateTracer (#27691)
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-07-13 14:44:42 +02:00
Delweng
1e069cf802 eth/tracers: add ReturnData in the tracer's response (#27704)
The struct logger (or opcode tracer) was missing the return data field even
if this was explicitly enabled by user via `"enableReturnData": true` in the config.
This PR fixes this issue.

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-07-13 14:43:25 +02:00
Delweng
5d035043ea internal/ethapi: add more testcase for GetTransactionReceipt (#27527)
* internal/ethapi: testBackend reuse the same db

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: implment GetTransaction

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: implement GetReceipts

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: insert receipts and setup txlookup

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: add simple success tx receipt test

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: add case create contract

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: add contract call receipt

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: add tx notfound

Signed-off-by: jsvisa <delweng@gmail.com>

* internal/ethapi: add dynamic fee testcase

* internal/ethapi: add accessList receipt

* internal/ethapi: no need to insert receipt chain, no error

* internal/ethapi: use HeaderByHash instead

* internal/ethapi: add one more case

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-07-13 06:47:32 -04:00
Delweng
10a136a4f9 internal: early exit if tx for getTxReceipt not found (#27712)
internal/ethapi: fast exit if tx notfound
2023-07-13 06:42:48 -04:00
Sina Mahmoodi
4f0d8f0d15 graphql: fix race in withdrawals test (#27706)
graphql: fix race in test
2023-07-13 06:41:58 -04:00
Delweng
714f75943b eth, miner: rm redundant type declare (#27713)
* eth: rm redundant type from array, slice, or map

* miner: rm redundant type from array, slice, or map
2023-07-13 09:55:31 +03:00
Marius Kjærstad
040a4a543b build: upgrade -dlgo version to Go 1.20.6 (#27708) 2023-07-12 20:38:12 +03:00
cui fliter
80b7bfe70d accounts, cmd/evm: fix docstrings (#27703)
fix function name in comment

Signed-off-by: cui fliter <imcusg@gmail.com>
2023-07-12 06:01:55 -04:00
Felix Lange
a426999fc9 p2p/discover: filter bootnodes by netrestrict (#27701)
This prevents an issue where the node would attempt to contact the bootstrap
nodes even if they weren't contained in the netrestrict list.
2023-07-12 12:01:38 +02:00
rjl493456442
0b1f97e151 core/rawdb: support freezer batch read with no size limit (#27687)
This change adds the ability to perform reads from freezer without size limitation. This can be useful in cases where callers are certain that out-of-memory will not happen (e.g. reading only a few elements). 

The previous API was designed to behave both optimally and secure while servicing a request from a peer, whereas this change should _not_ be used when an untrusted peer can influence the query size.
2023-07-12 03:19:01 -04:00
Felix Lange
cecd22143b go.mod: upgrade github.com/karalabe/usb to fix build warning (#27698) 2023-07-11 22:34:22 +02:00
Mskxn
7a565fa4fe console: add cleanup to avoid leaks in newTester (#27695) 2023-07-11 21:27:48 +02:00
lightclient
645b0db98e cmd/utils, p2p: clean up discovery setup (#27518)
This simplifies the code that initializes the discovery a bit, and
adds new flags for enabling/disabling discv4 and discv5 separately.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-07-11 21:21:32 +02:00
rjl493456442
4b06e4f25e core/state: value diff tracking in StateDB (#27349)
This change makes the StateDB track the state key value diff of a block transition.
We already tracked current account and storage values for the purpose of updating
the state snapshot. With this PR, we now also track the original (pre-transition) values
of accounts and storage slots.
2023-07-11 15:43:23 +02:00
Delweng
aecf3f9579 internal/blocktest: add package for shared test code (#27270) 2023-07-11 14:57:02 +02:00
lightclient
e1fd3d67e5 eth: better active protocol handler tracking (#27665)
Fixes an issue where waitgroups were used erroneously, which could lead to waitgroup being added to while wait was already invoked.
2023-07-11 03:57:42 -04:00
Charles Cooper
5c9cbc218a core/vm: implement EIP-5656, mcopy instruction (#26181)
Implements [EIP 5656](https://eips.ethereum.org/EIPS/eip-5656), MCOPY instruction, and enables it for Cancun. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-07-11 03:55:34 -04:00
Martin Holst Swende
af8b138c1a core/vm: define cancun + enable 1153 (tstore/tload) in cancun (#27663) 2023-07-10 14:40:31 -04:00
jwasinger
c2db667c8f miner: remove unused commented code (#27664) 2023-07-07 11:14:24 +03:00
Martin Holst Swende
c866dfdc78 core: remove outdated tests (#27662)
Back before #27178 , we spun up a number of ethash verifiers to verify headers. So we also had tests to ensure that we were indeed able to abort verification even if we had multiple workers running.

With PR #27178, we removed the parallelism in verification, and these tests are now failing, since we now just sequentially fire away the results as fast as possible on one routine.

This change removes the (sometimes failing) tests
2023-07-06 12:05:34 -04:00
lightclient
cbf2579691 p2p, p2p/discover: add dial metrics (#27621)
This PR adds metrics for p2p dialing, which gives us visibility into the quality of the dial 
candidates  returned by our discovery methods.
2023-07-06 16:20:31 +02:00
jwasinger
ea782809f7 cmd/geth: implement dev mode for post-merge (#27327)
This change adds back the 'geth --dev' mode of operation, using a cl-mocker. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
2023-07-06 04:42:34 -04:00
John Chase
ab0e0f3517 signer/core: show helptext when clef rejects signing (#27538)
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-07-06 03:50:44 -04:00
Darioush Jalali
83d7f426d1 core: stop chain when tests are finished (#27660)
core (blockchain_test): add chain.Stop() to tests
2023-07-06 02:56:42 -04:00
Exca-DK
863f6dac19 ethdb/leveldb: update leveldb metrics collection (#27643)
This removes text parsing in leveldb metrics collection code. All metrics
can now be accessed through the stats API provided by leveldb.

We also add new gauge-typed metrics that count the number of tables at each level.

---------

Co-authored-by: Exca-DK <Exca-DK@users.noreply.github.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-07-06 00:04:07 +02:00
rjl493456442
59f7b289c3 cmd, core, eth, graphql, trie: no persisted clean trie cache file (#27525)
The clean trie cache is persisted periodically, therefore Geth can
quickly warmup the cache in next restart.

However it will reduce the robustness of system. The assumption is
held in Geth that if the parent trie node is present, then the entire
sub-trie associated with the parent are all prensent.

Imagine the scenario that Geth rewinds itself to a past block and
restart, but Geth finds the root node of "future state" in clean
cache then regard this state is present in disk, while is not in fact.

Another example is offline pruning tool. Whenever an offline pruning
is performed, the clean cache file has to be removed to aviod hitting
the root node of "deleted states" in clean cache.

All in all, compare with the minor performance gain, system robustness
is something we care more.
2023-07-04 10:21:06 +03:00
Curith
6ca3ef9a7b node: fix listening on IPv6 address (#27628) (#27635) 2023-07-02 13:21:16 +02:00
Guillaume Ballet
8bbb16b70e core/state, light, les: make signature of ContractCode hash-independent (#27209)
* core/state, light, les: make signature of ContractCode hash-independent

* push current state for feedback

* les: fix unit test

* core, les, light: fix les unittests

* core/state, trie, les, light: fix state iterator

* core, les: address comments

* les: fix lint

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-06-28 12:11:02 +03:00
Guillaume Ballet
85b8d1c06c params, trie: add verkle fork management + upgrade go-verkle (#27464)
* params, trie: add verkle fork management + upgrade go-verkle

* remove the two verkle files

* core, eth, params: add missing function

* Gary's feedback

* remove trie/utils/verkle.go

* add verkle block override

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-06-28 12:08:48 +03:00
Marius van der Wijden
f5d3d486e4 eth: send big transactions by announce/retrieve only (#27618)
* eth: send big transactions by announce/retrieve only

* Update eth/handler.go

Co-authored-by: Martin Holst Swende <martin@swende.se>

* eth: remove superfluous bracket

* eth: add whitespace

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-06-28 12:06:20 +03:00
hero5512
eed7983c7c core/txpool/legacypool: fix typo (#27620) 2023-06-27 20:28:18 +03:00
Guillaume Ballet
c7b099b2ea trie, core/state: revert error removal in (*state.Trie).Commit (#27544)
* trie, core/state: revert error removal in (*state.Trie).Commit

* Gary's nitpick :)

Co-Authored-By:  rjl493456442 <garyrong0905@gmail.com>

---------

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
2023-06-27 15:36:38 +03:00
aaronbuchwald
d73eb87979 core: log message if DeriveFields returns error (#27530)
This error will never happen, but if it ever does happen, we will at least see it.
2023-06-27 10:29:19 +02:00
Sanghee Choi
900591299f common/lru: add test case for BasicLRU.Peek (#27559) 2023-06-27 10:27:40 +02:00
Marius van der Wijden
d7ea278fe3 core/vm: move TSTORE,TLOAD to correct opcode nums (#27613)
* core/vm: move TSTORE,TLOAD to correct opcode nums

* core/vm: cleanup
2023-06-27 03:25:08 -04:00
rjl493456442
4b90c4488d ethdb/pebble: use sync mode for pebble writes (#27615) 2023-06-27 03:19:02 -04:00
puhtaytow
b4bc9b0db6 cmd/geth: error message should not be capitalised (#27549)
error message should not be capitalized / consistency
2023-06-27 09:12:03 +03:00
Delweng
80441779d4 eth/protocols: put protocols in order (#27543)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-06-27 09:11:06 +03:00
Sanghee Choi
2754b197c9 common/math: fix typo in comment (#27561) 2023-06-25 17:33:50 +02:00
Francisco de Borja Aranda Castillejo
942ba4ddaa crypto/secp256k1: define NDEBUG only if not defined (#27550) 2023-06-23 19:02:05 +02:00
Guillaume Ballet
699243f8ae core/state, light, trie: add UpdateContractCode to the Trie interface (#27476)
Verkle trees store the code inside the trie. This PR changes the interface to pass the code, as well as the dirty flag to tell the trie package if the code is dirty and needs to be updated. This is a no-op for the MPT and the odr trie.
2023-06-22 08:52:52 -04:00
Exca-DK
5520cd97a1 p2p/discover: swap verification order in discv4 ping handler (#27532)
In all other UDPv4 methods, the deadline is checked first. It seems weird to me that ping is an exception. Deadline comparison is also less resource intensive.

Co-authored-by: Exca-DK <Exca-DK@users.noreply.github.com>
2023-06-22 10:06:14 +02:00
James Prestwich
fd5d2ef0a6 internal/ethapi: quantity-encode storage keys in eth_getProof response (#27309)
This changes the eth_getProof method implementation to re-encode the requested
storage keys, canonicalizing them in the response. For backwards-compatibility reasons,
go-ethereum accepts non-canonical hex keys. Accepting them is fine, but we should
not mirror invalid inputs into the output.

Closes #27306

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-21 18:11:11 +02:00
Martin Holst Swende
713fc8bbe6 ethdb/pebble: fsync for batch writes (#27522)
This is likely the culprit behind several data corruption issues, e.g. where data has been
written to the freezer, but the deletion from pebble does not go through due to process
crash.
2023-06-21 18:08:12 +02:00
rjl493456442
6d2aeb43d5 cmd, core/state, eth, tests, trie: improve state reader (#27428)
The state availability is checked during the creation of a state reader.

-    In hash-based database, if the specified root node does not exist on disk disk, then
    the state reader won't be created and an error will be returned.

-    In path-based database, if the specified state layer is not available, then the
    state reader won't be created and an error will be returned.

This change also contains a stricter semantics regarding the `Commit` operation: once it has been performed, the trie is no longer usable, and certain operations will return an error.
2023-06-20 15:31:45 -04:00
jwasinger
8c288b528d internal/ethapi: use same state for each invocation within EstimateGas (#27505)
EstimateGas repeatedly executes a transaction, performing a binary search with multiple gas prices to determine proper pricing. Each call retrieves a new copy of the state (https://github.com/ethereum/go-ethereum/blob/master/internal/ethapi/api.go#L1017) . Because the pending/latest state can change during the execution of EstimateGas, this can potentially cause strange behavior (as noted here: https://github.com/ethereum/go-ethereum/pull/27502#issue-1761957009).

This PR modifies EstimateGas to retrieve the state once and use a copy of it for every call invocation it does.
2023-06-20 08:40:18 -04:00
Felix Lange
1affc1c08d core/txpool: remove use of errors.Join function (#27523)
his function was added in Go 1.20, but our compatibility target
is Go 1.19.
2023-06-20 13:51:59 +02:00
Dan Laine
154b016b6c core: use slices package for sorting (#27489)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-20 11:58:47 +02:00
Delweng
84b05d4f34 internal/build: ignore some files in FindMainPackages (#27521) 2023-06-20 10:42:13 +02:00
Dan Laine
b1ef0bfe03 eth: use slices package for sorting (#27490)
Also adds Hash.Less method for sorting purposes.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 23:38:57 +02:00
hero5512
9a167c45d1 core/txpool/legacypool: narrow down the scope of the variable (#27471)
Variables discarded, included can be defined closer to their usage.

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-06-19 23:30:39 +02:00
rjl493456442
ceca4578ca trie: remove parameter 'fromLevel' in Prove (#27512)
This removes the feature where top nodes of the proof can be elided.
It was intended to be used by the LES server, to save bandwidth 
when the client had already fetched parts of the state and only needed
some extra nodes to complete the proof. Alas, it never got implemented
in the client.
2023-06-19 16:28:40 +02:00
Marius van der Wijden
091c25d983 go.mod: update kzg libraries to use big-endian (#27510)
* go.mod: update kzg libraries to use big-endian

* go.sum: ran go mod tidy

* core/testdata/precompiles: fix blob verification test

* core/testdata/precompiles: fix blob verification test
2023-06-19 15:08:13 +03:00
Dan Laine
50ecb16de0 tests, trie: use slices package for sorting (#27496)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 11:41:31 +02:00
Dan Laine
87e510d963 internal/ethapi, les: use slices package for sorting (#27492)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 11:33:48 +02:00
Dan Laine
a848212709 consensus/clique: use slices package for sorting (#27488)
Also adds Address.Less for sorting use in other packages.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 09:04:16 +02:00
Dan Laine
4367ab499f metrics: use slices package for sorting (#27493)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 08:53:15 +02:00
Sanghee Choi
760fd0c79b consensus/clique: fix typo in comment (#27503) 2023-06-19 08:47:00 +02:00
John Chase
cd3b8c3d78 cmd/evm: fix typos in documentation (#27501) 2023-06-19 08:44:54 +02:00
Dan Laine
4544dc5f32 cmd/devp2p: use slices package for sorting (#27487) 2023-06-19 08:42:49 +02:00
Dan Laine
311b742c84 accounts/keystore: use slices package for sorting (#27485)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 08:34:47 +02:00
Koichi Shiraishi
f0b5af74a3 rpc: avoid use of cgo by hard-coding maxPathSize (#27447)
Package rpc uses cgo to find the maximum UNIX domain socket path 
length. If exceeded, a warning is printed. This is the only use of cgo in this
package. It seems excessive to depend on cgo just for this warning, so
we now hard-code the usual limit for Linux instead.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 08:06:58 +02:00
Martin Holst Swende
e4660a1181 core/txpool/legacypool: handle missing head in reset (#27479)
Fixes #27301, a crash that could occur during txpool reorg handling.
2023-06-19 07:58:04 +02:00
hero5512
a71b9b9ffa core/txpool/legacypool: remove redundant check for floatingRatio == 0 (#27477)
floatingRatio is a constant and always non-zero. So there is no need to
check for == 0.
2023-06-19 07:52:40 +02:00
John Chase
168d0cc3b3 internal/jsre/deps: fix typos in web3.js (#27500) 2023-06-19 07:50:56 +02:00
Dan Laine
5d75123cb7 ethdb/dbtest: use slices package for sorting (#27491) 2023-06-19 07:48:47 +02:00
Dan Laine
289c6c3b15 p2p: use slices package for sorting (#27494)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-19 07:48:12 +02:00
jin
46ec972c9c core/txpool/legacypool: reheap the tx list if london fork not enabled (#27481)
This change ensures Reheap will be called even before the London fork activates.
Since Reheap would otherwise only be called through `SetBaseFee` after London,
the list would just keep growing if the fork was not enabled or not reached yet.
2023-06-18 22:43:53 +02:00
Dan Laine
36ca59f1ec build: use slices package for sorting (#27486) 2023-06-18 15:09:00 +02:00
Péter Szilágyi
d40a255e97 all: move main transaction pool into a subpool (#27463)
* all: move main transaction pool into a subpool

* go.mod: remove superfluous updates

* core/txpool: review fixes, handle txs rejected by all subpools

* core/txpool: typos
2023-06-16 15:29:40 +03:00
John Chase
c375936e81 rlp: fix typos (#27484)
fix typos

Co-authored-by: john <yejiarui@123.com>
2023-06-16 15:21:43 +03:00
cui fliter
604da5c84b cmd/evm: fix typos in docs (#27478)
fix some typos

Signed-off-by: cui fliter <imcusg@gmail.com>
2023-06-15 08:55:00 -04:00
Martin Holst Swende
9cf9fae668 core/types: add support for BlobTxType receipts (#27470)
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-15 14:18:54 +02:00
aaronbuchwald
93ecd77d77 core: remove unnecessary log copy (#27475)
The logs in this function are pulled straight from disk in rawdb.ReadRawReceipts and 
also modified in receipts.DeriveFields, so removing the copy should be fine.
2023-06-15 13:52:06 +02:00
Sina Mahmoodi
7823ff6d06 eth/tracers: refactor exporting js buffer (#27472)
We had to do this workaround because it wasn't possible to export typed arrays from
JS to []byte. This was added in dop251/goja@2352993, so we can use the better way now.
2023-06-14 19:07:24 +02:00
Sanghee Choi
acc2a2ac61 node: remove unused error return from Attach (#27450)
node: Delete the unused error from return parameters of Node.Attach() func
2023-06-14 08:24:47 -04:00
zhiqiangxu
6f08c2f3f1 rpc: add method to test for subscription support (#25942)
This adds two ways to check for subscription support. First, one can now check
whether the transport method (HTTP/WS/etc.) is capable of subscriptions using
the new Client.SupportsSubscriptions method.

Second, the error returned by Subscribe can now reliably be tested using this
pattern:
    
    sub, err := client.Subscribe(...)
    if errors.Is(err, rpc.ErrNotificationsUnsupported) {
        // no subscription support
    }

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-14 14:04:41 +02:00
Freeman Jiang
8bbaf882a6 core/types: add "chainID" field to legacy tx JSON encoding (#27452)
Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com>
2023-06-13 14:46:45 +02:00
mmsqe
f3314bb6df rpc: add limit for batch request items and response size (#26681)
This PR adds server-side limits for JSON-RPC batch requests. Before this change, batches
were limited only by processing time. The server would pick calls from the batch and
answer them until the response timeout occurred, then stop processing the remaining batch
items.

Here, we are adding two additional limits which can be configured:

- the 'item limit': batches can have at most N items
- the 'response size limit': batches can contain at most X response bytes

These limits are optional in package rpc. In Geth, we set a default limit of 1000 items
and 25MB response size.

When a batch goes over the limit, an error response is returned to the client. However,
doing this correctly isn't always possible. In JSON-RPC, only method calls with a valid
`id` can be responded to. Since batches may also contain non-call messages or
notifications, the best effort thing we can do to report an error with the batch itself is
reporting the limit violation as an error for the first method call in the batch. If a batch is
too large, but contains only notifications and responses, the error will be reported with
a null `id`.

The RPC client was also changed so it can deal with errors resulting from too large
batches. An older client connected to the server code in this PR could get stuck
until the request timeout occurred when the batch is too large. **Upgrading to a version
of the RPC client containing this change is strongly recommended to avoid timeout issues.**

For some weird reason, when writing the original client implementation, @fjl worked off of
the assumption that responses could be distributed across batches arbitrarily. So for a
batch request containing requests `[A B C]`, the server could respond with `[A B C]` but
also with `[A B] [C]` or even `[A] [B] [C]` and it wouldn't make a difference to the
client.

So in the implementation of BatchCallContext, the client waited for all requests in the
batch individually. If the server didn't respond to some of the requests in the batch, the
client would eventually just time out (if a context was used).

With the addition of batch limits into the server, we anticipate that people will hit this
kind of error way more often. To handle this properly, the client now waits for a single
response batch and expects it to contain all responses to the requests.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-06-13 13:38:58 +02:00
hero5512
5ac4da3653 internal/ethapi: remove error return on RPCMarshalBlock (#27449)
rm error when marshal block to rpc type allen
2023-06-13 03:02:11 -04:00
jwasinger
174d267f48 miner: log number of withdrawals in block upon payload update (#27457) 2023-06-13 02:55:05 -04:00
Delweng
281e8cd5ab eth/filters: reuse handleLogs method for removed logs (#27438) 2023-06-08 11:40:22 +02:00
KAI
5c51ef8527 accounts/keystore: handle error for invalid key in DecryptKey (#27432)
Co-authored-by: KAI <kaili@coinsummer.io>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-06-07 15:10:42 +02:00
Stephen Guo
99eb0b52aa rlp: use identical receiver names for encBuffer methods (#27430) 2023-06-07 12:40:06 +02:00
Sina Mahmoodi
fbe432fa15 graphql: implement withdrawals (EIP-4895) (#27072)
implements withdrawals in graphql as per https://github.com/ethereum/execution-apis/pull/400
2023-06-06 12:33:25 -04:00
Delweng
0783cb7d91 eth,core: add api debug_getTrieFlushInterval (#27303)
* core,eth: add api debug_getTrieFlushInterval

Signed-off-by: jsvisa <delweng@gmail.com>

* eth/api_debug: comment of SetTrieFlushInterval

Signed-off-by: jsvisa <delweng@gmail.com>

* Apply suggestions from code review

---------

Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-06-06 08:41:44 -04:00
Péter Szilágyi
950d5643b1 core/txpool: make transaction validation reusable across packages (pools) (#27429)
* core/txpool: abstraction prep work for secondary pools (blob pool)

* core/txpool: leave subpool concepts to a followup pr

* les: fix tests using hard coded errors

* core/txpool: use bitmaps instead of maps for tx type filtering
2023-06-06 12:53:29 +03:00
Paul Lange
4cf708d30b les: remove unused var AdvertiseProtocolVersions (#27405) 2023-06-06 04:34:22 -04:00
Daniel Katzan
b8ee2877c5 core/txpool: fix minor flaw in isGapped check (#27404)
This fix a minor implementation issue with the newly introduced isGapped function and it is described in ticket: https://github.com/ethereum/go-ethereum/issues/27401
2023-06-06 04:29:41 -04:00
Martin Holst Swende
8eb0c2de76 cmd/evm: make evm blocktest output logs if so instructed (#27396)
* cmd/evm: make evm blocktest output logs if so instructed

* Apply suggestions from code review

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>

---------

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2023-06-06 04:27:40 -04:00
rjl493456442
0e5d2c7c53 core/state/snapshot, core/types, eth: move account definition to type (#27323)
* core/state/snapshot, core/types, eth: move account definition to type

* core, eth: revert snapshot Account API change
2023-06-06 11:17:39 +03:00
Marius van der Wijden
c537ace249 core: 4844 opcode and precompile (#27356)
* core: crypto: implement BLOBHASH and pointEval precompile

* core: crypto: fixed nitpicks, moved precompile return value

* core/vm: fix review comments
2023-06-05 16:43:25 +03:00
rjl493456442
380fb4e249 core/state: clear out cached state data when reset occurs (#27376)
* core/state: remove cached snap data if reset occurs

* core/state: address comment from peter

* core/state: skip revert in case data is nil
2023-06-05 16:25:57 +03:00
John Chase
78f7a6b7f2 graphql: simplify tx resolve (#27285) 2023-06-05 11:07:01 +02:00
Péter Szilágyi
a7b2106edf eth/downloader: drop beacon head updates if the syncer is restarting (#27397)
* eth/downloader: drop beacon head updates if the syncer is restarting

* eth/donwloader: v2 of the goroutine spike preventer
2023-06-05 09:59:38 +03:00
Péter Szilágyi
c7c84ca16c all: remove the Rinkeby testnet (#27406) 2023-06-02 14:03:21 +03:00
rjl493456442
15bd21f3c8 core/state: mark account as dirty when resetObject occurs (#27339)
This changes the journal logic to mark the state object dirty immediately when it
is reset. 

We're mostly adding this change to appease the fuzzer. Marking it dirty immediately
makes no difference in practice because accounts will always be modified by EVM
right after creation.
2023-06-01 11:09:32 +02:00
jin
2372fb2781 internal/web3ext: fix parameter count of miner_start (#27400) 2023-06-01 10:33:10 +02:00
Guillaume Ballet
45a3ab42aa core/state: move slot RLP encoding into the MPT implementation (#27000)
Continuing with a series of PRs to make the Trie interface more generic, this PR moves
the RLP encoding of storage slots inside the StateTrie and light.Trie implementations,
as other types of tries don't use RLP.
2023-06-01 10:29:41 +02:00
Felix Lange
ac86547b01 p2p/discover: add Table configuration and Nodes method (#27387)
* p2p/discover: remove ReadRandomNodes

Even though it's public, this method is not callable by code outside of
package p2p/discover because one can't get a valid instance of Table.

* p2p/discover: add Table.Nodes

* p2p/discover: make Table settings configurable

In unit tests and externally developed cmd/devp2p test runs, it can be
useful to tune the timer intervals used by Table.
2023-05-31 13:37:10 +02:00
Péter Szilágyi
008086f935 core, eth/downloader: validate blobtx.To at serialization time (#27393) 2023-05-31 13:08:15 +03:00
Péter Szilágyi
495692c9db core, eth/downloader, params: validate blob tx bodies (#27392) 2023-05-31 11:12:26 +03:00
Péter Szilágyi
1f9b69b36d consensus, core, eth/downloader, params: 4844 chain validation (#27382) 2023-05-31 10:21:13 +03:00
ucwong
cc2ab421e4 go.mod: golang.org/x upgrade (#27299)
go.mod:golang upgrade
2023-05-31 03:10:16 -04:00
rjl493456442
d4961881d7 miner: suspend miner if node is syncing (#27218)
Drop the notions of uncles, and disables activities while syncing

-  Disable activities (e.g. generate pending state) while node is syncing,
-  Disable empty block submission (but empty block is still kept for payload building),
-  Drop uncle notion since (ethash is already deprecated)
2023-05-31 03:09:49 -04:00
James Prestwich
61dcf76230 internal/ethapi: prevent unnecessary resource usage in eth_getProof implementation (#27310)
Deserialize hex keys early to shortcut on invalid input, and re-use the account storageTrie for each proof for each proof in the account, preventing repeated deep-copying of the trie.

Closes #27308

 --------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2023-05-31 02:52:27 -04:00
Seungbae Yu
8013a494fe event: move type fixation logic into Feed.init (#27249)
This is a minor optimization/refactoring of Feed.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-05-30 16:34:32 +02:00
ucwong
560dceb58e les, eth: fix typo in comment (#27369) 2023-05-30 14:55:03 +02:00
jwasinger
d789c68b66 eth: make debug_StorageRangeAt take a block hash or number (#27328)
eth: make StorageRangeAt take a block hash or number

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-05-30 08:16:28 -04:00
Guillaume Ballet
188817468e core/types: remove superfluous todo-comment (#27383) 2023-05-30 04:49:09 -04:00
Delweng
c57b3436f4 internal/ethapi: add more testcases for block/header rpc (#27325)
Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Sina Mahmoodi <1591639+s1na@users.noreply.github.com>
2023-05-29 08:52:08 -04:00
Delweng
13166210c8 eth: split api.go into namespace based files (#27263)
This change splits up the multiple API functions / namespaces currently defined in the eth package into different per-namespace files.
2023-05-29 05:09:34 -04:00
Delweng
1816cdc9fd internal/ethapi: don't return header size from rpc (#27347)
RPC methods `eth_getHeaderBy*` returned a size value which was meant for internal
processes. Please instead use `size` field returned by `eth_getBlockBy*` if you're interested
in the RLP encoded storage size of the block.

Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-25 15:19:58 +02:00
Delweng
db9a178ad2 eth/filters: retrieve logs in async (#27135)
This change implements async log retrievals via feeding logs in channels, instead of returning slices. This is a first step to implement #15063.  

---------

Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Sina Mahmoodi <1591639+s1na@users.noreply.github.com>
2023-05-25 08:40:28 -04:00
Delweng
9358b62fcb accounts: replace noarg fmt.Errorf with errors.New (#27331)
* accounts: replace noarg fmt.Errorf with errors.New

Signed-off-by: jsvisa <delweng@gmail.com>

* accounts: go autoimport

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-25 08:25:58 -04:00
Delweng
6c732766c8 core,console: replace noarg fmt.Errorf with errors.New (#27332)
* core: replace noarg fmt.Errorf with errors.New

Signed-off-by: jsvisa <delweng@gmail.com>

* console: replace noarg fmt.Errorf with errors.New

Signed-off-by: jsvisa <delweng@gmail.com>

* core: go autoimport

Signed-off-by: jsvisa <delweng@gmail.com>

* core: dry

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-25 08:24:09 -04:00
Martin Holst Swende
690249de7b params: begin v1.12.1 release cycle 2023-05-25 12:02:11 +02:00
Martin Holst Swende
e501b3b05d params: go-ethereum v1.12.0 stable 2023-05-25 12:01:00 +02:00
Martin Holst Swende
33fdd030b1 ethdb/pebble: fix NewBatchWithSize to set db (#27350) 2023-05-25 10:31:05 +03:00
Delweng
8a78a4f79f eth,consensus: replace noarg fmt.Errorf with errors.New (#27330)
* eth: replace noarg fmt.Errorf with errors.New

Signed-off-by: jsvisa <delweng@gmail.com>

* consensus: replace noarg fmt.Errorf with errors.New

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-25 02:57:34 -04:00
Delweng
b21ba668e6 internal,tests: replace noarg fmt.Errorf with errors.New (#27335)
* internal: replace noarg fmt.Errorf with errors.New

Signed-off-by: jsvisa <delweng@gmail.com>

* tests: replace noarg fmt.Errorf with errors.New

Signed-off-by: jsvisa <delweng@gmail.com>

* tests: go autoimport

Signed-off-by: jsvisa <delweng@gmail.com>

* tests: go autoimport

Signed-off-by: jsvisa <delweng@gmail.com>

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-25 02:54:28 -04:00
Delweng
dd25a4f5ab les, signer, light: replace noarg fmt.Errorf with errors.New (#27336)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-25 02:51:13 -04:00
Delweng
21c87e0f1b crypto: replace noarg fmt.Errorf with errors.New (#27333)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-24 14:45:51 +02:00
Delweng
b0095eeb20 ethclient,event: replace noarg fmt.Errorf with errors.New (#27334)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-24 12:39:49 +02:00
Delweng
e9c3183c52 cmd: use errrors.New instead of empty fmt.Errorf (#27329)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-24 12:21:29 +02:00
Martin Holst Swende
9231770811 rpc: change BlockNumber constant values to match ethclient (#27219)
ethclient accepts certain negative block number values as specifiers for the "pending",
"safe" and "finalized" block. In case of "pending", the value accepted by ethclient (-1)
did not match rpc.PendingBlockNumber (-2).

This wasn't really a problem, but other values accepted by ethclient did match the
definitions in package rpc, and it's weird to have this one special case where they don't.

To fix it, we decided to change the values of the constants rather than changing ethclient.
The constant values are not otherwise significant. This is a breaking API change, but we
believe not a dangerous one.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-05-23 13:18:38 +02:00
Martin Holst Swende
1a18283e85 cmd/evm: make batched state-test execution possible (#27318)
implements the ability to run several state-tests in one instance. By not providing a statetest path to the `evm statetest` command, the path(s) will instead be read from `stdin`.
2023-05-23 06:23:17 -04:00
Park Changwan
bfded65ed8 core/state: do not ignore null addr while iterative dump (#27320)
fixes bug which caused the zero-address to be ignored during an iterative state-dump.

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-23 06:10:26 -04:00
minh-bq
a190da9d68 eth/tracers: fix flatCallTracer crasher (#27304)
FlatCallTracer had a crasher when it was passed `onlyTopCall: true` as config.
This PR ignores config fields inherited from the normal call tracer.
2023-05-23 11:02:50 +02:00
Chawin Aiemvaravutigul
5b792e0fdf accounts/abi: add ErrorById (#27277)
Adds `ErrorById` lookup
2023-05-22 12:45:55 -04:00
Sina Mahmoodi
b46d37ea52 graphql: upgrade UI to v2 (#27294)
Upgrades  graphiql to v2.4.4. The interface has become much nicer, and there are extra features like tabs, history, dark mode etc.

This change also now uses golang embed to bundle the resources.

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-22 08:15:05 -04:00
Delweng
6fe0252571 rpc, internal/cmdtest: increase timeout in tests (#27083)
This change gives the cmd-tests have a bit more time to finish before getting forcibly torn down.
2023-05-22 08:13:03 -04:00
Felix Lange
944e1a0f90 beacon/types: auto-generate SyncCommittee marshaling methods (#27296) 2023-05-19 17:05:50 +03:00
Shude Li
3223950a5d cmd/utils: do not check free disk space in dev mode (#27281) 2023-05-19 08:38:21 -04:00
Martin Holst Swende
99394adcb8 ethdb/pebble: prevent shutdown-panic (#27238)
One difference between pebble and leveldb is that the latter returns error when performing Get on a closed database, the former does a panic. This may be triggered during shutdown (see #27237)

This PR changes the pebble driver so we check that the db is not closed already, for several operations. It also adds tests to the db test-suite, so the previously implicit assumption of "not panic:ing at ops on closed database" is covered by tests.
2023-05-19 08:36:21 -04:00
Péter Szilágyi
85a4b82b33 all: tie timestamp based forks to the passage of London (#27279) 2023-05-19 11:27:19 +03:00
Shude Li
6a6318b1d2 go.mod: usegopkg.in/yaml.v3 instead of github.com/go-yaml/yaml (#27295) 2023-05-17 23:35:30 +02:00
Felföldi Zsolt
c08dc59aad beacon/types: add beacon chain data types (#27292)
* beacon/types: add beacon chain data types

* beacon/merkle: added comments

* go.mod: cleanups

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2023-05-17 17:39:33 +03:00
Felix Lange
41fafa47b6 go.mod: upgrade gencodec (#27288) 2023-05-17 15:03:38 +03:00
Stephen Guo
84c3799e21 rpc: more accurate checking of handler method signatures (#27287)
This changes the RPC server to ignore methods using *context.Context as parameter
and *error as return value type. Methods with such types would crash the server when
called.
2023-05-17 12:27:51 +02:00
Alex Mylonas
ae1d90e710 internal/ethapi: make NewAccount return EIP-55 format (#26973)
This change implements returning the address as EIP-55 encoded when creating a new account.
2023-05-17 04:29:56 -04:00
John Chase
2f2959d003 core/state/pruner: remove unused error-return (#27273) 2023-05-17 04:23:06 -04:00
Martin Holst Swende
eb83e7c540 core/state/snapshot: check difflayer staleness early (#27255)
This PR adds a staleness-check to AccountRLP, before checking the bloom-filter and potentially going directly into the disklayer.

---------

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
2023-05-16 09:18:39 -04:00
Marius van der Wijden
d46f69dc7a tests/fuzzers/bn256: add PairingCheck fuzzer (#27252)
* tests/fuzzers/bn256: scale gnark result by constant

* tests/fuzzers/bn256: scale gnark result by constant
2023-05-16 07:27:54 -04:00
Delweng
6e3aa86a2b internal/ethapi: minor refactor in block serialization (#27268) 2023-05-16 10:40:47 +02:00
joohhnnn
c2148c644d core/asm: remove unused return value (#27272) 2023-05-16 10:14:04 +02:00
oseau
7369752999 rpc: websocket should respect the "HTTP_PROXY" by default (#27264)
rpc: the default dialer for websocket should respect the proxy environment variables like "HTTP_PROXY"
2023-05-15 08:48:06 +03:00
Justin Traglia
9ca84e6b0b crypto/kzg4844: upgrade c-kzg-4844 to v0.2.0 (#27257)
Upgrade c-kzg-4844 to v0.2.0
2023-05-12 20:16:14 +03:00
Péter Szilágyi
1982437259 core/types: un-ssz blob txs, add json marshalling and tweaks (#27256) 2023-05-12 20:14:29 +03:00
makcandrov
dffd804ca2 internal/ethapi: remove unused err-return (#27240) 2023-05-11 08:23:47 -04:00
zhiqiangxu
0b66d47449 internal/ethapi: make EstimateGas use latest block by default (#24363)
* EstimateGas should use LatestBlockNumber by default

* graphql: default to use latest for gas estimation

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-11 08:23:05 -04:00
Exca-DK
a340721aa9 metrics: use sync.map in registry (#27159) 2023-05-11 05:39:13 -04:00
rjl493456442
a14301823e all: new empty trie with types.EmptyRootHash instead of null (#27230) 2023-05-11 10:19:42 +03:00
Guillaume Ballet
7577b9c28f core/state: unexport NodeIterator (#27239) 2023-05-11 10:15:44 +03:00
ucwong
d17ec0ea66 ethdb/memorydb: init map with known size (#27241)
ethdb:init map with known size
2023-05-11 10:13:25 +03:00
Delweng
c8b0afb2c4 ethclient: acquire the rpc.Client (#27246)
Signed-off-by: jsvisa <delweng@gmail.com>
2023-05-11 10:09:16 +03:00
Péter Szilágyi
2169fa343a crypto/kzg4844: pull in the C and Go libs for KZG cryptography (#27155)
* cryto/kzg4844: pull in the C and Go libs for KZG cryptography

* go.mod: pull in the KZG libraries

* crypto/kzg4844: add basic becnhmarks for ballpark numbers

* cmd, crypto: integrate both CKZG and GoKZG all the time, add flag

* cmd/utils, crypto/kzg4844: run library init on startup

* crypto/kzg4844: make linter happy

* crypto/kzg4844: push missing file

* crypto/kzg4844: fully disable CKZG but leave in the sources

* build, crypto/kzg4844, internal: link CKZG by default and with portable mode

* crypto/kzg4844: drop verifying the trusted setup in gokzg

* internal/build: yolo until it works?

* cmd/utils: make flag description friendlier

Co-authored-by: Martin Holst Swende <martin@swende.se>

* crypto/ckzg: no need for double availability check

* build: tiny flag cleanup nitpick

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-10 14:54:14 +03:00
ucwong
ae7db289b8 p2p: initialize maps with known size (#27229) 2023-05-10 10:52:26 +02:00
Seungbae Yu
a742943c78 node: fix typos in comments (#27236) 2023-05-10 10:42:55 +02:00
ucwong
0fb1be0930 event: initialize maps with known size (#27233)
event: initialize maps with known size
2023-05-09 15:29:32 -04:00
Guillaume Ballet
c62da24dce cmd/utils: report the blocknumber when block import fails (#27213)
When block import fails, the error displays the number of the first block past the import batch, not the number of the failing block. This change fixes this problem by identifying which blocks fails and reporting its number.
2023-05-09 03:57:42 -04:00
ucwong
c798507642 miner: initialize maps with capacity (#27228)
* miner : initialize maps with known size

* miner:some reverts
2023-05-09 03:24:43 -04:00
rjl493456442
5021d36d35 all: port boring changes from pbss (#27176)
* all: port boring changes from pbss

* core, trie: address comments from martin

* trie: minor fixes

* core/rawdb: update comment

* core, eth, tests, trie: address comments

* tests, trie: add extra check when update trie database

* trie/triedb/hashdb: degrade the error to warning
2023-05-09 10:11:04 +03:00
ucwong
81d328a73e log: report error when ctx key is non-string (#27226)
* log/format.go : invalid string cast fix

* log: some polish

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-08 05:38:50 -04:00
joohhnnn
7ac08ba4e0 cmd/geth: rename variable 'extapi' (#27223)
rename parameter

In this case, the naming of "extapi" might create some confusion. Although it represents an External Signer Backend, its name could be mistaken for an API. In reality, it is a backend instance used for communicating with external signers. A better naming choice could be "extBackend" or "externalBackend" to more accurately describe that it is a backend instance rather than an API.
2023-05-08 10:01:14 +03:00
ucwong
cc8d40c65f core/state: initialize maps with known size (#27222)
* core/state : fix map size avoid resizing

* core/state : fixed size
2023-05-08 09:59:14 +03:00
sjlee1125
604e215d1b eth/tracers: add txHash field on txTraceResult (#27183)
This PR modifies the interface for the results of `debug_traceBlock` and `debug_traceCall` by adding the `txHash`, allowing users to identify which transaction's trace result corresponds to. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-05 08:59:13 -04:00
ucwong
ba09403113 core/txpool : fix map size avoid resizing (#27221) 2023-05-05 12:33:01 +03:00
rjl493456442
79a57d49cb eth/downloader: fix error aggregator (#27217) 2023-05-05 08:55:32 +03:00
s7v7nislands
ffda2c64c4 rpc: use atomic types (#27214)
rpc: use atomic type
2023-05-04 04:54:45 -04:00
Péter Szilágyi
dde2da0efb all: remove ethash pow, only retain shims needed for consensus and tests (#27178)
* all: remove ethash pow, only retain shims needed for consensus and tests

* all: thank you linter

* all: disallow launching Geth in legacy PoW mode

* cmd/env/internal/t8ntool: remove dangling ethash flag
2023-05-03 12:58:39 +03:00
Marius van der Wijden
ac3418def6 accounts/abi: resolve name conflict for methods starting with a number (#26999)
This adds logic to prepend 'M' or 'E' to Solidity identifiers when they would
otherwise violate Go identifier naming rules.

Closes #26972

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-05-02 14:27:37 +02:00
David Dzhalaev
29c33d9bab graphql, internal: fix typos in comments (#27184)
* ✏️ Fix typos

* ️ Revert changes

* Update internal/web3ext/web3ext.go

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-02 04:57:07 -04:00
Guillaume Ballet
7f6c045e0d core: remove unused ContractCode method from BlockChain (#27186) 2023-05-02 04:56:08 -04:00
Martin Holst Swende
7d1ebe51b7 p2p/discover: fix lint nit (#27206) 2023-05-02 04:36:11 -04:00
ucwong
a9d7cdaf6e core/types: go generate (#27196)
Fixes a discrepancy between source and generated files, which was introduced when ExcessDataGas was added in https://github.com/ethereum/go-ethereum/pull/27046.
2023-05-02 04:32:27 -04:00
Sina Mahmoodi
ae66009640 internal/ethapi: add block overrides to eth_call (#26414)
Adds an optional config parameter to eth_call which allows users to override block context fields (same functionality that was added to traceCall in #24871)

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-05-02 04:28:43 -04:00
chirag-bgh
52c246fac3 eth/gasprice: fix typo (#27202) 2023-05-02 04:24:35 -04:00
ucwong
a865e28f28 p2p/discover : typo (#27193) 2023-04-28 21:34:08 +03:00
ucwong
c387186f88 eth/ethconfig: go fmt (#27194) 2023-04-28 21:33:14 +03:00
Felix Lange
47cdea5ac5 p2p/discover: concurrent TALKREQ handling (#27112)
This changes TALKREQ message processing to run the handler on separate goroutine,
instead of running on the main discv5 dispatcher goroutine. It's better this way because
it allows the handler to perform blocking actions.

I'm also adding a new method TalkRequestToID here. The method allows implementing
a request flow where one node A sends TALKREQ to another node B, and node B later
sends a TALKREQ back. With TalkRequestToID, node B does not need the ENR of A to
send its request.
2023-04-28 11:03:43 +02:00
Delweng
8f373227ac cmd/geth: make account commands not require datadir lock (#27084)
Makes the `geth account ... ` commands usable even if a geth-process is already executing, since the account commands do not read the chaindata, it was not required for those to use the same locking mechanism. 

---
Signed-off-by: jsvisa <delweng@gmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-04-27 06:57:29 -04:00
Péter Szilágyi
66c0c4e517 cmd, eth, les: replace Shanghai override flag with Cancun (#27171) 2023-04-26 18:17:37 +03:00
Stephen Guo
306d17749c light: use atomic type (#27169)
* light: use atomic type

* light: use a suitable name for the stopped switch in LightChain
2023-04-26 04:21:47 -04:00
Stephen Guo
25f9977f2d les: use atomic type (#27168) 2023-04-26 04:19:56 -04:00
Roberto Bayardo
f8aa623536 core/types: fix discrepancy in receipt.EffectiveGasPrice json encoding tags (#27114)
Regenerate receipt json code to remove omit empty. Previously, there was a discrepancy between the generated code and the source. 

---------

Co-authored-by: lightclient@protonmail.com <lightclient@protonmail.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-04-26 02:37:11 -04:00
rjl493456442
5d3f5805d5 trie: add node type common package (#27160)
* trie: add node type common package

In trie/types package, a few node wrappers are defined, which will be used
in both trie package, trie/snap package, etc. Therefore, a standalone common
package is created to put these stuffs.

* trie: rename trie/types to trie/trienode
2023-04-26 09:01:54 +03:00
Sina Mahmoodi
b1113aa07e eth: fix crash on querying finalized block (#27162)
eth: fix crash on querying nil finalized block
2023-04-25 09:15:43 -04:00
Sina Mahmoodi
2f98dd3838 graphql: encode Long values as hex (#26894)
This is a breaking GraphQL API change. All numeric values are now encoded as
hex strings. The motivation for this change is matching JSON-RPC outputs more
closely.

Numbers in query parameters are accepted as both decimal integers and hex strings.
2023-04-25 14:02:54 +02:00
Martin Holst Swende
9a12cc99de cmd/geth: remove DAO fork test (#27161)
* cmd/geth: fix test to not use explicit db

* cmd/geth: remove dao-test
2023-04-25 07:27:28 -04:00
Exca-DK
f8f95346f9 p2p/discover: add traffic metrics (#27008)
Co-authored-by: Exca-DK <dev@DESKTOP-RI45P4J.localdomain>
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
2023-04-25 12:12:34 +02:00
s7v7nislands
f541cad272 eth: use new atomic types (#27137) 2023-04-25 12:06:50 +02:00
rjl493456442
bbcb5ea37b core, trie: rework trie database (#26813)
* core, trie: rework trie database

* trie: fix comment
2023-04-24 10:38:52 +03:00
Péter Szilágyi
1e556d220c all: remove notion of trusted checkpoints in the post-merge world (#27147)
* all: remove notion of trusted checkpoints in the post-merge world

* light: remove unused function

* eth/ethconfig, les: remove unused config option

* les: make linter happy

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-04-24 09:37:10 +03:00
Péter Szilágyi
d3ece3a07c cmd/utils, node: switch to Pebble as the default db if none exists (#27136)
* cmd/utils, node: switch to Pebble as the default db if none exists

* node: fall back to LevelDB on platforms not supporting Pebble

* core/rawdb, node: default to Pebble at the node level

* cmd/geth: fix some tests explicitly using leveldb

* ethdb/pebble: allow double closes, makes tests simpler
2023-04-21 19:24:18 +03:00
Péter Szilágyi
bbc565ab05 core/types, params: add blob transaction type, RLP encoded for now (#27049)
* core/types, params: add blob transaction type, RLP encoded for now

* all: integrate Cancun (and timestamp based forks) into MakeSigner

* core/types: fix 2 back-and-forth type refactors

* core: fix review comment

* core/types: swap blob tx type id to 0x03
2023-04-21 12:52:02 +03:00
Martin Holst Swende
4ab4e4f3aa params: begin v1.11.7 release cycle 2023-04-20 20:16:04 +02:00
Martin Holst Swende
ea9e62ca3d params: go-ethereum v1.11.6 stable 2023-04-20 20:14:51 +02:00
rjl493456442
99f81d2724 all: refactor trie API (#26995)
In this PR, all TryXXX(e.g. TryGet) APIs of trie are renamed to XXX(e.g. Get) with an error returned.

The original XXX(e.g. Get) APIs are renamed to MustXXX(e.g. MustGet) and does not return any error -- they print a log output. A future PR will change the behaviour to panic on errorrs.
2023-04-20 06:57:24 -04:00
s7v7nislands
ae93e0b484 metrics: use atomic type (#27121) 2023-04-20 03:36:54 -04:00
Alex Beregszaszi
3f7afc3f57 core/vm: order opcodes properly (#27113) 2023-04-20 02:52:00 -04:00
Adrian Sutton
f2df2b1981 cmd/geth: rename --vmodule to --log.vmodule (#27071)
renames `--vmodule` to `--log.vmodule`, and prints a warning if the old form is used.
2023-04-19 07:18:02 -04:00
Martin Holst Swende
2b0a34bea6 cmd/devp2p: make crawler-route53-updater less verbose (#27116)
Follow-up to #26697, makes the crawler less verbose on route53-based scenarios.

It also changes the loglevel from debug to info on Updates, which are typically the root, and can be interesting to see.
2023-04-19 06:46:56 -04:00
s7v7nislands
3768b00747 consensus/ethash: use atomic type (#27068) 2023-04-18 14:54:06 +02:00
joohhnnn
b1972627d9 p2p: access embedded fields of Server directly (#27078) 2023-04-18 11:57:08 +02:00
Delweng
5e4d726e2a params: remove EIP150Hash from chainconfig (#27087)
The EIP150Hash was an idea where, after the fork, we hardcoded the forked hash as an extra defensive mechanism. It wasn't really used, since forks weren't contentious and for all the various testnets and private networks it's been a hassle to have around. 

This change removes that config field. 

---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-04-18 03:49:09 -04:00
Anusha
cb66eba85a core: fix comment to reflect function name (#27070) 2023-04-17 11:02:31 -04:00
Taeguk Kwon
bedf2856d1 signer/core: rename testdata files (#27063)
Sets a meaningful name on test-files
2023-04-17 10:36:47 -04:00
noel
8fe807c8f2 cmd/devp2p: fix erroneous log output in crawler (#27089)
cmd/devp2p: fix log of ignored recent nodes counter
2023-04-17 10:29:27 -04:00
Parithosh Jayanthi
5aa5295cf9 params: new sepolia bootnodes (#27099)
New sepolia bootnodes managed by EF devops
2023-04-17 04:15:25 -04:00
Péter Szilágyi
4a9fa31450 Merge pull request #27051 from sandakersmann/master
build: upgrade -dlgo version to Go 1.20.3
2023-04-08 17:13:55 +03:00
rjl493456442
b946b7a13b core, miner: drop transactions from the same sender when error occurs (#27038)
This PR unifies the error handling in miner. 

Whenever an error occur while applying a transaction, the transaction should be regarded as invalid and all following transactions from the same sender not executable because of the nonce restriction. The only exception is the `nonceTooLow` error which is handled separately.
2023-04-05 07:09:25 -04:00
Marius van der Wijden
230df98e4d core/txpool: disallow future churn by remote txs (#26907)
Prior to this change, it was possible that transactions are erroneously deemed as 'future' although they are in fact 'pending', causing them to be dropped due to 'future' not being allowed to replace 'pending'. 

This change fixes that, by doing a more in-depth inspection of the queue.
2023-04-05 04:59:32 -04:00
Marius Kjærstad
9d37102134 build: upgrade -dlgo version to Go 1.20.3 2023-04-04 22:24:30 +02:00
s7v7nislands
2adce0b066 eth/tracers: use atomic type (#27031)
Use the new atomic types in package eth/tracers

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-04-04 12:34:52 -04:00
Exca-DK
b4dcd1a391 metrics: make gauge_float64 and counter_float64 lock free (#27025)
Makes the float-gauges lock-free

name                      old time/op  new time/op  delta
CounterFloat64Parallel-8  1.45µs ±10%  0.85µs ± 6%  -41.65%  (p=0.008 n=5+5)

---------

Co-authored-by: Exca-DK <dev@DESKTOP-RI45P4J.localdomain>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-04-04 09:53:44 -04:00
Martin Holst Swende
ab1a404b01 all: remove debug-field from vm config (#27048)
This PR removes the Debug field from vmconfig, making it so that if a tracer is set, debug=true is implied.

---------

Co-authored-by: 0xTylerHolmes <tyler@ethereum.org>
Co-authored-by: Sina Mahmoodi <1591639+s1na@users.noreply.github.com>
2023-04-04 09:50:13 -04:00
Delweng
0b76eb3708 eth/tracers: report correct gasLimit in call tracers (#27029)
This includes a semantic change to the `callTracer` as well as `flatCallTracer`.
The value of field `gas` in the **first** call frame will change as follows:

- It previously contained gas available after initial deductions (i.e. tx costs)
- It will now contain the full tx gasLimit value

Signed-off-by: jsvisa <delweng@gmail.com>
2023-04-04 12:34:23 +02:00
Péter Szilágyi
d2cf49327f consensus/misc, params: add EIP-4844 blobfee conversions (#27041)
* consensus/misc, params: add EIP-4844 blobfee conversions

* consensus/misc: pull in fakeExponential test cases

* consensus/misc: reuse bigints

* consensus/misc: nit renames, additional larger testcase

---------

Co-authored-by: Roberto Bayardo <bayardo@alum.mit.edu>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-04-04 11:25:28 +03:00
Péter Szilágyi
91faf2c559 consensus, core/typer: add 4844 excessDataGas to header, tie it to Cancun (#27046) 2023-04-04 10:02:50 +03:00
joohhnnn
9b1a82c600 core/vm: clarify comment (#27045) 2023-04-04 02:59:40 -04:00
s7v7nislands
db18293c32 eth/downloader: use atomic types (#27030)
* eth/downloader: use atomic type

* Update eth/downloader/downloader_test.go

Co-authored-by: Martin Holst Swende <martin@swende.se>

* Update eth/downloader/downloader_test.go

Co-authored-by: Martin Holst Swende <martin@swende.se>

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-04-03 22:48:10 +03:00
Martin Holst Swende
beda6c41ad core/txpool: move some validation to outside of mutex (#27006)
Currently, most of transaction validation while holding the txpool mutex: one exception being an early-on signature check. 

This PR changes that, so that we do all non-stateful checks before we entering the mutex area. This means they can be performed in parallel, and to enable that, certain fields have been made atomic bools and uint64.
2023-04-03 07:16:57 -04:00
Martin Holst Swende
a25dd8064e test/fuzzers: fuzz rlp handling of big.Int and uint256.Int (#26917)
test/fuzzers: fuzz rlp handling of big.Lnt and uint256.Int
2023-04-03 05:42:34 -04:00
rjl493456442
94457cce07 cmd, miner, signer: avoid panic if keystore is not available (#27039)
* cmd, miner, singer: avoid panic if keystore is not available

* cmd/geth: print warning instead of panic
2023-04-03 05:08:06 -04:00
sudeep
7076ae00aa cmd/geth: enable log rotation (#26843)
This change enables log rotation, which can be activated using the flag --log.rotate. Additional parameters that can be given are: 

  - log.maxsize to set maximum size before files are rotated,
  - log.maxbackups to set how many files are retailed, 
  - log.maxage to configure max age of rotated files, 
  - log.compress whether to compress rotated files

The way to configure location of the logfile(s) is left unchanged, via the `log.logfile` parameter.  

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-04-03 05:05:36 -04:00
lightclient
2c5798464e common: delete MakeName (#27023)
common,p2p: remove unused function MakeName
2023-04-03 03:51:31 -04:00
ucwong
dc2f4b9304 go.mod : update snappy (#27027) 2023-04-03 03:35:13 -04:00
Guruprasad Kamath
bed07cd590 cmd/evm: use correct parent number for t8n base fee calculation (#27032)
Currently the t8n tool uses the same block number for the current block and its parent while calculating the base fee. This causes incorrect base fee calculation for the london fork block. This commit sets the parent block number to be one less than the current block number
2023-04-03 03:33:17 -04:00
aaronbuchwald
00a73fbcce accounts/abi/bind: handle UnpackLog with zero topics (#26920)
Adds error handling for the case that UnpackLog or UnpackLogIntoMap is called with a log that has zero topics.

---------

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-03-31 02:35:29 -04:00
s7v7nislands
b92d0ea3bb miner: use atomic type (#27013)
Use the new typed atomics in the miner package
2023-03-31 02:32:47 -04:00
openex
d0fbb10658 eth/catalyst: improve consensus heartbeat (#26896)
improve the heartbeat function that is no longer suitable in the current situation

Co-authored-by: “openex27” <“openexkevin@gmail.com”>
2023-03-30 15:09:35 -04:00
rjl493456442
9ce047452e common: fix json marshaller MixedcaseAddress (#26998)
Fix the json marshaller of MixedcaseAddress
2023-03-30 15:04:28 -04:00
s7v7nislands
50317bdace ethdb/pebble: use atomic type (#27014) 2023-03-30 15:02:14 -04:00
Adrian Sutton
2d1492821d cmd/geth: Add --log.format cli param (#27001)
Removes the new --log.logfmt directive and hides --log.json, replacing both with log.format=(json|logfmt|terminal). The hidden log.json option is still respected if log.format is not specified for backwards compatibility.

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-03-30 09:24:48 -04:00
Sina Mahmoodi
62fb7d3f85 graphql: revert storage access regression (#27007) 2023-03-30 06:57:49 -04:00
s7v7nislands
949cee2fe3 core: use atomic type (#27011) 2023-03-30 06:53:32 -04:00
Guillaume Ballet
a03490c6b2 remove @gballet as a GraphQL codeowner (#27012) 2023-03-30 04:58:23 -04:00
David Murdoch
7ca4f60a1a docs: update outdated DeriveSha docs comment (#26968) 2023-03-28 08:59:37 -04:00
Adrian Sutton
56c1f98f8a internal/debug: add log.logfmt flag to set logging to use logfmt (#26970) 2023-03-28 15:37:40 +03:00
jwasinger
fd94b4fcfa eth/tracers/native: prevent panic for LOG edge-cases (#26848)
This PR fixes OOM panic in the callTracer as well as panicing on
opcode validation errors (e.g. stack underflow) in callTracer and
prestateTracer.

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-03-28 11:46:53 +02:00
Sina Mahmoodi
a236e03d00 graphql: fix data races (#26965)
Fixes multiple data races caused by the fact that resolving fields are done concurrently by the graphql library. It also enforces caching at the stateobject level for account fields.
2023-03-28 03:08:10 -04:00
s7v7nislands
fb8a3aaf1e core/state: use atomic.Bool (#26992) 2023-03-28 03:06:50 -04:00
s7v7nislands
79532a25b1 core/bloombits: use atomic type (#26993) 2023-03-28 03:05:29 -04:00
s7v7nislands
881fed032c core/vm: use atomic.Bool (#26951)
Make use of new atomic types
---------

Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-03-27 09:40:20 -04:00
Delweng
117530b0e6 metrics/librato: ensure resp.body closed (#26969)
This change ensures that we call Close on a http response body, in various places in the source code (mostly tests)
2023-03-27 07:44:41 -04:00
Guillaume Ballet
41f89ca944 core/state, trie: remove Try prefix in Trie accessors (#26975)
This change renames StateTrie methods to remove the Try* prefix. 

We added the Trie methods with prefix 'Try' a long time ago, working
around the problem that most existing methods of Trie did not return the
database error. This weird naming convention has persisted until now.

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-03-27 10:48:46 +02:00
norwnd
df383addee ethclient: ensure returned subscription is nil on error (#26976) 2023-03-25 22:38:43 +01:00
ucwong
792d893ed0 rlp/rlpgen: print want/expect output string if mismatch (#26932)
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
2023-03-24 14:17:39 +01:00
Martin Holst Swende
0137bd69c5 go.mod: update golang.org/x/tools (#26960) 2023-03-24 12:39:20 +01:00
aaronbuchwald
b1acaf47aa eth/gasprice: change feehistory input type from int to uint64 (#26922)
Change input param type from int to uint64
2023-03-23 16:12:37 -04:00
Martin Holst Swende
f6c3a534a4 metrics/influxdb: use smaller dependency and reuse code between v1 and v2 reporters (#26963)
This change switches to use the smaller influxdata/influxdb1-client package instead of depending on the whole infuxdb package. The new smaller client is very similar to the influxdb-v2 client, which made it possible to refactor the two reporters to reuse code a lot more.
2023-03-23 15:12:32 -04:00
turboboost55
7dc100714d metrics: add cpu counters (#26796)
This PR adds counter metrics for the CPU system and the Geth process.
Currently the only metrics available for these items are gauges. Gauges are
fine when the consumer scrapes metrics data at the same interval as Geth
produces new values (every 3 seconds), but it is likely that most consumers
will not scrape that often. Intervals of 10, 15, or maybe even 30 seconds
are probably more common.

So the problem is, how does the consumer estimate what the CPU was doing in
between scrapes. With a counter, it's easy ... you just subtract two
successive values and divide by the time to get a nice, accurate average.
But with a gauge, you can't do that. A gauge reading is an instantaneous
picture of what was happening at that moment, but it gives you no idea
about what was going on between scrapes. Taking an average of values is
meaningless.
2023-03-23 14:13:50 +01:00
Guillaume Ballet
8990c92aea core/state: add account address to Trie slot accessors (#26934)
This changes the Trie interface to add the plain account address as a
parameter to all storage-related methods.

After the introduction of the TryAccount* functions, TryGet, TryUpdate and
TryDelete are now only meant to read an account's storage. In their current
form, they assume that an account storage is stored in a separate trie, and
that the hashing of the slot is independent of its account's address.

The proposed structure for a stateless storage breaks these two
assumptions: the hashing of a slot key requires the address and all slots
and accounts are stored in a single trie.

This PR therefore adds an address parameter to the interface. It is ignored
in the MPT version, so this change has no functional impact, however it
will reduce the diff size when merging verkle trees.
2023-03-23 11:52:22 +01:00
lightclient
37ecff0967 cmd/evm, tests: record preimages if dump is expected (#26955)
With #25287 we made it so that preimages were not recorded by default. This had the side effect that the evm command is no longer able to dump state since it does a preimage lookup to determine the address represented by a key.

This change enables the recording of preimages when the dump command is given.
2023-03-23 05:15:40 -04:00
Delweng
7f3fc15a8b core/rawdb: update freezertable read meter (#26946)
The meter for "for measuring the effective amount of data read" within the freezertable was never updated. This change remedies that. 
---------

Signed-off-by: jsvisa <delweng@gmail.com>
2023-03-23 03:34:40 -04:00
Marius van der Wijden
20f8eb756b eth/catalyst: fix races (#26950) 2023-03-22 13:36:26 -04:00
Martin Holst Swende
b3f43c89b3 core/vm: expose jumptable constructors (#26880)
When interacting with geth as a library to e.g. produce state tests, it is desirable to obtain the consensus-correct jumptable definition for a given fork. This changes adds accessors so the instructionset can be obtained and characteristics about opcodes can be inspected.
2023-03-21 07:14:47 -04:00
s7v7nislands
905a723fae core/rawdb: use atomic int added in go1.19 (#26935) 2023-03-21 07:10:23 -04:00
Péter Szilágyi
8a9a73c99b log: add special casing of uint256 into the logger (#26936) 2023-03-21 12:01:43 +02:00
Péter Szilágyi
2ed8013f08 build: allow building nightly archives via cron jobs (#26938) 2023-03-21 11:52:29 +02:00
Martin Holst Swende
7ecb578564 params: begin v1.11.6 release cycle 2023-03-21 09:04:26 +01:00
Martin Holst Swende
a38f410857 params: go-ethereum v1.11.5 stable 2023-03-21 09:03:04 +01:00
Marius van der Wijden
e6b6a8b738 core/txpool: allow future local transactions (#26930)
Local transactions should not be subject to the "future shouldn't churn pending txs" rule
2023-03-20 09:15:18 -04:00
Marius van der Wijden
5d23d21fff params: schedule shanghai fork on mainnet (#26908)
Schedules the shanghai hardfork on timestamp 1681338455 as discussed on ACDE 157: https://github.com/ethereum/execution-specs/pull/727
2023-03-20 07:38:34 -04:00
s7v7nislands
80ff0b4e6a core/txpool: use atomic int added in go1.19 (#26913)
Makes use of atomic.Uint64 instead of atomic by pointer
2023-03-20 04:12:24 -04:00
Marius van der Wijden
81b0aa0cc7 trie: reduce unit test time (#26918) 2023-03-20 04:09:35 -04:00
Darioush Jalali
ee8e83fa5f eth: fix output file permissions in admin_exportChain (#26912)
* api: Use 0700 file permissions for ExportChain

* change perm to 0644

* Update api.go

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-03-17 20:06:06 +02:00
Martin Holst Swende
58d0f6440b rlp: support for uint256 (#26898)
This adds built-in support in package rlp for encoding, decoding and generating code dealing with uint256.Int.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-03-17 06:51:55 -04:00
Darioush Jalali
b7bfbc1e64 trie, accounts/abi: add error-checks (#26914) 2023-03-17 06:19:51 -04:00
Darioush Jalali
f733657383 internal/ethapi: avoid int overflow in GetTransactionReceipt (#26911) 2023-03-16 23:53:39 +01:00
Marius van der Wijden
d8066dcde8 eth/catalyst: increase update consensus timeout (#26840)
Increases the time between consensus updates that we give the CL before we start warning the user.
2023-03-16 15:35:36 -04:00
rjl493456442
48d1bf0678 consensus: improve consensus engine definition (#26871)
Makes clear the distinction between Finalize and FinalizedAndAssemble:

- In Finalize function, a series of state operations are applied according to consensus rules. The statedb is mutated and the root hash can be checked and compared afterwards.

This function should be used in block processing(receive afrom network and apply it locally) but not block generation.

- In FinalizeAndAssemble function, after applying state mutations, the block is also to be assembled with the latest
  state root computed, updating the header. 

 This function should be used in block generation only.
2023-03-16 15:34:25 -04:00
rjl493456442
bba2a1bac5 core: show db error-info in case of mismatched hash root (#26870)
When a database failure occurs, bubble it up a into statedb, and report it in suitable places, such as during a 'bad block' report.
2023-03-16 03:12:34 -04:00
Felix Lange
f86913bc3e cmd/devp2p, cmd/geth: add version in --help output (#26895)
Not sure why this was removed, it's pretty useful to see the version
also in --help.
2023-03-15 14:34:36 +01:00
Jonathan Otto
6bc68f8d94 Increase websocket frame size (from erigon rpc client) (#26883)
This increases the maximum allowed message size to 32MB.

Originally submitted at https://github.com/ledgerwatch/erigon/pull/2739

example block failure: https://etherscan.io/tx/0x1317d973a55cedf9b0f2df6ea48e8077dd176f5444a3423368a46d6e4db89982#internal
2023-03-14 18:41:28 +01:00
Stephen Flynn
b5c9be3358 all: update links in documentation (#26882)
Co-authored-by: Stephen Flynn <stephen.flynn@gapac.com>
2023-03-14 10:23:49 -04:00
Martin Holst Swende
eca3d39c31 p2p/discover: pass invalid discv5 packets to Unhandled channel (#26699)
This makes it possible to run another protocol alongside discv5, by reading 
unhandled packets from the channel.
2023-03-14 12:40:40 +01:00
rjl493456442
c8a6b7100c core/state, trie: port changes from PBSS (#26763) 2023-03-14 04:50:53 -04:00
Felix Lange
94ff721911 .travis.yml: reenable PPA build on tag push (#26873) 2023-03-13 14:10:19 +01:00
lightclient
5f81db68c6 eth: return error if 'safe' or 'finalized' tag used pre-merge (#26862)
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-03-13 06:51:23 -04:00
ucwong
d1c5f918a3 core/txpool: use priceList.Put instead of heap.Push (#26863)
Minor refactor to use the 'intended' accessor
2023-03-13 04:45:25 -04:00
s7v7nislands
a20e38720c core: minor code refactor (#26852)
* core: refactor code

* core: drop it from this anonymous goroutine func
2023-03-13 04:02:50 -04:00
xiyang
ca61048178 code/vm: fix comment typo (#26865)
it should be constantinople rather than contantinople
2023-03-13 09:30:32 +02:00
Guruprasad Kamath
789de23d16 tests: define MuirGlacier fork (#26856)
add muir glacier to t8n
2023-03-10 15:47:05 -05:00
Felix Lange
4930614a09 params: begin v1.11.5 release cycle 2023-03-10 20:00:23 +01:00
Felix Lange
7e3b149be0 params: go-ethereum v1.11.4 stable 2023-03-10 19:53:52 +01:00
Marius van der Wijden
6cf2e921a7 core/txpool: implement additional DoS defenses (#26648)
This adds two new rules to the transaction pool:

- A future transaction can not evict a pending transaction.
- A transaction can not overspend available funds of a sender.

---

Co-authored-by: dwn1998 <42262393+dwn1998@users.noreply.github.com>
Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-03-10 18:30:26 +01:00
Felix Lange
564db9a95f core: add Timestamp method in BlockGen (#26844)
Since forks are now scheduled by block time, it can be necessary
to check the timestamp of a block while generating transactions.
2023-03-10 14:03:27 +01:00
panicalways
051493d9bf p2p: small comment typo (#26850)
Update server.go
2023-03-10 11:45:49 +02:00
Péter Szilágyi
df02799543 travis: only build PPAs nightly, not on every push, too heavy (#26846) 2023-03-09 16:44:54 +02:00
Roberto Bayardo
67ac5f0ae7 core, core/types: plain Message struct (#25977)
Here, the core.Message interface turns into a plain struct and
types.Message gets removed.

This is a breaking change to packages core and core/types. While we do
not promise API stability for package core, we do for core/types. An
exception can be made for types.Message, since it doesn't have any
purpose apart from invoking the state transition in package core.
types.Message was also marked deprecated by the same commit it
got added in, 4dca5d4db7 (November 2016).

The core.Message interface was added in December 2014, in commit
db494170dc, for the purpose of 'testing' state transitions. It's the
same change that made transaction struct fields private. Before that,
the state transition used *types.Transaction directly.

Over time, multiple implementations of the interface accrued across
different packages, since constructing a Message is required whenever
one wants to invoke the state transition. These implementations all
looked very similar, a struct with private fields exposing the fields
as accessor methods.

By changing Message into a struct with public fields we can remove all
these useless interface implementations. It will also hopefully
simplify future changes to the type with less updates to apply across
all of go-ethereum when a field is added to Message.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-03-09 14:19:12 +01:00
Martin Holst Swende
08f6a2a89d cmd/evm: update readmes for the tests (#26841) 2023-03-09 07:06:47 -05:00
Felix Lange
5395362e0f core/forkid: fix issue in validation test (#26544)
This changes the test to match the comment description. Using timestampedConfig in this test case is incorrect, the comment says 'local is at Gray Glacier' and isn't aware of more forks.
2023-03-09 06:37:44 -05:00
xiyang
1bf1168432 core/vm: fix typo in comment (#26838)
fixes eip 220 ->  2200
2023-03-09 04:39:17 -05:00
Martin Holst Swende
b80f05bde2 core/vm: use golang native big.Int (#26834)
reverts #26021, to use the upstream bigint instead.
2023-03-08 13:12:53 -05:00
Rafael Matias
e14043db71 params: remove EF azure bootnodes (#26828) 2023-03-08 11:13:56 +01:00
Daniel Fernandes
02796f6bee signer/core: accept all solidity primitive types for EIP-712 signing (#26770)
Accept all primitive types in Solidity for EIP-712 from intN, uintN, intN[], uintN[] for N as 0 to 256 in multiples of 8

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-03-08 02:48:53 -05:00
rjl493456442
f7661a662a core/rawdb: find smallest block stored in key-value store when chain gapped (#26719)
This change prints out more information about the problem, in the case where geth detects a gap between leveldb and ancients, so we can determine more exactly where the gap is (what the first missing is). Also prints out more metadata. 

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-03-08 02:39:13 -05:00
Felix Lange
bb4ac2d396 params: begin v1.11.4 release cycle 2023-03-07 18:18:59 +01:00
Felix Lange
5ed08c4735 params: go-ethereum v1.11.3 stable 2023-03-07 18:17:32 +01:00
Felix Lange
a54d91ac5a build: update to go 1.20.2 (#26824) 2023-03-07 18:16:21 +01:00
Marius van der Wijden
78429f7733 beacon/engine: don't omit empty withdrawals in ExecutionPayloadBodies (#26698)
This ensures the "withdrawals" field will always be present in responses
to getPayloadBodiesByRangeV1 and getPayloadBodiesByHashV1.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-03-07 16:30:04 +01:00
James Prestwich
1e3177de22 accounts/usbwallet: mitigate ledger app chunking issue (#26773)
This PR mitigates an issue with Ledger's on-device RLP deserialization, see
https://github.com/LedgerHQ/app-ethereum/issues/409

Ledger's RLP deserialization code does not validate the length of the RLP list received,
and it may prematurely enter the signing flow when a APDU chunk boundary falls immediately
before the EIP-155 chain_id when deserializing a transaction. Since the chain_id is
uninitialized, it is 0 during this signing flow. This may cause the user to accidentally
sign the transaction with chain_id = 0. That signature would be returned from the device 1
packet earlier than expected by the communication loop. The device blocks the
second-to-last packet waiting for the signer flow, and then errors on the successive
packet (which contains the chain_id, zeroed r, and zeroed s)

Since the signature's early arrival causes successive errors during the communication
process, geth does not parse the improper signature produced by the device, and therefore
no improperly-signed transaction can be created. User funds are not at risk.

We mitigate by selecting the highest chunk size that leaves at least 4 bytes in the
final chunk.
2023-03-07 15:20:04 +01:00
Sina Mahmoodi
41af42e97c eth/tracers/native: set created address to nil in case of failure (#26779)
Fixes #26073
2023-03-07 14:39:11 +01:00
Guruprasad Kamath
cb1f6bdbc8 cmd/evm: correct alloc for t8n testdata (#26822)
Fixes a minor error in the testdata
2023-03-07 05:32:52 -05:00
Adrian Sutton
39be753bf5 internal/ethapi: add tests for transaction types JSON marshal/unmarshal (#26667)
Checks that Transaction.MarshalJSON and newRPCTransaction JSON output can be parsed by Transaction.UnmarshalJSON

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-03-07 05:26:19 -05:00
rjl493456442
77e33e5a49 core, miner: revert block gas counter in case of invalid transaction (#26799)
This change fixes a flaw where, in certain scenarios, the block sealer did not accurately reset the remaining gas after failing to include an invalid transaction. Fixes #26791
2023-03-07 05:23:52 -05:00
Felix Lange
4688d3c8f4 ethclient: fix panic when requesting missing blocks (#26817)
This fixes a regression introduced by #26723.
Fixes #26816.
2023-03-07 05:21:23 -05:00
turboboost55
544e4a700b metrics: improve accuracy of CPU gauges (#26793)
This PR changes metrics collection to actually measure the time interval between collections, rather
than assume 3 seconds. I did some ad hoc profiling, and on slower hardware (eg, my Raspberry Pi 4)
I routinely saw intervals between 3.3 - 3.5 seconds, with some being as high as 4.5 seconds. This
will generally cause the CPU gauge readings to be too high, and in some cases can cause impossibly
large values for the CPU load metrics (eg. greater than 400 for a 4 core CPU).

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
2023-03-07 00:29:48 +01:00
Marius van der Wijden
5bc2ef984f core, eth/catalyst: fix race conditions in tests (#26790)
Fixes a race in TestNewPayloadOnInvalidTerminalBlock where setting the TTD raced with
the miner. Solution: set the TTD on the blockchain config not the genesis config.

Also fixes a race in CopyHeader which resulted in race reports all over the place.
2023-03-06 23:32:27 +01:00
Felix Lange
87186148e0 core/types: add EffectiveGasPrice in Receipt (#26713)
This change adds a struct field EffectiveGasPrice in types.Receipt. The field is present
in RPC responses, but not in the Go struct, and thus can't easily be accessed via ethclient.

Co-authored-by: PulsarAI <dev@pulsar-systems.fi>
2023-03-06 17:19:41 +01:00
Péter Szilágyi
4c23fe97c5 eth: remove admin.peers[i].eth.head and difficulty (#26804) 2023-03-06 09:27:46 +02:00
Marius van der Wijden
d865a5d6ae core, params: schedule Shanghai on goerli (#26795)
* core: params: schedule Shanghai on goerli

* core/forkid: fix comment
2023-03-06 09:26:43 +02:00
Péter Szilágyi
27e59827d8 travi: remove strange leftover Go version 2023-03-03 12:26:04 +02:00
Péter Szilágyi
403cac71eb README, go.mod, event, internal/version: bump min Go to 1.19 (#26803) 2023-03-03 12:24:09 +02:00
Péter Szilágyi
010189538e core: fix a merge fault (#26802) 2023-03-03 12:11:39 +02:00
Péter Szilágyi
19f74fa3c0 core/rawdb, ethdb/pebble: disable pebble on openbsd (#26801) 2023-03-03 12:05:00 +02:00
Péter Szilágyi
cd31f2dee2 all: change chain head markers from block to header (#26777) 2023-03-02 08:29:15 +02:00
Peter (bitfly)
e1b98f49a5 ethclient: include withdrawals in ethclient block responses (#26778)
* include withdrawals in ethclient responses

* omit empty withdrawals array in json serialization
2023-02-28 15:40:24 +02:00
rjl493456442
2bb622ce40 ethdb/pebble: fix max memorytable size (#26776) 2023-02-28 15:34:12 +02:00
rjl493456442
98b0ea62b5 ethdb/pebble: fix range compaction (#26771)
* ethdb/pebble: fix range compaction

* ethdb/pebble: add comment
2023-02-28 15:32:51 +02:00
Dan Cline
2ea48f8a22 core: improve withdrawal index assignment in GenerateChain (#26756)
This fixes an issue where the withdrawal index was not calculated correctly
for multiple withdrawals in a single block.

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
2023-02-28 11:46:32 +01:00
Chris Ziogas
2ad150d986 eth/tracers: add native flatCallTracer (aka parity style tracer) (#26377)
Adds support for a native call tracer with the Parity format, which outputs call frames
in a flat array. This tracer accepts the following options:

- `convertParityErrors: true` will convert error messages to match those of Parity
- `includePrecompiles: true` will report all calls to precompiles. The default
  matches Parity's behavior where CALL and STATICCALLs to precompiles are excluded

Incompatibilities with Parity include:

- Parity removes the result object in case of failure. This behavior is maintained
  with the exception of reverts. Revert output usually contains useful information,
  i.e. Solidity revert reason.
- The `gasUsed` field accounts for intrinsic gas (e.g. 21000 for simple transfers)
  and refunds unlike Parity
- Block rewards are not reported

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
2023-02-28 13:54:37 +03:30
Martin Holst Swende
c155c8e179 cmd/devp2p: faster crawling + less verbose dns updates (#26697)
This improves the speed of DHT crawling by using concurrent requests.
It also removes logging of individual DNS updates.
2023-02-27 11:36:26 +01:00
Péter Szilágyi
ee530c0d5a Merge pull request #26721 from holiman/nocover
ci: disable coverage reporting in appveyor and travis
2023-02-23 13:24:31 +02:00
Péter Szilágyi
b3ae073488 eth: use the last announced finalized block as the sync ancient limit (#26685) 2023-02-23 13:22:41 +02:00
Martin Holst Swende
09a9ccdbce core/rawdb, node: use standalone flock dependency (#26633) 2023-02-23 09:11:50 +02:00
Nate Armstrong
a36c68f12c log: improve documentation (#26753)
Add usage examples
2023-02-22 07:39:41 -05:00
Péter Szilágyi
f6a7cc68d5 params: begin v.1.11.3 release cycle 2023-02-22 14:25:19 +02:00
Péter Szilágyi
73b01f40ce params: release Geth v1.11.2 2023-02-22 14:23:51 +02:00
Péter Szilágyi
f86f048646 common/math: allow HexOrDecimal to accept unquoted decimals too (#26758) 2023-02-22 13:55:09 +02:00
Yier
4034c675be eth/filters: fix a breaking change and return rpctransaction (#26757)
* eth/filters: fix a breaking change and return rpctransaction

* eth/filters: fix test cases

---------

Co-authored-by: Catror <me@catror.com>
2023-02-22 13:06:43 +02:00
rjl493456442
fe01a2f63b all: use unified emptyRootHash and emptyCodeHash (#26718)
The EmptyRootHash and EmptyCodeHash are defined everywhere in the codebase, this PR replaces all of them with unified one defined in core/types package, and also defines constants for TxRoot, WithdrawalsRoot and UncleRoot
2023-02-21 06:12:27 -05:00
Péter Szilágyi
2f20fd31ee core/rawdb: expose chain freezer constructor without internals (#26748) 2023-02-21 13:10:01 +02:00
Martin Holst Swende
6d2d126100 core: fix accessor mismatch for genesis state (#26747) 2023-02-21 12:18:33 +02:00
Péter Szilágyi
90d25514af core, eth: merge snap-sync chain download progress logs (#26676) 2023-02-21 12:17:34 +02:00
Sungwoo Kim
7d4db69607 cmd/geth: clarify dumpconfig options (#26729)
Clarifies the documentation around dumpconfi

Signed-off-by: Sungwoo Kim <git@sung-woo.kim>
2023-02-21 02:35:04 -05:00
rjl493456442
13ef21d467 Revert "core/trie: remove trie tracer (#26665)" (#26732)
This reverts commit 7c749c947a.
2023-02-20 09:54:52 -05:00
Péter Szilágyi
ba4267fcac build: enable Lunar Lobster PPA builds 2023-02-20 13:26:37 +02:00
Péter Szilágyi
41dee2623e build: fix Go 1.19.0 bootstrapper issues on 386 PPA 2023-02-20 12:36:46 +02:00
Péter Szilágyi
4519054816 build: fix (finaly?) the PPA env vars for Go bootstrapping 2023-02-20 11:31:19 +02:00
Péter Szilágyi
c02334be1e build: yet another weird PPA fix 2023-02-20 11:07:33 +02:00
Péter Szilágyi
165268430c internal/build: revert raising the chunk size for PPA 2023-02-20 10:43:55 +02:00
Péter Szilágyi
a43efceaf2 build: add some PPA debug logs, sigh 2023-02-20 10:31:35 +02:00
Péter Szilágyi
4ec4235fc4 build: fix gobootstrap path for the PPA 2023-02-20 10:09:00 +02:00
Péter Szilágyi
e1e2781105 build: fix setting env var, temp early exit 2023-02-20 09:57:37 +02:00
Péter Szilágyi
2166c86041 build: ship bootstrapper Go along with builder for PPA (#26731) 2023-02-20 08:53:15 +02:00
Felix Lange
1db978ca6b rpc: fix unmarshaling of null result in CallContext (#26723)
The change fixes unmarshaling of JSON null results into json.RawMessage.

---------

Co-authored-by: Jason Yuan <jason.yuan@curvegrid.com>
Co-authored-by: Jason Yuan <jason.yuan869@gmail.com>
2023-02-19 14:23:18 -05:00
Martin Holst Swende
7c749c947a core/trie: remove trie tracer (#26665)
This PR contains a small portion of the full pbss PR, namely

    Remove the tracer from trie (and comitter), and instead using an accessList.
    Related changes to the Nodeset.


---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2023-02-19 14:10:19 -05:00
Roman Krasiuk
15e5e6176b eth/catalyst: request too large error (#26722)
The method `GetPayloadBodiesByRangeV1` now returns "-38004: Too large request" error if the requested range is too large, according to spec

Co-authored-by: Martin Holst Swende <martin@swende.se>
2023-02-17 13:30:38 -05:00
Martin Holst Swende
a0d63bc69a ci: disable coverage reporting in appveyor and travis 2023-02-17 15:34:30 +01:00
Marius van der Wijden
6428663faf eth/catalyst: send INVALID instead of INVALID_BLOCK_HASH (#26696)
This change will break one hive test, but pass another and it will be the better way going forward
2023-02-17 05:25:09 -05:00
Martin Holst Swende
b40c10916c params: begin v1.11.2 release cycle 2023-02-16 20:53:16 +01:00
1417 changed files with 128888 additions and 112197 deletions

13
.github/CODEOWNERS vendored
View File

@@ -4,19 +4,22 @@
accounts/usbwallet @karalabe
accounts/scwallet @gballet
accounts/abi @gballet @MariusVanDerWijden
beacon/engine @lightclient
cmd/clef @holiman
cmd/evm @holiman @MariusVanDerWijden @lightclient
consensus @karalabe
core/ @karalabe @holiman @rjl493456442
eth/ @karalabe @holiman @rjl493456442
eth/catalyst/ @gballet
eth/catalyst/ @gballet @lightclient
eth/tracers/ @s1na
graphql/ @gballet @s1na
core/tracing/ @s1na
graphql/ @s1na
internal/ethapi @lightclient
internal/era @lightclient
les/ @zsfelfoldi @rjl493456442
light/ @zsfelfoldi @rjl493456442
node/ @fjl
p2p/ @fjl @zsfelfoldi
params/ @fjl @holiman @karalabe @gballet @rjl493456442 @zsfelfoldi
rpc/ @fjl @holiman
p2p/simulations @fjl
p2p/protocols @fjl
p2p/testing @fjl
signer/ @holiman

View File

@@ -35,6 +35,6 @@ and help.
## Configuration, dependencies, and tests
Please see the [Developers' Guide](https://geth.ethereum.org/docs/developers/devguide)
Please see the [Developers' Guide](https://geth.ethereum.org/docs/developers/geth-developer/dev-guide)
for more details on configuring your environment, managing project dependencies
and testing procedures.

24
.github/workflows/go.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: i386 linux tests
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.23.0
cache: false
- name: Run tests
run: go test -short ./...
env:
GOOS: linux
GOARCH: 386

11
.gitignore vendored
View File

@@ -28,6 +28,14 @@ build/_vendor/pkg
/build/bin/
/geth*.zip
# used by the build/ci.go archive + upload tool
/geth*.tar.gz
/geth*.tar.gz.sig
/geth*.tar.gz.asc
/geth*.zip.sig
/geth*.zip.asc
# travis
profile.tmp
profile.cov
@@ -47,3 +55,6 @@ profile.cov
/dashboard/assets/package-lock.json
**/yarn-error.log
logs/
tests/spec-tests/

View File

@@ -6,13 +6,10 @@ run:
# default is true. Enables skipping of directories:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs-use-default: true
skip-files:
- core/genesis_alloc.go
linters:
disable-all: true
enable:
- goconst
- goimports
- gosimple
- govet
@@ -26,7 +23,10 @@ linters:
- durationcheck
- exportloopref
- whitespace
- revive # only certain checks enabled
### linters we tried and will not be using:
###
# - structcheck # lots of false positives
# - errcheck #lot of false positives
# - contextcheck
@@ -39,24 +39,35 @@ linters:
linters-settings:
gofmt:
simplify: true
goconst:
min-len: 3 # minimum length of string constant
min-occurrences: 6 # minimum number of occurrences
revive:
enable-all-rules: false
# here we enable specific useful rules
# see https://golangci-lint.run/usage/linters/#revive for supported rules
rules:
- name: receiver-naming
severity: warning
disabled: false
exclude: [""]
issues:
exclude-files:
- core/genesis_alloc.go
exclude-rules:
- path: crypto/bn256/cloudflare/optate.go
linters:
- deadcode
- staticcheck
- path: crypto/bn256/
linters:
- revive
- path: cmd/utils/flags.go
text: "SA1019: cfg.TxLookupLimit is deprecated: use 'TransactionHistory' instead."
- path: cmd/utils/flags.go
text: "SA1019: ethconfig.Defaults.TxLookupLimit is deprecated: use 'TransactionHistory' instead."
- path: internal/build/pgp.go
text: 'SA1019: "golang.org/x/crypto/openpgp" is deprecated: this package is unmaintained except for security fixes.'
- path: core/vm/contracts.go
text: 'SA1019: "golang.org/x/crypto/ripemd160" is deprecated: RIPEMD-160 is a legacy hash and should not be used for new applications.'
- path: accounts/usbwallet/trezor.go
text: 'SA1019: "github.com/golang/protobuf/proto" is deprecated: Use the "google.golang.org/protobuf/proto" package instead.'
- path: accounts/usbwallet/trezor/
text: 'SA1019: "github.com/golang/protobuf/proto" is deprecated: Use the "google.golang.org/protobuf/proto" package instead.'
exclude:
- 'SA1019: event.TypeMux is deprecated: use Feed'
- 'SA1019: strings.Title is deprecated'

View File

@@ -56,7 +56,6 @@ Diederik Loerakker <proto@protolambda.com>
Dimitry Khokhlov <winsvega@mail.ru>
Domino Valdano <dominoplural@gmail.com>
Domino Valdano <dominoplural@gmail.com> <jeff@okcupid.com>
Edgar Aroutiounian <edgar.factorial@gmail.com>

View File

@@ -5,31 +5,17 @@ jobs:
allow_failures:
- stage: build
os: osx
go: 1.17.x
env:
- azure-osx
include:
# This builder only tests code linters on latest version of Go
- stage: lint
os: linux
dist: bionic
go: 1.20.x
env:
- lint
git:
submodules: false # avoid cloning ethereum/tests
script:
- go run build/ci.go lint
# These builders create the Docker sub-images for multi-arch push and each
# will attempt to push the multi-arch image if they are the last builder
# This builder create and push the Docker images for all architectures
- stage: build
if: type = push
os: linux
arch: amd64
dist: bionic
go: 1.20.x
dist: focal
go: 1.23.x
env:
- docker
services:
@@ -39,69 +25,27 @@ jobs:
before_install:
- export DOCKER_CLI_EXPERIMENTAL=enabled
script:
- go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go
- stage: build
if: type = push
os: linux
arch: arm64
dist: bionic
go: 1.20.x
env:
- docker
services:
- docker
git:
submodules: false # avoid cloning ethereum/tests
before_install:
- export DOCKER_CLI_EXPERIMENTAL=enabled
script:
- go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go
# This builder does the Ubuntu PPA upload
- stage: build
if: type = push
os: linux
dist: bionic
go: 1.20.x
env:
- ubuntu-ppa
- GO111MODULE=on
git:
submodules: false # avoid cloning ethereum/tests
addons:
apt:
packages:
- devscripts
- debhelper
- dput
- fakeroot
- python-bzrlib
- python-paramiko
script:
- echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
- go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
- go run build/ci.go dockerx -platform "linux/amd64,linux/arm64" -upload ethereum/client-go
# This builder does the Linux Azure uploads
- stage: build
if: type = push
os: linux
dist: bionic
dist: focal
sudo: required
go: 1.20.x
go: 1.23.x
env:
- azure-linux
- GO111MODULE=on
git:
submodules: false # avoid cloning ethereum/tests
addons:
apt:
packages:
- gcc-multilib
script:
# Build for the primary platforms that Trusty can manage
# build amd64
- go run build/ci.go install -dlgo
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
# build 386
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib
- git status --porcelain
- go run build/ci.go install -dlgo -arch 386
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
@@ -122,56 +66,61 @@ jobs:
- stage: build
if: type = push
os: osx
go: 1.20.x
osx_image: xcode14.2
go: 1.23.1 # See https://github.com/ethereum/go-ethereum/pull/30478
env:
- azure-osx
- GO111MODULE=on
git:
submodules: false # avoid cloning ethereum/tests
script:
- ln -sf /Users/travis/gopath/bin/go1.23.1 /usr/local/bin/go # Work around travis go-setup bug
- go run build/ci.go install -dlgo
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
- go run build/ci.go install -dlgo -arch arm64
- go run build/ci.go archive -arch arm64 -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
# These builders run the tests
- stage: build
if: type = push
os: linux
arch: amd64
dist: bionic
go: 1.20.x
env:
- GO111MODULE=on
dist: focal
go: 1.23.x
script:
- go run build/ci.go test -coverage $TEST_PACKAGES
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
- stage: build
if: type = pull_request
if: type = push
os: linux
arch: arm64
dist: bionic
go: 1.19.x
env:
- GO111MODULE=on
dist: focal
go: 1.22.x
script:
- go run build/ci.go test -coverage $TEST_PACKAGES
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
# This builder does the Ubuntu PPA nightly uploads
- stage: build
if: type = cron || (type = push && tag ~= /^v[0-9]/)
os: linux
dist: bionic
go: 1.19.x
dist: focal
go: 1.23.x
env:
- GO111MODULE=on
- ubuntu-ppa
git:
submodules: false # avoid cloning ethereum/tests
before_install:
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot
script:
- go run build/ci.go test -coverage $TEST_PACKAGES
- echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
- go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
# This builder does the Azure archive purges to avoid accumulating junk
- stage: build
if: type = cron
os: linux
dist: bionic
go: 1.20.x
dist: focal
go: 1.23.x
env:
- azure-purge
- GO111MODULE=on
git:
submodules: false # avoid cloning ethereum/tests
script:
@@ -181,10 +130,9 @@ jobs:
- stage: build
if: type = cron
os: linux
dist: bionic
go: 1.20.x
dist: focal
go: 1.23.x
env:
- GO111MODULE=on
- racetests
script:
- go run build/ci.go test -race -coverage $TEST_PACKAGES
- travis_wait 60 go run build/ci.go test -race $TEST_PACKAGES

View File

@@ -4,7 +4,7 @@ ARG VERSION=""
ARG BUILDNUM=""
# Build Geth in a stock Go builder container
FROM golang:1.20-alpine as builder
FROM golang:1.23-alpine AS builder
RUN apk add --no-cache gcc musl-dev linux-headers git
@@ -25,7 +25,7 @@ COPY --from=builder /go-ethereum/build/bin/geth /usr/local/bin/
EXPOSE 8545 8546 30303 30303/udp
ENTRYPOINT ["geth"]
# Add some metadata labels to help programatic image consumption
# Add some metadata labels to help programmatic image consumption
ARG COMMIT=""
ARG VERSION=""
ARG BUILDNUM=""

View File

@@ -4,7 +4,7 @@ ARG VERSION=""
ARG BUILDNUM=""
# Build Geth in a stock Go builder container
FROM golang:1.20-alpine as builder
FROM golang:1.23-alpine AS builder
RUN apk add --no-cache gcc musl-dev linux-headers git
@@ -14,6 +14,13 @@ COPY go.sum /go-ethereum/
RUN cd /go-ethereum && go mod download
ADD . /go-ethereum
# This is not strictly necessary, but it matches the "Dockerfile" steps, thus
# makes it so that under certain circumstances, the docker layer can be cached,
# and the builder can jump to the next (build all) command, with the go cache fully loaded.
#
RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/geth
RUN cd /go-ethereum && go run build/ci.go install -static
# Pull all binaries into a second stage deploy alpine container
@@ -24,7 +31,7 @@ COPY --from=builder /go-ethereum/build/bin/* /usr/local/bin/
EXPOSE 8545 8546 30303 30303/udp
# Add some metadata labels to help programatic image consumption
# Add some metadata labels to help programmatic image consumption
ARG COMMIT=""
ARG VERSION=""
ARG BUILDNUM=""

View File

@@ -2,37 +2,56 @@
# with Go source code. If you know what GOPATH is then you probably
# don't need to bother with make.
.PHONY: geth android ios evm all test clean
.PHONY: geth all test lint fmt clean devtools help
GOBIN = ./build/bin
GO ?= latest
GORUN = env GO111MODULE=on go run
GORUN = go run
#? geth: Build geth.
geth:
$(GORUN) build/ci.go install ./cmd/geth
@echo "Done building."
@echo "Run \"$(GOBIN)/geth\" to launch geth."
#? all: Build all packages and executables.
all:
$(GORUN) build/ci.go install
#? test: Run the tests.
test: all
$(GORUN) build/ci.go test
#? lint: Run certain pre-selected linters.
lint: ## Run linters.
$(GORUN) build/ci.go lint
#? fmt: Ensure consistent code formatting.
fmt:
gofmt -s -w $(shell find . -name "*.go")
#? clean: Clean go cache, built executables, and the auto generated folder.
clean:
env GO111MODULE=on go clean -cache
go clean -cache
rm -fr build/_workspace/pkg/ $(GOBIN)/*
# The devtools target installs tools required for 'go generate'.
# You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'.
#? devtools: Install recommended developer tools.
devtools:
env GOBIN= go install golang.org/x/tools/cmd/stringer@latest
env GOBIN= go install github.com/fjl/gencodec@latest
env GOBIN= go install github.com/golang/protobuf/protoc-gen-go@latest
env GOBIN= go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
env GOBIN= go install ./cmd/abigen
@type "solc" 2> /dev/null || echo 'Please install solc'
@type "protoc" 2> /dev/null || echo 'Please install protoc'
#? help: Get more info on make commands.
help: Makefile
@echo ''
@echo 'Usage:'
@echo ' make [target]'
@echo ''
@echo 'Targets:'
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'

View File

@@ -1,12 +1,12 @@
## Go Ethereum
Official Golang execution layer implementation of the Ethereum protocol.
Golang execution layer implementation of the Ethereum protocol.
[![API Reference](
https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667
https://pkg.go.dev/badge/github.com/ethereum/go-ethereum
)](https://pkg.go.dev/github.com/ethereum/go-ethereum?tab=doc)
[![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum)
[![Travis](https://travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.com/ethereum/go-ethereum)
[![Travis](https://app.travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://app.travis-ci.com/github/ethereum/go-ethereum)
[![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv)
Automated builds are available for stable releases and the unstable master branch. Binary
@@ -16,7 +16,7 @@ archives are published at https://geth.ethereum.org/downloads/.
For prerequisites and detailed build instructions please read the [Installation Instructions](https://geth.ethereum.org/docs/getting-started/installing-geth).
Building `geth` requires both a Go (version 1.18 or later) and a C compiler. You can install
Building `geth` requires both a Go (version 1.22 or later) and a C compiler. You can install
them using your favourite package manager. Once the dependencies are installed, run
```shell
@@ -36,10 +36,10 @@ directory.
| Command | Description |
| :--------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default), archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI page](https://geth.ethereum.org/docs/interface/command-line-options) for command line options. |
| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default), archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI page](https://geth.ethereum.org/docs/fundamentals/command-line-options) for command line options. |
| `clef` | Stand-alone signing tool, which can be used as a backend signer for `geth`. |
| `devp2p` | Utilities to interact with nodes on the networking layer, without running a full blockchain. |
| `abigen` | Source code generator to convert Ethereum contract definitions into easy-to-use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://docs.soliditylang.org/en/develop/abi-spec.html) with expanded functionality if the contract bytecode is also available. However, it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://geth.ethereum.org/docs/dapp/native-bindings) page for details. |
| `abigen` | Source code generator to convert Ethereum contract definitions into easy-to-use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://docs.soliditylang.org/en/develop/abi-spec.html) with expanded functionality if the contract bytecode is also available. However, it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings) page for details. |
| `bootnode` | Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks. |
| `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow isolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug run`). |
| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user-friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). |
@@ -47,7 +47,7 @@ directory.
## Running `geth`
Going through all the possible command line flags is out of scope here (please consult our
[CLI Wiki page](https://geth.ethereum.org/docs/interface/command-line-options)),
[CLI Wiki page](https://geth.ethereum.org/docs/fundamentals/command-line-options)),
but we've enumerated a few common parameter combos to get you up to speed quickly
on how you can run your own `geth` instance.
@@ -82,14 +82,14 @@ This command will:
* Start `geth` in snap sync mode (default, can be changed with the `--syncmode` flag),
causing it to download more data in exchange for avoiding processing the entire history
of the Ethereum network, which is very CPU intensive.
* Start the built-in interactive [JavaScript console](https://geth.ethereum.org/docs/interface/javascript-console),
* Start the built-in interactive [JavaScript console](https://geth.ethereum.org/docs/interacting-with-geth/javascript-console),
(via the trailing `console` subcommand) through which you can interact using [`web3` methods](https://github.com/ChainSafe/web3.js/blob/0.20.7/DOCUMENTATION.md)
(note: the `web3` version bundled within `geth` is very old, and not up to date with official docs),
as well as `geth`'s own [management APIs](https://geth.ethereum.org/docs/rpc/server).
as well as `geth`'s own [management APIs](https://geth.ethereum.org/docs/interacting-with-geth/rpc).
This tool is optional and if you leave it out you can always attach it to an already running
`geth` instance with `geth attach`.
### A Full node on the Görli test network
### A Full node on the Holesky test network
Transitioning towards developers, if you'd like to play around with creating Ethereum
contracts, you almost certainly would like to do that without any real money involved until
@@ -98,23 +98,23 @@ network, you want to join the **test** network with your node, which is fully eq
the main network, but with play-Ether only.
```shell
$ geth --goerli console
$ geth --holesky console
```
The `console` subcommand has the same meaning as above and is equally
useful on the testnet too.
Specifying the `--goerli` flag, however, will reconfigure your `geth` instance a bit:
Specifying the `--holesky` flag, however, will reconfigure your `geth` instance a bit:
* Instead of connecting to the main Ethereum network, the client will connect to the Görli
* Instead of connecting to the main Ethereum network, the client will connect to the Holesky
test network, which uses different P2P bootnodes, different network IDs and genesis
states.
* Instead of using the default data directory (`~/.ethereum` on Linux for example), `geth`
will nest itself one level deeper into a `goerli` subfolder (`~/.ethereum/goerli` on
will nest itself one level deeper into a `holesky` subfolder (`~/.ethereum/holesky` on
Linux). Note, on OSX and Linux this also means that attaching to a running testnet node
requires the use of a custom endpoint since `geth attach` will try to attach to a
production node endpoint by default, e.g.,
`geth attach <datadir>/goerli/geth.ipc`. Windows users are not affected by
`geth attach <datadir>/holesky/geth.ipc`. Windows users are not affected by
this.
*Note: Although some internal protective measures prevent transactions from
@@ -123,15 +123,6 @@ use separate accounts for play and real money. Unless you manually move
accounts, `geth` will by default correctly separate the two networks and will not make any
accounts available between them.*
### Full node on the Rinkeby test network
Go Ethereum also supports connecting to the older proof-of-authority based test network
called [*Rinkeby*](https://www.rinkeby.io) which is operated by members of the community.
```shell
$ geth --rinkeby console
```
### Configuration
As an alternative to passing the numerous flags to the `geth` binary, you can also pass a
@@ -175,7 +166,7 @@ accessible from the outside.
As a developer, sooner rather than later you'll want to start interacting with `geth` and the
Ethereum network via your own programs and not manually through the console. To aid
this, `geth` has built-in support for a JSON-RPC based APIs ([standard APIs](https://ethereum.github.io/execution-apis/api-documentation/)
and [`geth` specific APIs](https://geth.ethereum.org/docs/rpc/server)).
and [`geth` specific APIs](https://geth.ethereum.org/docs/interacting-with-geth/rpc)).
These can be exposed via HTTP, WebSockets and IPC (UNIX sockets on UNIX based
platforms, and named pipes on Windows).

View File

@@ -171,5 +171,5 @@ i4O1UeWKs9owWttan9+PI47ozBSKOTxmMqLSQ0f56Np9FJsV0ilGxRKfjhzJ4KniOMUBA7mP
epy6lH7HmxjjOR7eo0DaSxQGQpThAtFGwkWkFh8yki8j3E42kkrxvEyyYZDXn2YcI3bpqhJx
PtwCMZUJ3kc/skOrs6bOI19iBNaEoNX5Dllm7UHjOgWNDQkcCuOCxucKano=
=arte
-----END PGP PUBLIC KEY BLOCK------
-----END PGP PUBLIC KEY BLOCK-----
```

View File

@@ -22,13 +22,14 @@ import (
"errors"
"fmt"
"io"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
// The ABI holds information about a contract's context and available
// invokable methods. It will allow you to type check function calls and
// invocable methods. It will allow you to type check function calls and
// packs data accordingly.
type ABI struct {
Constructor Method
@@ -222,6 +223,17 @@ func (abi *ABI) EventByID(topic common.Hash) (*Event, error) {
return nil, fmt.Errorf("no event with id: %#x", topic.Hex())
}
// ErrorByID looks up an error by the 4-byte id,
// returns nil if none found.
func (abi *ABI) ErrorByID(sigdata [4]byte) (*Error, error) {
for _, errABI := range abi.Errors {
if bytes.Equal(errABI.ID[:4], sigdata[:]) {
return &errABI, nil
}
}
return nil, fmt.Errorf("no error with id: %#x", sigdata[:])
}
// HasFallback returns an indicator whether a fallback function is included.
func (abi *ABI) HasFallback() bool {
return abi.Fallback.Type == Fallback
@@ -235,21 +247,65 @@ func (abi *ABI) HasReceive() bool {
// revertSelector is a special function selector for revert reason unpacking.
var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
// panicSelector is a special function selector for panic reason unpacking.
var panicSelector = crypto.Keccak256([]byte("Panic(uint256)"))[:4]
// panicReasons map is for readable panic codes
// see this linkage for the details
// https://docs.soliditylang.org/en/v0.8.21/control-structures.html#panic-via-assert-and-error-via-require
// the reason string list is copied from ether.js
// https://github.com/ethers-io/ethers.js/blob/fa3a883ff7c88611ce766f58bdd4b8ac90814470/src.ts/abi/interface.ts#L207-L218
var panicReasons = map[uint64]string{
0x00: "generic panic",
0x01: "assert(false)",
0x11: "arithmetic underflow or overflow",
0x12: "division or modulo by zero",
0x21: "enum overflow",
0x22: "invalid encoded storage byte array accessed",
0x31: "out-of-bounds array access; popping on an empty array",
0x32: "out-of-bounds access of an array or bytesN",
0x41: "out of memory",
0x51: "uninitialized function",
}
// UnpackRevert resolves the abi-encoded revert reason. According to the solidity
// spec https://solidity.readthedocs.io/en/latest/control-structures.html#revert,
// the provided revert reason is abi-encoded as if it were a call to a function
// `Error(string)`. So it's a special tool for it.
// the provided revert reason is abi-encoded as if it were a call to function
// `Error(string)` or `Panic(uint256)`. So it's a special tool for it.
func UnpackRevert(data []byte) (string, error) {
if len(data) < 4 {
return "", errors.New("invalid data for unpacking")
}
if !bytes.Equal(data[:4], revertSelector) {
switch {
case bytes.Equal(data[:4], revertSelector):
typ, err := NewType("string", "", nil)
if err != nil {
return "", err
}
unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:])
if err != nil {
return "", err
}
return unpacked[0].(string), nil
case bytes.Equal(data[:4], panicSelector):
typ, err := NewType("uint256", "", nil)
if err != nil {
return "", err
}
unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:])
if err != nil {
return "", err
}
pCode := unpacked[0].(*big.Int)
// uint64 safety check for future
// but the code is not bigger than MAX(uint64) now
if pCode.IsUint64() {
if reason, ok := panicReasons[pCode.Uint64()]; ok {
return reason, nil
}
}
return fmt.Sprintf("unknown panic code: %#x", pCode), nil
default:
return "", errors.New("invalid data for unpacking")
}
typ, _ := NewType("string", "", nil)
unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:])
if err != nil {
return "", err
}
return unpacked[0].(string), nil
}

View File

@@ -120,6 +120,7 @@ var methods = map[string]Method{
}
func TestReader(t *testing.T) {
t.Parallel()
abi := ABI{
Methods: methods,
}
@@ -151,6 +152,7 @@ func TestReader(t *testing.T) {
}
func TestInvalidABI(t *testing.T) {
t.Parallel()
json := `[{ "type" : "function", "name" : "", "constant" : fals }]`
_, err := JSON(strings.NewReader(json))
if err == nil {
@@ -170,6 +172,7 @@ func TestInvalidABI(t *testing.T) {
// constructor(uint256 a, uint256 b) public{}
// }
func TestConstructor(t *testing.T) {
t.Parallel()
json := `[{ "inputs": [{"internalType": "uint256","name": "a","type": "uint256" },{ "internalType": "uint256","name": "b","type": "uint256"}],"stateMutability": "nonpayable","type": "constructor"}]`
method := NewMethod("", "", Constructor, "nonpayable", false, false, []Argument{{"a", Uint256, false}, {"b", Uint256, false}}, nil)
// Test from JSON
@@ -199,6 +202,7 @@ func TestConstructor(t *testing.T) {
}
func TestTestNumbers(t *testing.T) {
t.Parallel()
abi, err := JSON(strings.NewReader(jsondata))
if err != nil {
t.Fatal(err)
@@ -236,6 +240,7 @@ func TestTestNumbers(t *testing.T) {
}
func TestMethodSignature(t *testing.T) {
t.Parallel()
m := NewMethod("foo", "foo", Function, "", false, false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil)
exp := "foo(string,string)"
if m.Sig != exp {
@@ -274,6 +279,7 @@ func TestMethodSignature(t *testing.T) {
}
func TestOverloadedMethodSignature(t *testing.T) {
t.Parallel()
json := `[{"constant":true,"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"i","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"}],"name":"bar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"},{"indexed":false,"name":"j","type":"uint256"}],"name":"bar","type":"event"}]`
abi, err := JSON(strings.NewReader(json))
if err != nil {
@@ -297,6 +303,7 @@ func TestOverloadedMethodSignature(t *testing.T) {
}
func TestCustomErrors(t *testing.T) {
t.Parallel()
json := `[{ "inputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ],"name": "MyError", "type": "error"} ]`
abi, err := JSON(strings.NewReader(json))
if err != nil {
@@ -311,6 +318,7 @@ func TestCustomErrors(t *testing.T) {
}
func TestMultiPack(t *testing.T) {
t.Parallel()
abi, err := JSON(strings.NewReader(jsondata))
if err != nil {
t.Fatal(err)
@@ -348,6 +356,7 @@ func ExampleJSON() {
}
func TestInputVariableInputLength(t *testing.T) {
t.Parallel()
const definition = `[
{ "type" : "function", "name" : "strOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" } ] },
{ "type" : "function", "name" : "bytesOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" } ] },
@@ -476,6 +485,7 @@ func TestInputVariableInputLength(t *testing.T) {
}
func TestInputFixedArrayAndVariableInputLength(t *testing.T) {
t.Parallel()
abi, err := JSON(strings.NewReader(jsondata))
if err != nil {
t.Error(err)
@@ -650,6 +660,7 @@ func TestInputFixedArrayAndVariableInputLength(t *testing.T) {
}
func TestDefaultFunctionParsing(t *testing.T) {
t.Parallel()
const definition = `[{ "name" : "balance", "type" : "function" }]`
abi, err := JSON(strings.NewReader(definition))
@@ -663,6 +674,7 @@ func TestDefaultFunctionParsing(t *testing.T) {
}
func TestBareEvents(t *testing.T) {
t.Parallel()
const definition = `[
{ "type" : "event", "name" : "balance" },
{ "type" : "event", "name" : "anon", "anonymous" : true},
@@ -739,6 +751,7 @@ func TestBareEvents(t *testing.T) {
//
// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
func TestUnpackEvent(t *testing.T) {
t.Parallel()
const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
abi, err := JSON(strings.NewReader(abiJSON))
if err != nil {
@@ -777,6 +790,7 @@ func TestUnpackEvent(t *testing.T) {
}
func TestUnpackEventIntoMap(t *testing.T) {
t.Parallel()
const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
abi, err := JSON(strings.NewReader(abiJSON))
if err != nil {
@@ -827,6 +841,7 @@ func TestUnpackEventIntoMap(t *testing.T) {
}
func TestUnpackMethodIntoMap(t *testing.T) {
t.Parallel()
const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
abi, err := JSON(strings.NewReader(abiJSON))
if err != nil {
@@ -877,6 +892,7 @@ func TestUnpackMethodIntoMap(t *testing.T) {
}
func TestUnpackIntoMapNamingConflict(t *testing.T) {
t.Parallel()
// Two methods have the same name
var abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"get","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
abi, err := JSON(strings.NewReader(abiJSON))
@@ -960,6 +976,7 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) {
}
func TestABI_MethodById(t *testing.T) {
t.Parallel()
abi, err := JSON(strings.NewReader(jsondata))
if err != nil {
t.Fatal(err)
@@ -992,6 +1009,7 @@ func TestABI_MethodById(t *testing.T) {
}
func TestABI_EventById(t *testing.T) {
t.Parallel()
tests := []struct {
name string
json string
@@ -1057,9 +1075,39 @@ func TestABI_EventById(t *testing.T) {
}
}
func TestABI_ErrorByID(t *testing.T) {
t.Parallel()
abi, err := JSON(strings.NewReader(`[
{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"MyError1","type":"error"},
{"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string","name":"b","type":"string"},{"internalType":"address","name":"c","type":"address"}],"internalType":"struct MyError.MyStruct","name":"x","type":"tuple"},{"internalType":"address","name":"y","type":"address"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string","name":"b","type":"string"},{"internalType":"address","name":"c","type":"address"}],"internalType":"struct MyError.MyStruct","name":"z","type":"tuple"}],"name":"MyError2","type":"error"},
{"inputs":[{"internalType":"uint256[]","name":"x","type":"uint256[]"}],"name":"MyError3","type":"error"}
]`))
if err != nil {
t.Fatal(err)
}
for name, m := range abi.Errors {
a := fmt.Sprintf("%v", &m)
var id [4]byte
copy(id[:], m.ID[:4])
m2, err := abi.ErrorByID(id)
if err != nil {
t.Fatalf("Failed to look up ABI error: %v", err)
}
b := fmt.Sprintf("%v", m2)
if a != b {
t.Errorf("Error %v (id %x) not 'findable' by id in ABI", name, id)
}
}
// test unsuccessful lookups
if _, err = abi.ErrorByID([4]byte{}); err == nil {
t.Error("Expected error: no error with this id")
}
}
// TestDoubleDuplicateMethodNames checks that if transfer0 already exists, there won't be a name
// conflict and that the second transfer method will be renamed transfer1.
func TestDoubleDuplicateMethodNames(t *testing.T) {
t.Parallel()
abiJSON := `[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transfer0","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"customFallback","type":"string"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
contractAbi, err := JSON(strings.NewReader(abiJSON))
if err != nil {
@@ -1089,6 +1137,7 @@ func TestDoubleDuplicateMethodNames(t *testing.T) {
// event send();
// }
func TestDoubleDuplicateEventNames(t *testing.T) {
t.Parallel()
abiJSON := `[{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint256","name": "a","type": "uint256"}],"name": "send","type": "event"},{"anonymous": false,"inputs": [],"name": "send0","type": "event"},{ "anonymous": false, "inputs": [],"name": "send","type": "event"}]`
contractAbi, err := JSON(strings.NewReader(abiJSON))
if err != nil {
@@ -1116,6 +1165,7 @@ func TestDoubleDuplicateEventNames(t *testing.T) {
// event send(uint256, uint256);
// }
func TestUnnamedEventParam(t *testing.T) {
t.Parallel()
abiJSON := `[{ "anonymous": false, "inputs": [{ "indexed": false,"internalType": "uint256", "name": "","type": "uint256"},{"indexed": false,"internalType": "uint256","name": "","type": "uint256"}],"name": "send","type": "event"}]`
contractAbi, err := JSON(strings.NewReader(abiJSON))
if err != nil {
@@ -1145,9 +1195,13 @@ func TestUnpackRevert(t *testing.T) {
{"", "", errors.New("invalid data for unpacking")},
{"08c379a1", "", errors.New("invalid data for unpacking")},
{"08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000", "revert reason", nil},
{"4e487b710000000000000000000000000000000000000000000000000000000000000000", "generic panic", nil},
{"4e487b7100000000000000000000000000000000000000000000000000000000000000ff", "unknown panic code: 0xff", nil},
}
for index, c := range cases {
index, c := index, c
t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) {
t.Parallel()
got, err := UnpackRevert(common.Hex2Bytes(c.input))
if c.expectErr != nil {
if err == nil {
@@ -1164,3 +1218,10 @@ func TestUnpackRevert(t *testing.T) {
})
}
}
func TestInternalContractType(t *testing.T) {
jsonData := `[{"inputs":[{"components":[{"internalType":"uint256","name":"dailyLimit","type":"uint256"},{"internalType":"uint256","name":"txLimit","type":"uint256"},{"internalType":"uint256","name":"accountDailyLimit","type":"uint256"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"bool","name":"onlyWhitelisted","type":"bool"}],"internalType":"struct IMessagePassingBridge.BridgeLimits","name":"bridgeLimits","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.AccountLimit","name":"accountDailyLimit","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.BridgeDailyLimit","name":"bridgeDailyLimit","type":"tuple"},{"internalType":"contract INameService","name":"nameService","type":"INameService"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"canBridge","outputs":[{"internalType":"bool","name":"isWithinLimit","type":"bool"},{"internalType":"string","name":"error","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFrom18ToTokenDecimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFromTokenTo18Decimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"}]`
if _, err := JSON(strings.NewReader(jsonData)); err != nil {
t.Fatal(err)
}
}

View File

@@ -20,20 +20,34 @@ import (
"fmt"
"reflect"
"strings"
"testing"
"github.com/ethereum/go-ethereum/accounts/abi"
fuzz "github.com/google/gofuzz"
)
// TestReplicate can be used to replicate crashers from the fuzzing tests.
// Just replace testString with the data in .quoted
func TestReplicate(t *testing.T) {
t.Parallel()
//t.Skip("Test only useful for reproducing issues")
fuzzAbi([]byte("\x20\x20\x20\x20\x20\x20\x20\x20\x80\x00\x00\x00\x20\x20\x20\x20\x00"))
//fuzzAbi([]byte("asdfasdfkadsf;lasdf;lasd;lfk"))
}
// FuzzABI is the main entrypoint for fuzzing
func FuzzABI(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzAbi(data)
})
}
var (
names = []string{"_name", "name", "NAME", "name_", "__", "_name_", "n"}
stateMut = []string{"", "pure", "view", "payable"}
stateMutabilites = []*string{&stateMut[0], &stateMut[1], &stateMut[2], &stateMut[3]}
pays = []string{"", "true", "false"}
payables = []*string{&pays[0], &pays[1]}
vNames = []string{"a", "b", "c", "d", "e", "f", "g"}
varNames = append(vNames, names...)
varTypes = []string{"bool", "address", "bytes", "string",
names = []string{"_name", "name", "NAME", "name_", "__", "_name_", "n"}
stateMut = []string{"pure", "view", "payable"}
pays = []string{"true", "false"}
vNames = []string{"a", "b", "c", "d", "e", "f", "g"}
varNames = append(vNames, names...)
varTypes = []string{"bool", "address", "bytes", "string",
"uint8", "int8", "uint8", "int8", "uint16", "int16",
"uint24", "int24", "uint32", "int32", "uint40", "int40", "uint48", "int48", "uint56", "int56",
"uint64", "int64", "uint72", "int72", "uint80", "int80", "uint88", "int88", "uint96", "int96",
@@ -47,7 +61,7 @@ var (
"bytes32", "bytes"}
)
func unpackPack(abi abi.ABI, method string, input []byte) ([]interface{}, bool) {
func unpackPack(abi ABI, method string, input []byte) ([]interface{}, bool) {
if out, err := abi.Unpack(method, input); err == nil {
_, err := abi.Pack(method, out...)
if err != nil {
@@ -63,7 +77,7 @@ func unpackPack(abi abi.ABI, method string, input []byte) ([]interface{}, bool)
return nil, false
}
func packUnpack(abi abi.ABI, method string, input *[]interface{}) bool {
func packUnpack(abi ABI, method string, input *[]interface{}) bool {
if packed, err := abi.Pack(method, input); err == nil {
outptr := reflect.New(reflect.TypeOf(input))
err := abi.UnpackIntoInterface(outptr.Interface(), method, packed)
@@ -79,12 +93,12 @@ func packUnpack(abi abi.ABI, method string, input *[]interface{}) bool {
return false
}
type args struct {
type arg struct {
name string
typ string
}
func createABI(name string, stateMutability, payable *string, inputs []args) (abi.ABI, error) {
func createABI(name string, stateMutability, payable *string, inputs []arg) (ABI, error) {
sig := fmt.Sprintf(`[{ "type" : "function", "name" : "%v" `, name)
if stateMutability != nil {
sig += fmt.Sprintf(`, "stateMutability": "%v" `, *stateMutability)
@@ -111,60 +125,55 @@ func createABI(name string, stateMutability, payable *string, inputs []args) (ab
sig += "} ]"
}
sig += `}]`
return abi.JSON(strings.NewReader(sig))
//fmt.Printf("sig: %s\n", sig)
return JSON(strings.NewReader(sig))
}
func runFuzzer(input []byte) int {
good := false
fuzzer := fuzz.NewFromGoFuzz(input)
name := names[getUInt(fuzzer)%len(names)]
stateM := stateMutabilites[getUInt(fuzzer)%len(stateMutabilites)]
payable := payables[getUInt(fuzzer)%len(payables)]
maxLen := 5
for k := 1; k < maxLen; k++ {
var arg []args
for i := k; i > 0; i-- {
argName := varNames[i]
argTyp := varTypes[getUInt(fuzzer)%len(varTypes)]
if getUInt(fuzzer)%10 == 0 {
argTyp += "[]"
} else if getUInt(fuzzer)%10 == 0 {
arrayArgs := getUInt(fuzzer)%30 + 1
argTyp += fmt.Sprintf("[%d]", arrayArgs)
}
arg = append(arg, args{
name: argName,
typ: argTyp,
})
func fuzzAbi(input []byte) {
var (
fuzzer = fuzz.NewFromGoFuzz(input)
name = oneOf(fuzzer, names)
stateM = oneOfOrNil(fuzzer, stateMut)
payable = oneOfOrNil(fuzzer, pays)
arguments []arg
)
for i := 0; i < upTo(fuzzer, 10); i++ {
argName := oneOf(fuzzer, varNames)
argTyp := oneOf(fuzzer, varTypes)
switch upTo(fuzzer, 10) {
case 0: // 10% chance to make it a slice
argTyp += "[]"
case 1: // 10% chance to make it an array
argTyp += fmt.Sprintf("[%d]", 1+upTo(fuzzer, 30))
default:
}
abi, err := createABI(name, stateM, payable, arg)
if err != nil {
continue
}
structs, b := unpackPack(abi, name, input)
c := packUnpack(abi, name, &structs)
good = good || b || c
arguments = append(arguments, arg{name: argName, typ: argTyp})
}
if good {
return 1
abi, err := createABI(name, stateM, payable, arguments)
if err != nil {
//fmt.Printf("err: %v\n", err)
panic(err)
}
return 0
structs, _ := unpackPack(abi, name, input)
_ = packUnpack(abi, name, &structs)
}
func Fuzz(input []byte) int {
return runFuzzer(input)
}
func getUInt(fuzzer *fuzz.Fuzzer) int {
func upTo(fuzzer *fuzz.Fuzzer, max int) int {
var i int
fuzzer.Fuzz(&i)
if i < 0 {
i = -i
if i < 0 {
return 0
}
return (-1 - i) % max
}
return i
return i % max
}
func oneOf(fuzzer *fuzz.Fuzzer, options []string) string {
return options[upTo(fuzzer, len(options))]
}
func oneOfOrNil(fuzzer *fuzz.Fuzzer, options []string) *string {
if i := upTo(fuzzer, len(options)+1); i < len(options) {
return &options[i]
}
return nil
}

View File

@@ -80,7 +80,7 @@ func (arguments Arguments) isTuple() bool {
func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) {
if len(data) == 0 {
if len(arguments.NonIndexed()) != 0 {
return nil, errors.New("abi: attempting to unmarshall an empty string while arguments are expected")
return nil, errors.New("abi: attempting to unmarshal an empty string while arguments are expected")
}
return make([]interface{}, 0), nil
}
@@ -95,7 +95,7 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte)
}
if len(data) == 0 {
if len(arguments.NonIndexed()) != 0 {
return errors.New("abi: attempting to unmarshall an empty string while arguments are expected")
return errors.New("abi: attempting to unmarshal an empty string while arguments are expected")
}
return nil // Nothing to unmarshal, return
}
@@ -127,7 +127,7 @@ func (arguments Arguments) Copy(v interface{}, values []interface{}) error {
return arguments.copyAtomic(v, values[0])
}
// unpackAtomic unpacks ( hexdata -> go ) a single value
// copyAtomic copies ( hexdata -> go ) a single value
func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{}) error {
dst := reflect.ValueOf(v).Elem()
src := reflect.ValueOf(marshalledValues)

View File

@@ -56,7 +56,7 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) {
}
// NewKeyStoreTransactor is a utility method to easily create a transaction signer from
// an decrypted key from a keystore.
// a decrypted key from a keystore.
//
// Deprecated: Use NewKeyStoreTransactorWithChainID instead.
func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) {
@@ -117,7 +117,7 @@ func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.I
}
// NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from
// an decrypted key from a keystore.
// a decrypted key from a keystore.
func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) {
if chainID == nil {
return nil, ErrNoChainID
@@ -142,10 +142,10 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou
// NewKeyedTransactorWithChainID is a utility method to easily create a transaction signer
// from a single private key.
func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*TransactOpts, error) {
keyAddr := crypto.PubkeyToAddress(key.PublicKey)
if chainID == nil {
return nil, ErrNoChainID
}
keyAddr := crypto.PubkeyToAddress(key.PublicKey)
signer := types.LatestSignerForChainID(chainID)
return &TransactOpts{
From: keyAddr,

View File

@@ -29,13 +29,17 @@ import (
var (
// ErrNoCode is returned by call and transact operations for which the requested
// recipient contract to operate on does not exist in the state db or does not
// have any code associated with it (i.e. suicided).
// have any code associated with it (i.e. self-destructed).
ErrNoCode = errors.New("no contract code at given address")
// ErrNoPendingState is raised when attempting to perform a pending state action
// on a backend that doesn't implement PendingContractCaller.
ErrNoPendingState = errors.New("backend does not support pending state")
// ErrNoBlockHashState is raised when attempting to perform a block hash action
// on a backend that doesn't implement BlockHashContractCaller.
ErrNoBlockHashState = errors.New("backend does not support block hash state")
// ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves
// an empty contract behind.
ErrNoCodeAfterDeploy = errors.New("no contract code after deployment")
@@ -64,11 +68,27 @@ type PendingContractCaller interface {
PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error)
}
// BlockHashContractCaller defines methods to perform contract calls on a specific block hash.
// Call will try to discover this interface when access to a block by hash is requested.
// If the backend does not support the block hash state, Call returns ErrNoBlockHashState.
type BlockHashContractCaller interface {
// CodeAtHash returns the code of the given account in the state at the specified block hash.
CodeAtHash(ctx context.Context, contract common.Address, blockHash common.Hash) ([]byte, error)
// CallContractAtHash executes an Ethereum contract call against the state at the specified block hash.
CallContractAtHash(ctx context.Context, call ethereum.CallMsg, blockHash common.Hash) ([]byte, error)
}
// ContractTransactor defines the methods needed to allow operating with a contract
// on a write only basis. Besides the transacting method, the remainder are helpers
// used when the user does not provide some needed values, but rather leaves it up
// to the transactor to decide.
type ContractTransactor interface {
ethereum.GasEstimator
ethereum.GasPricer
ethereum.GasPricer1559
ethereum.TransactionSender
// HeaderByNumber returns a block header from the current canonical chain. If
// number is nil, the latest known header is returned.
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
@@ -78,38 +98,6 @@ type ContractTransactor interface {
// PendingNonceAt retrieves the current pending nonce associated with an account.
PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
// SuggestGasPrice retrieves the currently suggested gas price to allow a timely
// execution of a transaction.
SuggestGasPrice(ctx context.Context) (*big.Int, error)
// SuggestGasTipCap retrieves the currently suggested 1559 priority fee to allow
// a timely execution of a transaction.
SuggestGasTipCap(ctx context.Context) (*big.Int, error)
// EstimateGas tries to estimate the gas needed to execute a specific
// transaction based on the current pending state of the backend blockchain.
// There is no guarantee that this is the true gas limit requirement as other
// transactions may be added or removed by miners, but it should provide a basis
// for setting a reasonable default.
EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error)
// SendTransaction injects the transaction into the pending pool for execution.
SendTransaction(ctx context.Context, tx *types.Transaction) error
}
// ContractFilterer defines the methods needed to access log events using one-off
// queries or continuous event subscriptions.
type ContractFilterer interface {
// FilterLogs executes a log filter operation, blocking during execution and
// returning all the results in one batch.
//
// TODO(karalabe): Deprecate when the subscription one can return past data too.
FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error)
// SubscribeFilterLogs creates a background log filtering operation, returning
// a subscription immediately, which can be used to stream the found events.
SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error)
}
// DeployBackend wraps the operations needed by WaitMined and WaitDeployed.
@@ -118,6 +106,12 @@ type DeployBackend interface {
CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)
}
// ContractFilterer defines the methods needed to access log events using one-off
// queries or continuous event subscriptions.
type ContractFilterer interface {
ethereum.LogFilterer
}
// ContractBackend defines the methods needed to work with contracts on a read-write basis.
type ContractBackend interface {
ContractCaller

View File

@@ -18,921 +18,35 @@ package backends
import (
"context"
"errors"
"fmt"
"math/big"
"sync"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/ethclient/simulated"
)
// This nil assignment ensures at compile time that SimulatedBackend implements bind.ContractBackend.
var _ bind.ContractBackend = (*SimulatedBackend)(nil)
var (
errBlockNumberUnsupported = errors.New("simulatedBackend cannot access blocks other than the latest block")
errBlockDoesNotExist = errors.New("block does not exist in blockchain")
errTransactionDoesNotExist = errors.New("transaction does not exist")
)
// SimulatedBackend implements bind.ContractBackend, simulating a blockchain in
// the background. Its main purpose is to allow for easy testing of contract bindings.
// Simulated backend implements the following interfaces:
// ChainReader, ChainStateReader, ContractBackend, ContractCaller, ContractFilterer, ContractTransactor,
// DeployBackend, GasEstimator, GasPricer, LogFilterer, PendingContractCaller, TransactionReader, and TransactionSender
// SimulatedBackend is a simulated blockchain.
// Deprecated: use package github.com/ethereum/go-ethereum/ethclient/simulated instead.
type SimulatedBackend struct {
database ethdb.Database // In memory database to store our testing data
blockchain *core.BlockChain // Ethereum blockchain to handle the consensus
mu sync.Mutex
pendingBlock *types.Block // Currently pending block that will be imported on request
pendingState *state.StateDB // Currently pending state that will be the active on request
pendingReceipts types.Receipts // Currently receipts for the pending block
events *filters.EventSystem // for filtering log events live
filterSystem *filters.FilterSystem // for filtering database logs
config *params.ChainConfig
*simulated.Backend
simulated.Client
}
// NewSimulatedBackendWithDatabase creates a new binding backend based on the given database
// and uses a simulated blockchain for testing purposes.
// A simulated backend always uses chainID 1337.
func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
genesis := core.Genesis{
Config: params.AllEthashProtocolChanges,
GasLimit: gasLimit,
Alloc: alloc,
}
blockchain, _ := core.NewBlockChain(database, nil, &genesis, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
backend := &SimulatedBackend{
database: database,
blockchain: blockchain,
config: genesis.Config,
}
filterBackend := &filterBackend{database, blockchain, backend}
backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{})
backend.events = filters.NewEventSystem(backend.filterSystem, false)
backend.rollback(blockchain.CurrentBlock())
return backend
// Fork sets the head to a new block, which is based on the provided parentHash.
func (b *SimulatedBackend) Fork(ctx context.Context, parentHash common.Hash) error {
return b.Backend.Fork(parentHash)
}
// NewSimulatedBackend creates a new binding backend using a simulated blockchain
// for testing purposes.
//
// A simulated backend always uses chainID 1337.
func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
return NewSimulatedBackendWithDatabase(rawdb.NewMemoryDatabase(), alloc, gasLimit)
}
// Close terminates the underlying blockchain's update loop.
func (b *SimulatedBackend) Close() error {
b.blockchain.Stop()
return nil
}
// Commit imports all the pending transactions as a single block and starts a
// fresh new state.
func (b *SimulatedBackend) Commit() common.Hash {
b.mu.Lock()
defer b.mu.Unlock()
if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil {
panic(err) // This cannot happen unless the simulator is wrong, fail in that case
}
blockHash := b.pendingBlock.Hash()
// Using the last inserted block here makes it possible to build on a side
// chain after a fork.
b.rollback(b.pendingBlock)
return blockHash
}
// Rollback aborts all pending transactions, reverting to the last committed state.
func (b *SimulatedBackend) Rollback() {
b.mu.Lock()
defer b.mu.Unlock()
b.rollback(b.blockchain.CurrentBlock())
}
func (b *SimulatedBackend) rollback(parent *types.Block) {
blocks, _ := core.GenerateChain(b.config, parent, ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {})
b.pendingBlock = blocks[0]
b.pendingState, _ = state.New(b.pendingBlock.Root(), b.blockchain.StateCache(), nil)
}
// Fork creates a side-chain that can be used to simulate reorgs.
//
// This function should be called with the ancestor block where the new side
// chain should be started. Transactions (old and new) can then be applied on
// top and Commit-ed.
//
// Note, the side-chain will only become canonical (and trigger the events) when
// it becomes longer. Until then CallContract will still operate on the current
// canonical chain.
//
// There is a % chance that the side chain becomes canonical at the same length
// to simulate live network behavior.
func (b *SimulatedBackend) Fork(ctx context.Context, parent common.Hash) error {
b.mu.Lock()
defer b.mu.Unlock()
if len(b.pendingBlock.Transactions()) != 0 {
return errors.New("pending block dirty")
}
block, err := b.blockByHash(ctx, parent)
if err != nil {
return err
}
b.rollback(block)
return nil
}
// stateByBlockNumber retrieves a state by a given blocknumber.
func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) {
if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 {
return b.blockchain.State()
}
block, err := b.blockByNumber(ctx, blockNumber)
if err != nil {
return nil, err
}
return b.blockchain.StateAt(block.Root())
}
// CodeAt returns the code associated with a certain account in the blockchain.
func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
b.mu.Lock()
defer b.mu.Unlock()
stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
if err != nil {
return nil, err
}
return stateDB.GetCode(contract), nil
}
// BalanceAt returns the wei balance of a certain account in the blockchain.
func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (*big.Int, error) {
b.mu.Lock()
defer b.mu.Unlock()
stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
if err != nil {
return nil, err
}
return stateDB.GetBalance(contract), nil
}
// NonceAt returns the nonce of a certain account in the blockchain.
func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (uint64, error) {
b.mu.Lock()
defer b.mu.Unlock()
stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
if err != nil {
return 0, err
}
return stateDB.GetNonce(contract), nil
}
// StorageAt returns the value of key in the storage of an account in the blockchain.
func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) {
b.mu.Lock()
defer b.mu.Unlock()
stateDB, err := b.stateByBlockNumber(ctx, blockNumber)
if err != nil {
return nil, err
}
val := stateDB.GetState(contract, key)
return val[:], nil
}
// TransactionReceipt returns the receipt of a transaction.
func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
b.mu.Lock()
defer b.mu.Unlock()
receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash, b.config)
if receipt == nil {
return nil, ethereum.NotFound
}
return receipt, nil
}
// TransactionByHash checks the pool of pending transactions in addition to the
// blockchain. The isPending return value indicates whether the transaction has been
// mined yet. Note that the transaction may not be part of the canonical chain even if
// it's not pending.
func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) {
b.mu.Lock()
defer b.mu.Unlock()
tx := b.pendingBlock.Transaction(txHash)
if tx != nil {
return tx, true, nil
}
tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash)
if tx != nil {
return tx, false, nil
}
return nil, false, ethereum.NotFound
}
// BlockByHash retrieves a block based on the block hash.
func (b *SimulatedBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
b.mu.Lock()
defer b.mu.Unlock()
return b.blockByHash(ctx, hash)
}
// blockByHash retrieves a block based on the block hash without Locking.
func (b *SimulatedBackend) blockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
if hash == b.pendingBlock.Hash() {
return b.pendingBlock, nil
}
block := b.blockchain.GetBlockByHash(hash)
if block != nil {
return block, nil
}
return nil, errBlockDoesNotExist
}
// BlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found.
func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
b.mu.Lock()
defer b.mu.Unlock()
return b.blockByNumber(ctx, number)
}
// blockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found without Lock.
func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 {
return b.blockchain.CurrentBlock(), nil
}
block := b.blockchain.GetBlockByNumber(uint64(number.Int64()))
if block == nil {
return nil, errBlockDoesNotExist
}
return block, nil
}
// HeaderByHash returns a block header from the current canonical chain.
func (b *SimulatedBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
b.mu.Lock()
defer b.mu.Unlock()
if hash == b.pendingBlock.Hash() {
return b.pendingBlock.Header(), nil
}
header := b.blockchain.GetHeaderByHash(hash)
if header == nil {
return nil, errBlockDoesNotExist
}
return header, nil
}
// HeaderByNumber returns a block header from the current canonical chain. If number is
// nil, the latest known header is returned.
func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) (*types.Header, error) {
b.mu.Lock()
defer b.mu.Unlock()
if block == nil || block.Cmp(b.pendingBlock.Number()) == 0 {
return b.blockchain.CurrentHeader(), nil
}
return b.blockchain.GetHeaderByNumber(uint64(block.Int64())), nil
}
// TransactionCount returns the number of transactions in a given block.
func (b *SimulatedBackend) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) {
b.mu.Lock()
defer b.mu.Unlock()
if blockHash == b.pendingBlock.Hash() {
return uint(b.pendingBlock.Transactions().Len()), nil
}
block := b.blockchain.GetBlockByHash(blockHash)
if block == nil {
return uint(0), errBlockDoesNotExist
}
return uint(block.Transactions().Len()), nil
}
// TransactionInBlock returns the transaction for a specific block at a specific index.
func (b *SimulatedBackend) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) {
b.mu.Lock()
defer b.mu.Unlock()
if blockHash == b.pendingBlock.Hash() {
transactions := b.pendingBlock.Transactions()
if uint(len(transactions)) < index+1 {
return nil, errTransactionDoesNotExist
}
return transactions[index], nil
}
block := b.blockchain.GetBlockByHash(blockHash)
if block == nil {
return nil, errBlockDoesNotExist
}
transactions := block.Transactions()
if uint(len(transactions)) < index+1 {
return nil, errTransactionDoesNotExist
}
return transactions[index], nil
}
// PendingCodeAt returns the code associated with an account in the pending state.
func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) {
b.mu.Lock()
defer b.mu.Unlock()
return b.pendingState.GetCode(contract), nil
}
func newRevertError(result *core.ExecutionResult) *revertError {
reason, errUnpack := abi.UnpackRevert(result.Revert())
err := errors.New("execution reverted")
if errUnpack == nil {
err = fmt.Errorf("execution reverted: %v", reason)
}
return &revertError{
error: err,
reason: hexutil.Encode(result.Revert()),
// Deprecated: please use simulated.Backend from package
// github.com/ethereum/go-ethereum/ethclient/simulated instead.
func NewSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
b := simulated.NewBackend(alloc, simulated.WithBlockGasLimit(gasLimit))
return &SimulatedBackend{
Backend: b,
Client: b.Client(),
}
}
// revertError is an API error that encompasses an EVM revert with JSON error
// code and a binary data blob.
type revertError struct {
error
reason string // revert reason hex encoded
}
// ErrorCode returns the JSON error code for a revert.
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
func (e *revertError) ErrorCode() int {
return 3
}
// ErrorData returns the hex encoded revert reason.
func (e *revertError) ErrorData() interface{} {
return e.reason
}
// CallContract executes a contract call.
func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
b.mu.Lock()
defer b.mu.Unlock()
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
return nil, errBlockNumberUnsupported
}
stateDB, err := b.blockchain.State()
if err != nil {
return nil, err
}
res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), stateDB)
if err != nil {
return nil, err
}
// If the result contains a revert reason, try to unpack and return it.
if len(res.Revert()) > 0 {
return nil, newRevertError(res)
}
return res.Return(), res.Err
}
// PendingCallContract executes a contract call on the pending state.
func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) {
b.mu.Lock()
defer b.mu.Unlock()
defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot())
res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState)
if err != nil {
return nil, err
}
// If the result contains a revert reason, try to unpack and return it.
if len(res.Revert()) > 0 {
return nil, newRevertError(res)
}
return res.Return(), res.Err
}
// PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving
// the nonce currently pending for the account.
func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) {
b.mu.Lock()
defer b.mu.Unlock()
return b.pendingState.GetOrNewStateObject(account).Nonce(), nil
}
// SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated
// chain doesn't have miners, we just return a gas price of 1 for any call.
func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
b.mu.Lock()
defer b.mu.Unlock()
if b.pendingBlock.Header().BaseFee != nil {
return b.pendingBlock.Header().BaseFee, nil
}
return big.NewInt(1), nil
}
// SuggestGasTipCap implements ContractTransactor.SuggestGasTipCap. Since the simulated
// chain doesn't have miners, we just return a gas tip of 1 for any call.
func (b *SimulatedBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
return big.NewInt(1), nil
}
// EstimateGas executes the requested code against the currently pending block/state and
// returns the used amount of gas.
func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) {
b.mu.Lock()
defer b.mu.Unlock()
// Determine the lowest and highest possible gas limits to binary search in between
var (
lo uint64 = params.TxGas - 1
hi uint64
cap uint64
)
if call.Gas >= params.TxGas {
hi = call.Gas
} else {
hi = b.pendingBlock.GasLimit()
}
// Normalize the max fee per gas the call is willing to spend.
var feeCap *big.Int
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
} else if call.GasPrice != nil {
feeCap = call.GasPrice
} else if call.GasFeeCap != nil {
feeCap = call.GasFeeCap
} else {
feeCap = common.Big0
}
// Recap the highest gas allowance with account's balance.
if feeCap.BitLen() != 0 {
balance := b.pendingState.GetBalance(call.From) // from can't be nil
available := new(big.Int).Set(balance)
if call.Value != nil {
if call.Value.Cmp(available) >= 0 {
return 0, core.ErrInsufficientFundsForTransfer
}
available.Sub(available, call.Value)
}
allowance := new(big.Int).Div(available, feeCap)
if allowance.IsUint64() && hi > allowance.Uint64() {
transfer := call.Value
if transfer == nil {
transfer = new(big.Int)
}
log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance,
"sent", transfer, "feecap", feeCap, "fundable", allowance)
hi = allowance.Uint64()
}
}
cap = hi
// Create a helper to check if a gas allowance results in an executable transaction
executable := func(gas uint64) (bool, *core.ExecutionResult, error) {
call.Gas = gas
snapshot := b.pendingState.Snapshot()
res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState)
b.pendingState.RevertToSnapshot(snapshot)
if err != nil {
if errors.Is(err, core.ErrIntrinsicGas) {
return true, nil, nil // Special case, raise gas limit
}
return true, nil, err // Bail out
}
return res.Failed(), res, nil
}
// Execute the binary search and hone in on an executable gas limit
for lo+1 < hi {
mid := (hi + lo) / 2
failed, _, err := executable(mid)
// If the error is not nil(consensus error), it means the provided message
// call or transaction will never be accepted no matter how much gas it is
// assigned. Return the error directly, don't struggle any more
if err != nil {
return 0, err
}
if failed {
lo = mid
} else {
hi = mid
}
}
// Reject the transaction as invalid if it still fails at the highest allowance
if hi == cap {
failed, result, err := executable(hi)
if err != nil {
return 0, err
}
if failed {
if result != nil && result.Err != vm.ErrOutOfGas {
if len(result.Revert()) > 0 {
return 0, newRevertError(result)
}
return 0, result.Err
}
// Otherwise, the specified gas cap is too low
return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap)
}
}
return hi, nil
}
// callContract implements common code between normal and pending contract calls.
// state is modified during execution, make sure to copy it if necessary.
func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, stateDB *state.StateDB) (*core.ExecutionResult, error) {
// Gas prices post 1559 need to be initialized
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
}
head := b.blockchain.CurrentHeader()
if !b.blockchain.Config().IsLondon(head.Number) {
// If there's no basefee, then it must be a non-1559 execution
if call.GasPrice == nil {
call.GasPrice = new(big.Int)
}
call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
} else {
// A basefee is provided, necessitating 1559-type execution
if call.GasPrice != nil {
// User specified the legacy gas field, convert to 1559 gas typing
call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice
} else {
// User specified 1559 gas fields (or none), use those
if call.GasFeeCap == nil {
call.GasFeeCap = new(big.Int)
}
if call.GasTipCap == nil {
call.GasTipCap = new(big.Int)
}
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
call.GasPrice = new(big.Int)
if call.GasFeeCap.BitLen() > 0 || call.GasTipCap.BitLen() > 0 {
call.GasPrice = math.BigMin(new(big.Int).Add(call.GasTipCap, head.BaseFee), call.GasFeeCap)
}
}
}
// Ensure message is initialized properly.
if call.Gas == 0 {
call.Gas = 50000000
}
if call.Value == nil {
call.Value = new(big.Int)
}
// Set infinite balance to the fake caller account.
from := stateDB.GetOrNewStateObject(call.From)
from.SetBalance(math.MaxBig256)
// Execute the call.
msg := callMsg{call}
txContext := core.NewEVMTxContext(msg)
evmContext := core.NewEVMBlockContext(block.Header(), b.blockchain, nil)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
return core.NewStateTransition(vmEnv, msg, gasPool).TransitionDb()
}
// SendTransaction updates the pending block to include the given transaction.
func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error {
b.mu.Lock()
defer b.mu.Unlock()
// Get the last block
block, err := b.blockByHash(ctx, b.pendingBlock.ParentHash())
if err != nil {
return fmt.Errorf("could not fetch parent")
}
// Check transaction validity
signer := types.MakeSigner(b.blockchain.Config(), block.Number())
sender, err := types.Sender(signer, tx)
if err != nil {
return fmt.Errorf("invalid transaction: %v", err)
}
nonce := b.pendingState.GetNonce(sender)
if tx.Nonce() != nonce {
return fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce)
}
// Include tx in chain
blocks, receipts := core.GenerateChain(b.config, block, ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) {
for _, tx := range b.pendingBlock.Transactions() {
block.AddTxWithChain(b.blockchain, tx)
}
block.AddTxWithChain(b.blockchain, tx)
})
stateDB, _ := b.blockchain.State()
b.pendingBlock = blocks[0]
b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil)
b.pendingReceipts = receipts[0]
return nil
}
// FilterLogs executes a log filter operation, blocking during execution and
// returning all the results in one batch.
//
// TODO(karalabe): Deprecate when the subscription one can return past data too.
func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) {
var filter *filters.Filter
if query.BlockHash != nil {
// Block filter requested, construct a single-shot filter
filter = b.filterSystem.NewBlockFilter(*query.BlockHash, query.Addresses, query.Topics)
} else {
// Initialize unset filter boundaries to run from genesis to chain head
from := int64(0)
if query.FromBlock != nil {
from = query.FromBlock.Int64()
}
to := int64(-1)
if query.ToBlock != nil {
to = query.ToBlock.Int64()
}
// Construct the range filter
filter = b.filterSystem.NewRangeFilter(from, to, query.Addresses, query.Topics)
}
// Run the filter and return all the logs
logs, err := filter.Logs(ctx)
if err != nil {
return nil, err
}
res := make([]types.Log, len(logs))
for i, nLog := range logs {
res[i] = *nLog
}
return res, nil
}
// SubscribeFilterLogs creates a background log filtering operation, returning a
// subscription immediately, which can be used to stream the found events.
func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) {
// Subscribe to contract events
sink := make(chan []*types.Log)
sub, err := b.events.SubscribeLogs(query, sink)
if err != nil {
return nil, err
}
// Since we're getting logs in batches, we need to flatten them into a plain stream
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case logs := <-sink:
for _, nlog := range logs {
select {
case ch <- *nlog:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// SubscribeNewHead returns an event subscription for a new header.
func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) {
// subscribe to a new head
sink := make(chan *types.Header)
sub := b.events.SubscribeNewHeads(sink)
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case head := <-sink:
select {
case ch <- head:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// AdjustTime adds a time shift to the simulated clock.
// It can only be called on empty blocks.
func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
b.mu.Lock()
defer b.mu.Unlock()
if len(b.pendingBlock.Transactions()) != 0 {
return errors.New("Could not adjust time on non-empty block")
}
// Get the last block
block := b.blockchain.GetBlockByHash(b.pendingBlock.ParentHash())
if block == nil {
return fmt.Errorf("could not find parent")
}
blocks, _ := core.GenerateChain(b.config, block, ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) {
block.OffsetTime(int64(adjustment.Seconds()))
})
stateDB, _ := b.blockchain.State()
b.pendingBlock = blocks[0]
b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil)
return nil
}
// Blockchain returns the underlying blockchain.
func (b *SimulatedBackend) Blockchain() *core.BlockChain {
return b.blockchain
}
// callMsg implements core.Message to allow passing it as a transaction simulator.
type callMsg struct {
ethereum.CallMsg
}
func (m callMsg) From() common.Address { return m.CallMsg.From }
func (m callMsg) Nonce() uint64 { return 0 }
func (m callMsg) IsFake() bool { return true }
func (m callMsg) To() *common.Address { return m.CallMsg.To }
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
type filterBackend struct {
db ethdb.Database
bc *core.BlockChain
backend *SimulatedBackend
}
func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db }
func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") }
func (fb *filterBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
switch number {
case rpc.PendingBlockNumber:
if block := fb.backend.pendingBlock; block != nil {
return block.Header(), nil
}
return nil, nil
case rpc.LatestBlockNumber:
return fb.bc.CurrentHeader(), nil
case rpc.FinalizedBlockNumber:
if block := fb.bc.CurrentFinalizedBlock(); block != nil {
return block.Header(), nil
}
return nil, errors.New("finalized block not found")
case rpc.SafeBlockNumber:
if block := fb.bc.CurrentSafeBlock(); block != nil {
return block.Header(), nil
}
return nil, errors.New("safe block not found")
default:
return fb.bc.GetHeaderByNumber(uint64(number.Int64())), nil
}
}
func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
return fb.bc.GetHeaderByHash(hash), nil
}
func (fb *filterBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
if body := fb.bc.GetBody(hash); body != nil {
return body, nil
}
return nil, errors.New("block body not found")
}
func (fb *filterBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
return fb.backend.pendingBlock, fb.backend.pendingReceipts
}
func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
number := rawdb.ReadHeaderNumber(fb.db, hash)
if number == nil {
return nil, nil
}
return rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()), nil
}
func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
logs := rawdb.ReadLogs(fb.db, hash, number, fb.bc.Config())
return logs, nil
}
func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
return nullSubscription()
}
func (fb *filterBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
return fb.bc.SubscribeChainEvent(ch)
}
func (fb *filterBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
return fb.bc.SubscribeRemovedLogsEvent(ch)
}
func (fb *filterBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
return fb.bc.SubscribeLogsEvent(ch)
}
func (fb *filterBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
return nullSubscription()
}
func (fb *filterBackend) BloomStatus() (uint64, uint64) { return 4096, 0 }
func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.MatcherSession) {
panic("not supported")
}
func (fb *filterBackend) ChainConfig() *params.ChainConfig {
panic("not supported")
}
func (fb *filterBackend) CurrentHeader() *types.Header {
panic("not supported")
}
func nullSubscription() event.Subscription {
return event.NewSubscription(func(quit <-chan struct{}) error {
<-quit
return nil
})
}

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,11 @@ import (
const basefeeWiggleMultiplier = 2
var (
errNoEventSignature = errors.New("no event signature")
errEventSignatureMismatch = errors.New("event signature mismatch")
)
// SignerFn is a signer function callback when a contract requires a method to
// sign the transaction before submission.
type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error)
@@ -43,6 +48,7 @@ type CallOpts struct {
Pending bool // Whether to operate on the pending state or the last known one
From common.Address // Optional the sender address, otherwise the first account is used
BlockNumber *big.Int // Optional the block number on which the call should be performed
BlockHash common.Hash // Optional the block hash on which the call should be performed
Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
}
@@ -53,11 +59,12 @@ type TransactOpts struct {
Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state)
Signer SignerFn // Method to use for signing the transaction (mandatory)
Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds)
GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle)
GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle)
GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds)
GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle)
GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle)
GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
AccessList types.AccessList // Access list to set for the transaction execution (nil = no access list)
Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
@@ -184,6 +191,23 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri
return ErrNoCode
}
}
} else if opts.BlockHash != (common.Hash{}) {
bh, ok := c.caller.(BlockHashContractCaller)
if !ok {
return ErrNoBlockHashState
}
output, err = bh.CallContractAtHash(ctx, msg, opts.BlockHash)
if err != nil {
return err
}
if len(output) == 0 {
// Make sure we have a contract to operate on, and bail out otherwise.
if code, err = bh.CodeAtHash(ctx, c.address, opts.BlockHash); err != nil {
return err
} else if len(code) == 0 {
return ErrNoCode
}
}
} else {
output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber)
if err != nil {
@@ -215,7 +239,7 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in
if err != nil {
return nil, err
}
// todo(rjl493456442) check the method is payable or not,
// todo(rjl493456442) check whether the method is payable or not,
// reject invalid transaction at the first place
return c.transact(opts, &c.address, input)
}
@@ -223,7 +247,7 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in
// RawTransact initiates a transaction with the given raw calldata as the input.
// It's usually used to initiate transactions for invoking **Fallback** function.
func (c *BoundContract) RawTransact(opts *TransactOpts, calldata []byte) (*types.Transaction, error) {
// todo(rjl493456442) check the method is payable or not,
// todo(rjl493456442) check whether the method is payable or not,
// reject invalid transaction at the first place
return c.transact(opts, &c.address, calldata)
}
@@ -277,20 +301,21 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add
return nil, err
}
baseTx := &types.DynamicFeeTx{
To: contract,
Nonce: nonce,
GasFeeCap: gasFeeCap,
GasTipCap: gasTipCap,
Gas: gasLimit,
Value: value,
Data: input,
To: contract,
Nonce: nonce,
GasFeeCap: gasFeeCap,
GasTipCap: gasTipCap,
Gas: gasLimit,
Value: value,
Data: input,
AccessList: opts.AccessList,
}
return types.NewTx(baseTx), nil
}
func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
if opts.GasFeeCap != nil || opts.GasTipCap != nil {
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
if opts.GasFeeCap != nil || opts.GasTipCap != nil || opts.AccessList != nil {
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas or accessList specified but london is not active yet")
}
// Normalize value
value := opts.Value
@@ -438,7 +463,7 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int
if err != nil {
return nil, nil, err
}
sub, err := event.NewSubscription(func(quit <-chan struct{}) error {
sub := event.NewSubscription(func(quit <-chan struct{}) error {
for _, log := range buff {
select {
case logs <- log:
@@ -447,11 +472,8 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int
}
}
return nil
}), nil
})
if err != nil {
return nil, nil, err
}
return logs, sub, nil
}
@@ -488,8 +510,12 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter
// UnpackLog unpacks a retrieved log into the provided output structure.
func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) error {
// Anonymous events are not supported.
if len(log.Topics) == 0 {
return errNoEventSignature
}
if log.Topics[0] != c.abi.Events[event].ID {
return fmt.Errorf("event signature mismatch")
return errEventSignatureMismatch
}
if len(log.Data) > 0 {
if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil {
@@ -507,8 +533,12 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log)
// UnpackLogIntoMap unpacks a retrieved log into the provided map.
func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error {
// Anonymous events are not supported.
if len(log.Topics) == 0 {
return errNoEventSignature
}
if log.Topics[0] != c.abi.Events[event].ID {
return fmt.Errorf("event signature mismatch")
return errEventSignatureMismatch
}
if len(log.Data) > 0 {
if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil {

View File

@@ -114,7 +114,28 @@ func (mc *mockPendingCaller) PendingCallContract(ctx context.Context, call ether
return mc.pendingCallContractBytes, mc.pendingCallContractErr
}
type mockBlockHashCaller struct {
*mockCaller
codeAtHashBytes []byte
codeAtHashErr error
codeAtHashCalled bool
callContractAtHashCalled bool
callContractAtHashBytes []byte
callContractAtHashErr error
}
func (mc *mockBlockHashCaller) CodeAtHash(ctx context.Context, contract common.Address, hash common.Hash) ([]byte, error) {
mc.codeAtHashCalled = true
return mc.codeAtHashBytes, mc.codeAtHashErr
}
func (mc *mockBlockHashCaller) CallContractAtHash(ctx context.Context, call ethereum.CallMsg, hash common.Hash) ([]byte, error) {
mc.callContractAtHashCalled = true
return mc.callContractAtHashBytes, mc.callContractAtHashErr
}
func TestPassingBlockNumber(t *testing.T) {
t.Parallel()
mc := &mockPendingCaller{
mockCaller: &mockCaller{
codeAtBytes: []byte{1, 2, 3},
@@ -166,6 +187,7 @@ func TestPassingBlockNumber(t *testing.T) {
const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158"
func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) {
t.Parallel()
hash := crypto.Keccak256Hash([]byte("testName"))
topics := []common.Hash{
crypto.Keccak256Hash([]byte("received(string,address,uint256,bytes)")),
@@ -186,7 +208,26 @@ func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) {
unpackAndCheck(t, bc, expectedReceivedMap, mockLog)
}
func TestUnpackAnonymousLogIntoMap(t *testing.T) {
t.Parallel()
mockLog := newMockLog(nil, common.HexToHash("0x0"))
abiString := `[{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"received","type":"event"}]`
parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
var received map[string]interface{}
err := bc.UnpackLogIntoMap(received, "received", mockLog)
if err == nil {
t.Error("unpacking anonymous event is not supported")
}
if err.Error() != "no event signature" {
t.Errorf("expected error 'no event signature', got '%s'", err)
}
}
func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) {
t.Parallel()
sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"})
if err != nil {
t.Fatal(err)
@@ -212,6 +253,7 @@ func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) {
}
func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) {
t.Parallel()
arrBytes, err := rlp.EncodeToBytes([2]common.Address{common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")})
if err != nil {
t.Fatal(err)
@@ -237,6 +279,7 @@ func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) {
}
func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) {
t.Parallel()
mockAddress := common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")
addrBytes := mockAddress.Bytes()
hash := crypto.Keccak256Hash([]byte("mockFunction(address,uint)"))
@@ -263,6 +306,7 @@ func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) {
}
func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) {
t.Parallel()
bytes := []byte{1, 2, 3, 4, 5}
hash := crypto.Keccak256Hash(bytes)
topics := []common.Hash{
@@ -285,6 +329,7 @@ func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) {
}
func TestTransactGasFee(t *testing.T) {
t.Parallel()
assert := assert.New(t)
// GasTipCap and GasFeeCap
@@ -360,6 +405,7 @@ func newMockLog(topics []common.Hash, txHash common.Hash) types.Log {
}
func TestCall(t *testing.T) {
t.Parallel()
var method, methodWithArg = "something", "somethingArrrrg"
tests := []struct {
name, method string
@@ -383,6 +429,15 @@ func TestCall(t *testing.T) {
Pending: true,
},
method: method,
}, {
name: "ok hash",
mc: &mockBlockHashCaller{
codeAtHashBytes: []byte{0},
},
opts: &bind.CallOpts{
BlockHash: common.Hash{0xaa},
},
method: method,
}, {
name: "pack error, no method",
mc: new(mockCaller),
@@ -396,6 +451,14 @@ func TestCall(t *testing.T) {
},
method: method,
wantErrExact: bind.ErrNoPendingState,
}, {
name: "interface error, blockHash but not a BlockHashContractCaller",
mc: new(mockCaller),
opts: &bind.CallOpts{
BlockHash: common.Hash{0xaa},
},
method: method,
wantErrExact: bind.ErrNoBlockHashState,
}, {
name: "pending call canceled",
mc: &mockPendingCaller{
@@ -443,6 +506,34 @@ func TestCall(t *testing.T) {
mc: new(mockCaller),
method: method,
wantErrExact: bind.ErrNoCode,
}, {
name: "call contract at hash error",
mc: &mockBlockHashCaller{
callContractAtHashErr: context.DeadlineExceeded,
},
opts: &bind.CallOpts{
BlockHash: common.Hash{0xaa},
},
method: method,
wantErrExact: context.DeadlineExceeded,
}, {
name: "code at error",
mc: &mockBlockHashCaller{
codeAtHashErr: errors.New(""),
},
opts: &bind.CallOpts{
BlockHash: common.Hash{0xaa},
},
method: method,
wantErr: true,
}, {
name: "no code at hash",
mc: new(mockBlockHashCaller),
opts: &bind.CallOpts{
BlockHash: common.Hash{0xaa},
},
method: method,
wantErrExact: bind.ErrNoCode,
}, {
name: "unpack error missing arg",
mc: &mockCaller{
@@ -490,6 +581,7 @@ func TestCall(t *testing.T) {
// TestCrashers contains some strings which previously caused the abi codec to crash.
func TestCrashers(t *testing.T) {
t.Parallel()
abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"_1"}]}]}]`))
abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"&"}]}]}]`))
abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"----"}]}]}]`))

View File

@@ -79,7 +79,7 @@ func isKeyWord(arg string) bool {
// Bind generates a Go wrapper around a contract ABI. This wrapper isn't meant
// to be used as is in client code, but rather as an intermediate struct which
// enforces compile time type safety and naming convention opposed to having to
// enforces compile time type safety and naming convention as opposed to having to
// manually maintain hard coded strings that break on runtime.
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) {
var (
@@ -133,12 +133,19 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
// Normalize the method for capital cases and non-anonymous inputs/outputs
normalized := original
normalizedName := methodNormalizer[lang](alias(aliases, original.Name))
// Ensure there is no duplicated identifier
var identifiers = callIdentifiers
if !original.IsConstant() {
identifiers = transactIdentifiers
}
// Name shouldn't start with a digit. It will make the generated code invalid.
if len(normalizedName) > 0 && unicode.IsDigit(rune(normalizedName[0])) {
normalizedName = fmt.Sprintf("M%s", normalizedName)
normalizedName = abi.ResolveNameConflict(normalizedName, func(name string) bool {
_, ok := identifiers[name]
return ok
})
}
if identifiers[normalizedName] {
return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName)
}
@@ -182,6 +189,14 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
// Ensure there is no duplicated identifier
normalizedName := methodNormalizer[lang](alias(aliases, original.Name))
// Name shouldn't start with a digit. It will make the generated code invalid.
if len(normalizedName) > 0 && unicode.IsDigit(rune(normalizedName[0])) {
normalizedName = fmt.Sprintf("E%s", normalizedName)
normalizedName = abi.ResolveNameConflict(normalizedName, func(name string) bool {
_, ok := eventIdentifiers[name]
return ok
})
}
if eventIdentifiers[normalizedName] {
return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName)
}
@@ -348,7 +363,7 @@ func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
// parameters that are not value types i.e. arrays and structs are not
// stored directly but instead a keccak256-hash of an encoding is stored.
//
// We only convert stringS and bytes to hash, still need to deal with
// We only convert strings and bytes to hash, still need to deal with
// array(both fixed-size and dynamic-size) and struct.
if bound == "string" || bound == "[]byte" {
bound = "common.Hash"

View File

@@ -289,7 +289,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -297,7 +297,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy an interaction tester contract and call a transaction on it
@@ -305,6 +305,7 @@ var bindTests = []struct {
if err != nil {
t.Fatalf("Failed to deploy interactor contract: %v", err)
}
sim.Commit()
if _, err := interactor.Transact(auth, "Transact string"); err != nil {
t.Fatalf("Failed to transact with interactor contract: %v", err)
}
@@ -344,7 +345,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -352,7 +353,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a tuple tester contract and execute a structured call on it
@@ -390,7 +391,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -398,7 +399,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a tuple tester contract and execute a structured call on it
@@ -448,7 +449,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -456,7 +457,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a slice tester contract and execute a n array call on it
@@ -496,7 +497,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -504,7 +505,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a default method invoker contract and execute its default method
@@ -512,6 +513,7 @@ var bindTests = []struct {
if err != nil {
t.Fatalf("Failed to deploy defaulter contract: %v", err)
}
sim.Commit()
if _, err := (&DefaulterRaw{defaulter}).Transfer(auth); err != nil {
t.Fatalf("Failed to invoke default method: %v", err)
}
@@ -562,7 +564,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -570,7 +572,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a structs method invoker contract and execute its default method
@@ -608,12 +610,12 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
`,
`
// Create a simulator and wrap a non-deployed contract
sim := backends.NewSimulatedBackend(core.GenesisAlloc{}, uint64(10000000000))
sim := backends.NewSimulatedBackend(types.GenesisAlloc{}, uint64(10000000000))
defer sim.Close()
nonexistent, err := NewNonExistent(common.Address{}, sim)
@@ -647,12 +649,12 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
`,
`
// Create a simulator and wrap a non-deployed contract
sim := backends.NewSimulatedBackend(core.GenesisAlloc{}, uint64(10000000000))
sim := backends.NewSimulatedBackend(types.GenesisAlloc{}, uint64(10000000000))
defer sim.Close()
nonexistent, err := NewNonExistentStruct(common.Address{}, sim)
@@ -694,7 +696,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -702,7 +704,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a funky gas pattern contract
@@ -744,7 +746,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -752,7 +754,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a sender tester contract and execute a structured call on it
@@ -819,7 +821,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -827,7 +829,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a underscorer tester contract and execute a structured call on it
@@ -913,7 +915,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -921,7 +923,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy an eventer contract
@@ -1103,7 +1105,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -1111,7 +1113,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
//deploy the test contract
@@ -1238,7 +1240,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
@@ -1246,7 +1248,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
_, _, contract, err := DeployTuple(auth, sim)
@@ -1380,7 +1382,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -1388,7 +1390,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
//deploy the test contract
@@ -1446,14 +1448,14 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
// Initialize test accounts
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// deploy the test contract
@@ -1535,7 +1537,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
`,
`
// Initialize test accounts
@@ -1543,7 +1545,7 @@ var bindTests = []struct {
addr := crypto.PubkeyToAddress(key.PublicKey)
// Deploy registrar contract
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
@@ -1598,14 +1600,14 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
`,
`
key, _ := crypto.GenerateKey()
addr := crypto.PubkeyToAddress(key.PublicKey)
// Deploy registrar contract
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
@@ -1659,7 +1661,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
@@ -1667,7 +1669,7 @@ var bindTests = []struct {
key, _ := crypto.GenerateKey()
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000)
defer sim.Close()
// Deploy a tester contract and execute a structured call on it
@@ -1677,7 +1679,7 @@ var bindTests = []struct {
}
sim.Commit()
// This test the existence of the free retreiver call for view and pure functions
// This test the existence of the free retriever call for view and pure functions
if num, err := pav.PureFunc(nil); err != nil {
t.Fatalf("Failed to call anonymous field retriever: %v", err)
} else if num.Cmp(big.NewInt(42)) != 0 {
@@ -1720,14 +1722,14 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
`,
`
key, _ := crypto.GenerateKey()
addr := crypto.PubkeyToAddress(key.PublicKey)
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 1000000)
sim := backends.NewSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 1000000)
defer sim.Close()
opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
@@ -1808,7 +1810,7 @@ var bindTests = []struct {
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/ethconfig"
`,
@@ -1816,7 +1818,7 @@ var bindTests = []struct {
var (
key, _ = crypto.GenerateKey()
user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim = backends.NewSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
)
defer sim.Close()
@@ -1874,11 +1876,12 @@ var bindTests = []struct {
[]string{"0x6080604052348015600f57600080fd5b5060998061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063726c638214602d575b600080fd5b60336035565b005b60405163024876cd60e61b815260016004820152600260248201526003604482015260640160405180910390fdfea264697066735822122093f786a1bc60216540cd999fbb4a6109e0fef20abcff6e9107fb2817ca968f3c64736f6c63430008070033"},
[]string{`[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError1","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError2","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"MyError3","type":"error"},{"inputs":[],"name":"Error","outputs":[],"stateMutability":"pure","type":"function"}]`},
`
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/ethconfig"
`,
@@ -1886,7 +1889,7 @@ var bindTests = []struct {
var (
key, _ = crypto.GenerateKey()
user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim = backends.NewSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
)
defer sim.Close()
@@ -1895,7 +1898,7 @@ var bindTests = []struct {
t.Fatal(err)
}
sim.Commit()
_, err = bind.WaitDeployed(nil, sim, tx)
_, err = bind.WaitDeployed(context.Background(), sim, tx)
if err != nil {
t.Error(err)
}
@@ -1926,11 +1929,12 @@ var bindTests = []struct {
bytecode: []string{`0x608060405234801561001057600080fd5b506040516101c43803806101c48339818101604052810190610032919061014a565b50610177565b6000604051905090565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100958261004c565b810181811067ffffffffffffffff821117156100b4576100b361005d565b5b80604052505050565b60006100c7610038565b90506100d3828261008c565b919050565b6000819050919050565b6100eb816100d8565b81146100f657600080fd5b50565b600081519050610108816100e2565b92915050565b60006020828403121561012457610123610047565b5b61012e60206100bd565b9050600061013e848285016100f9565b60008301525092915050565b6000602082840312156101605761015f610042565b5b600061016e8482850161010e565b91505092915050565b603f806101856000396000f3fe6080604052600080fdfea2646970667358221220cdffa667affecefac5561f65f4a4ba914204a8d4eb859d8cd426fb306e5c12a364736f6c634300080a0033`},
abi: []string{`[{"inputs":[{"components":[{"internalType":"uint256","name":"field","type":"uint256"}],"internalType":"struct ConstructorWithStructParam.StructType","name":"st","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"}]`},
imports: `
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/ethconfig"
`,
@@ -1938,7 +1942,7 @@ var bindTests = []struct {
var (
key, _ = crypto.GenerateKey()
user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim = backends.NewSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
)
defer sim.Close()
@@ -1948,7 +1952,7 @@ var bindTests = []struct {
}
sim.Commit()
if _, err = bind.WaitDeployed(nil, sim, tx); err != nil {
if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil {
t.Logf("Deployment tx: %+v", tx)
t.Errorf("bind.WaitDeployed(nil, %T, <deployment tx>) got err %v; want nil err", sim, err)
}
@@ -1974,11 +1978,12 @@ var bindTests = []struct {
bytecode: []string{"0x608060405234801561001057600080fd5b5061042b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063c2bb515f1461003b578063cce7b04814610059575b600080fd5b610043610075565b60405161005091906101af565b60405180910390f35b610073600480360381019061006e91906103ac565b6100b5565b005b61007d6100b8565b604051806040016040528060405180602001604052806000815250815260200160405180602001604052806000815250815250905090565b50565b604051806040016040528060608152602001606081525090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561010c5780820151818401526020810190506100f1565b8381111561011b576000848401525b50505050565b6000601f19601f8301169050919050565b600061013d826100d2565b61014781856100dd565b93506101578185602086016100ee565b61016081610121565b840191505092915050565b600060408301600083015184820360008601526101888282610132565b915050602083015184820360208601526101a28282610132565b9150508091505092915050565b600060208201905081810360008301526101c9818461016b565b905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61022282610121565b810181811067ffffffffffffffff82111715610241576102406101ea565b5b80604052505050565b60006102546101d1565b90506102608282610219565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561028f5761028e6101ea565b5b61029882610121565b9050602081019050919050565b82818337600083830152505050565b60006102c76102c284610274565b61024a565b9050828152602081018484840111156102e3576102e261026f565b5b6102ee8482856102a5565b509392505050565b600082601f83011261030b5761030a61026a565b5b813561031b8482602086016102b4565b91505092915050565b60006040828403121561033a576103396101e5565b5b610344604061024a565b9050600082013567ffffffffffffffff81111561036457610363610265565b5b610370848285016102f6565b600083015250602082013567ffffffffffffffff81111561039457610393610265565b5b6103a0848285016102f6565b60208301525092915050565b6000602082840312156103c2576103c16101db565b5b600082013567ffffffffffffffff8111156103e0576103df6101e0565b5b6103ec84828501610324565b9150509291505056fea264697066735822122033bca1606af9b6aeba1673f98c52003cec19338539fb44b86690ce82c51483b564736f6c634300080e0033"},
abi: []string{`[ { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "int256", "name": "msg", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "_msg", "type": "int256" } ], "name": "log", "type": "event" }, { "inputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "req", "type": "tuple" } ], "name": "addRequest", "outputs": [], "stateMutability": "pure", "type": "function" }, { "inputs": [], "name": "getRequest", "outputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "", "type": "tuple" } ], "stateMutability": "pure", "type": "function" } ]`},
imports: `
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/ethconfig"
`,
@@ -1986,7 +1991,7 @@ var bindTests = []struct {
var (
key, _ = crypto.GenerateKey()
user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim = backends.NewSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
)
defer sim.Close()
@@ -1996,7 +2001,7 @@ var bindTests = []struct {
}
sim.Commit()
if _, err = bind.WaitDeployed(nil, sim, tx); err != nil {
if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil {
t.Logf("Deployment tx: %+v", tx)
t.Errorf("bind.WaitDeployed(nil, %T, <deployment tx>) got err %v; want nil err", sim, err)
}
@@ -2014,11 +2019,12 @@ var bindTests = []struct {
bytecode: []string{"0x608060405234801561001057600080fd5b5060dc8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063527a119f14602d575b600080fd5b60436004803603810190603f9190605b565b6045565b005b50565b6000813590506055816092565b92915050565b600060208284031215606e57606d608d565b5b6000607a848285016048565b91505092915050565b6000819050919050565b600080fd5b6099816083565b811460a357600080fd5b5056fea2646970667358221220d4f4525e2615516394055d369fb17df41c359e5e962734f27fd683ea81fd9db164736f6c63430008070033"},
abi: []string{`[{"inputs":[{"internalType":"uint256","name":"range","type":"uint256"}],"name":"functionWithKeywordParameter","outputs":[],"stateMutability":"pure","type":"function"}]`},
imports: `
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/ethconfig"
`,
@@ -2026,7 +2032,7 @@ var bindTests = []struct {
var (
key, _ = crypto.GenerateKey()
user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim = backends.NewSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
sim = backends.NewSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, ethconfig.Defaults.Miner.GasCeil)
)
_, tx, _, err := DeployRangeKeyword(user, sim)
if err != nil {
@@ -2034,16 +2040,40 @@ var bindTests = []struct {
}
sim.Commit()
if _, err = bind.WaitDeployed(nil, sim, tx); err != nil {
if _, err = bind.WaitDeployed(context.Background(), sim, tx); err != nil {
t.Errorf("error deploying the contract: %v", err)
}
`,
}, {
name: "NumericMethodName",
contract: `
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
contract NumericMethodName {
event _1TestEvent(address _param);
function _1test() public pure {}
function __1test() public pure {}
function __2test() public pure {}
}
`,
bytecode: []string{"0x6080604052348015600f57600080fd5b5060958061001e6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80639d993132146041578063d02767c7146049578063ffa02795146051575b600080fd5b60476059565b005b604f605b565b005b6057605d565b005b565b565b56fea26469706673582212200382ca602dff96a7e2ba54657985e2b4ac423a56abe4a1f0667bc635c4d4371f64736f6c63430008110033"},
abi: []string{`[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_param","type":"address"}],"name":"_1TestEvent","type":"event"},{"inputs":[],"name":"_1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__2test","outputs":[],"stateMutability":"pure","type":"function"}]`},
imports: `
"github.com/ethereum/go-ethereum/common"
`,
tester: `
if b, err := NewNumericMethodName(common.Address{}, nil); b == nil || err != nil {
t.Fatalf("combined binding (%v) nil or error (%v) not nil", b, nil)
}
`,
},
}
// Tests that packages generated by the binder can be successfully compiled and
// the requested tester run against it.
func TestGolangBindings(t *testing.T) {
t.Parallel()
// Skip the test if no Go command can be found
gocmd := runtime.GOROOT() + "/bin/go"
if !common.FileExist(gocmd) {

View File

@@ -0,0 +1,487 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package {{.Package}}
import (
"math/big"
"strings"
"errors"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
_ = abi.ConvertType
)
{{$structs := .Structs}}
{{range $structs}}
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
type {{.Name}} struct {
{{range $field := .Fields}}
{{$field.Name}} {{$field.Type}}{{end}}
}
{{end}}
{{range $contract := .Contracts}}
// {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract.
var {{.Type}}MetaData = &bind.MetaData{
ABI: "{{.InputABI}}",
{{if $contract.FuncSigs -}}
Sigs: map[string]string{
{{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}",
{{end}}
},
{{end -}}
{{if .InputBin -}}
Bin: "0x{{.InputBin}}",
{{end}}
}
// {{.Type}}ABI is the input ABI used to generate the binding from.
// Deprecated: Use {{.Type}}MetaData.ABI instead.
var {{.Type}}ABI = {{.Type}}MetaData.ABI
{{if $contract.FuncSigs}}
// Deprecated: Use {{.Type}}MetaData.Sigs instead.
// {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs
{{end}}
{{if .InputBin}}
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
// Deprecated: Use {{.Type}}MetaData.Bin instead.
var {{.Type}}Bin = {{.Type}}MetaData.Bin
// Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
parsed, err := {{.Type}}MetaData.GetAbi()
if err != nil {
return common.Address{}, nil, nil, err
}
if parsed == nil {
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
}
{{range $pattern, $name := .Libraries}}
{{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend)
{{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:])
{{end}}
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
}
{{end}}
// {{.Type}} is an auto generated Go binding around an Ethereum contract.
type {{.Type}} struct {
{{.Type}}Caller // Read-only binding to the contract
{{.Type}}Transactor // Write-only binding to the contract
{{.Type}}Filterer // Log filterer for contract events
}
// {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract.
type {{.Type}}Caller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract.
type {{.Type}}Transactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
type {{.Type}}Filterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// {{.Type}}Session is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type {{.Type}}Session struct {
Contract *{{.Type}} // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type {{.Type}}CallerSession struct {
Contract *{{.Type}}Caller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type {{.Type}}TransactorSession struct {
Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract.
type {{.Type}}Raw struct {
Contract *{{.Type}} // Generic contract binding to access the raw methods on
}
// {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type {{.Type}}CallerRaw struct {
Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on
}
// {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type {{.Type}}TransactorRaw struct {
Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on
}
// New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) {
contract, err := bind{{.Type}}(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
}
// New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) {
contract, err := bind{{.Type}}(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &{{.Type}}Caller{contract: contract}, nil
}
// New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) {
contract, err := bind{{.Type}}(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &{{.Type}}Transactor{contract: contract}, nil
}
// New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) {
contract, err := bind{{.Type}}(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &{{.Type}}Filterer{contract: contract}, nil
}
// bind{{.Type}} binds a generic wrapper to an already deployed contract.
func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := {{.Type}}MetaData.GetAbi()
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...)
}
{{range .Calls}}
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) {
var out []interface{}
err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
{{if .Structured}}
outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} })
if err != nil {
return *outstruct, err
}
{{range $i, $t := .Normalized.Outputs}}
outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
return *outstruct, err
{{else}}
if err != nil {
return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err
}
{{range $i, $t := .Normalized.Outputs}}
out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err
{{end}}
}
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
}
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
}
{{end}}
{{range .Transacts}}
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
}
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
}
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
}
{{end}}
{{if .Fallback}}
// Fallback is a paid mutator transaction binding the contract fallback function.
//
// Solidity: {{.Fallback.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) {
return _{{$contract.Type}}.contract.RawTransact(opts, calldata)
}
// Fallback is a paid mutator transaction binding the contract fallback function.
//
// Solidity: {{.Fallback.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
}
// Fallback is a paid mutator transaction binding the contract fallback function.
//
// Solidity: {{.Fallback.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
}
{{end}}
{{if .Receive}}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: {{.Receive.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: {{.Receive.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: {{.Receive.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
}
{{end}}
{{range .Events}}
// {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract.
type {{$contract.Type}}{{.Normalized.Name}}Iterator struct {
Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool {
// If the iterator failed, stop iterating
if (it.fail != nil) {
return false
}
// If the iterator completed, deliver directly whatever's available
if (it.done) {
select {
case log := <-it.logs:
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract.
type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}}
{{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}}
Raw types.Log // Blockchain specific contextual infos
}
// Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) {
{{range .Normalized.Inputs}}
{{if .Indexed}}var {{.Name}}Rule []interface{}
for _, {{.Name}}Item := range {{.Name}} {
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
}{{end}}{{end}}
logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
if err != nil {
return nil, err
}
return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil
}
// Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) {
{{range .Normalized.Inputs}}
{{if .Indexed}}var {{.Name}}Rule []interface{}
for _, {{.Name}}Item := range {{.Name}} {
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
}{{end}}{{end}}
logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new({{$contract.Type}}{{.Normalized.Name}})
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) {
event := new({{$contract.Type}}{{.Normalized.Name}})
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
{{end}}
{{end}}

View File

@@ -16,7 +16,11 @@
package bind
import "github.com/ethereum/go-ethereum/accounts/abi"
import (
_ "embed"
"github.com/ethereum/go-ethereum/accounts/abi"
)
// tmplData is the data structure required to fill the binding template.
type tmplData struct {
@@ -80,492 +84,6 @@ var tmplSource = map[Lang]string{
// tmplSourceGo is the Go source template that the generated Go contract binding
// is based on.
const tmplSourceGo = `
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package {{.Package}}
import (
"math/big"
"strings"
"errors"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
_ = abi.ConvertType
)
{{$structs := .Structs}}
{{range $structs}}
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
type {{.Name}} struct {
{{range $field := .Fields}}
{{$field.Name}} {{$field.Type}}{{end}}
}
{{end}}
{{range $contract := .Contracts}}
// {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract.
var {{.Type}}MetaData = &bind.MetaData{
ABI: "{{.InputABI}}",
{{if $contract.FuncSigs -}}
Sigs: map[string]string{
{{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}",
{{end}}
},
{{end -}}
{{if .InputBin -}}
Bin: "0x{{.InputBin}}",
{{end}}
}
// {{.Type}}ABI is the input ABI used to generate the binding from.
// Deprecated: Use {{.Type}}MetaData.ABI instead.
var {{.Type}}ABI = {{.Type}}MetaData.ABI
{{if $contract.FuncSigs}}
// Deprecated: Use {{.Type}}MetaData.Sigs instead.
// {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs
{{end}}
{{if .InputBin}}
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
// Deprecated: Use {{.Type}}MetaData.Bin instead.
var {{.Type}}Bin = {{.Type}}MetaData.Bin
// Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
parsed, err := {{.Type}}MetaData.GetAbi()
if err != nil {
return common.Address{}, nil, nil, err
}
if parsed == nil {
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
}
{{range $pattern, $name := .Libraries}}
{{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend)
{{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:])
{{end}}
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
}
{{end}}
// {{.Type}} is an auto generated Go binding around an Ethereum contract.
type {{.Type}} struct {
{{.Type}}Caller // Read-only binding to the contract
{{.Type}}Transactor // Write-only binding to the contract
{{.Type}}Filterer // Log filterer for contract events
}
// {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract.
type {{.Type}}Caller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract.
type {{.Type}}Transactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
type {{.Type}}Filterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// {{.Type}}Session is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type {{.Type}}Session struct {
Contract *{{.Type}} // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type {{.Type}}CallerSession struct {
Contract *{{.Type}}Caller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type {{.Type}}TransactorSession struct {
Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract.
type {{.Type}}Raw struct {
Contract *{{.Type}} // Generic contract binding to access the raw methods on
}
// {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type {{.Type}}CallerRaw struct {
Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on
}
// {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type {{.Type}}TransactorRaw struct {
Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on
}
// New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) {
contract, err := bind{{.Type}}(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
}
// New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) {
contract, err := bind{{.Type}}(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &{{.Type}}Caller{contract: contract}, nil
}
// New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) {
contract, err := bind{{.Type}}(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &{{.Type}}Transactor{contract: contract}, nil
}
// New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract.
func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) {
contract, err := bind{{.Type}}(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &{{.Type}}Filterer{contract: contract}, nil
}
// bind{{.Type}} binds a generic wrapper to an already deployed contract.
func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := {{.Type}}MetaData.GetAbi()
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...)
}
{{range .Calls}}
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) {
var out []interface{}
err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
{{if .Structured}}
outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} })
if err != nil {
return *outstruct, err
}
{{range $i, $t := .Normalized.Outputs}}
outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
return *outstruct, err
{{else}}
if err != nil {
return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err
}
{{range $i, $t := .Normalized.Outputs}}
out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err
{{end}}
}
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
}
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
}
{{end}}
{{range .Transacts}}
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
}
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
}
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
}
{{end}}
{{if .Fallback}}
// Fallback is a paid mutator transaction binding the contract fallback function.
//
// Solidity: {{.Fallback.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) {
return _{{$contract.Type}}.contract.RawTransact(opts, calldata)
}
// Fallback is a paid mutator transaction binding the contract fallback function.
//
// Solidity: {{.Fallback.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
}
// Fallback is a paid mutator transaction binding the contract fallback function.
//
// Solidity: {{.Fallback.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
}
{{end}}
{{if .Receive}}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: {{.Receive.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: {{.Receive.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: {{.Receive.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) {
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
}
{{end}}
{{range .Events}}
// {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract.
type {{$contract.Type}}{{.Normalized.Name}}Iterator struct {
Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool {
// If the iterator failed, stop iterating
if (it.fail != nil) {
return false
}
// If the iterator completed, deliver directly whatever's available
if (it.done) {
select {
case log := <-it.logs:
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract.
type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}}
{{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}}
Raw types.Log // Blockchain specific contextual infos
}
// Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) {
{{range .Normalized.Inputs}}
{{if .Indexed}}var {{.Name}}Rule []interface{}
for _, {{.Name}}Item := range {{.Name}} {
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
}{{end}}{{end}}
logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
if err != nil {
return nil, err
}
return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil
}
// Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) {
{{range .Normalized.Inputs}}
{{if .Indexed}}var {{.Name}}Rule []interface{}
for _, {{.Name}}Item := range {{.Name}} {
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
}{{end}}{{end}}
logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new({{$contract.Type}}{{.Normalized.Name}})
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}.
//
// Solidity: {{.Original.String}}
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) {
event := new({{$contract.Type}}{{.Normalized.Name}})
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
{{end}}
{{end}}
`
//
//go:embed source.go.tpl
var tmplSourceGo string

View File

@@ -24,11 +24,11 @@ import (
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient/simulated"
"github.com/ethereum/go-ethereum/params"
)
var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
@@ -53,21 +53,21 @@ var waitDeployedTests = map[string]struct {
}
func TestWaitDeployed(t *testing.T) {
t.Parallel()
for name, test := range waitDeployedTests {
backend := backends.NewSimulatedBackend(
core.GenesisAlloc{
backend := simulated.NewBackend(
types.GenesisAlloc{
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)},
},
10000000,
)
defer backend.Close()
// Create the transaction
head, _ := backend.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
head, _ := backend.Client().HeaderByNumber(context.Background(), nil) // Should be child's, good enough
gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei))
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, gasPrice, common.FromHex(test.code))
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
tx, _ = types.SignTx(tx, types.LatestSignerForChainID(big.NewInt(1337)), testKey)
// Wait for it to get mined in the background.
var (
@@ -77,12 +77,14 @@ func TestWaitDeployed(t *testing.T) {
ctx = context.Background()
)
go func() {
address, err = bind.WaitDeployed(ctx, backend, tx)
address, err = bind.WaitDeployed(ctx, backend.Client(), tx)
close(mined)
}()
// Send and mine the transaction.
backend.SendTransaction(ctx, tx)
if err := backend.Client().SendTransaction(ctx, tx); err != nil {
t.Errorf("test %q: failed to send transaction: %v", name, err)
}
backend.Commit()
select {
@@ -100,41 +102,44 @@ func TestWaitDeployed(t *testing.T) {
}
func TestWaitDeployedCornerCases(t *testing.T) {
backend := backends.NewSimulatedBackend(
core.GenesisAlloc{
backend := simulated.NewBackend(
types.GenesisAlloc{
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)},
},
10000000,
)
defer backend.Close()
head, _ := backend.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
head, _ := backend.Client().HeaderByNumber(context.Background(), nil) // Should be child's, good enough
gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
// Create a transaction to an account.
code := "6060604052600a8060106000396000f360606040526008565b00"
tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, gasPrice, common.FromHex(code))
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
backend.SendTransaction(ctx, tx)
if err := backend.Client().SendTransaction(ctx, tx); err != nil {
t.Errorf("failed to send transaction: %q", err)
}
backend.Commit()
notContentCreation := errors.New("tx is not contract creation")
if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContentCreation.Error() {
t.Errorf("error missmatch: want %q, got %q, ", notContentCreation, err)
notContractCreation := errors.New("tx is not contract creation")
if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != notContractCreation.Error() {
t.Errorf("error mismatch: want %q, got %q, ", notContractCreation, err)
}
// Create a transaction that is not mined.
tx = types.NewContractCreation(1, big.NewInt(0), 3000000, gasPrice, common.FromHex(code))
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey)
go func() {
contextCanceled := errors.New("context canceled")
if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != contextCanceled.Error() {
t.Errorf("error missmatch: want %q, got %q, ", contextCanceled, err)
if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != contextCanceled.Error() {
t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err)
}
}()
backend.SendTransaction(ctx, tx)
if err := backend.Client().SendTransaction(ctx, tx); err != nil {
t.Errorf("failed to send transaction: %q", err)
}
cancel()
}

View File

@@ -18,7 +18,6 @@ package abi
import (
"bytes"
"errors"
"fmt"
"strings"
@@ -32,7 +31,7 @@ type Error struct {
str string
// Sig contains the string signature according to the ABI spec.
// e.g. error foo(uint32 a, int b) = "foo(uint32,int256)"
// e.g. error foo(uint32 a, int b) = "foo(uint32,int256)"
// Please note that "int" is substitute for its canonical representation "int256"
Sig string
@@ -78,16 +77,16 @@ func NewError(name string, inputs Arguments) Error {
}
}
func (e *Error) String() string {
func (e Error) String() string {
return e.str
}
func (e *Error) Unpack(data []byte) (interface{}, error) {
if len(data) < 4 {
return "", errors.New("invalid data for unpacking")
return "", fmt.Errorf("insufficient data for unpacking: have %d, want at least 4", len(data))
}
if !bytes.Equal(data[:4], e.ID[:4]) {
return "", errors.New("invalid data for unpacking")
return "", fmt.Errorf("invalid identifier, have %#x want %#x", data[:4], e.ID[:4])
}
return e.Inputs.Unpack(data[4:])
}

View File

@@ -81,6 +81,7 @@ var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa
var mixedCaseData1 = "00000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000020489e8000000000000000000000000000000000000000000000000000000000000000f4241"
func TestEventId(t *testing.T) {
t.Parallel()
var table = []struct {
definition string
expectations map[string]common.Hash
@@ -112,6 +113,7 @@ func TestEventId(t *testing.T) {
}
func TestEventString(t *testing.T) {
t.Parallel()
var table = []struct {
definition string
expectations map[string]string
@@ -146,6 +148,7 @@ func TestEventString(t *testing.T) {
// TestEventMultiValueWithArrayUnpack verifies that array fields will be counted after parsing array.
func TestEventMultiValueWithArrayUnpack(t *testing.T) {
t.Parallel()
definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": false, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"uint8"}]}]`
abi, err := JSON(strings.NewReader(definition))
require.NoError(t, err)
@@ -161,6 +164,7 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) {
}
func TestEventTupleUnpack(t *testing.T) {
t.Parallel()
type EventTransfer struct {
Value *big.Int
}
@@ -351,6 +355,7 @@ func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, ass
// TestEventUnpackIndexed verifies that indexed field will be skipped by event decoder.
func TestEventUnpackIndexed(t *testing.T) {
t.Parallel()
definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8"},{"indexed": false, "name":"value2", "type":"uint8"}]}]`
type testStruct struct {
Value1 uint8 // indexed
@@ -368,6 +373,7 @@ func TestEventUnpackIndexed(t *testing.T) {
// TestEventIndexedWithArrayUnpack verifies that decoder will not overflow when static array is indexed input.
func TestEventIndexedWithArrayUnpack(t *testing.T) {
t.Parallel()
definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"string"}]}]`
type testStruct struct {
Value1 [2]uint8 // indexed

View File

@@ -117,24 +117,23 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str
sig = fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ","))
id = crypto.Keccak256([]byte(sig))[:4]
}
// Extract meaningful state mutability of solidity method.
// If it's default value, never print it.
state := mutability
if state == "nonpayable" {
state = ""
}
if state != "" {
state = state + " "
}
identity := fmt.Sprintf("function %v", rawName)
if funType == Fallback {
switch funType {
case Fallback:
identity = "fallback"
} else if funType == Receive {
case Receive:
identity = "receive"
} else if funType == Constructor {
case Constructor:
identity = "constructor"
}
str := fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputNames, ", "), state, strings.Join(outputNames, ", "))
var str string
// Extract meaningful state mutability of solidity method.
// If it's empty string or default value "nonpayable", never print it.
if mutability == "" || mutability == "nonpayable" {
str = fmt.Sprintf("%v(%v) returns(%v)", identity, strings.Join(inputNames, ", "), strings.Join(outputNames, ", "))
} else {
str = fmt.Sprintf("%v(%v) %s returns(%v)", identity, strings.Join(inputNames, ", "), mutability, strings.Join(outputNames, ", "))
}
return Method{
Name: name,

View File

@@ -35,6 +35,7 @@ const methoddata = `
]`
func TestMethodString(t *testing.T) {
t.Parallel()
var table = []struct {
method string
expectation string
@@ -84,11 +85,12 @@ func TestMethodString(t *testing.T) {
for _, test := range table {
var got string
if test.method == "fallback" {
switch test.method {
case "fallback":
got = abi.Fallback.String()
} else if test.method == "receive" {
case "receive":
got = abi.Receive.String()
} else {
default:
got = abi.Methods[test.method].String()
}
if got != test.expectation {
@@ -98,6 +100,7 @@ func TestMethodString(t *testing.T) {
}
func TestMethodSig(t *testing.T) {
t.Parallel()
var cases = []struct {
method string
expect string

View File

@@ -57,7 +57,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) {
reflectValue = mustArrayToByteSlice(reflectValue)
}
if reflectValue.Type() != reflect.TypeOf([]byte{}) {
return []byte{}, errors.New("Bytes type is neither slice nor array")
return []byte{}, errors.New("bytes type is neither slice nor array")
}
return packBytesSlice(reflectValue.Bytes(), reflectValue.Len()), nil
case FixedBytesTy, FunctionTy:
@@ -66,7 +66,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) {
}
return common.RightPadBytes(reflectValue.Bytes(), 32), nil
default:
return []byte{}, fmt.Errorf("Could not pack element, unknown type: %v", t.T)
return []byte{}, fmt.Errorf("could not pack element, unknown type: %v", t.T)
}
}

View File

@@ -32,8 +32,11 @@ import (
// TestPack tests the general pack/unpack tests in packing_test.go
func TestPack(t *testing.T) {
t.Parallel()
for i, test := range packUnpackTests {
i, test := i, test
t.Run(strconv.Itoa(i), func(t *testing.T) {
t.Parallel()
encb, err := hex.DecodeString(test.packed)
if err != nil {
t.Fatalf("invalid hex %s: %v", test.packed, err)
@@ -57,6 +60,7 @@ func TestPack(t *testing.T) {
}
func TestMethodPack(t *testing.T) {
t.Parallel()
abi, err := JSON(strings.NewReader(jsondata))
if err != nil {
t.Fatal(err)
@@ -177,6 +181,7 @@ func TestMethodPack(t *testing.T) {
}
func TestPackNumber(t *testing.T) {
t.Parallel()
tests := []struct {
value reflect.Value
packed []byte

View File

@@ -24,7 +24,7 @@ import (
"strings"
)
// ConvertType converts an interface of a runtime type into a interface of the
// ConvertType converts an interface of a runtime type into an interface of the
// given type, e.g. turn this code:
//
// var fields []reflect.StructField
@@ -33,7 +33,7 @@ import (
// Name: "X",
// Type: reflect.TypeOf(new(big.Int)),
// Tag: reflect.StructTag("json:\"" + "x" + "\""),
// }
// })
//
// into:
//
@@ -134,7 +134,7 @@ func setSlice(dst, src reflect.Value) error {
dst.Set(slice)
return nil
}
return errors.New("Cannot set slice, destination not settable")
return errors.New("cannot set slice, destination not settable")
}
func setArray(dst, src reflect.Value) error {
@@ -155,7 +155,7 @@ func setArray(dst, src reflect.Value) error {
dst.Set(array)
return nil
}
return errors.New("Cannot set array, destination not settable")
return errors.New("cannot set array, destination not settable")
}
func setStruct(dst, src reflect.Value) error {
@@ -163,7 +163,7 @@ func setStruct(dst, src reflect.Value) error {
srcField := src.Field(i)
dstField := dst.Field(i)
if !dstField.IsValid() || !srcField.IsValid() {
return fmt.Errorf("Could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField)
return fmt.Errorf("could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField)
}
if err := set(dstField, srcField); err != nil {
return err
@@ -228,7 +228,7 @@ func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[stri
structFieldName := ToCamelCase(argName)
if structFieldName == "" {
return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct")
return nil, errors.New("abi: purely underscored output cannot unpack to struct")
}
// this abi has already been paired, skip it... unless there exists another, yet unassigned

View File

@@ -170,8 +170,11 @@ var reflectTests = []reflectTest{
}
func TestReflectNameToStruct(t *testing.T) {
t.Parallel()
for _, test := range reflectTests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
m, err := mapArgNamesToStructFields(test.args, reflect.ValueOf(test.struc))
if len(test.err) > 0 {
if err == nil || err.Error() != test.err {
@@ -192,6 +195,7 @@ func TestReflectNameToStruct(t *testing.T) {
}
func TestConvertType(t *testing.T) {
t.Parallel()
// Test Basic Struct
type T struct {
X *big.Int

View File

@@ -17,6 +17,7 @@
package abi
import (
"errors"
"fmt"
)
@@ -40,7 +41,7 @@ func isIdentifierSymbol(c byte) bool {
func parseToken(unescapedSelector string, isIdent bool) (string, string, error) {
if len(unescapedSelector) == 0 {
return "", "", fmt.Errorf("empty token")
return "", "", errors.New("empty token")
}
firstChar := unescapedSelector[0]
position := 1
@@ -110,7 +111,7 @@ func parseCompositeType(unescapedSelector string) ([]interface{}, string, error)
func parseType(unescapedSelector string) (interface{}, string, error) {
if len(unescapedSelector) == 0 {
return nil, "", fmt.Errorf("empty type")
return nil, "", errors.New("empty type")
}
if unescapedSelector[0] == '(' {
return parseCompositeType(unescapedSelector)

View File

@@ -24,6 +24,7 @@ import (
)
func TestParseSelector(t *testing.T) {
t.Parallel()
mkType := func(types ...interface{}) []ArgumentMarshaling {
var result []ArgumentMarshaling
for i, typeOrComponents := range types {

View File

@@ -24,6 +24,7 @@ import (
"reflect"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
)
@@ -41,8 +42,7 @@ func MakeTopics(query ...[]interface{}) ([][]common.Hash, error) {
case common.Address:
copy(topic[common.HashLength-common.AddressLength:], rule[:])
case *big.Int:
blob := rule.Bytes()
copy(topic[common.HashLength-len(blob):], blob)
copy(topic[:], math.U256Bytes(rule))
case bool:
if rule {
topic[common.HashLength-1] = 1
@@ -75,7 +75,7 @@ func MakeTopics(query ...[]interface{}) ([][]common.Hash, error) {
copy(topic[:], hash[:])
default:
// todo(rjl493456442) according solidity documentation, indexed event
// todo(rjl493456442) according to solidity documentation, indexed event
// parameters that are not value types i.e. arrays and structs are not
// stored directly but instead a keccak256-hash of an encoding is stored.
//

View File

@@ -17,6 +17,7 @@
package abi
import (
"math"
"math/big"
"reflect"
"testing"
@@ -26,6 +27,7 @@ import (
)
func TestMakeTopics(t *testing.T) {
t.Parallel()
type args struct {
query [][]interface{}
}
@@ -54,9 +56,27 @@ func TestMakeTopics(t *testing.T) {
false,
},
{
"support *big.Int types in topics",
args{[][]interface{}{{big.NewInt(1).Lsh(big.NewInt(2), 254)}}},
[][]common.Hash{{common.Hash{128}}},
"support positive *big.Int types in topics",
args{[][]interface{}{
{big.NewInt(1)},
{big.NewInt(1).Lsh(big.NewInt(2), 254)},
}},
[][]common.Hash{
{common.HexToHash("0000000000000000000000000000000000000000000000000000000000000001")},
{common.Hash{128}},
},
false,
},
{
"support negative *big.Int types in topics",
args{[][]interface{}{
{big.NewInt(-1)},
{big.NewInt(math.MinInt64)},
}},
[][]common.Hash{
{common.MaxHash},
{common.HexToHash("ffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000")},
},
false,
},
{
@@ -117,7 +137,9 @@ func TestMakeTopics(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got, err := MakeTopics(tt.args.query...)
if (err != nil) != tt.wantErr {
t.Errorf("makeTopics() error = %v, wantErr %v", err, tt.wantErr)
@@ -347,10 +369,13 @@ func setupTopicsTests() []topicTest {
}
func TestParseTopics(t *testing.T) {
t.Parallel()
tests := setupTopicsTests()
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
createObj := tt.args.createObj()
if err := ParseTopics(createObj, tt.args.fields, tt.args.topics); (err != nil) != tt.wantErr {
t.Errorf("parseTopics() error = %v, wantErr %v", err, tt.wantErr)
@@ -364,10 +389,13 @@ func TestParseTopics(t *testing.T) {
}
func TestParseTopicsIntoMap(t *testing.T) {
t.Parallel()
tests := setupTopicsTests()
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
outMap := make(map[string]interface{})
if err := ParseTopicsIntoMap(outMap, tt.args.fields, tt.args.topics); (err != nil) != tt.wantErr {
t.Errorf("parseTopicsIntoMap() error = %v, wantErr %v", err, tt.wantErr)

View File

@@ -64,13 +64,16 @@ type Type struct {
var (
// typeRegex parses the abi sub types
typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?")
// sliceSizeRegex grab the slice size
sliceSizeRegex = regexp.MustCompile("[0-9]+")
)
// NewType creates a new reflection type of abi type given in t.
func NewType(t string, internalType string, components []ArgumentMarshaling) (typ Type, err error) {
// check that array brackets are equal if they exist
if strings.Count(t, "[") != strings.Count(t, "]") {
return Type{}, fmt.Errorf("invalid arg type in abi")
return Type{}, errors.New("invalid arg type in abi")
}
typ.stringKind = t
@@ -91,8 +94,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
// grab the last cell and create a type from there
sliced := t[i:]
// grab the slice size with regexp
re := regexp.MustCompile("[0-9]+")
intz := re.FindAllString(sliced, -1)
intz := sliceSizeRegex.FindAllString(sliced, -1)
if len(intz) == 0 {
// is a slice
@@ -109,7 +111,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
}
typ.stringKind = embeddedType.stringKind + sliced
} else {
return Type{}, fmt.Errorf("invalid formatting of array type")
return Type{}, errors.New("invalid formatting of array type")
}
return typ, err
}
@@ -179,9 +181,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
return Type{}, errors.New("abi: purely anonymous or underscored field is not supported")
}
fieldName := ResolveNameConflict(name, func(s string) bool { return used[s] })
if err != nil {
return Type{}, err
}
used[fieldName] = true
if !isValidFieldName(fieldName) {
return Type{}, fmt.Errorf("field %d has invalid name", idx)
@@ -220,7 +219,12 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
typ.T = FunctionTy
typ.Size = 24
default:
return Type{}, fmt.Errorf("unsupported arg type: %s", t)
if strings.HasPrefix(internalType, "contract ") {
typ.Size = 20
typ.T = AddressTy
} else {
return Type{}, fmt.Errorf("unsupported arg type: %s", t)
}
}
return
@@ -348,7 +352,7 @@ func (t Type) pack(v reflect.Value) ([]byte, error) {
}
}
// requireLengthPrefix returns whether the type requires any sort of length
// requiresLengthPrefix returns whether the type requires any sort of length
// prefixing.
func (t Type) requiresLengthPrefix() bool {
return t.T == StringTy || t.T == BytesTy || t.T == SliceTy

View File

@@ -25,12 +25,13 @@ import (
"github.com/ethereum/go-ethereum/common"
)
// typeWithoutStringer is a alias for the Type type which simply doesn't implement
// typeWithoutStringer is an alias for the Type type which simply doesn't implement
// the stringer interface to allow printing type details in the tests below.
type typeWithoutStringer Type
// Tests that all allowed types get recognized by the type parser.
func TestTypeRegexp(t *testing.T) {
t.Parallel()
tests := []struct {
blob string
components []ArgumentMarshaling
@@ -117,6 +118,7 @@ func TestTypeRegexp(t *testing.T) {
}
func TestTypeCheck(t *testing.T) {
t.Parallel()
for i, test := range []struct {
typ string
components []ArgumentMarshaling
@@ -308,6 +310,7 @@ func TestTypeCheck(t *testing.T) {
}
func TestInternalType(t *testing.T) {
t.Parallel()
components := []ArgumentMarshaling{{Name: "a", Type: "int64"}}
internalType := "struct a.b[]"
kind := Type{
@@ -332,6 +335,7 @@ func TestInternalType(t *testing.T) {
}
func TestGetTypeSize(t *testing.T) {
t.Parallel()
var testCases = []struct {
typ string
components []ArgumentMarshaling
@@ -368,6 +372,7 @@ func TestGetTypeSize(t *testing.T) {
}
func TestNewFixedBytesOver32(t *testing.T) {
t.Parallel()
_, err := NewType("bytes4096", "", nil)
if err == nil {
t.Errorf("fixed bytes with size over 32 is not spec'd")

View File

@@ -18,6 +18,7 @@ package abi
import (
"encoding/binary"
"errors"
"fmt"
"math"
"math/big"
@@ -125,7 +126,7 @@ func readBool(word []byte) (bool, error) {
// readFunctionType enforces that standard by always presenting it as a 24-array (address + sig = 24 bytes)
func readFunctionType(t Type, word []byte) (funcTy [24]byte, err error) {
if t.T != FunctionTy {
return [24]byte{}, fmt.Errorf("abi: invalid type in call to make function type byte array")
return [24]byte{}, errors.New("abi: invalid type in call to make function type byte array")
}
if garbage := binary.BigEndian.Uint64(word[24:32]); garbage != 0 {
err = fmt.Errorf("abi: got improperly encoded function type, got %v", word)
@@ -138,7 +139,7 @@ func readFunctionType(t Type, word []byte) (funcTy [24]byte, err error) {
// ReadFixedBytes uses reflection to create a fixed array to be read from.
func ReadFixedBytes(t Type, word []byte) (interface{}, error) {
if t.T != FixedBytesTy {
return nil, fmt.Errorf("abi: invalid type in call to make fixed byte array")
return nil, errors.New("abi: invalid type in call to make fixed byte array")
}
// convert
array := reflect.New(t.GetType()).Elem()
@@ -159,14 +160,15 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error)
// this value will become our slice or our array, depending on the type
var refSlice reflect.Value
if t.T == SliceTy {
switch t.T {
case SliceTy:
// declare our slice
refSlice = reflect.MakeSlice(t.GetType(), size, size)
} else if t.T == ArrayTy {
case ArrayTy:
// declare our array
refSlice = reflect.New(t.GetType()).Elem()
} else {
return nil, fmt.Errorf("abi: invalid type in array/slice unpacking stage")
default:
return nil, errors.New("abi: invalid type in array/slice unpacking stage")
}
// Arrays have packed elements, resulting in longer unpack steps.

View File

@@ -33,6 +33,7 @@ import (
// TestUnpack tests the general pack/unpack tests in packing_test.go
func TestUnpack(t *testing.T) {
t.Parallel()
for i, test := range packUnpackTests {
t.Run(strconv.Itoa(i)+" "+test.def, func(t *testing.T) {
//Unpack
@@ -206,13 +207,13 @@ var unpackTests = []unpackTest{
def: `[{"type":"bool"}]`,
enc: "",
want: false,
err: "abi: attempting to unmarshall an empty string while arguments are expected",
err: "abi: attempting to unmarshal an empty string while arguments are expected",
},
{
def: `[{"type":"bytes32","indexed":true},{"type":"uint256","indexed":false}]`,
enc: "",
want: false,
err: "abi: attempting to unmarshall an empty string while arguments are expected",
err: "abi: attempting to unmarshal an empty string while arguments are expected",
},
{
def: `[{"type":"bool","indexed":true},{"type":"uint64","indexed":true}]`,
@@ -224,6 +225,7 @@ var unpackTests = []unpackTest{
// TestLocalUnpackTests runs test specially designed only for unpacking.
// All test cases that can be used to test packing and unpacking should move to packing_test.go
func TestLocalUnpackTests(t *testing.T) {
t.Parallel()
for i, test := range unpackTests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
//Unpack
@@ -251,6 +253,7 @@ func TestLocalUnpackTests(t *testing.T) {
}
func TestUnpackIntoInterfaceSetDynamicArrayOutput(t *testing.T) {
t.Parallel()
abi, err := JSON(strings.NewReader(`[{"constant":true,"inputs":[],"name":"testDynamicFixedBytes15","outputs":[{"name":"","type":"bytes15[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"testDynamicFixedBytes32","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"}]`))
if err != nil {
t.Fatal(err)
@@ -321,6 +324,7 @@ func methodMultiReturn(require *require.Assertions) (ABI, []byte, methodMultiOut
}
func TestMethodMultiReturn(t *testing.T) {
t.Parallel()
type reversed struct {
String string
Int *big.Int
@@ -400,6 +404,7 @@ func TestMethodMultiReturn(t *testing.T) {
}
func TestMultiReturnWithArray(t *testing.T) {
t.Parallel()
const definition = `[{"name" : "multi", "type": "function", "outputs": [{"type": "uint64[3]"}, {"type": "uint64"}]}]`
abi, err := JSON(strings.NewReader(definition))
if err != nil {
@@ -423,6 +428,7 @@ func TestMultiReturnWithArray(t *testing.T) {
}
func TestMultiReturnWithStringArray(t *testing.T) {
t.Parallel()
const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]`
abi, err := JSON(strings.NewReader(definition))
if err != nil {
@@ -453,6 +459,7 @@ func TestMultiReturnWithStringArray(t *testing.T) {
}
func TestMultiReturnWithStringSlice(t *testing.T) {
t.Parallel()
const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]`
abi, err := JSON(strings.NewReader(definition))
if err != nil {
@@ -485,6 +492,7 @@ func TestMultiReturnWithStringSlice(t *testing.T) {
}
func TestMultiReturnWithDeeplyNestedArray(t *testing.T) {
t.Parallel()
// Similar to TestMultiReturnWithArray, but with a special case in mind:
// values of nested static arrays count towards the size as well, and any element following
// after such nested array argument should be read with the correct offset,
@@ -525,6 +533,7 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) {
}
func TestUnmarshal(t *testing.T) {
t.Parallel()
const definition = `[
{ "name" : "int", "type": "function", "outputs": [ { "type": "uint256" } ] },
{ "name" : "bool", "type": "function", "outputs": [ { "type": "bool" } ] },
@@ -774,6 +783,7 @@ func TestUnmarshal(t *testing.T) {
}
func TestUnpackTuple(t *testing.T) {
t.Parallel()
const simpleTuple = `[{"name":"tuple","type":"function","outputs":[{"type":"tuple","name":"ret","components":[{"type":"int256","name":"a"},{"type":"int256","name":"b"}]}]}]`
abi, err := JSON(strings.NewReader(simpleTuple))
if err != nil {
@@ -876,6 +886,7 @@ func TestUnpackTuple(t *testing.T) {
}
func TestOOMMaliciousInput(t *testing.T) {
t.Parallel()
oomTests := []unpackTest{
{
def: `[{"type": "uint8[]"}]`,
@@ -946,6 +957,7 @@ func TestOOMMaliciousInput(t *testing.T) {
}
func TestPackAndUnpackIncompatibleNumber(t *testing.T) {
t.Parallel()
var encodeABI Arguments
uint256Ty, err := NewType("uint256", "", nil)
if err != nil {

View File

@@ -195,7 +195,7 @@ func TextHash(data []byte) []byte {
//
// This gives context to the signed message and prevents signing of transactions.
func TextAndHash(data []byte) ([]byte, string) {
msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), string(data))
msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
hasher := sha3.NewLegacyKeccak256()
hasher.Write([]byte(msg))
return hasher.Sum(nil), msg

View File

@@ -24,6 +24,7 @@ import (
)
func TestTextHash(t *testing.T) {
t.Parallel()
hash := TextHash([]byte("Hello Joe"))
want := hexutil.MustDecode("0xa080337ae51c4e064c189e113edd0ba391df9206e2f49db658bb32cf2911730b")
if !bytes.Equal(hash, want) {

View File

@@ -17,6 +17,7 @@
package external
import (
"errors"
"fmt"
"math/big"
"sync"
@@ -98,11 +99,11 @@ func (api *ExternalSigner) Status() (string, error) {
}
func (api *ExternalSigner) Open(passphrase string) error {
return fmt.Errorf("operation not supported on external signers")
return errors.New("operation not supported on external signers")
}
func (api *ExternalSigner) Close() error {
return fmt.Errorf("operation not supported on external signers")
return errors.New("operation not supported on external signers")
}
func (api *ExternalSigner) Accounts() []accounts.Account {
@@ -145,7 +146,7 @@ func (api *ExternalSigner) Contains(account accounts.Account) bool {
}
func (api *ExternalSigner) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) {
return accounts.Account{}, fmt.Errorf("operation not supported on external signers")
return accounts.Account{}, errors.New("operation not supported on external signers")
}
func (api *ExternalSigner) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) {
@@ -204,7 +205,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
to = &t
}
args := &apitypes.SendTxArgs{
Data: &data,
Input: &data,
Nonce: hexutil.Uint64(tx.Nonce()),
Value: hexutil.Big(*tx.Value()),
Gas: hexutil.Uint64(tx.Gas()),
@@ -214,7 +215,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
switch tx.Type() {
case types.LegacyTxType, types.AccessListTxType:
args.GasPrice = (*hexutil.Big)(tx.GasPrice())
case types.DynamicFeeTxType:
case types.DynamicFeeTxType, types.BlobTxType:
args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap())
args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap())
default:
@@ -234,6 +235,17 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
accessList := tx.AccessList()
args.AccessList = &accessList
}
if tx.Type() == types.BlobTxType {
args.BlobHashes = tx.BlobHashes()
sidecar := tx.BlobTxSidecar()
if sidecar == nil {
return nil, errors.New("blobs must be present for signing")
}
args.Blobs = sidecar.Blobs
args.Commitments = sidecar.Commitments
args.Proofs = sidecar.Proofs
}
var res signTransactionResult
if err := api.client.Call(&res, "account_signTransaction", args); err != nil {
return nil, err
@@ -242,14 +254,14 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
}
func (api *ExternalSigner) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) {
return []byte{}, fmt.Errorf("password-operations not supported on external signers")
return []byte{}, errors.New("password-operations not supported on external signers")
}
func (api *ExternalSigner) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
return nil, fmt.Errorf("password-operations not supported on external signers")
return nil, errors.New("password-operations not supported on external signers")
}
func (api *ExternalSigner) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) {
return nil, fmt.Errorf("password-operations not supported on external signers")
return nil, errors.New("password-operations not supported on external signers")
}
func (api *ExternalSigner) listAccounts() ([]common.Address, error) {

View File

@@ -25,6 +25,7 @@ import (
// Tests that HD derivation paths can be correctly parsed into our internal binary
// representation.
func TestHDPathParsing(t *testing.T) {
t.Parallel()
tests := []struct {
input string
output DerivationPath
@@ -89,6 +90,7 @@ func testDerive(t *testing.T, next func() DerivationPath, expected []string) {
}
func TestHdPathIteration(t *testing.T) {
t.Parallel()
testDerive(t, DefaultIterator(DefaultBaseDerivationPath),
[]string{
"m/44'/60'/0'/0/0", "m/44'/60'/0'/0/1",

View File

@@ -22,6 +22,7 @@ import (
"fmt"
"os"
"path/filepath"
"slices"
"sort"
"strings"
"sync"
@@ -38,11 +39,10 @@ import (
// exist yet, the code will attempt to create a watcher at most this often.
const minReloadInterval = 2 * time.Second
type accountsByURL []accounts.Account
func (s accountsByURL) Len() int { return len(s) }
func (s accountsByURL) Less(i, j int) bool { return s[i].URL.Cmp(s[j].URL) < 0 }
func (s accountsByURL) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// byURL defines the sorting order for accounts.
func byURL(a, b accounts.Account) int {
return a.URL.Cmp(b.URL)
}
// AmbiguousAddrError is returned when attempting to unlock
// an address for which more than one file exists.
@@ -67,7 +67,7 @@ type accountCache struct {
keydir string
watcher *watcher
mu sync.Mutex
all accountsByURL
all []accounts.Account
byAddr map[common.Address][]accounts.Account
throttle *time.Timer
notify chan struct{}
@@ -194,7 +194,7 @@ func (ac *accountCache) find(a accounts.Account) (accounts.Account, error) {
default:
err := &AmbiguousAddrError{Addr: a.Address, Matches: make([]accounts.Account, len(matches))}
copy(err.Matches, matches)
sort.Sort(accountsByURL(err.Matches))
slices.SortFunc(err.Matches, byURL)
return accounts.Account{}, err
}
}

View File

@@ -17,12 +17,13 @@
package keystore
import (
"errors"
"fmt"
"math/rand"
"os"
"path/filepath"
"reflect"
"sort"
"slices"
"testing"
"time"
@@ -50,7 +51,7 @@ var (
}
)
// waitWatcherStarts waits up to 1s for the keystore watcher to start.
// waitWatcherStart waits up to 1s for the keystore watcher to start.
func waitWatcherStart(ks *KeyStore) bool {
// On systems where file watch is not supported, just return "ok".
if !ks.cache.watcher.enabled() {
@@ -67,14 +68,14 @@ func waitWatcherStart(ks *KeyStore) bool {
func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error {
var list []accounts.Account
for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(200 * time.Millisecond) {
for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(100 * time.Millisecond) {
list = ks.Accounts()
if reflect.DeepEqual(list, wantAccounts) {
// ks should have also received change notifications
select {
case <-ks.changes:
default:
return fmt.Errorf("wasn't notified of new accounts")
return errors.New("wasn't notified of new accounts")
}
return nil
}
@@ -85,7 +86,7 @@ func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error {
func TestWatchNewFile(t *testing.T) {
t.Parallel()
dir, ks := tmpKeyStore(t, false)
dir, ks := tmpKeyStore(t)
// Ensure the watcher is started before adding any files.
ks.Accounts()
@@ -113,7 +114,7 @@ func TestWatchNewFile(t *testing.T) {
func TestWatchNoDir(t *testing.T) {
t.Parallel()
// Create ks but not the directory that it watches.
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int()))
dir := filepath.Join(t.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int()))
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
list := ks.Accounts()
if len(list) > 0 {
@@ -125,7 +126,6 @@ func TestWatchNoDir(t *testing.T) {
}
// Create the directory and copy a key file into it.
os.MkdirAll(dir, 0700)
defer os.RemoveAll(dir)
file := filepath.Join(dir, "aaa")
if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil {
t.Fatal(err)
@@ -151,6 +151,7 @@ func TestWatchNoDir(t *testing.T) {
}
func TestCacheInitialReload(t *testing.T) {
t.Parallel()
cache, _ := newAccountCache(cachetestDir)
accounts := cache.accounts()
if !reflect.DeepEqual(accounts, cachetestAccounts) {
@@ -159,6 +160,7 @@ func TestCacheInitialReload(t *testing.T) {
}
func TestCacheAddDeleteOrder(t *testing.T) {
t.Parallel()
cache, _ := newAccountCache("testdata/no-such-dir")
cache.watcher.running = true // prevent unexpected reloads
@@ -202,7 +204,7 @@ func TestCacheAddDeleteOrder(t *testing.T) {
// Check that the account list is sorted by filename.
wantAccounts := make([]accounts.Account, len(accs))
copy(wantAccounts, accs)
sort.Sort(accountsByURL(wantAccounts))
slices.SortFunc(wantAccounts, byURL)
list := cache.accounts()
if !reflect.DeepEqual(list, wantAccounts) {
t.Fatalf("got accounts: %s\nwant %s", spew.Sdump(accs), spew.Sdump(wantAccounts))
@@ -243,6 +245,7 @@ func TestCacheAddDeleteOrder(t *testing.T) {
}
func TestCacheFind(t *testing.T) {
t.Parallel()
dir := filepath.Join("testdata", "dir")
cache, _ := newAccountCache(dir)
cache.watcher.running = true // prevent unexpected reloads
@@ -321,7 +324,8 @@ func TestUpdatedKeyfileContents(t *testing.T) {
t.Parallel()
// Create a temporary keystore to test with
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int()))
dir := t.TempDir()
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
list := ks.Accounts()
@@ -331,9 +335,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
if !waitWatcherStart(ks) {
t.Fatal("keystore watcher didn't start in time")
}
// Create the directory and copy a key file into it.
os.MkdirAll(dir, 0700)
defer os.RemoveAll(dir)
// Copy a key file into it
file := filepath.Join(dir, "aaa")
// Place one of our testfiles in there
@@ -349,7 +351,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
return
}
// needed so that modTime of `file` is different to its current value after forceCopyFile
time.Sleep(time.Second)
os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
// Now replace file contents
if err := forceCopyFile(file, cachetestAccounts[1].URL.Path); err != nil {
@@ -365,7 +367,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
}
// needed so that modTime of `file` is different to its current value after forceCopyFile
time.Sleep(time.Second)
os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
// Now replace file contents again
if err := forceCopyFile(file, cachetestAccounts[2].URL.Path); err != nil {
@@ -381,7 +383,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
}
// needed so that modTime of `file` is different to its current value after os.WriteFile
time.Sleep(time.Second)
os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second))
// Now replace file contents with crap
if err := os.WriteFile(file, []byte("foo"), 0600); err != nil {

View File

@@ -87,15 +87,6 @@ func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
return ks
}
// NewPlaintextKeyStore creates a keystore for the given directory.
// Deprecated: Use NewKeyStore.
func NewPlaintextKeyStore(keydir string) *KeyStore {
keydir, _ = filepath.Abs(keydir)
ks := &KeyStore{storage: &keyStorePlain{keydir}}
ks.init(keydir)
return ks
}
func (ks *KeyStore) init(keydir string) {
// Lock the mutex since the account cache might call back with events
ks.mu.Lock()
@@ -321,11 +312,10 @@ func (ks *KeyStore) Unlock(a accounts.Account, passphrase string) error {
// Lock removes the private key with the given address from memory.
func (ks *KeyStore) Lock(addr common.Address) error {
ks.mu.Lock()
if unl, found := ks.unlocked[addr]; found {
ks.mu.Unlock()
unl, found := ks.unlocked[addr]
ks.mu.Unlock()
if found {
ks.expire(addr, unl, time.Duration(0)*time.Nanosecond)
} else {
ks.mu.Unlock()
}
return nil
}
@@ -509,7 +499,5 @@ func (ks *KeyStore) isUpdating() bool {
// zeroKey zeroes a private key in memory.
func zeroKey(k *ecdsa.PrivateKey) {
b := k.D.Bits()
for i := range b {
b[i] = 0
}
clear(b)
}

View File

@@ -0,0 +1,34 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package keystore
import (
"testing"
)
func FuzzPassword(f *testing.F) {
f.Fuzz(func(t *testing.T, password string) {
ks := NewKeyStore(t.TempDir(), LightScryptN, LightScryptP)
a, err := ks.NewAccount(password)
if err != nil {
t.Fatal(err)
}
if err := ks.Unlock(a, password); err != nil {
t.Fatal(err)
}
})
}

View File

@@ -20,7 +20,7 @@ import (
"math/rand"
"os"
"runtime"
"sort"
"slices"
"strings"
"sync"
"sync/atomic"
@@ -36,7 +36,8 @@ import (
var testSigData = make([]byte, 32)
func TestKeyStore(t *testing.T) {
dir, ks := tmpKeyStore(t, true)
t.Parallel()
dir, ks := tmpKeyStore(t)
a, err := ks.NewAccount("foo")
if err != nil {
@@ -70,7 +71,8 @@ func TestKeyStore(t *testing.T) {
}
func TestSign(t *testing.T) {
_, ks := tmpKeyStore(t, true)
t.Parallel()
_, ks := tmpKeyStore(t)
pass := "" // not used but required by API
a1, err := ks.NewAccount(pass)
@@ -86,7 +88,8 @@ func TestSign(t *testing.T) {
}
func TestSignWithPassphrase(t *testing.T) {
_, ks := tmpKeyStore(t, true)
t.Parallel()
_, ks := tmpKeyStore(t)
pass := "passwd"
acc, err := ks.NewAccount(pass)
@@ -114,7 +117,7 @@ func TestSignWithPassphrase(t *testing.T) {
func TestTimedUnlock(t *testing.T) {
t.Parallel()
_, ks := tmpKeyStore(t, true)
_, ks := tmpKeyStore(t)
pass := "foo"
a1, err := ks.NewAccount(pass)
@@ -149,7 +152,7 @@ func TestTimedUnlock(t *testing.T) {
func TestOverrideUnlock(t *testing.T) {
t.Parallel()
_, ks := tmpKeyStore(t, false)
_, ks := tmpKeyStore(t)
pass := "foo"
a1, err := ks.NewAccount(pass)
@@ -190,7 +193,7 @@ func TestOverrideUnlock(t *testing.T) {
// This test should fail under -race if signing races the expiration goroutine.
func TestSignRace(t *testing.T) {
t.Parallel()
_, ks := tmpKeyStore(t, false)
_, ks := tmpKeyStore(t)
// Create a test account.
a1, err := ks.NewAccount("")
@@ -235,7 +238,7 @@ func waitForKsUpdating(t *testing.T, ks *KeyStore, wantStatus bool, maxTime time
func TestWalletNotifierLifecycle(t *testing.T) {
t.Parallel()
// Create a temporary keystore to test with
_, ks := tmpKeyStore(t, false)
_, ks := tmpKeyStore(t)
// Ensure that the notification updater is not running yet
time.Sleep(250 * time.Millisecond)
@@ -280,7 +283,8 @@ type walletEvent struct {
// Tests that wallet notifications and correctly fired when accounts are added
// or deleted from the keystore.
func TestWalletNotifications(t *testing.T) {
_, ks := tmpKeyStore(t, false)
t.Parallel()
_, ks := tmpKeyStore(t)
// Subscribe to the wallet feed and collect events.
var (
@@ -339,9 +343,10 @@ func TestWalletNotifications(t *testing.T) {
checkEvents(t, wantEvents, events)
}
// TestImportExport tests the import functionality of a keystore.
// TestImportECDSA tests the import functionality of a keystore.
func TestImportECDSA(t *testing.T) {
_, ks := tmpKeyStore(t, true)
t.Parallel()
_, ks := tmpKeyStore(t)
key, err := crypto.GenerateKey()
if err != nil {
t.Fatalf("failed to generate key: %v", key)
@@ -357,9 +362,10 @@ func TestImportECDSA(t *testing.T) {
}
}
// TestImportECDSA tests the import and export functionality of a keystore.
// TestImportExport tests the import and export functionality of a keystore.
func TestImportExport(t *testing.T) {
_, ks := tmpKeyStore(t, true)
t.Parallel()
_, ks := tmpKeyStore(t)
acc, err := ks.NewAccount("old")
if err != nil {
t.Fatalf("failed to create account: %v", acc)
@@ -368,7 +374,7 @@ func TestImportExport(t *testing.T) {
if err != nil {
t.Fatalf("failed to export account: %v", acc)
}
_, ks2 := tmpKeyStore(t, true)
_, ks2 := tmpKeyStore(t)
if _, err = ks2.Import(json, "old", "old"); err == nil {
t.Errorf("importing with invalid password succeeded")
}
@@ -387,7 +393,8 @@ func TestImportExport(t *testing.T) {
// TestImportRace tests the keystore on races.
// This test should fail under -race if importing races.
func TestImportRace(t *testing.T) {
_, ks := tmpKeyStore(t, true)
t.Parallel()
_, ks := tmpKeyStore(t)
acc, err := ks.NewAccount("old")
if err != nil {
t.Fatalf("failed to create account: %v", acc)
@@ -396,20 +403,20 @@ func TestImportRace(t *testing.T) {
if err != nil {
t.Fatalf("failed to export account: %v", acc)
}
_, ks2 := tmpKeyStore(t, true)
var atom uint32
_, ks2 := tmpKeyStore(t)
var atom atomic.Uint32
var wg sync.WaitGroup
wg.Add(2)
for i := 0; i < 2; i++ {
go func() {
defer wg.Done()
if _, err := ks2.Import(json, "new", "new"); err != nil {
atomic.AddUint32(&atom, 1)
atom.Add(1)
}
}()
}
wg.Wait()
if atom != 1 {
if atom.Load() != 1 {
t.Errorf("Import is racy")
}
}
@@ -424,7 +431,7 @@ func checkAccounts(t *testing.T, live map[common.Address]accounts.Account, walle
for _, account := range live {
liveList = append(liveList, account)
}
sort.Sort(accountsByURL(liveList))
slices.SortFunc(liveList, byURL)
for j, wallet := range wallets {
if accs := wallet.Accounts(); len(accs) != 1 {
t.Errorf("wallet %d: contains invalid number of accounts: have %d, want 1", j, len(accs))
@@ -450,11 +457,7 @@ func checkEvents(t *testing.T, want []walletEvent, have []walletEvent) {
}
}
func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) {
func tmpKeyStore(t *testing.T) (string, *KeyStore) {
d := t.TempDir()
newKs := NewPlaintextKeyStore
if encrypted {
newKs = func(kd string) *KeyStore { return NewKeyStore(kd, veryLightScryptN, veryLightScryptP) }
}
return d, newKs(d)
return d, NewKeyStore(d, veryLightScryptN, veryLightScryptP)
}

View File

@@ -136,7 +136,7 @@ func (ks keyStorePassphrase) JoinPath(filename string) string {
return filepath.Join(ks.keysDirPath, filename)
}
// Encryptdata encrypts the data given as 'data' with the password 'auth'.
// EncryptDataV3 encrypts the data given as 'data' with the password 'auth'.
func EncryptDataV3(data, auth []byte, scryptN, scryptP int) (CryptoJSON, error) {
salt := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, salt); err != nil {
@@ -225,10 +225,13 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) {
if err != nil {
return nil, err
}
key := crypto.ToECDSAUnsafe(keyBytes)
key, err := crypto.ToECDSA(keyBytes)
if err != nil {
return nil, fmt.Errorf("invalid key: %w", err)
}
id, err := uuid.FromBytes(keyId)
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid UUID: %w", err)
}
return &Key{
Id: id,

View File

@@ -30,6 +30,7 @@ const (
// Tests that a json key file can be decrypted and encrypted in multiple rounds.
func TestKeyEncryptDecrypt(t *testing.T) {
t.Parallel()
keyjson, err := os.ReadFile("testdata/very-light-scrypt.json")
if err != nil {
t.Fatal(err)
@@ -54,7 +55,7 @@ func TestKeyEncryptDecrypt(t *testing.T) {
// Recrypt with a new password and start over
password += "new data appended" // nolint: gosec
if keyjson, err = EncryptKey(key, password, veryLightScryptN, veryLightScryptP); err != nil {
t.Errorf("test %d: failed to recrypt key %v", i, err)
t.Errorf("test %d: failed to re-encrypt key %v", i, err)
}
}
}

View File

@@ -40,6 +40,7 @@ func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) {
}
func TestKeyStorePlain(t *testing.T) {
t.Parallel()
_, ks := tmpKeyStoreIface(t, false)
pass := "" // not used but required by API
@@ -60,6 +61,7 @@ func TestKeyStorePlain(t *testing.T) {
}
func TestKeyStorePassphrase(t *testing.T) {
t.Parallel()
_, ks := tmpKeyStoreIface(t, true)
pass := "foo"
@@ -80,6 +82,7 @@ func TestKeyStorePassphrase(t *testing.T) {
}
func TestKeyStorePassphraseDecryptionFail(t *testing.T) {
t.Parallel()
_, ks := tmpKeyStoreIface(t, true)
pass := "foo"
@@ -93,6 +96,7 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) {
}
func TestImportPreSaleKey(t *testing.T) {
t.Parallel()
dir, ks := tmpKeyStoreIface(t, true)
// file content of a presale key file generated with:

View File

@@ -20,6 +20,7 @@
package keystore
import (
"os"
"time"
"github.com/ethereum/go-ethereum/log"
@@ -77,7 +78,9 @@ func (w *watcher) loop() {
}
defer watcher.Close()
if err := watcher.Add(w.ac.keydir); err != nil {
logger.Warn("Failed to watch keystore folder", "err", err)
if !os.IsNotExist(err) {
logger.Warn("Failed to watch keystore folder", "err", err)
}
return
}
@@ -122,7 +125,7 @@ func (w *watcher) loop() {
if !ok {
return
}
log.Info("Filsystem watcher error", "err", err)
log.Info("Filesystem watcher error", "err", err)
case <-debounce.C:
w.ac.scanAccounts()
rescanTriggered = false

View File

@@ -98,6 +98,9 @@ func NewManager(config *Config, backends ...Backend) *Manager {
// Close terminates the account manager's internal notification processes.
func (am *Manager) Close() error {
for _, w := range am.wallets {
w.Close()
}
errc := make(chan error)
am.quit <- errc
return <-errc

View File

@@ -8,7 +8,7 @@
## Preparing the smartcard
**WARNING: FOILLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS**
**WARNING: FOLLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS**
You can use status' [keycard-cli](https://github.com/status-im/keycard-cli) and you should get _at least_ version 2.1.1 of their [smartcard application](https://github.com/status-im/status-keycard/releases/download/2.2.1/keycard_v2.2.1.cap)

View File

@@ -95,6 +95,7 @@ func (hub *Hub) readPairings() error {
}
return err
}
defer pairingFile.Close()
pairingData, err := io.ReadAll(pairingFile)
if err != nil {
@@ -241,7 +242,7 @@ func (hub *Hub) refreshWallets() {
card.Disconnect(pcsc.LeaveCard)
continue
}
// Card connected, start tracking in amongs the wallets
// Card connected, start tracking among the wallets
hub.wallets[reader] = wallet
events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived})
}

View File

@@ -20,10 +20,10 @@ import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
@@ -71,11 +71,11 @@ func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSes
if err != nil {
return nil, fmt.Errorf("could not unmarshal public key from card: %v", err)
}
secret, _ := key.Curve.ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes())
secret, _ := crypto.S256().ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes())
return &SecureChannelSession{
card: card,
secret: secret.Bytes(),
publicKey: elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y),
publicKey: crypto.FromECDSAPub(&key.PublicKey),
}, nil
}
@@ -125,7 +125,7 @@ func (s *SecureChannelSession) Pair(pairingPassword []byte) error {
// Unpair disestablishes an existing pairing.
func (s *SecureChannelSession) Unpair() error {
if s.PairingKey == nil {
return fmt.Errorf("cannot unpair: not paired")
return errors.New("cannot unpair: not paired")
}
_, err := s.transmitEncrypted(claSCWallet, insUnpair, s.PairingIndex, 0, []byte{})
@@ -141,7 +141,7 @@ func (s *SecureChannelSession) Unpair() error {
// Open initializes the secure channel.
func (s *SecureChannelSession) Open() error {
if s.iv != nil {
return fmt.Errorf("session already opened")
return errors.New("session already opened")
}
response, err := s.open()
@@ -215,7 +215,7 @@ func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*responseAPDU, error
// transmitEncrypted sends an encrypted message, and decrypts and returns the response.
func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []byte) (*responseAPDU, error) {
if s.iv == nil {
return nil, fmt.Errorf("channel not open")
return nil, errors.New("channel not open")
}
data, err := s.encryptAPDU(data)
@@ -254,7 +254,7 @@ func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []b
return nil, err
}
if !bytes.Equal(s.iv, rmac) {
return nil, fmt.Errorf("invalid MAC in response")
return nil, errors.New("invalid MAC in response")
}
rapdu := &responseAPDU{}
@@ -319,7 +319,7 @@ func unpad(data []byte, terminator byte) ([]byte, error) {
return nil, fmt.Errorf("expected end of padding, got %d", data[len(data)-i])
}
}
return nil, fmt.Errorf("expected end of padding, got 0")
return nil, errors.New("expected end of padding, got 0")
}
// updateIV is an internal method that updates the initialization vector after

View File

@@ -73,6 +73,14 @@ var (
DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes())
)
var (
// PinRegexp is the regular expression used to validate PIN codes.
pinRegexp = regexp.MustCompile(`^[0-9]{6,}$`)
// PukRegexp is the regular expression used to validate PUK codes.
pukRegexp = regexp.MustCompile(`^[0-9]{12,}$`)
)
// List of APDU command-related constants
const (
claISO7816 = 0
@@ -252,7 +260,7 @@ func (w *Wallet) release() error {
// with the wallet.
func (w *Wallet) pair(puk []byte) error {
if w.session.paired() {
return fmt.Errorf("wallet already paired")
return errors.New("wallet already paired")
}
pairing, err := w.session.pair(puk)
if err != nil {
@@ -380,7 +388,7 @@ func (w *Wallet) Open(passphrase string) error {
case passphrase == "":
return ErrPINUnblockNeeded
case status.PinRetryCount > 0:
if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) {
if !pinRegexp.MatchString(passphrase) {
w.log.Error("PIN needs to be at least 6 digits")
return ErrPINNeeded
}
@@ -388,7 +396,7 @@ func (w *Wallet) Open(passphrase string) error {
return err
}
default:
if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) {
if !pukRegexp.MatchString(passphrase) {
w.log.Error("PUK needs to be at least 12 digits")
return ErrPINUnblockNeeded
}
@@ -776,16 +784,16 @@ func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationP
return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme)
}
parts := strings.SplitN(account.URL.Path, "/", 2)
if len(parts) != 2 {
url, path, found := strings.Cut(account.URL.Path, "/")
if !found {
return nil, fmt.Errorf("invalid URL format: %s", account.URL)
}
if parts[0] != fmt.Sprintf("%x", w.PublicKey[1:3]) {
if url != fmt.Sprintf("%x", w.PublicKey[1:3]) {
return nil, fmt.Errorf("URL %s is not for this wallet", account.URL)
}
return accounts.ParseDerivationPath(parts[1])
return accounts.ParseDerivationPath(path)
}
// Session represents a secured communication session with the wallet.
@@ -813,7 +821,7 @@ func (s *Session) pair(secret []byte) (smartcardPairing, error) {
// unpair deletes an existing pairing.
func (s *Session) unpair() error {
if !s.verified {
return fmt.Errorf("unpair requires that the PIN be verified")
return errors.New("unpair requires that the PIN be verified")
}
return s.Channel.Unpair()
}
@@ -907,7 +915,7 @@ func (s *Session) initialize(seed []byte) error {
return err
}
if status == "Online" {
return fmt.Errorf("card is already initialized, cowardly refusing to proceed")
return errors.New("card is already initialized, cowardly refusing to proceed")
}
s.Wallet.lock.Lock()

View File

@@ -21,6 +21,7 @@ import (
)
func TestURLParsing(t *testing.T) {
t.Parallel()
url, err := parseURL("https://ethereum.org")
if err != nil {
t.Errorf("unexpected error: %v", err)
@@ -40,6 +41,7 @@ func TestURLParsing(t *testing.T) {
}
func TestURLString(t *testing.T) {
t.Parallel()
url := URL{Scheme: "https", Path: "ethereum.org"}
if url.String() != "https://ethereum.org" {
t.Errorf("expected: %v, got: %v", "https://ethereum.org", url.String())
@@ -52,10 +54,11 @@ func TestURLString(t *testing.T) {
}
func TestURLMarshalJSON(t *testing.T) {
t.Parallel()
url := URL{Scheme: "https", Path: "ethereum.org"}
json, err := url.MarshalJSON()
if err != nil {
t.Errorf("unexpcted error: %v", err)
t.Errorf("unexpected error: %v", err)
}
if string(json) != "\"https://ethereum.org\"" {
t.Errorf("expected: %v, got: %v", "\"https://ethereum.org\"", string(json))
@@ -63,10 +66,11 @@ func TestURLMarshalJSON(t *testing.T) {
}
func TestURLUnmarshalJSON(t *testing.T) {
t.Parallel()
url := &URL{}
err := url.UnmarshalJSON([]byte("\"https://ethereum.org\""))
if err != nil {
t.Errorf("unexpcted error: %v", err)
t.Errorf("unexpected error: %v", err)
}
if url.Scheme != "https" {
t.Errorf("expected: %v, got: %v", "https", url.Scheme)
@@ -77,6 +81,7 @@ func TestURLUnmarshalJSON(t *testing.T) {
}
func TestURLComparison(t *testing.T) {
t.Parallel()
tests := []struct {
urlA URL
urlB URL

View File

@@ -26,7 +26,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/karalabe/usb"
"github.com/karalabe/hid"
)
// LedgerScheme is the protocol scheme prefixing account and wallet URLs.
@@ -63,9 +63,9 @@ type Hub struct {
stateLock sync.RWMutex // Protects the internals of the hub from racey access
// TODO(karalabe): remove if hotplug lands on Windows
commsPend int // Number of operations blocking enumeration
commsLock sync.Mutex // Lock protecting the pending counter and enumeration
enumFails uint32 // Number of times enumeration has failed
commsPend int // Number of operations blocking enumeration
commsLock sync.Mutex // Lock protecting the pending counter and enumeration
enumFails atomic.Uint32 // Number of times enumeration has failed
}
// NewLedgerHub creates a new hardware wallet manager for Ledger devices.
@@ -109,7 +109,7 @@ func NewTrezorHubWithWebUSB() (*Hub, error) {
// newHub creates a new hardware wallet manager for generic USB devices.
func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) {
if !usb.Supported() {
if !hid.Supported() {
return nil, errors.New("unsupported platform")
}
hub := &Hub{
@@ -151,11 +151,11 @@ func (hub *Hub) refreshWallets() {
return
}
// If USB enumeration is continually failing, don't keep trying indefinitely
if atomic.LoadUint32(&hub.enumFails) > 2 {
if hub.enumFails.Load() > 2 {
return
}
// Retrieve the current list of USB wallet devices
var devices []usb.DeviceInfo
var devices []hid.DeviceInfo
if runtime.GOOS == "linux" {
// hidapi on Linux opens the device during enumeration to retrieve some infos,
@@ -170,9 +170,9 @@ func (hub *Hub) refreshWallets() {
return
}
}
infos, err := usb.Enumerate(hub.vendorID, 0)
infos, err := hid.Enumerate(hub.vendorID, 0)
if err != nil {
failcount := atomic.AddUint32(&hub.enumFails, 1)
failcount := hub.enumFails.Add(1)
if runtime.GOOS == "linux" {
// See rationale before the enumeration why this is needed and only on Linux.
hub.commsLock.Unlock()
@@ -181,7 +181,7 @@ func (hub *Hub) refreshWallets() {
"vendor", hub.vendorID, "failcount", failcount, "err", err)
return
}
atomic.StoreUint32(&hub.enumFails, 0)
hub.enumFails.Store(0)
for _, info := range infos {
for _, id := range hub.productIDs {

View File

@@ -16,7 +16,7 @@
// This file contains the implementation for interacting with the Ledger hardware
// wallets. The wire protocol spec can be found in the Ledger Blue GitHub repo:
// https://raw.githubusercontent.com/LedgerHQ/blue-app-eth/master/doc/ethapp.asc
// https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc
package usbwallet
@@ -59,6 +59,8 @@ const (
ledgerP1InitTransactionData ledgerParam1 = 0x00 // First transaction data block for signing
ledgerP1ContTransactionData ledgerParam1 = 0x80 // Subsequent transaction data block for signing
ledgerP2DiscardAddressChainCode ledgerParam2 = 0x00 // Do not return the chain code along with the address
ledgerEip155Size int = 3 // Size of the EIP-155 chain_id,r,s in unsigned transactions
)
// errLedgerReplyInvalidHeader is the error message returned by a Ledger data exchange
@@ -277,7 +279,7 @@ func (w *ledgerDriver) ledgerDerive(derivationPath []uint32) (common.Address, er
}
hexstr := reply[1 : 1+int(reply[0])]
// Decode the hex sting into an Ethereum address and return
// Decode the hex string into an Ethereum address and return
var address common.Address
if _, err = hex.Decode(address[:], hexstr); err != nil {
return common.Address{}, err
@@ -347,9 +349,15 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
op = ledgerP1InitTransactionData
reply []byte
)
// Chunk size selection to mitigate an underlying RLP deserialization issue on the ledger app.
// https://github.com/LedgerHQ/app-ethereum/issues/409
chunk := 255
for ; len(payload)%chunk <= ledgerEip155Size; chunk-- {
}
for len(payload) > 0 {
// Calculate the size of the next data chunk
chunk := 255
if chunk > len(payload) {
chunk = len(payload)
}

View File

@@ -33,7 +33,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/golang/protobuf/proto"
"google.golang.org/protobuf/proto"
)
// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,8 @@
syntax = "proto2";
package hw.trezor.messages.common;
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
/**
* Response: Success of the previous request
* @end

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,8 @@
syntax = "proto2";
package hw.trezor.messages.ethereum;
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
// Sugar for easier handling in Java
option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageEthereum";

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,8 @@
syntax = "proto2";
package hw.trezor.messages.management;
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
// Sugar for easier handling in Java
option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageManagement";

File diff suppressed because it is too large Load Diff

View File

@@ -9,10 +9,13 @@ package hw.trezor.messages;
* Messages for TREZOR communication
*/
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
// Sugar for easier handling in Java
option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessage";
import "google/protobuf/descriptor.proto";
/**

View File

@@ -16,7 +16,7 @@
// This file contains the implementation for interacting with the Trezor hardware
// wallets. The wire protocol spec can be found on the SatoshiLabs website:
// https://wiki.trezor.io/Developers_guide-Message_Workflows
// https://docs.trezor.io/trezor-firmware/common/message-workflows.html
// !!! STAHP !!!
//
@@ -39,10 +39,10 @@
// - Download the latest protoc https://github.com/protocolbuffers/protobuf/releases
// - Build with the usual `./configure && make` and ensure it's on your $PATH
// - Delete all the .proto and .pb.go files, pull in fresh ones from Trezor
// - Grab the latest Go plugin `go get -u github.com/golang/protobuf/protoc-gen-go`
// - Vendor in the latest Go plugin `govendor fetch github.com/golang/protobuf/...`
// - Grab the latest Go plugin `go get -u google.golang.org/protobuf/cmd/protoc-gen-go`
// - Vendor in the latest Go plugin `govendor fetch google.golang.org/protobuf/...`
//go:generate protoc -I/usr/local/include:. --go_out=import_path=trezor:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto
//go:generate protoc -I/usr/local/include:. --go_out=paths=source_relative:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto
// Package trezor contains the wire protocol.
package trezor
@@ -50,7 +50,7 @@ package trezor
import (
"reflect"
"github.com/golang/protobuf/proto"
"google.golang.org/protobuf/proto"
)
// Type returns the protocol buffer type number of a specific message. If the

View File

@@ -31,7 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/karalabe/usb"
"github.com/karalabe/hid"
)
// Maximum time between wallet health checks to detect USB unplugs.
@@ -79,8 +79,8 @@ type wallet struct {
driver driver // Hardware implementation of the low level device operations
url *accounts.URL // Textual URL uniquely identifying this wallet
info usb.DeviceInfo // Known USB device infos about the wallet
device usb.Device // USB device advertising itself as a hardware wallet
info hid.DeviceInfo // Known USB device infos about the wallet
device hid.Device // USB device advertising itself as a hardware wallet
accounts []accounts.Account // List of derive accounts pinned on the hardware wallet
paths map[common.Address]accounts.DerivationPath // Known derivation paths for signing operations
@@ -483,6 +483,10 @@ func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun
w.stateLock.Lock()
defer w.stateLock.Unlock()
if w.device == nil {
return accounts.Account{}, accounts.ErrWalletClosed
}
if _, ok := w.paths[address]; !ok {
w.accounts = append(w.accounts, account)
w.paths[address] = make(accounts.DerivationPath, len(path))
@@ -624,7 +628,7 @@ func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID
return signed, nil
}
// SignHashWithPassphrase implements accounts.Wallet, however signing arbitrary
// SignTextWithPassphrase implements accounts.Wallet, however signing arbitrary
// data is not supported for Ledger wallets, so this method will always return
// an error.
func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) {

View File

@@ -24,9 +24,10 @@ for:
- image: Ubuntu
build_script:
- go run build/ci.go lint
- go run build/ci.go generate -verify
- go run build/ci.go install -dlgo
test_script:
- go run build/ci.go test -dlgo -coverage
- go run build/ci.go test -dlgo -short
# linux/386 is disabled.
- matrix:
@@ -54,4 +55,4 @@ for:
- go run build/ci.go archive -arch %GETH_ARCH% -type zip -signer WINDOWS_SIGNING_KEY -upload gethstore/builds
- go run build/ci.go nsis -arch %GETH_ARCH% -signer WINDOWS_SIGNING_KEY -upload gethstore/builds
test_script:
- go run build/ci.go test -dlgo -arch %GETH_ARCH% -cc %GETH_CC% -coverage
- go run build/ci.go test -dlgo -arch %GETH_ARCH% -cc %GETH_CC% -short

163
beacon/blsync/block_sync.go Executable file
View File

@@ -0,0 +1,163 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package blsync
import (
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/light/sync"
"github.com/ethereum/go-ethereum/beacon/params"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
)
// beaconBlockSync implements request.Module; it fetches the beacon blocks belonging
// to the validated and prefetch heads.
type beaconBlockSync struct {
recentBlocks *lru.Cache[common.Hash, *types.BeaconBlock]
locked map[common.Hash]request.ServerAndID
serverHeads map[request.Server]common.Hash
headTracker headTracker
lastHeadInfo types.HeadInfo
chainHeadFeed event.FeedOf[types.ChainHeadEvent]
}
type headTracker interface {
PrefetchHead() types.HeadInfo
ValidatedOptimistic() (types.OptimisticUpdate, bool)
ValidatedFinality() (types.FinalityUpdate, bool)
}
// newBeaconBlockSync returns a new beaconBlockSync.
func newBeaconBlockSync(headTracker headTracker) *beaconBlockSync {
return &beaconBlockSync{
headTracker: headTracker,
recentBlocks: lru.NewCache[common.Hash, *types.BeaconBlock](10),
locked: make(map[common.Hash]request.ServerAndID),
serverHeads: make(map[request.Server]common.Hash),
}
}
func (s *beaconBlockSync) SubscribeChainHead(ch chan<- types.ChainHeadEvent) event.Subscription {
return s.chainHeadFeed.Subscribe(ch)
}
// Process implements request.Module.
func (s *beaconBlockSync) Process(requester request.Requester, events []request.Event) {
for _, event := range events {
switch event.Type {
case request.EvResponse, request.EvFail, request.EvTimeout:
sid, req, resp := event.RequestInfo()
blockRoot := common.Hash(req.(sync.ReqBeaconBlock))
log.Debug("Beacon block event", "type", event.Type.Name, "hash", blockRoot)
if resp != nil {
s.recentBlocks.Add(blockRoot, resp.(*types.BeaconBlock))
}
if s.locked[blockRoot] == sid {
delete(s.locked, blockRoot)
}
case sync.EvNewHead:
s.serverHeads[event.Server] = event.Data.(types.HeadInfo).BlockRoot
case request.EvUnregistered:
delete(s.serverHeads, event.Server)
}
}
s.updateEventFeed()
// request validated head block if unavailable and not yet requested
if vh, ok := s.headTracker.ValidatedOptimistic(); ok {
s.tryRequestBlock(requester, vh.Attested.Hash(), false)
}
// request prefetch head if the given server has announced it
if prefetchHead := s.headTracker.PrefetchHead().BlockRoot; prefetchHead != (common.Hash{}) {
s.tryRequestBlock(requester, prefetchHead, true)
}
}
func (s *beaconBlockSync) tryRequestBlock(requester request.Requester, blockRoot common.Hash, needSameHead bool) {
if _, ok := s.recentBlocks.Get(blockRoot); ok {
return
}
if _, ok := s.locked[blockRoot]; ok {
return
}
for _, server := range requester.CanSendTo() {
if needSameHead && (s.serverHeads[server] != blockRoot) {
continue
}
id := requester.Send(server, sync.ReqBeaconBlock(blockRoot))
s.locked[blockRoot] = request.ServerAndID{Server: server, ID: id}
return
}
}
func blockHeadInfo(block *types.BeaconBlock) types.HeadInfo {
if block == nil {
return types.HeadInfo{}
}
return types.HeadInfo{Slot: block.Slot(), BlockRoot: block.Root()}
}
func (s *beaconBlockSync) updateEventFeed() {
optimistic, ok := s.headTracker.ValidatedOptimistic()
if !ok {
return
}
validatedHead := optimistic.Attested.Hash()
headBlock, ok := s.recentBlocks.Get(validatedHead)
if !ok {
return
}
var finalizedHash common.Hash
if finality, ok := s.headTracker.ValidatedFinality(); ok {
he := optimistic.Attested.Epoch()
fe := finality.Attested.Header.Epoch()
switch {
case he == fe:
finalizedHash = finality.Finalized.PayloadHeader.BlockHash()
case he < fe:
return
case he == fe+1:
parent, ok := s.recentBlocks.Get(optimistic.Attested.ParentRoot)
if !ok || parent.Slot()/params.EpochLength == fe {
return // head is at first slot of next epoch, wait for finality update
}
}
}
headInfo := blockHeadInfo(headBlock)
if headInfo == s.lastHeadInfo {
return
}
s.lastHeadInfo = headInfo
// new head block and finality info available; extract executable data and send event to feed
execBlock, err := headBlock.ExecutionPayload()
if err != nil {
log.Error("Error extracting execution block from validated beacon block", "error", err)
return
}
s.chainHeadFeed.Send(types.ChainHeadEvent{
BeaconHead: optimistic.Attested.Header,
Block: execBlock,
Finalized: finalizedHash,
})
}

View File

@@ -0,0 +1,163 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package blsync
import (
"testing"
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/light/sync"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
zrntcommon "github.com/protolambda/zrnt/eth2/beacon/common"
"github.com/protolambda/zrnt/eth2/beacon/deneb"
)
var (
testServer1 = testServer("testServer1")
testServer2 = testServer("testServer2")
testBlock1 = types.NewBeaconBlock(&deneb.BeaconBlock{
Slot: 123,
Body: deneb.BeaconBlockBody{
ExecutionPayload: deneb.ExecutionPayload{
BlockNumber: 456,
BlockHash: zrntcommon.Hash32(common.HexToHash("905ac721c4058d9ed40b27b6b9c1bdd10d4333e4f3d9769100bf9dfb80e5d1f6")),
},
},
})
testBlock2 = types.NewBeaconBlock(&deneb.BeaconBlock{
Slot: 124,
Body: deneb.BeaconBlockBody{
ExecutionPayload: deneb.ExecutionPayload{
BlockNumber: 457,
BlockHash: zrntcommon.Hash32(common.HexToHash("011703f39c664efc1c6cf5f49ca09b595581eec572d4dfddd3d6179a9e63e655")),
},
},
})
)
type testServer string
func (t testServer) Name() string {
return string(t)
}
func TestBlockSync(t *testing.T) {
ht := &testHeadTracker{}
blockSync := newBeaconBlockSync(ht)
headCh := make(chan types.ChainHeadEvent, 16)
blockSync.SubscribeChainHead(headCh)
ts := sync.NewTestScheduler(t, blockSync)
ts.AddServer(testServer1, 1)
ts.AddServer(testServer2, 1)
expHeadBlock := func(expHead *types.BeaconBlock) {
t.Helper()
var expNumber, headNumber uint64
if expHead != nil {
p, err := expHead.ExecutionPayload()
if err != nil {
t.Fatalf("expHead.ExecutionPayload() failed: %v", err)
}
expNumber = p.NumberU64()
}
select {
case event := <-headCh:
headNumber = event.Block.NumberU64()
default:
}
if headNumber != expNumber {
t.Errorf("Wrong head block, expected block number %d, got %d)", expNumber, headNumber)
}
}
// no block requests expected until head tracker knows about a head
ts.Run(1)
expHeadBlock(nil)
// set block 1 as prefetch head, announced by server 2
head1 := blockHeadInfo(testBlock1)
ht.prefetch = head1
ts.ServerEvent(sync.EvNewHead, testServer2, head1)
// expect request to server 2 which has announced the head
ts.Run(2, testServer2, sync.ReqBeaconBlock(head1.BlockRoot))
// valid response
ts.RequestEvent(request.EvResponse, ts.Request(2, 1), testBlock1)
ts.AddAllowance(testServer2, 1)
ts.Run(3)
// head block still not expected as the fetched block is not the validated head yet
expHeadBlock(nil)
// set as validated head, expect no further requests but block 1 set as head block
ht.validated.Header = testBlock1.Header()
ts.Run(4)
expHeadBlock(testBlock1)
// set block 2 as prefetch head, announced by server 1
head2 := blockHeadInfo(testBlock2)
ht.prefetch = head2
ts.ServerEvent(sync.EvNewHead, testServer1, head2)
// expect request to server 1
ts.Run(5, testServer1, sync.ReqBeaconBlock(head2.BlockRoot))
// req2 fails, no further requests expected because server 2 has not announced it
ts.RequestEvent(request.EvFail, ts.Request(5, 1), nil)
ts.Run(6)
// set as validated head before retrieving block; now it's assumed to be available from server 2 too
ht.validated.Header = testBlock2.Header()
// expect req2 retry to server 2
ts.Run(7, testServer2, sync.ReqBeaconBlock(head2.BlockRoot))
// now head block should be unavailable again
expHeadBlock(nil)
// valid response, now head block should be block 2 immediately as it is already validated
ts.RequestEvent(request.EvResponse, ts.Request(7, 1), testBlock2)
ts.Run(8)
expHeadBlock(testBlock2)
}
type testHeadTracker struct {
prefetch types.HeadInfo
validated types.SignedHeader
}
func (h *testHeadTracker) PrefetchHead() types.HeadInfo {
return h.prefetch
}
func (h *testHeadTracker) ValidatedOptimistic() (types.OptimisticUpdate, bool) {
return types.OptimisticUpdate{
Attested: types.HeaderWithExecProof{Header: h.validated.Header},
Signature: h.validated.Signature,
SignatureSlot: h.validated.SignatureSlot,
}, h.validated.Header != (types.Header{})
}
// TODO add test case for finality
func (h *testHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
finalized := types.NewExecutionHeader(new(deneb.ExecutionPayloadHeader))
return types.FinalityUpdate{
Attested: types.HeaderWithExecProof{Header: h.validated.Header},
Finalized: types.HeaderWithExecProof{PayloadHeader: finalized},
Signature: h.validated.Signature,
SignatureSlot: h.validated.SignatureSlot,
}, h.validated.Header != (types.Header{})
}

115
beacon/blsync/client.go Normal file
View File

@@ -0,0 +1,115 @@
// Copyright 2024 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package blsync
import (
"strings"
"github.com/ethereum/go-ethereum/beacon/light"
"github.com/ethereum/go-ethereum/beacon/light/api"
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/light/sync"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/ethdb/memorydb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
"github.com/urfave/cli/v2"
)
type Client struct {
urls []string
customHeader map[string]string
chainConfig *lightClientConfig
scheduler *request.Scheduler
blockSync *beaconBlockSync
engineRPC *rpc.Client
chainHeadSub event.Subscription
engineClient *engineClient
}
func NewClient(ctx *cli.Context) *Client {
if !ctx.IsSet(utils.BeaconApiFlag.Name) {
utils.Fatalf("Beacon node light client API URL not specified")
}
var (
chainConfig = makeChainConfig(ctx)
customHeader = make(map[string]string)
)
for _, s := range ctx.StringSlice(utils.BeaconApiHeaderFlag.Name) {
kv := strings.Split(s, ":")
if len(kv) != 2 {
utils.Fatalf("Invalid custom API header entry: %s", s)
}
customHeader[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1])
}
// create data structures
var (
db = memorydb.New()
threshold = ctx.Int(utils.BeaconThresholdFlag.Name)
committeeChain = light.NewCommitteeChain(db, chainConfig.ChainConfig, threshold, !ctx.Bool(utils.BeaconNoFilterFlag.Name))
headTracker = light.NewHeadTracker(committeeChain, threshold)
)
headSync := sync.NewHeadSync(headTracker, committeeChain)
// set up scheduler and sync modules
scheduler := request.NewScheduler()
checkpointInit := sync.NewCheckpointInit(committeeChain, chainConfig.Checkpoint)
forwardSync := sync.NewForwardUpdateSync(committeeChain)
beaconBlockSync := newBeaconBlockSync(headTracker)
scheduler.RegisterTarget(headTracker)
scheduler.RegisterTarget(committeeChain)
scheduler.RegisterModule(checkpointInit, "checkpointInit")
scheduler.RegisterModule(forwardSync, "forwardSync")
scheduler.RegisterModule(headSync, "headSync")
scheduler.RegisterModule(beaconBlockSync, "beaconBlockSync")
return &Client{
scheduler: scheduler,
urls: ctx.StringSlice(utils.BeaconApiFlag.Name),
customHeader: customHeader,
chainConfig: &chainConfig,
blockSync: beaconBlockSync,
}
}
func (c *Client) SetEngineRPC(engine *rpc.Client) {
c.engineRPC = engine
}
func (c *Client) Start() error {
headCh := make(chan types.ChainHeadEvent, 16)
c.chainHeadSub = c.blockSync.SubscribeChainHead(headCh)
c.engineClient = startEngineClient(c.chainConfig, c.engineRPC, headCh)
c.scheduler.Start()
for _, url := range c.urls {
beaconApi := api.NewBeaconLightApi(url, c.customHeader)
c.scheduler.RegisterServer(request.NewServer(api.NewApiServer(beaconApi), &mclock.System{}))
}
return nil
}
func (c *Client) Stop() error {
c.engineClient.stop()
c.chainHeadSub.Unsubscribe()
c.scheduler.Stop()
return nil
}

114
beacon/blsync/config.go Normal file
View File

@@ -0,0 +1,114 @@
// Copyright 2022 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package blsync
import (
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/urfave/cli/v2"
)
// lightClientConfig contains beacon light client configuration
type lightClientConfig struct {
*types.ChainConfig
Checkpoint common.Hash
}
var (
MainnetConfig = lightClientConfig{
ChainConfig: (&types.ChainConfig{
GenesisValidatorsRoot: common.HexToHash("0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"),
GenesisTime: 1606824023,
}).
AddFork("GENESIS", 0, []byte{0, 0, 0, 0}).
AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}).
AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}).
AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}).
AddFork("DENEB", 269568, []byte{4, 0, 0, 0}),
Checkpoint: common.HexToHash("0x388be41594ec7d6a6894f18c73f3469f07e2c19a803de4755d335817ed8e2e5a"),
}
SepoliaConfig = lightClientConfig{
ChainConfig: (&types.ChainConfig{
GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),
GenesisTime: 1655733600,
}).
AddFork("GENESIS", 0, []byte{144, 0, 0, 105}).
AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
AddFork("DENEB", 132608, []byte{144, 0, 0, 115}),
Checkpoint: common.HexToHash("0x1005a6d9175e96bfbce4d35b80f468e9bff0b674e1e861d16e09e10005a58e81"),
}
)
func makeChainConfig(ctx *cli.Context) lightClientConfig {
var config lightClientConfig
customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name)
utils.CheckExclusive(ctx, utils.MainnetFlag, utils.SepoliaFlag, utils.BeaconConfigFlag)
switch {
case ctx.Bool(utils.MainnetFlag.Name):
config = MainnetConfig
case ctx.Bool(utils.SepoliaFlag.Name):
config = SepoliaConfig
default:
if !customConfig {
config = MainnetConfig
}
}
// Genesis root and time should always be specified together with custom chain config
if customConfig {
if !ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
utils.Fatalf("Custom beacon chain config is specified but genesis root is missing")
}
if !ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
utils.Fatalf("Custom beacon chain config is specified but genesis time is missing")
}
if !ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
utils.Fatalf("Custom beacon chain config is specified but checkpoint is missing")
}
config.ChainConfig = &types.ChainConfig{
GenesisTime: ctx.Uint64(utils.BeaconGenesisTimeFlag.Name),
}
if c, err := hexutil.Decode(ctx.String(utils.BeaconGenesisRootFlag.Name)); err == nil && len(c) <= 32 {
copy(config.GenesisValidatorsRoot[:len(c)], c)
} else {
utils.Fatalf("Invalid hex string", "beacon.genesis.gvroot", ctx.String(utils.BeaconGenesisRootFlag.Name), "error", err)
}
if err := config.ChainConfig.LoadForks(ctx.String(utils.BeaconConfigFlag.Name)); err != nil {
utils.Fatalf("Could not load beacon chain config file", "file name", ctx.String(utils.BeaconConfigFlag.Name), "error", err)
}
} else {
if ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
utils.Fatalf("Genesis root is specified but custom beacon chain config is missing")
}
if ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
utils.Fatalf("Genesis time is specified but custom beacon chain config is missing")
}
}
// Checkpoint is required with custom chain config and is optional with pre-defined config
if ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
if c, err := hexutil.Decode(ctx.String(utils.BeaconCheckpointFlag.Name)); err == nil && len(c) <= 32 {
copy(config.Checkpoint[:len(c)], c)
} else {
utils.Fatalf("Invalid hex string", "beacon.checkpoint", ctx.String(utils.BeaconCheckpointFlag.Name), "error", err)
}
}
return config
}

View File

@@ -0,0 +1,150 @@
// Copyright 2024 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package blsync
import (
"context"
"strings"
"sync"
"time"
"github.com/ethereum/go-ethereum/beacon/engine"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
ctypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
)
type engineClient struct {
config *lightClientConfig
rpc *rpc.Client
rootCtx context.Context
cancelRoot context.CancelFunc
wg sync.WaitGroup
}
func startEngineClient(config *lightClientConfig, rpc *rpc.Client, headCh <-chan types.ChainHeadEvent) *engineClient {
ctx, cancel := context.WithCancel(context.Background())
ec := &engineClient{
config: config,
rpc: rpc,
rootCtx: ctx,
cancelRoot: cancel,
}
ec.wg.Add(1)
go ec.updateLoop(headCh)
return ec
}
func (ec *engineClient) stop() {
ec.cancelRoot()
ec.wg.Wait()
}
func (ec *engineClient) updateLoop(headCh <-chan types.ChainHeadEvent) {
defer ec.wg.Done()
for {
select {
case <-ec.rootCtx.Done():
log.Debug("Stopping engine API update loop")
return
case event := <-headCh:
if ec.rpc == nil { // dry run, no engine API specified
log.Info("New execution block retrieved", "number", event.Block.NumberU64(), "hash", event.Block.Hash(), "finalized", event.Finalized)
continue
}
fork := ec.config.ForkAtEpoch(event.BeaconHead.Epoch())
forkName := strings.ToLower(fork.Name)
log.Debug("Calling NewPayload", "number", event.Block.NumberU64(), "hash", event.Block.Hash())
if status, err := ec.callNewPayload(forkName, event); err == nil {
log.Info("Successful NewPayload", "number", event.Block.NumberU64(), "hash", event.Block.Hash(), "status", status)
} else {
log.Error("Failed NewPayload", "number", event.Block.NumberU64(), "hash", event.Block.Hash(), "error", err)
}
log.Debug("Calling ForkchoiceUpdated", "head", event.Block.Hash())
if status, err := ec.callForkchoiceUpdated(forkName, event); err == nil {
log.Info("Successful ForkchoiceUpdated", "head", event.Block.Hash(), "status", status)
} else {
log.Error("Failed ForkchoiceUpdated", "head", event.Block.Hash(), "error", err)
}
}
}
}
func (ec *engineClient) callNewPayload(fork string, event types.ChainHeadEvent) (string, error) {
execData := engine.BlockToExecutableData(event.Block, nil, nil).ExecutionPayload
var (
method string
params = []any{execData}
)
switch fork {
case "deneb":
method = "engine_newPayloadV3"
parentBeaconRoot := event.BeaconHead.ParentRoot
blobHashes := collectBlobHashes(event.Block)
params = append(params, blobHashes, parentBeaconRoot)
case "capella":
method = "engine_newPayloadV2"
default:
method = "engine_newPayloadV1"
}
ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5)
defer cancel()
var resp engine.PayloadStatusV1
err := ec.rpc.CallContext(ctx, &resp, method, params...)
return resp.Status, err
}
func collectBlobHashes(b *ctypes.Block) []common.Hash {
list := make([]common.Hash, 0)
for _, tx := range b.Transactions() {
list = append(list, tx.BlobHashes()...)
}
return list
}
func (ec *engineClient) callForkchoiceUpdated(fork string, event types.ChainHeadEvent) (string, error) {
update := engine.ForkchoiceStateV1{
HeadBlockHash: event.Block.Hash(),
SafeBlockHash: event.Finalized,
FinalizedBlockHash: event.Finalized,
}
var method string
switch fork {
case "deneb":
method = "engine_forkchoiceUpdatedV3"
case "capella":
method = "engine_forkchoiceUpdatedV2"
default:
method = "engine_forkchoiceUpdatedV1"
}
ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5)
defer cancel()
var resp engine.ForkChoiceResponse
err := ec.rpc.CallContext(ctx, &resp, method, update, nil)
return resp.PayloadStatus.Status, err
}

View File

@@ -74,13 +74,13 @@ var (
// - newPayloadV1: if the payload was accepted, but not processed (side chain)
ACCEPTED = "ACCEPTED"
INVALIDBLOCKHASH = "INVALID_BLOCK_HASH"
GenericServerError = &EngineAPIError{code: -32000, msg: "Server error"}
UnknownPayload = &EngineAPIError{code: -38001, msg: "Unknown payload"}
InvalidForkChoiceState = &EngineAPIError{code: -38002, msg: "Invalid forkchoice state"}
InvalidPayloadAttributes = &EngineAPIError{code: -38003, msg: "Invalid payload attributes"}
TooLargeRequest = &EngineAPIError{code: -38004, msg: "Too large request"}
InvalidParams = &EngineAPIError{code: -32602, msg: "Invalid parameters"}
UnsupportedFork = &EngineAPIError{code: -38005, msg: "Unsupported fork"}
STATUS_INVALID = ForkChoiceResponse{PayloadStatus: PayloadStatusV1{Status: INVALID}, PayloadID: nil}
STATUS_SYNCING = ForkChoiceResponse{PayloadStatus: PayloadStatusV1{Status: SYNCING}, PayloadID: nil}

View File

@@ -20,12 +20,14 @@ func (p PayloadAttributes) MarshalJSON() ([]byte, error) {
Random common.Hash `json:"prevRandao" gencodec:"required"`
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
}
var enc PayloadAttributes
enc.Timestamp = hexutil.Uint64(p.Timestamp)
enc.Random = p.Random
enc.SuggestedFeeRecipient = p.SuggestedFeeRecipient
enc.Withdrawals = p.Withdrawals
enc.BeaconRoot = p.BeaconRoot
return json.Marshal(&enc)
}
@@ -36,6 +38,7 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
Random *common.Hash `json:"prevRandao" gencodec:"required"`
SuggestedFeeRecipient *common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
}
var dec PayloadAttributes
if err := json.Unmarshal(input, &dec); err != nil {
@@ -56,5 +59,8 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
if dec.Withdrawals != nil {
p.Withdrawals = dec.Withdrawals
}
if dec.BeaconRoot != nil {
p.BeaconRoot = dec.BeaconRoot
}
return nil
}

View File

@@ -17,21 +17,25 @@ var _ = (*executableDataMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (e ExecutableData) MarshalJSON() ([]byte, error) {
type ExecutableData struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
Deposits types.Deposits `json:"depositRequests"`
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
}
var enc ExecutableData
enc.ParentHash = e.ParentHash
@@ -54,27 +58,35 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
}
}
enc.Withdrawals = e.Withdrawals
enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed)
enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas)
enc.Deposits = e.Deposits
enc.ExecutionWitness = e.ExecutionWitness
return json.Marshal(&enc)
}
// UnmarshalJSON unmarshals from JSON.
func (e *ExecutableData) UnmarshalJSON(input []byte) error {
type ExecutableData struct {
ParentHash *common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot *common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random *common.Hash `json:"prevRandao" gencodec:"required"`
Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash *common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
ParentHash *common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot *common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random *common.Hash `json:"prevRandao" gencodec:"required"`
Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash *common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
Deposits *types.Deposits `json:"depositRequests"`
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
}
var dec ExecutableData
if err := json.Unmarshal(input, &dec); err != nil {
@@ -142,5 +154,17 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
if dec.Withdrawals != nil {
e.Withdrawals = dec.Withdrawals
}
if dec.BlobGasUsed != nil {
e.BlobGasUsed = (*uint64)(dec.BlobGasUsed)
}
if dec.ExcessBlobGas != nil {
e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)
}
if dec.Deposits != nil {
e.Deposits = *dec.Deposits
}
if dec.ExecutionWitness != nil {
e.ExecutionWitness = dec.ExecutionWitness
}
return nil
}

View File

@@ -17,10 +17,16 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
Override bool `json:"shouldOverrideBuilder"`
Witness *hexutil.Bytes `json:"witness"`
}
var enc ExecutionPayloadEnvelope
enc.ExecutionPayload = e.ExecutionPayload
enc.BlockValue = (*hexutil.Big)(e.BlockValue)
enc.BlobsBundle = e.BlobsBundle
enc.Override = e.Override
enc.Witness = e.Witness
return json.Marshal(&enc)
}
@@ -29,6 +35,9 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
Override *bool `json:"shouldOverrideBuilder"`
Witness *hexutil.Bytes `json:"witness"`
}
var dec ExecutionPayloadEnvelope
if err := json.Unmarshal(input, &dec); err != nil {
@@ -42,5 +51,14 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
return errors.New("missing required field 'blockValue' for ExecutionPayloadEnvelope")
}
e.BlockValue = (*big.Int)(dec.BlockValue)
if dec.BlobsBundle != nil {
e.BlobsBundle = dec.BlobsBundle
}
if dec.Override != nil {
e.Override = *dec.Override
}
if dec.Witness != nil {
e.Witness = dec.Witness
}
return nil
}

View File

@@ -19,13 +19,25 @@ package engine
import (
"fmt"
"math/big"
"slices"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
)
// PayloadVersion denotes the version of PayloadAttributes used to request the
// building of the payload to commence.
type PayloadVersion byte
var (
PayloadV1 PayloadVersion = 0x1
PayloadV2 PayloadVersion = 0x2
PayloadV3 PayloadVersion = 0x3
)
//go:generate go run github.com/fjl/gencodec -type PayloadAttributes -field-override payloadAttributesMarshaling -out gen_blockparams.go
// PayloadAttributes describes the environment context in which a block should
@@ -35,6 +47,7 @@ type PayloadAttributes struct {
Random common.Hash `json:"prevRandao" gencodec:"required"`
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
}
// JSON type overrides for PayloadAttributes.
@@ -46,21 +59,25 @@ type payloadAttributesMarshaling struct {
// ExecutableData is the data necessary to execute an EL payload.
type ExecutableData struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number uint64 `json:"blockNumber" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Timestamp uint64 `json:"timestamp" gencodec:"required"`
ExtraData []byte `json:"extraData" gencodec:"required"`
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions [][]byte `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number uint64 `json:"blockNumber" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Timestamp uint64 `json:"timestamp" gencodec:"required"`
ExtraData []byte `json:"extraData" gencodec:"required"`
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions [][]byte `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *uint64 `json:"blobGasUsed"`
ExcessBlobGas *uint64 `json:"excessBlobGas"`
Deposits types.Deposits `json:"depositRequests"`
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
}
// JSON type overrides for executableData.
@@ -73,6 +90,16 @@ type executableDataMarshaling struct {
ExtraData hexutil.Bytes
LogsBloom hexutil.Bytes
Transactions []hexutil.Bytes
BlobGasUsed *hexutil.Uint64
ExcessBlobGas *hexutil.Uint64
}
// StatelessPayloadStatusV1 is the result of a stateless payload execution.
type StatelessPayloadStatusV1 struct {
Status string `json:"status"`
StateRoot common.Hash `json:"stateRoot"`
ReceiptsRoot common.Hash `json:"receiptsRoot"`
ValidationError *string `json:"validationError"`
}
//go:generate go run github.com/fjl/gencodec -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go
@@ -80,6 +107,15 @@ type executableDataMarshaling struct {
type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *big.Int `json:"blockValue" gencodec:"required"`
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
Override bool `json:"shouldOverrideBuilder"`
Witness *hexutil.Bytes `json:"witness"`
}
type BlobsBundleV1 struct {
Commitments []hexutil.Bytes `json:"commitments"`
Proofs []hexutil.Bytes `json:"proofs"`
Blobs []hexutil.Bytes `json:"blobs"`
}
// JSON type overrides for ExecutionPayloadEnvelope.
@@ -88,9 +124,10 @@ type executionPayloadEnvelopeMarshaling struct {
}
type PayloadStatusV1 struct {
Status string `json:"status"`
LatestValidHash *common.Hash `json:"latestValidHash"`
ValidationError *string `json:"validationError"`
Status string `json:"status"`
Witness *hexutil.Bytes `json:"witness"`
LatestValidHash *common.Hash `json:"latestValidHash"`
ValidationError *string `json:"validationError"`
}
type TransitionConfigurationV1 struct {
@@ -102,6 +139,16 @@ type TransitionConfigurationV1 struct {
// PayloadID is an identifier of the payload build process
type PayloadID [8]byte
// Version returns the payload version associated with the identifier.
func (b PayloadID) Version() PayloadVersion {
return PayloadVersion(b[0])
}
// Is returns whether the identifier matches any of provided payload versions.
func (b PayloadID) Is(versions ...PayloadVersion) bool {
return slices.Contains(versions, b.Version())
}
func (b PayloadID) String() string {
return hexutil.Encode(b[:])
}
@@ -152,86 +199,179 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
// ExecutableDataToBlock constructs a block from executable data.
// It verifies that the following fields:
//
// len(extraData) <= 32
// uncleHash = emptyUncleHash
// difficulty = 0
// len(extraData) <= 32
// uncleHash = emptyUncleHash
// difficulty = 0
// if versionedHashes != nil, versionedHashes match to blob transactions
//
// and that the blockhash of the constructed block matches the parameters. Nil
// Withdrawals value will propagate through the returned block. Empty
// Withdrawals value must be passed via non-nil, length 0 value in params.
func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) {
txs, err := decodeTransactions(params.Transactions)
// Withdrawals value must be passed via non-nil, length 0 value in data.
func ExecutableDataToBlock(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) {
block, err := ExecutableDataToBlockNoHash(data, versionedHashes, beaconRoot)
if err != nil {
return nil, err
}
if len(params.ExtraData) > 32 {
return nil, fmt.Errorf("invalid extradata length: %v", len(params.ExtraData))
if block.Hash() != data.BlockHash {
return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", data.BlockHash, block.Hash())
}
if len(params.LogsBloom) != 256 {
return nil, fmt.Errorf("invalid logsBloom length: %v", len(params.LogsBloom))
return block, nil
}
// ExecutableDataToBlockNoHash is analogous to ExecutableDataToBlock, but is used
// for stateless execution, so it skips checking if the executable data hashes to
// the requested hash (stateless has to *compute* the root hash, it's not given).
func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) {
txs, err := decodeTransactions(data.Transactions)
if err != nil {
return nil, err
}
if len(data.ExtraData) > int(params.MaximumExtraDataSize) {
return nil, fmt.Errorf("invalid extradata length: %v", len(data.ExtraData))
}
if len(data.LogsBloom) != 256 {
return nil, fmt.Errorf("invalid logsBloom length: %v", len(data.LogsBloom))
}
// Check that baseFeePerGas is not negative or too big
if params.BaseFeePerGas != nil && (params.BaseFeePerGas.Sign() == -1 || params.BaseFeePerGas.BitLen() > 256) {
return nil, fmt.Errorf("invalid baseFeePerGas: %v", params.BaseFeePerGas)
if data.BaseFeePerGas != nil && (data.BaseFeePerGas.Sign() == -1 || data.BaseFeePerGas.BitLen() > 256) {
return nil, fmt.Errorf("invalid baseFeePerGas: %v", data.BaseFeePerGas)
}
var blobHashes = make([]common.Hash, 0, len(txs))
for _, tx := range txs {
blobHashes = append(blobHashes, tx.BlobHashes()...)
}
if len(blobHashes) != len(versionedHashes) {
return nil, fmt.Errorf("invalid number of versionedHashes: %v blobHashes: %v", versionedHashes, blobHashes)
}
for i := 0; i < len(blobHashes); i++ {
if blobHashes[i] != versionedHashes[i] {
return nil, fmt.Errorf("invalid versionedHash at %v: %v blobHashes: %v", i, versionedHashes, blobHashes)
}
}
// Only set withdrawalsRoot if it is non-nil. This allows CLs to use
// ExecutableData before withdrawals are enabled by marshaling
// Withdrawals as the json null value.
var withdrawalsRoot *common.Hash
if params.Withdrawals != nil {
h := types.DeriveSha(types.Withdrawals(params.Withdrawals), trie.NewStackTrie(nil))
if data.Withdrawals != nil {
h := types.DeriveSha(types.Withdrawals(data.Withdrawals), trie.NewStackTrie(nil))
withdrawalsRoot = &h
}
// Compute requestsHash if any requests are non-nil.
var (
requestsHash *common.Hash
requests types.Requests
)
if data.Deposits != nil {
requests = make(types.Requests, 0)
for _, d := range data.Deposits {
requests = append(requests, types.NewRequest(d))
}
h := types.DeriveSha(requests, trie.NewStackTrie(nil))
requestsHash = &h
}
header := &types.Header{
ParentHash: params.ParentHash,
UncleHash: types.EmptyUncleHash,
Coinbase: params.FeeRecipient,
Root: params.StateRoot,
TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
ReceiptHash: params.ReceiptsRoot,
Bloom: types.BytesToBloom(params.LogsBloom),
Difficulty: common.Big0,
Number: new(big.Int).SetUint64(params.Number),
GasLimit: params.GasLimit,
GasUsed: params.GasUsed,
Time: params.Timestamp,
BaseFee: params.BaseFeePerGas,
Extra: params.ExtraData,
MixDigest: params.Random,
WithdrawalsHash: withdrawalsRoot,
ParentHash: data.ParentHash,
UncleHash: types.EmptyUncleHash,
Coinbase: data.FeeRecipient,
Root: data.StateRoot,
TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
ReceiptHash: data.ReceiptsRoot,
Bloom: types.BytesToBloom(data.LogsBloom),
Difficulty: common.Big0,
Number: new(big.Int).SetUint64(data.Number),
GasLimit: data.GasLimit,
GasUsed: data.GasUsed,
Time: data.Timestamp,
BaseFee: data.BaseFeePerGas,
Extra: data.ExtraData,
MixDigest: data.Random,
WithdrawalsHash: withdrawalsRoot,
ExcessBlobGas: data.ExcessBlobGas,
BlobGasUsed: data.BlobGasUsed,
ParentBeaconRoot: beaconRoot,
RequestsHash: requestsHash,
}
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals)
if block.Hash() != params.BlockHash {
return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", params.BlockHash, block.Hash())
}
return block, nil
return types.NewBlockWithHeader(header).
WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals, Requests: requests}).
WithWitness(data.ExecutionWitness),
nil
}
// BlockToExecutableData constructs the ExecutableData structure by filling the
// fields from the given block. It assumes the given block is post-merge block.
func BlockToExecutableData(block *types.Block, fees *big.Int) *ExecutionPayloadEnvelope {
func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.BlobTxSidecar) *ExecutionPayloadEnvelope {
data := &ExecutableData{
BlockHash: block.Hash(),
ParentHash: block.ParentHash(),
FeeRecipient: block.Coinbase(),
StateRoot: block.Root(),
Number: block.NumberU64(),
GasLimit: block.GasLimit(),
GasUsed: block.GasUsed(),
BaseFeePerGas: block.BaseFee(),
Timestamp: block.Time(),
ReceiptsRoot: block.ReceiptHash(),
LogsBloom: block.Bloom().Bytes(),
Transactions: encodeTransactions(block.Transactions()),
Random: block.MixDigest(),
ExtraData: block.Extra(),
Withdrawals: block.Withdrawals(),
BlockHash: block.Hash(),
ParentHash: block.ParentHash(),
FeeRecipient: block.Coinbase(),
StateRoot: block.Root(),
Number: block.NumberU64(),
GasLimit: block.GasLimit(),
GasUsed: block.GasUsed(),
BaseFeePerGas: block.BaseFee(),
Timestamp: block.Time(),
ReceiptsRoot: block.ReceiptHash(),
LogsBloom: block.Bloom().Bytes(),
Transactions: encodeTransactions(block.Transactions()),
Random: block.MixDigest(),
ExtraData: block.Extra(),
Withdrawals: block.Withdrawals(),
BlobGasUsed: block.BlobGasUsed(),
ExcessBlobGas: block.ExcessBlobGas(),
ExecutionWitness: block.ExecutionWitness(),
}
return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees}
bundle := BlobsBundleV1{
Commitments: make([]hexutil.Bytes, 0),
Blobs: make([]hexutil.Bytes, 0),
Proofs: make([]hexutil.Bytes, 0),
}
for _, sidecar := range sidecars {
for j := range sidecar.Blobs {
bundle.Blobs = append(bundle.Blobs, hexutil.Bytes(sidecar.Blobs[j][:]))
bundle.Commitments = append(bundle.Commitments, hexutil.Bytes(sidecar.Commitments[j][:]))
bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:]))
}
}
setRequests(block.Requests(), data)
return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees, BlobsBundle: &bundle, Override: false}
}
// ExecutionPayloadBodyV1 is used in the response to GetPayloadBodiesByHashV1 and GetPayloadBodiesByRangeV1
type ExecutionPayloadBodyV1 struct {
TransactionData []hexutil.Bytes `json:"transactions"`
Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
// setRequests differentiates the different request types and
// assigns them to the associated fields in ExecutableData.
func setRequests(requests types.Requests, data *ExecutableData) {
if requests != nil {
// If requests is non-nil, it means deposits are available in block and we
// should return an empty slice instead of nil if there are no deposits.
data.Deposits = make(types.Deposits, 0)
}
for _, r := range requests {
if d, ok := r.Inner().(*types.Deposit); ok {
data.Deposits = append(data.Deposits, d)
}
}
}
// ExecutionPayloadBody is used in the response to GetPayloadBodiesByHash and GetPayloadBodiesByRange
type ExecutionPayloadBody struct {
TransactionData []hexutil.Bytes `json:"transactions"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
Deposits types.Deposits `json:"depositRequests"`
}
// Client identifiers to support ClientVersionV1.
const (
ClientCode = "GE"
ClientName = "go-ethereum"
)
// ClientVersionV1 contains information which identifies a client implementation.
type ClientVersionV1 struct {
Code string `json:"code"`
Name string `json:"name"`
Version string `json:"version"`
Commit string `json:"commit"`
}
func (v *ClientVersionV1) String() string {
return fmt.Sprintf("%s-%s-%s-%s", v.Code, v.Name, v.Version, v.Commit)
}

114
beacon/light/api/api_server.go Executable file
View File

@@ -0,0 +1,114 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package api
import (
"reflect"
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/light/sync"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
// ApiServer is a wrapper around BeaconLightApi that implements request.requestServer.
type ApiServer struct {
api *BeaconLightApi
eventCallback func(event request.Event)
unsubscribe func()
}
// NewApiServer creates a new ApiServer.
func NewApiServer(api *BeaconLightApi) *ApiServer {
return &ApiServer{api: api}
}
// Subscribe implements request.requestServer.
func (s *ApiServer) Subscribe(eventCallback func(event request.Event)) {
s.eventCallback = eventCallback
listener := HeadEventListener{
OnNewHead: func(slot uint64, blockRoot common.Hash) {
log.Debug("New head received", "slot", slot, "blockRoot", blockRoot)
eventCallback(request.Event{Type: sync.EvNewHead, Data: types.HeadInfo{Slot: slot, BlockRoot: blockRoot}})
},
OnOptimistic: func(update types.OptimisticUpdate) {
log.Debug("New optimistic update received", "slot", update.Attested.Slot, "blockRoot", update.Attested.Hash(), "signerCount", update.Signature.SignerCount())
eventCallback(request.Event{Type: sync.EvNewOptimisticUpdate, Data: update})
},
OnFinality: func(update types.FinalityUpdate) {
log.Debug("New finality update received", "slot", update.Attested.Slot, "blockRoot", update.Attested.Hash(), "signerCount", update.Signature.SignerCount())
eventCallback(request.Event{Type: sync.EvNewFinalityUpdate, Data: update})
},
OnError: func(err error) {
log.Warn("Head event stream error", "err", err)
},
}
s.unsubscribe = s.api.StartHeadListener(listener)
}
// SendRequest implements request.requestServer.
func (s *ApiServer) SendRequest(id request.ID, req request.Request) {
go func() {
var resp request.Response
var err error
switch data := req.(type) {
case sync.ReqUpdates:
log.Debug("Beacon API: requesting light client update", "reqid", id, "period", data.FirstPeriod, "count", data.Count)
var r sync.RespUpdates
r.Updates, r.Committees, err = s.api.GetBestUpdatesAndCommittees(data.FirstPeriod, data.Count)
resp = r
case sync.ReqHeader:
var r sync.RespHeader
log.Debug("Beacon API: requesting header", "reqid", id, "hash", common.Hash(data))
r.Header, r.Canonical, r.Finalized, err = s.api.GetHeader(common.Hash(data))
resp = r
case sync.ReqCheckpointData:
log.Debug("Beacon API: requesting checkpoint data", "reqid", id, "hash", common.Hash(data))
resp, err = s.api.GetCheckpointData(common.Hash(data))
case sync.ReqBeaconBlock:
log.Debug("Beacon API: requesting block", "reqid", id, "hash", common.Hash(data))
resp, err = s.api.GetBeaconBlock(common.Hash(data))
case sync.ReqFinality:
log.Debug("Beacon API: requesting finality update")
resp, err = s.api.GetFinalityUpdate()
default:
}
if err != nil {
log.Warn("Beacon API request failed", "type", reflect.TypeOf(req), "reqid", id, "err", err)
s.eventCallback(request.Event{Type: request.EvFail, Data: request.RequestResponse{ID: id, Request: req}})
} else {
log.Debug("Beacon API request answered", "type", reflect.TypeOf(req), "reqid", id)
s.eventCallback(request.Event{Type: request.EvResponse, Data: request.RequestResponse{ID: id, Request: req, Response: resp}})
}
}()
}
// Unsubscribe implements request.requestServer.
// Note: Unsubscribe should not be called concurrently with Subscribe.
func (s *ApiServer) Unsubscribe() {
if s.unsubscribe != nil {
s.unsubscribe()
s.unsubscribe = nil
}
}
// Name implements request.Server
func (s *ApiServer) Name() string {
return s.api.url
}

599
beacon/light/api/light_api.go Executable file
View File

@@ -0,0 +1,599 @@
// Copyright 2022 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more detaiapi.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package api
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"sync"
"time"
"github.com/donovanhide/eventsource"
"github.com/ethereum/go-ethereum/beacon/merkle"
"github.com/ethereum/go-ethereum/beacon/params"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
)
var (
ErrNotFound = errors.New("404 Not Found")
ErrInternal = errors.New("500 Internal Server Error")
)
type CommitteeUpdate struct {
Version string
Update types.LightClientUpdate
NextSyncCommittee types.SerializedSyncCommittee
}
// See data structure definition here:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientupdate
type committeeUpdateJson struct {
Version string `json:"version"`
Data committeeUpdateData `json:"data"`
}
type committeeUpdateData struct {
Header jsonBeaconHeader `json:"attested_header"`
NextSyncCommittee types.SerializedSyncCommittee `json:"next_sync_committee"`
NextSyncCommitteeBranch merkle.Values `json:"next_sync_committee_branch"`
FinalizedHeader *jsonBeaconHeader `json:"finalized_header,omitempty"`
FinalityBranch merkle.Values `json:"finality_branch,omitempty"`
SyncAggregate types.SyncAggregate `json:"sync_aggregate"`
SignatureSlot common.Decimal `json:"signature_slot"`
}
type jsonBeaconHeader struct {
Beacon types.Header `json:"beacon"`
}
type jsonHeaderWithExecProof struct {
Beacon types.Header `json:"beacon"`
Execution json.RawMessage `json:"execution"`
ExecutionBranch merkle.Values `json:"execution_branch"`
}
// UnmarshalJSON unmarshals from JSON.
func (u *CommitteeUpdate) UnmarshalJSON(input []byte) error {
var dec committeeUpdateJson
if err := json.Unmarshal(input, &dec); err != nil {
return err
}
u.Version = dec.Version
u.NextSyncCommittee = dec.Data.NextSyncCommittee
u.Update = types.LightClientUpdate{
AttestedHeader: types.SignedHeader{
Header: dec.Data.Header.Beacon,
Signature: dec.Data.SyncAggregate,
SignatureSlot: uint64(dec.Data.SignatureSlot),
},
NextSyncCommitteeRoot: u.NextSyncCommittee.Root(),
NextSyncCommitteeBranch: dec.Data.NextSyncCommitteeBranch,
FinalityBranch: dec.Data.FinalityBranch,
}
if dec.Data.FinalizedHeader != nil {
u.Update.FinalizedHeader = &dec.Data.FinalizedHeader.Beacon
}
return nil
}
// fetcher is an interface useful for debug-harnessing the http api.
type fetcher interface {
Do(req *http.Request) (*http.Response, error)
}
// BeaconLightApi requests light client information from a beacon node REST API.
// Note: all required API endpoints are currently only implemented by Lodestar.
type BeaconLightApi struct {
url string
client fetcher
customHeaders map[string]string
}
func NewBeaconLightApi(url string, customHeaders map[string]string) *BeaconLightApi {
return &BeaconLightApi{
url: url,
client: &http.Client{
Timeout: time.Second * 10,
},
customHeaders: customHeaders,
}
}
func (api *BeaconLightApi) httpGet(path string, params url.Values) ([]byte, error) {
uri, err := api.buildURL(path, params)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, err
}
for k, v := range api.customHeaders {
req.Header.Set(k, v)
}
resp, err := api.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
switch resp.StatusCode {
case 200:
return io.ReadAll(resp.Body)
case 404:
return nil, ErrNotFound
case 500:
return nil, ErrInternal
default:
return nil, fmt.Errorf("unexpected error from API endpoint \"%s\": status code %d", path, resp.StatusCode)
}
}
// GetBestUpdatesAndCommittees fetches and validates LightClientUpdate for given
// period and full serialized committee for the next period (committee root hash
// equals update.NextSyncCommitteeRoot).
// Note that the results are validated but the update signature should be verified
// by the caller as its validity depends on the update chain.
func (api *BeaconLightApi) GetBestUpdatesAndCommittees(firstPeriod, count uint64) ([]*types.LightClientUpdate, []*types.SerializedSyncCommittee, error) {
resp, err := api.httpGet("/eth/v1/beacon/light_client/updates", map[string][]string{
"start_period": {strconv.FormatUint(firstPeriod, 10)},
"count": {strconv.FormatUint(count, 10)},
})
if err != nil {
return nil, nil, err
}
var data []CommitteeUpdate
if err := json.Unmarshal(resp, &data); err != nil {
return nil, nil, err
}
if len(data) != int(count) {
return nil, nil, errors.New("invalid number of committee updates")
}
updates := make([]*types.LightClientUpdate, int(count))
committees := make([]*types.SerializedSyncCommittee, int(count))
for i, d := range data {
if d.Update.AttestedHeader.Header.SyncPeriod() != firstPeriod+uint64(i) {
return nil, nil, errors.New("wrong committee update header period")
}
if err := d.Update.Validate(); err != nil {
return nil, nil, err
}
if d.NextSyncCommittee.Root() != d.Update.NextSyncCommitteeRoot {
return nil, nil, errors.New("wrong sync committee root")
}
updates[i], committees[i] = new(types.LightClientUpdate), new(types.SerializedSyncCommittee)
*updates[i], *committees[i] = d.Update, d.NextSyncCommittee
}
return updates, committees, nil
}
// GetOptimisticUpdate fetches the latest available optimistic update.
// Note that the signature should be verified by the caller as its validity
// depends on the update chain.
//
// See data structure definition here:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate
func (api *BeaconLightApi) GetOptimisticUpdate() (types.OptimisticUpdate, error) {
resp, err := api.httpGet("/eth/v1/beacon/light_client/optimistic_update", nil)
if err != nil {
return types.OptimisticUpdate{}, err
}
return decodeOptimisticUpdate(resp)
}
func decodeOptimisticUpdate(enc []byte) (types.OptimisticUpdate, error) {
var data struct {
Version string
Data struct {
Attested jsonHeaderWithExecProof `json:"attested_header"`
Aggregate types.SyncAggregate `json:"sync_aggregate"`
SignatureSlot common.Decimal `json:"signature_slot"`
} `json:"data"`
}
if err := json.Unmarshal(enc, &data); err != nil {
return types.OptimisticUpdate{}, err
}
// Decode the execution payload headers.
attestedExecHeader, err := types.ExecutionHeaderFromJSON(data.Version, data.Data.Attested.Execution)
if err != nil {
return types.OptimisticUpdate{}, fmt.Errorf("invalid attested header: %v", err)
}
if data.Data.Attested.Beacon.StateRoot == (common.Hash{}) {
// workaround for different event encoding format in Lodestar
if err := json.Unmarshal(enc, &data.Data); err != nil {
return types.OptimisticUpdate{}, err
}
}
if len(data.Data.Aggregate.Signers) != params.SyncCommitteeBitmaskSize {
return types.OptimisticUpdate{}, errors.New("invalid sync_committee_bits length")
}
if len(data.Data.Aggregate.Signature) != params.BLSSignatureSize {
return types.OptimisticUpdate{}, errors.New("invalid sync_committee_signature length")
}
return types.OptimisticUpdate{
Attested: types.HeaderWithExecProof{
Header: data.Data.Attested.Beacon,
PayloadHeader: attestedExecHeader,
PayloadBranch: data.Data.Attested.ExecutionBranch,
},
Signature: data.Data.Aggregate,
SignatureSlot: uint64(data.Data.SignatureSlot),
}, nil
}
// GetFinalityUpdate fetches the latest available finality update.
//
// See data structure definition here:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientfinalityupdate
func (api *BeaconLightApi) GetFinalityUpdate() (types.FinalityUpdate, error) {
resp, err := api.httpGet("/eth/v1/beacon/light_client/finality_update", nil)
if err != nil {
return types.FinalityUpdate{}, err
}
return decodeFinalityUpdate(resp)
}
func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) {
var data struct {
Version string
Data struct {
Attested jsonHeaderWithExecProof `json:"attested_header"`
Finalized jsonHeaderWithExecProof `json:"finalized_header"`
FinalityBranch merkle.Values `json:"finality_branch"`
Aggregate types.SyncAggregate `json:"sync_aggregate"`
SignatureSlot common.Decimal `json:"signature_slot"`
}
}
if err := json.Unmarshal(enc, &data); err != nil {
return types.FinalityUpdate{}, err
}
// Decode the execution payload headers.
attestedExecHeader, err := types.ExecutionHeaderFromJSON(data.Version, data.Data.Attested.Execution)
if err != nil {
return types.FinalityUpdate{}, fmt.Errorf("invalid attested header: %v", err)
}
finalizedExecHeader, err := types.ExecutionHeaderFromJSON(data.Version, data.Data.Finalized.Execution)
if err != nil {
return types.FinalityUpdate{}, fmt.Errorf("invalid finalized header: %v", err)
}
// Perform sanity checks.
if len(data.Data.Aggregate.Signers) != params.SyncCommitteeBitmaskSize {
return types.FinalityUpdate{}, errors.New("invalid sync_committee_bits length")
}
if len(data.Data.Aggregate.Signature) != params.BLSSignatureSize {
return types.FinalityUpdate{}, errors.New("invalid sync_committee_signature length")
}
return types.FinalityUpdate{
Attested: types.HeaderWithExecProof{
Header: data.Data.Attested.Beacon,
PayloadHeader: attestedExecHeader,
PayloadBranch: data.Data.Attested.ExecutionBranch,
},
Finalized: types.HeaderWithExecProof{
Header: data.Data.Finalized.Beacon,
PayloadHeader: finalizedExecHeader,
PayloadBranch: data.Data.Finalized.ExecutionBranch,
},
FinalityBranch: data.Data.FinalityBranch,
Signature: data.Data.Aggregate,
SignatureSlot: uint64(data.Data.SignatureSlot),
}, nil
}
// GetHeader fetches and validates the beacon header with the given blockRoot.
// If blockRoot is null hash then the latest head header is fetched.
// The values of the canonical and finalized flags are also returned. Note that
// these flags are not validated.
func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, bool, bool, error) {
var blockId string
if blockRoot == (common.Hash{}) {
blockId = "head"
} else {
blockId = blockRoot.Hex()
}
resp, err := api.httpGet(fmt.Sprintf("/eth/v1/beacon/headers/%s", blockId), nil)
if err != nil {
return types.Header{}, false, false, err
}
var data struct {
Finalized bool `json:"finalized"`
Data struct {
Root common.Hash `json:"root"`
Canonical bool `json:"canonical"`
Header struct {
Message types.Header `json:"message"`
Signature hexutil.Bytes `json:"signature"`
} `json:"header"`
} `json:"data"`
}
if err := json.Unmarshal(resp, &data); err != nil {
return types.Header{}, false, false, err
}
header := data.Data.Header.Message
if blockRoot == (common.Hash{}) {
blockRoot = data.Data.Root
}
if header.Hash() != blockRoot {
return types.Header{}, false, false, errors.New("retrieved beacon header root does not match")
}
return header, data.Data.Canonical, data.Finalized, nil
}
// GetCheckpointData fetches and validates bootstrap data belonging to the given checkpoint.
func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types.BootstrapData, error) {
resp, err := api.httpGet(fmt.Sprintf("/eth/v1/beacon/light_client/bootstrap/0x%x", checkpointHash[:]), nil)
if err != nil {
return nil, err
}
// See data structure definition here:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientbootstrap
type bootstrapData struct {
Data struct {
Header jsonBeaconHeader `json:"header"`
Committee *types.SerializedSyncCommittee `json:"current_sync_committee"`
CommitteeBranch merkle.Values `json:"current_sync_committee_branch"`
} `json:"data"`
}
var data bootstrapData
if err := json.Unmarshal(resp, &data); err != nil {
return nil, err
}
if data.Data.Committee == nil {
return nil, errors.New("sync committee is missing")
}
header := data.Data.Header.Beacon
if header.Hash() != checkpointHash {
return nil, fmt.Errorf("invalid checkpoint block header, have %v want %v", header.Hash(), checkpointHash)
}
checkpoint := &types.BootstrapData{
Header: header,
CommitteeBranch: data.Data.CommitteeBranch,
CommitteeRoot: data.Data.Committee.Root(),
Committee: data.Data.Committee,
}
if err := checkpoint.Validate(); err != nil {
return nil, fmt.Errorf("invalid checkpoint: %w", err)
}
if checkpoint.Header.Hash() != checkpointHash {
return nil, errors.New("wrong checkpoint hash")
}
return checkpoint, nil
}
func (api *BeaconLightApi) GetBeaconBlock(blockRoot common.Hash) (*types.BeaconBlock, error) {
resp, err := api.httpGet(fmt.Sprintf("/eth/v2/beacon/blocks/0x%x", blockRoot), nil)
if err != nil {
return nil, err
}
var beaconBlockMessage struct {
Version string
Data struct {
Message json.RawMessage `json:"message"`
}
}
if err := json.Unmarshal(resp, &beaconBlockMessage); err != nil {
return nil, fmt.Errorf("invalid block json data: %v", err)
}
block, err := types.BlockFromJSON(beaconBlockMessage.Version, beaconBlockMessage.Data.Message)
if err != nil {
return nil, err
}
computedRoot := block.Root()
if computedRoot != blockRoot {
return nil, fmt.Errorf("Beacon block root hash mismatch (expected: %x, got: %x)", blockRoot, computedRoot)
}
return block, nil
}
func decodeHeadEvent(enc []byte) (uint64, common.Hash, error) {
var data struct {
Slot common.Decimal `json:"slot"`
Block common.Hash `json:"block"`
}
if err := json.Unmarshal(enc, &data); err != nil {
return 0, common.Hash{}, err
}
return uint64(data.Slot), data.Block, nil
}
type HeadEventListener struct {
OnNewHead func(slot uint64, blockRoot common.Hash)
OnOptimistic func(head types.OptimisticUpdate)
OnFinality func(head types.FinalityUpdate)
OnError func(err error)
}
// StartHeadListener creates an event subscription for heads and signed (optimistic)
// head updates and calls the specified callback functions when they are received.
// The callbacks are also called for the current head and optimistic head at startup.
// They are never called concurrently.
func (api *BeaconLightApi) StartHeadListener(listener HeadEventListener) func() {
var (
ctx, closeCtx = context.WithCancel(context.Background())
streamCh = make(chan *eventsource.Stream, 1)
wg sync.WaitGroup
)
// When connected to a Lodestar node the subscription blocks until the first actual
// event arrives; therefore we create the subscription in a separate goroutine while
// letting the main goroutine sync up to the current head.
wg.Add(1)
go func() {
defer wg.Done()
stream := api.startEventStream(ctx, &listener)
if stream == nil {
// This case happens when the context was closed.
return
}
// Stream was opened, wait for close signal.
streamCh <- stream
<-ctx.Done()
stream.Close()
}()
wg.Add(1)
go func() {
defer wg.Done()
// Request initial data.
log.Trace("Requesting initial head header")
if head, _, _, err := api.GetHeader(common.Hash{}); err == nil {
log.Trace("Retrieved initial head header", "slot", head.Slot, "hash", head.Hash())
listener.OnNewHead(head.Slot, head.Hash())
} else {
log.Debug("Failed to retrieve initial head header", "error", err)
}
log.Trace("Requesting initial optimistic update")
if optimisticUpdate, err := api.GetOptimisticUpdate(); err == nil {
log.Trace("Retrieved initial optimistic update", "slot", optimisticUpdate.Attested.Slot, "hash", optimisticUpdate.Attested.Hash())
listener.OnOptimistic(optimisticUpdate)
} else {
log.Debug("Failed to retrieve initial optimistic update", "error", err)
}
log.Trace("Requesting initial finality update")
if finalityUpdate, err := api.GetFinalityUpdate(); err == nil {
log.Trace("Retrieved initial finality update", "slot", finalityUpdate.Finalized.Slot, "hash", finalityUpdate.Finalized.Hash())
listener.OnFinality(finalityUpdate)
} else {
log.Debug("Failed to retrieve initial finality update", "error", err)
}
log.Trace("Starting event stream processing loop")
// Receive the stream.
var stream *eventsource.Stream
select {
case stream = <-streamCh:
case <-ctx.Done():
log.Trace("Stopping event stream processing loop")
return
}
for {
select {
case event, ok := <-stream.Events:
if !ok {
log.Trace("Event stream closed")
return
}
log.Trace("New event received from event stream", "type", event.Event())
switch event.Event() {
case "head":
slot, blockRoot, err := decodeHeadEvent([]byte(event.Data()))
if err == nil {
listener.OnNewHead(slot, blockRoot)
} else {
listener.OnError(fmt.Errorf("error decoding head event: %v", err))
}
case "light_client_optimistic_update":
optimisticUpdate, err := decodeOptimisticUpdate([]byte(event.Data()))
if err == nil {
listener.OnOptimistic(optimisticUpdate)
} else {
listener.OnError(fmt.Errorf("error decoding optimistic update event: %v", err))
}
case "light_client_finality_update":
finalityUpdate, err := decodeFinalityUpdate([]byte(event.Data()))
if err == nil {
listener.OnFinality(finalityUpdate)
} else {
listener.OnError(fmt.Errorf("error decoding finality update event: %v", err))
}
default:
listener.OnError(fmt.Errorf("unexpected event: %s", event.Event()))
}
case err, ok := <-stream.Errors:
if !ok {
return
}
listener.OnError(err)
}
}
}()
return func() {
closeCtx()
wg.Wait()
}
}
// startEventStream establishes an event stream. This will keep retrying until the stream has been
// established. It can only return nil when the context is canceled.
func (api *BeaconLightApi) startEventStream(ctx context.Context, listener *HeadEventListener) *eventsource.Stream {
for retry := true; retry; retry = ctxSleep(ctx, 5*time.Second) {
log.Trace("Sending event subscription request")
uri, err := api.buildURL("/eth/v1/events", map[string][]string{"topics": {"head", "light_client_finality_update", "light_client_optimistic_update"}})
if err != nil {
listener.OnError(fmt.Errorf("error creating event subscription URL: %v", err))
continue
}
req, err := http.NewRequestWithContext(ctx, "GET", uri, nil)
if err != nil {
listener.OnError(fmt.Errorf("error creating event subscription request: %v", err))
continue
}
for k, v := range api.customHeaders {
req.Header.Set(k, v)
}
stream, err := eventsource.SubscribeWithRequest("", req)
if err != nil {
listener.OnError(fmt.Errorf("error creating event subscription: %v", err))
continue
}
log.Trace("Successfully created event stream")
return stream
}
return nil
}
func ctxSleep(ctx context.Context, timeout time.Duration) (ok bool) {
timer := time.NewTimer(timeout)
defer timer.Stop()
select {
case <-timer.C:
return true
case <-ctx.Done():
return false
}
}
func (api *BeaconLightApi) buildURL(path string, params url.Values) (string, error) {
uri, err := url.Parse(api.url)
if err != nil {
return "", err
}
uri = uri.JoinPath(path)
if params != nil {
uri.RawQuery = params.Encode()
}
return uri.String(), nil
}

125
beacon/light/canonical.go Normal file
View File

@@ -0,0 +1,125 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package light
import (
"encoding/binary"
"fmt"
"github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
)
// canonicalStore stores instances of the given type in a database and caches
// them in memory, associated with a continuous range of period numbers.
// Note: canonicalStore is not thread safe and it is the caller's responsibility
// to avoid concurrent access.
type canonicalStore[T any] struct {
keyPrefix []byte
periods periodRange
cache *lru.Cache[uint64, T]
}
// newCanonicalStore creates a new canonicalStore and loads all keys associated
// with the keyPrefix in order to determine the ranges available in the database.
func newCanonicalStore[T any](db ethdb.Iteratee, keyPrefix []byte) (*canonicalStore[T], error) {
cs := &canonicalStore[T]{
keyPrefix: keyPrefix,
cache: lru.NewCache[uint64, T](100),
}
var (
iter = db.NewIterator(keyPrefix, nil)
kl = len(keyPrefix)
first = true
)
defer iter.Release()
for iter.Next() {
if len(iter.Key()) != kl+8 {
log.Warn("Invalid key length in the canonical chain database", "key", fmt.Sprintf("%#x", iter.Key()))
continue
}
period := binary.BigEndian.Uint64(iter.Key()[kl : kl+8])
if first {
cs.periods.Start = period
} else if cs.periods.End != period {
return nil, fmt.Errorf("gap in the canonical chain database between periods %d and %d", cs.periods.End, period-1)
}
first = false
cs.periods.End = period + 1
}
return cs, nil
}
// databaseKey returns the database key belonging to the given period.
func (cs *canonicalStore[T]) databaseKey(period uint64) []byte {
return binary.BigEndian.AppendUint64(append([]byte{}, cs.keyPrefix...), period)
}
// add adds the given item to the database. It also ensures that the range remains
// continuous. Can be used either with a batch or database backend.
func (cs *canonicalStore[T]) add(backend ethdb.KeyValueWriter, period uint64, value T) error {
if !cs.periods.canExpand(period) {
return fmt.Errorf("period expansion is not allowed, first: %d, next: %d, period: %d", cs.periods.Start, cs.periods.End, period)
}
enc, err := rlp.EncodeToBytes(value)
if err != nil {
return err
}
if err := backend.Put(cs.databaseKey(period), enc); err != nil {
return err
}
cs.cache.Add(period, value)
cs.periods.expand(period)
return nil
}
// deleteFrom removes items starting from the given period.
func (cs *canonicalStore[T]) deleteFrom(db ethdb.KeyValueWriter, fromPeriod uint64) (deleted periodRange) {
keepRange, deleteRange := cs.periods.split(fromPeriod)
deleteRange.each(func(period uint64) {
db.Delete(cs.databaseKey(period))
cs.cache.Remove(period)
})
cs.periods = keepRange
return deleteRange
}
// get returns the item at the given period or the null value of the given type
// if no item is present.
func (cs *canonicalStore[T]) get(backend ethdb.KeyValueReader, period uint64) (T, bool) {
var null, value T
if !cs.periods.contains(period) {
return null, false
}
if value, ok := cs.cache.Get(period); ok {
return value, true
}
enc, err := backend.Get(cs.databaseKey(period))
if err != nil {
log.Error("Canonical store value not found", "period", period, "start", cs.periods.Start, "end", cs.periods.End)
return null, false
}
if err := rlp.DecodeBytes(enc, &value); err != nil {
log.Error("Error decoding canonical store value", "error", err)
return null, false
}
cs.cache.Add(period, value)
return value, true
}

View File

@@ -0,0 +1,529 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package light
import (
"errors"
"fmt"
"math"
"sync"
"time"
"github.com/ethereum/go-ethereum/beacon/params"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
)
var (
ErrNeedCommittee = errors.New("sync committee required")
ErrInvalidUpdate = errors.New("invalid committee update")
ErrInvalidPeriod = errors.New("invalid update period")
ErrWrongCommitteeRoot = errors.New("wrong committee root")
ErrCannotReorg = errors.New("can not reorg committee chain")
)
// CommitteeChain is a passive data structure that can validate, hold and update
// a chain of beacon light sync committees and updates. It requires at least one
// externally set fixed committee root at the beginning of the chain which can
// be set either based on a BootstrapData or a trusted source (a local beacon
// full node). This makes the structure useful for both light client and light
// server setups.
//
// It always maintains the following consistency constraints:
// - a committee can only be present if its root hash matches an existing fixed
// root or if it is proven by an update at the previous period
// - an update can only be present if a committee is present at the same period
// and the update signature is valid and has enough participants.
// The committee at the next period (proven by the update) should also be
// present (note that this means they can only be added together if neither
// is present yet). If a fixed root is present at the next period then the
// update can only be present if it proves the same committee root.
//
// Once synced to the current sync period, CommitteeChain can also validate
// signed beacon headers.
type CommitteeChain struct {
// chainmu guards against concurrent access to the canonicalStore structures
// (updates, committees, fixedCommitteeRoots) and ensures that they stay consistent
// with each other and with committeeCache.
chainmu sync.RWMutex
db ethdb.KeyValueStore
updates *canonicalStore[*types.LightClientUpdate]
committees *canonicalStore[*types.SerializedSyncCommittee]
fixedCommitteeRoots *canonicalStore[common.Hash]
committeeCache *lru.Cache[uint64, syncCommittee] // cache deserialized committees
changeCounter uint64
clock mclock.Clock // monotonic clock (simulated clock in tests)
unixNano func() int64 // system clock (simulated clock in tests)
sigVerifier committeeSigVerifier // BLS sig verifier (dummy verifier in tests)
config *types.ChainConfig
signerThreshold int
minimumUpdateScore types.UpdateScore
enforceTime bool // enforceTime specifies whether the age of a signed header should be checked
}
// NewCommitteeChain creates a new CommitteeChain.
func NewCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool) *CommitteeChain {
return newCommitteeChain(db, config, signerThreshold, enforceTime, blsVerifier{}, &mclock.System{}, func() int64 { return time.Now().UnixNano() })
}
// NewTestCommitteeChain creates a new CommitteeChain for testing.
func NewTestCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, clock *mclock.Simulated) *CommitteeChain {
return newCommitteeChain(db, config, signerThreshold, enforceTime, dummyVerifier{}, clock, func() int64 { return int64(clock.Now()) })
}
// newCommitteeChain creates a new CommitteeChain with the option of replacing the
// clock source and signature verification for testing purposes.
func newCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, sigVerifier committeeSigVerifier, clock mclock.Clock, unixNano func() int64) *CommitteeChain {
s := &CommitteeChain{
committeeCache: lru.NewCache[uint64, syncCommittee](10),
db: db,
sigVerifier: sigVerifier,
clock: clock,
unixNano: unixNano,
config: config,
signerThreshold: signerThreshold,
enforceTime: enforceTime,
minimumUpdateScore: types.UpdateScore{
SignerCount: uint32(signerThreshold),
SubPeriodIndex: params.SyncPeriodLength / 16,
},
}
var err1, err2, err3 error
if s.fixedCommitteeRoots, err1 = newCanonicalStore[common.Hash](db, rawdb.FixedCommitteeRootKey); err1 != nil {
log.Error("Error creating fixed committee root store", "error", err1)
}
if s.committees, err2 = newCanonicalStore[*types.SerializedSyncCommittee](db, rawdb.SyncCommitteeKey); err2 != nil {
log.Error("Error creating committee store", "error", err2)
}
if s.updates, err3 = newCanonicalStore[*types.LightClientUpdate](db, rawdb.BestUpdateKey); err3 != nil {
log.Error("Error creating update store", "error", err3)
}
if err1 != nil || err2 != nil || err3 != nil || !s.checkConstraints() {
log.Info("Resetting invalid committee chain")
s.Reset()
}
// roll back invalid updates (might be necessary if forks have been changed since last time)
for !s.updates.periods.isEmpty() {
update, ok := s.updates.get(s.db, s.updates.periods.End-1)
if !ok {
log.Error("Sync committee update missing", "period", s.updates.periods.End-1)
s.Reset()
break
}
if valid, err := s.verifyUpdate(update); err != nil {
log.Error("Error validating update", "period", s.updates.periods.End-1, "error", err)
} else if valid {
break
}
if err := s.rollback(s.updates.periods.End); err != nil {
log.Error("Error writing batch into chain database", "error", err)
}
}
if !s.committees.periods.isEmpty() {
log.Trace("Sync committee chain loaded", "first period", s.committees.periods.Start, "last period", s.committees.periods.End-1)
}
return s
}
// checkConstraints checks committee chain validity constraints
func (s *CommitteeChain) checkConstraints() bool {
isNotInFixedCommitteeRootRange := func(r periodRange) bool {
return s.fixedCommitteeRoots.periods.isEmpty() ||
r.Start < s.fixedCommitteeRoots.periods.Start ||
r.Start >= s.fixedCommitteeRoots.periods.End
}
valid := true
if !s.updates.periods.isEmpty() {
if isNotInFixedCommitteeRootRange(s.updates.periods) {
log.Error("Start update is not in the fixed roots range")
valid = false
}
if s.committees.periods.Start > s.updates.periods.Start || s.committees.periods.End <= s.updates.periods.End {
log.Error("Missing committees in update range")
valid = false
}
}
if !s.committees.periods.isEmpty() {
if isNotInFixedCommitteeRootRange(s.committees.periods) {
log.Error("Start committee is not in the fixed roots range")
valid = false
}
if s.committees.periods.End > s.fixedCommitteeRoots.periods.End && s.committees.periods.End > s.updates.periods.End+1 {
log.Error("Last committee is neither in the fixed roots range nor proven by updates")
valid = false
}
}
return valid
}
// Reset resets the committee chain.
func (s *CommitteeChain) Reset() {
s.chainmu.Lock()
defer s.chainmu.Unlock()
if err := s.rollback(0); err != nil {
log.Error("Error writing batch into chain database", "error", err)
}
s.changeCounter++
}
// CheckpointInit initializes a CommitteeChain based on a checkpoint.
// Note: if the chain is already initialized and the committees proven by the
// checkpoint do match the existing chain then the chain is retained and the
// new checkpoint becomes fixed.
func (s *CommitteeChain) CheckpointInit(bootstrap types.BootstrapData) error {
s.chainmu.Lock()
defer s.chainmu.Unlock()
if err := bootstrap.Validate(); err != nil {
return err
}
period := bootstrap.Header.SyncPeriod()
if err := s.deleteFixedCommitteeRootsFrom(period + 2); err != nil {
s.Reset()
return err
}
if s.addFixedCommitteeRoot(period, bootstrap.CommitteeRoot) != nil {
s.Reset()
if err := s.addFixedCommitteeRoot(period, bootstrap.CommitteeRoot); err != nil {
s.Reset()
return err
}
}
if err := s.addFixedCommitteeRoot(period+1, common.Hash(bootstrap.CommitteeBranch[0])); err != nil {
s.Reset()
return err
}
if err := s.addCommittee(period, bootstrap.Committee); err != nil {
s.Reset()
return err
}
s.changeCounter++
return nil
}
// addFixedCommitteeRoot sets a fixed committee root at the given period.
// Note that the period where the first committee is added has to have a fixed
// root which can either come from a BootstrapData or a trusted source.
func (s *CommitteeChain) addFixedCommitteeRoot(period uint64, root common.Hash) error {
if root == (common.Hash{}) {
return ErrWrongCommitteeRoot
}
batch := s.db.NewBatch()
oldRoot := s.getCommitteeRoot(period)
if !s.fixedCommitteeRoots.periods.canExpand(period) {
// Note: the fixed committee root range should always be continuous and
// therefore the expected syncing method is to forward sync and optionally
// backward sync periods one by one, starting from a checkpoint. The only
// case when a root that is not adjacent to the already fixed ones can be
// fixed is when the same root has already been proven by an update chain.
// In this case the all roots in between can and should be fixed.
// This scenario makes sense when a new trusted checkpoint is added to an
// existing chain, ensuring that it will not be rolled back (might be
// important in case of low signer participation rate).
if root != oldRoot {
return ErrInvalidPeriod
}
// if the old root exists and matches the new one then it is guaranteed
// that the given period is after the existing fixed range and the roots
// in between can also be fixed.
for p := s.fixedCommitteeRoots.periods.End; p < period; p++ {
if err := s.fixedCommitteeRoots.add(batch, p, s.getCommitteeRoot(p)); err != nil {
return err
}
}
}
if oldRoot != (common.Hash{}) && (oldRoot != root) {
// existing old root was different, we have to reorg the chain
if err := s.rollback(period); err != nil {
return err
}
}
if err := s.fixedCommitteeRoots.add(batch, period, root); err != nil {
return err
}
if err := batch.Write(); err != nil {
log.Error("Error writing batch into chain database", "error", err)
return err
}
return nil
}
// deleteFixedCommitteeRootsFrom deletes fixed roots starting from the given period.
// It also maintains chain consistency, meaning that it also deletes updates and
// committees if they are no longer supported by a valid update chain.
func (s *CommitteeChain) deleteFixedCommitteeRootsFrom(period uint64) error {
if period >= s.fixedCommitteeRoots.periods.End {
return nil
}
batch := s.db.NewBatch()
s.fixedCommitteeRoots.deleteFrom(batch, period)
if s.updates.periods.isEmpty() || period <= s.updates.periods.Start {
// Note: the first period of the update chain should always be fixed so if
// the fixed root at the first update is removed then the entire update chain
// and the proven committees have to be removed. Earlier committees in the
// remaining fixed root range can stay.
s.updates.deleteFrom(batch, period)
s.deleteCommitteesFrom(batch, period)
} else {
// The update chain stays intact, some previously fixed committee roots might
// get unfixed but are still proven by the update chain. If there were
// committees present after the range proven by updates, those should be
// removed if the belonging fixed roots are also removed.
fromPeriod := s.updates.periods.End + 1 // not proven by updates
if period > fromPeriod {
fromPeriod = period // also not justified by fixed roots
}
s.deleteCommitteesFrom(batch, fromPeriod)
}
if err := batch.Write(); err != nil {
log.Error("Error writing batch into chain database", "error", err)
return err
}
return nil
}
// deleteCommitteesFrom deletes committees starting from the given period.
func (s *CommitteeChain) deleteCommitteesFrom(batch ethdb.Batch, period uint64) {
deleted := s.committees.deleteFrom(batch, period)
for period := deleted.Start; period < deleted.End; period++ {
s.committeeCache.Remove(period)
}
}
// addCommittee adds a committee at the given period if possible.
func (s *CommitteeChain) addCommittee(period uint64, committee *types.SerializedSyncCommittee) error {
if !s.committees.periods.canExpand(period) {
return ErrInvalidPeriod
}
root := s.getCommitteeRoot(period)
if root == (common.Hash{}) {
return ErrInvalidPeriod
}
if root != committee.Root() {
return ErrWrongCommitteeRoot
}
if !s.committees.periods.contains(period) {
if err := s.committees.add(s.db, period, committee); err != nil {
return err
}
s.committeeCache.Remove(period)
}
return nil
}
// InsertUpdate adds a new update if possible.
func (s *CommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommittee *types.SerializedSyncCommittee) error {
s.chainmu.Lock()
defer s.chainmu.Unlock()
period := update.AttestedHeader.Header.SyncPeriod()
if !s.updates.periods.canExpand(period) || !s.committees.periods.contains(period) {
return ErrInvalidPeriod
}
if s.minimumUpdateScore.BetterThan(update.Score()) {
return ErrInvalidUpdate
}
oldRoot := s.getCommitteeRoot(period + 1)
reorg := oldRoot != (common.Hash{}) && oldRoot != update.NextSyncCommitteeRoot
if oldUpdate, ok := s.updates.get(s.db, period); ok && !update.Score().BetterThan(oldUpdate.Score()) {
// a better or equal update already exists; no changes, only fail if new one tried to reorg
if reorg {
return ErrCannotReorg
}
return nil
}
if s.fixedCommitteeRoots.periods.contains(period+1) && reorg {
return ErrCannotReorg
}
if ok, err := s.verifyUpdate(update); err != nil {
return err
} else if !ok {
return ErrInvalidUpdate
}
addCommittee := !s.committees.periods.contains(period+1) || reorg
if addCommittee {
if nextCommittee == nil {
return ErrNeedCommittee
}
if nextCommittee.Root() != update.NextSyncCommitteeRoot {
return ErrWrongCommitteeRoot
}
}
s.changeCounter++
if reorg {
if err := s.rollback(period + 1); err != nil {
return err
}
}
batch := s.db.NewBatch()
if addCommittee {
if err := s.committees.add(batch, period+1, nextCommittee); err != nil {
return err
}
s.committeeCache.Remove(period + 1)
}
if err := s.updates.add(batch, period, update); err != nil {
return err
}
if err := batch.Write(); err != nil {
log.Error("Error writing batch into chain database", "error", err)
return err
}
log.Info("Inserted new committee update", "period", period, "next committee root", update.NextSyncCommitteeRoot)
return nil
}
// NextSyncPeriod returns the next period where an update can be added and also
// whether the chain is initialized at all.
func (s *CommitteeChain) NextSyncPeriod() (uint64, bool) {
s.chainmu.RLock()
defer s.chainmu.RUnlock()
if s.committees.periods.isEmpty() {
return 0, false
}
if !s.updates.periods.isEmpty() {
return s.updates.periods.End, true
}
return s.committees.periods.End - 1, true
}
func (s *CommitteeChain) ChangeCounter() uint64 {
s.chainmu.RLock()
defer s.chainmu.RUnlock()
return s.changeCounter
}
// rollback removes all committees and fixed roots from the given period and updates
// starting from the previous period.
func (s *CommitteeChain) rollback(period uint64) error {
max := s.updates.periods.End + 1
if s.committees.periods.End > max {
max = s.committees.periods.End
}
if s.fixedCommitteeRoots.periods.End > max {
max = s.fixedCommitteeRoots.periods.End
}
for max > period {
max--
batch := s.db.NewBatch()
s.deleteCommitteesFrom(batch, max)
s.fixedCommitteeRoots.deleteFrom(batch, max)
if max > 0 {
s.updates.deleteFrom(batch, max-1)
}
if err := batch.Write(); err != nil {
log.Error("Error writing batch into chain database", "error", err)
return err
}
}
return nil
}
// getCommitteeRoot returns the committee root at the given period, either fixed,
// proven by a previous update or both. It returns an empty hash if the committee
// root is unknown.
func (s *CommitteeChain) getCommitteeRoot(period uint64) common.Hash {
if root, ok := s.fixedCommitteeRoots.get(s.db, period); ok || period == 0 {
return root
}
if update, ok := s.updates.get(s.db, period-1); ok {
return update.NextSyncCommitteeRoot
}
return common.Hash{}
}
// getSyncCommittee returns the deserialized sync committee at the given period.
func (s *CommitteeChain) getSyncCommittee(period uint64) (syncCommittee, error) {
if c, ok := s.committeeCache.Get(period); ok {
return c, nil
}
if sc, ok := s.committees.get(s.db, period); ok {
c, err := s.sigVerifier.deserializeSyncCommittee(sc)
if err != nil {
return nil, fmt.Errorf("sync committee #%d deserialization error: %v", period, err)
}
s.committeeCache.Add(period, c)
return c, nil
}
return nil, fmt.Errorf("missing serialized sync committee #%d", period)
}
// VerifySignedHeader returns true if the given signed header has a valid signature
// according to the local committee chain. The caller should ensure that the
// committees advertised by the same source where the signed header came from are
// synced before verifying the signature.
// The age of the header is also returned (the time elapsed since the beginning
// of the given slot, according to the local system clock). If enforceTime is
// true then negative age (future) headers are rejected.
func (s *CommitteeChain) VerifySignedHeader(head types.SignedHeader) (bool, time.Duration, error) {
s.chainmu.RLock()
defer s.chainmu.RUnlock()
return s.verifySignedHeader(head)
}
func (s *CommitteeChain) verifySignedHeader(head types.SignedHeader) (bool, time.Duration, error) {
var age time.Duration
now := s.unixNano()
if head.Header.Slot < (uint64(now-math.MinInt64)/uint64(time.Second)-s.config.GenesisTime)/12 {
age = time.Duration(now - int64(time.Second)*int64(s.config.GenesisTime+head.Header.Slot*12))
} else {
age = time.Duration(math.MinInt64)
}
if s.enforceTime && age < 0 {
return false, age, nil
}
committee, err := s.getSyncCommittee(types.SyncPeriod(head.SignatureSlot))
if err != nil {
return false, 0, err
}
if committee == nil {
return false, age, nil
}
if signingRoot, err := s.config.Forks.SigningRoot(head.Header); err == nil {
return s.sigVerifier.verifySignature(committee, signingRoot, &head.Signature), age, nil
}
return false, age, nil
}
// verifyUpdate checks whether the header signature is correct and the update
// fits into the specified constraints (assumes that the update has been
// successfully validated previously)
func (s *CommitteeChain) verifyUpdate(update *types.LightClientUpdate) (bool, error) {
// Note: SignatureSlot determines the sync period of the committee used for signature
// verification. Though in reality SignatureSlot is always bigger than update.Header.Slot,
// setting them as equal here enforces the rule that they have to be in the same sync
// period in order for the light client update proof to be meaningful.
ok, age, err := s.verifySignedHeader(update.AttestedHeader)
if age < 0 {
log.Warn("Future committee update received", "age", age)
}
return ok, err
}

View File

@@ -0,0 +1,356 @@
// Copyright 2022 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package light
import (
"crypto/rand"
"testing"
"time"
"github.com/ethereum/go-ethereum/beacon/params"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/ethdb/memorydb"
)
var (
testGenesis = newTestGenesis()
testGenesis2 = newTestGenesis()
tfBase = newTestForks(testGenesis, types.Forks{
&types.Fork{Epoch: 0, Version: []byte{0}},
})
tfAlternative = newTestForks(testGenesis, types.Forks{
&types.Fork{Epoch: 0, Version: []byte{0}},
&types.Fork{Epoch: 0x700, Version: []byte{1}},
})
tfAnotherGenesis = newTestForks(testGenesis2, types.Forks{
&types.Fork{Epoch: 0, Version: []byte{0}},
})
tcBase = newTestCommitteeChain(nil, tfBase, true, 0, 10, 400, false)
tcBaseWithInvalidUpdates = newTestCommitteeChain(tcBase, tfBase, false, 5, 10, 200, false) // signer count too low
tcBaseWithBetterUpdates = newTestCommitteeChain(tcBase, tfBase, false, 5, 10, 440, false)
tcReorgWithWorseUpdates = newTestCommitteeChain(tcBase, tfBase, true, 5, 10, 400, false)
tcReorgWithWorseUpdates2 = newTestCommitteeChain(tcBase, tfBase, true, 5, 10, 380, false)
tcReorgWithBetterUpdates = newTestCommitteeChain(tcBase, tfBase, true, 5, 10, 420, false)
tcReorgWithFinalizedUpdates = newTestCommitteeChain(tcBase, tfBase, true, 5, 10, 400, true)
tcFork = newTestCommitteeChain(tcBase, tfAlternative, true, 7, 10, 400, false)
tcAnotherGenesis = newTestCommitteeChain(nil, tfAnotherGenesis, true, 0, 10, 400, false)
)
func TestCommitteeChainFixedCommitteeRoots(t *testing.T) {
for _, reload := range []bool{false, true} {
c := newCommitteeChainTest(t, tfBase, 300, true)
c.setClockPeriod(7)
c.addFixedCommitteeRoot(tcBase, 4, nil)
c.addFixedCommitteeRoot(tcBase, 5, nil)
c.addFixedCommitteeRoot(tcBase, 6, nil)
c.addFixedCommitteeRoot(tcBase, 8, ErrInvalidPeriod) // range has to be continuous
c.addFixedCommitteeRoot(tcBase, 3, nil)
c.addFixedCommitteeRoot(tcBase, 2, nil)
if reload {
c.reloadChain()
}
c.addCommittee(tcBase, 4, nil)
c.addCommittee(tcBase, 6, ErrInvalidPeriod) // range has to be continuous
c.addCommittee(tcBase, 5, nil)
c.addCommittee(tcBase, 6, nil)
c.addCommittee(tcAnotherGenesis, 3, ErrWrongCommitteeRoot)
c.addCommittee(tcBase, 3, nil)
if reload {
c.reloadChain()
}
c.verifyRange(tcBase, 3, 6)
}
}
func TestCommitteeChainCheckpointSync(t *testing.T) {
for _, enforceTime := range []bool{false, true} {
for _, reload := range []bool{false, true} {
c := newCommitteeChainTest(t, tfBase, 300, enforceTime)
if enforceTime {
c.setClockPeriod(6)
}
c.insertUpdate(tcBase, 3, true, ErrInvalidPeriod)
c.addFixedCommitteeRoot(tcBase, 3, nil)
c.addFixedCommitteeRoot(tcBase, 4, nil)
c.insertUpdate(tcBase, 4, true, ErrInvalidPeriod) // still no committee
c.addCommittee(tcBase, 3, nil)
c.addCommittee(tcBase, 4, nil)
if reload {
c.reloadChain()
}
c.verifyRange(tcBase, 3, 4)
c.insertUpdate(tcBase, 3, false, nil) // update can be added without committee here
c.insertUpdate(tcBase, 4, false, ErrNeedCommittee) // but not here as committee 5 is not there yet
c.insertUpdate(tcBase, 4, true, nil)
c.verifyRange(tcBase, 3, 5)
c.insertUpdate(tcBaseWithInvalidUpdates, 5, true, ErrInvalidUpdate) // signer count too low
c.insertUpdate(tcBase, 5, true, nil)
if reload {
c.reloadChain()
}
if enforceTime {
c.insertUpdate(tcBase, 6, true, ErrInvalidUpdate) // future update rejected
c.setClockPeriod(7)
}
c.insertUpdate(tcBase, 6, true, nil) // when the time comes it's accepted
if reload {
c.reloadChain()
}
if enforceTime {
c.verifyRange(tcBase, 3, 6) // committee 7 is there but still in the future
c.setClockPeriod(8)
}
c.verifyRange(tcBase, 3, 7) // now period 7 can also be verified
// try reverse syncing an update
c.insertUpdate(tcBase, 2, false, ErrInvalidPeriod) // fixed committee is needed first
c.addFixedCommitteeRoot(tcBase, 2, nil)
c.addCommittee(tcBase, 2, nil)
c.insertUpdate(tcBase, 2, false, nil)
c.verifyRange(tcBase, 2, 7)
}
}
}
func TestCommitteeChainReorg(t *testing.T) {
for _, reload := range []bool{false, true} {
for _, addBetterUpdates := range []bool{false, true} {
c := newCommitteeChainTest(t, tfBase, 300, true)
c.setClockPeriod(11)
c.addFixedCommitteeRoot(tcBase, 3, nil)
c.addFixedCommitteeRoot(tcBase, 4, nil)
c.addCommittee(tcBase, 3, nil)
for period := uint64(3); period < 10; period++ {
c.insertUpdate(tcBase, period, true, nil)
}
if reload {
c.reloadChain()
}
c.verifyRange(tcBase, 3, 10)
c.insertUpdate(tcReorgWithWorseUpdates, 5, true, ErrCannotReorg)
c.insertUpdate(tcReorgWithWorseUpdates2, 5, true, ErrCannotReorg)
if addBetterUpdates {
// add better updates for the base chain and expect first reorg to fail
// (only add updates as committees should be the same)
for period := uint64(5); period < 10; period++ {
c.insertUpdate(tcBaseWithBetterUpdates, period, false, nil)
}
if reload {
c.reloadChain()
}
c.verifyRange(tcBase, 3, 10) // still on the same chain
c.insertUpdate(tcReorgWithBetterUpdates, 5, true, ErrCannotReorg)
} else {
// reorg with better updates
c.insertUpdate(tcReorgWithBetterUpdates, 5, false, ErrNeedCommittee)
c.verifyRange(tcBase, 3, 10) // no success yet, still on the base chain
c.verifyRange(tcReorgWithBetterUpdates, 3, 5)
c.insertUpdate(tcReorgWithBetterUpdates, 5, true, nil)
// successful reorg, base chain should only match before the reorg period
if reload {
c.reloadChain()
}
c.verifyRange(tcBase, 3, 5)
c.verifyRange(tcReorgWithBetterUpdates, 3, 6)
for period := uint64(6); period < 10; period++ {
c.insertUpdate(tcReorgWithBetterUpdates, period, true, nil)
}
c.verifyRange(tcReorgWithBetterUpdates, 3, 10)
}
// reorg with finalized updates; should succeed even if base chain updates
// have been improved because a finalized update beats everything else
c.insertUpdate(tcReorgWithFinalizedUpdates, 5, false, ErrNeedCommittee)
c.insertUpdate(tcReorgWithFinalizedUpdates, 5, true, nil)
if reload {
c.reloadChain()
}
c.verifyRange(tcReorgWithFinalizedUpdates, 3, 6)
for period := uint64(6); period < 10; period++ {
c.insertUpdate(tcReorgWithFinalizedUpdates, period, true, nil)
}
c.verifyRange(tcReorgWithFinalizedUpdates, 3, 10)
}
}
}
func TestCommitteeChainFork(t *testing.T) {
c := newCommitteeChainTest(t, tfAlternative, 300, true)
c.setClockPeriod(11)
// trying to sync a chain on an alternative fork with the base chain data
c.addFixedCommitteeRoot(tcBase, 0, nil)
c.addFixedCommitteeRoot(tcBase, 1, nil)
c.addCommittee(tcBase, 0, nil)
// shared section should sync without errors
for period := uint64(0); period < 7; period++ {
c.insertUpdate(tcBase, period, true, nil)
}
c.insertUpdate(tcBase, 7, true, ErrInvalidUpdate) // wrong fork
// committee root #7 is still the same but signatures are already signed with
// a different fork id so period 7 should only verify on the alternative fork
c.verifyRange(tcBase, 0, 6)
c.verifyRange(tcFork, 0, 7)
for period := uint64(7); period < 10; period++ {
c.insertUpdate(tcFork, period, true, nil)
}
c.verifyRange(tcFork, 0, 10)
// reload the chain while switching to the base fork
c.config = tfBase
c.reloadChain()
// updates 7..9 should be rolled back now
c.verifyRange(tcFork, 0, 6) // again, period 7 only verifies on the right fork
c.verifyRange(tcBase, 0, 7)
c.insertUpdate(tcFork, 7, true, ErrInvalidUpdate) // wrong fork
for period := uint64(7); period < 10; period++ {
c.insertUpdate(tcBase, period, true, nil)
}
c.verifyRange(tcBase, 0, 10)
}
type committeeChainTest struct {
t *testing.T
db *memorydb.Database
clock *mclock.Simulated
config types.ChainConfig
signerThreshold int
enforceTime bool
chain *CommitteeChain
}
func newCommitteeChainTest(t *testing.T, config types.ChainConfig, signerThreshold int, enforceTime bool) *committeeChainTest {
c := &committeeChainTest{
t: t,
db: memorydb.New(),
clock: &mclock.Simulated{},
config: config,
signerThreshold: signerThreshold,
enforceTime: enforceTime,
}
c.chain = NewTestCommitteeChain(c.db, &config, signerThreshold, enforceTime, c.clock)
return c
}
func (c *committeeChainTest) reloadChain() {
c.chain = NewTestCommitteeChain(c.db, &c.config, c.signerThreshold, c.enforceTime, c.clock)
}
func (c *committeeChainTest) setClockPeriod(period float64) {
target := mclock.AbsTime(period * float64(time.Second*12*params.SyncPeriodLength))
wait := time.Duration(target - c.clock.Now())
if wait < 0 {
c.t.Fatalf("Invalid setClockPeriod")
}
c.clock.Run(wait)
}
func (c *committeeChainTest) addFixedCommitteeRoot(tc *testCommitteeChain, period uint64, expErr error) {
if err := c.chain.addFixedCommitteeRoot(period, tc.periods[period].committee.Root()); err != expErr {
c.t.Errorf("Incorrect error output from addFixedCommitteeRoot at period %d (expected %v, got %v)", period, expErr, err)
}
}
func (c *committeeChainTest) addCommittee(tc *testCommitteeChain, period uint64, expErr error) {
if err := c.chain.addCommittee(period, tc.periods[period].committee); err != expErr {
c.t.Errorf("Incorrect error output from addCommittee at period %d (expected %v, got %v)", period, expErr, err)
}
}
func (c *committeeChainTest) insertUpdate(tc *testCommitteeChain, period uint64, addCommittee bool, expErr error) {
var committee *types.SerializedSyncCommittee
if addCommittee {
committee = tc.periods[period+1].committee
}
if err := c.chain.InsertUpdate(tc.periods[period].update, committee); err != expErr {
c.t.Errorf("Incorrect error output from InsertUpdate at period %d (expected %v, got %v)", period, expErr, err)
}
}
func (c *committeeChainTest) verifySignedHeader(tc *testCommitteeChain, period float64, expOk bool) {
slot := uint64(period * float64(params.SyncPeriodLength))
signedHead := GenerateTestSignedHeader(types.Header{Slot: slot}, &tc.config, tc.periods[types.SyncPeriod(slot)].committee, slot+1, 400)
if ok, _, _ := c.chain.VerifySignedHeader(signedHead); ok != expOk {
c.t.Errorf("Incorrect output from VerifySignedHeader at period %f (expected %v, got %v)", period, expOk, ok)
}
}
func (c *committeeChainTest) verifyRange(tc *testCommitteeChain, begin, end uint64) {
if begin > 0 {
c.verifySignedHeader(tc, float64(begin)-0.5, false)
}
for period := begin; period <= end; period++ {
c.verifySignedHeader(tc, float64(period)+0.5, true)
}
c.verifySignedHeader(tc, float64(end)+1.5, false)
}
func newTestGenesis() types.ChainConfig {
var config types.ChainConfig
rand.Read(config.GenesisValidatorsRoot[:])
return config
}
func newTestForks(config types.ChainConfig, forks types.Forks) types.ChainConfig {
for _, fork := range forks {
config.AddFork(fork.Name, fork.Epoch, fork.Version)
}
return config
}
func newTestCommitteeChain(parent *testCommitteeChain, config types.ChainConfig, newCommittees bool, begin, end int, signerCount int, finalizedHeader bool) *testCommitteeChain {
tc := &testCommitteeChain{
config: config,
}
if parent != nil {
tc.periods = make([]testPeriod, len(parent.periods))
copy(tc.periods, parent.periods)
}
if newCommittees {
if begin == 0 {
tc.fillCommittees(begin, end+1)
} else {
tc.fillCommittees(begin+1, end+1)
}
}
tc.fillUpdates(begin, end, signerCount, finalizedHeader)
return tc
}
type testPeriod struct {
committee *types.SerializedSyncCommittee
update *types.LightClientUpdate
}
type testCommitteeChain struct {
periods []testPeriod
config types.ChainConfig
}
func (tc *testCommitteeChain) fillCommittees(begin, end int) {
if len(tc.periods) <= end {
tc.periods = append(tc.periods, make([]testPeriod, end+1-len(tc.periods))...)
}
for i := begin; i <= end; i++ {
tc.periods[i].committee = GenerateTestCommittee()
}
}
func (tc *testCommitteeChain) fillUpdates(begin, end int, signerCount int, finalizedHeader bool) {
for i := begin; i <= end; i++ {
tc.periods[i].update = GenerateTestUpdate(&tc.config, uint64(i), tc.periods[i].committee, tc.periods[i+1].committee, signerCount, finalizedHeader)
}
}

View File

@@ -0,0 +1,161 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package light
import (
"errors"
"sync"
"time"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/log"
)
// HeadTracker keeps track of the latest validated head and the "prefetch" head
// which is the (not necessarily validated) head announced by the majority of
// servers.
type HeadTracker struct {
lock sync.RWMutex
committeeChain *CommitteeChain
minSignerCount int
optimisticUpdate types.OptimisticUpdate
hasOptimisticUpdate bool
finalityUpdate types.FinalityUpdate
hasFinalityUpdate bool
prefetchHead types.HeadInfo
changeCounter uint64
}
// NewHeadTracker creates a new HeadTracker.
func NewHeadTracker(committeeChain *CommitteeChain, minSignerCount int) *HeadTracker {
return &HeadTracker{
committeeChain: committeeChain,
minSignerCount: minSignerCount,
}
}
// ValidatedOptimistic returns the latest validated optimistic update.
func (h *HeadTracker) ValidatedOptimistic() (types.OptimisticUpdate, bool) {
h.lock.RLock()
defer h.lock.RUnlock()
return h.optimisticUpdate, h.hasOptimisticUpdate
}
// ValidatedFinality returns the latest validated finality update.
func (h *HeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
h.lock.RLock()
defer h.lock.RUnlock()
return h.finalityUpdate, h.hasFinalityUpdate
}
// ValidateOptimistic validates the given optimistic update. If the update is
// successfully validated and it is better than the old validated update (higher
// slot or same slot and more signers) then ValidatedOptimistic is updated.
// The boolean return flag signals if ValidatedOptimistic has been changed.
func (h *HeadTracker) ValidateOptimistic(update types.OptimisticUpdate) (bool, error) {
h.lock.Lock()
defer h.lock.Unlock()
if err := update.Validate(); err != nil {
return false, err
}
replace, err := h.validate(update.SignedHeader(), h.optimisticUpdate.SignedHeader())
if replace {
h.optimisticUpdate, h.hasOptimisticUpdate = update, true
h.changeCounter++
}
return replace, err
}
// ValidateFinality validates the given finality update. If the update is
// successfully validated and it is better than the old validated update (higher
// slot or same slot and more signers) then ValidatedFinality is updated.
// The boolean return flag signals if ValidatedFinality has been changed.
func (h *HeadTracker) ValidateFinality(update types.FinalityUpdate) (bool, error) {
h.lock.Lock()
defer h.lock.Unlock()
if err := update.Validate(); err != nil {
return false, err
}
replace, err := h.validate(update.SignedHeader(), h.finalityUpdate.SignedHeader())
if replace {
h.finalityUpdate, h.hasFinalityUpdate = update, true
h.changeCounter++
}
return replace, err
}
func (h *HeadTracker) validate(head, oldHead types.SignedHeader) (bool, error) {
signerCount := head.Signature.SignerCount()
if signerCount < h.minSignerCount {
return false, errors.New("low signer count")
}
if head.Header.Slot < oldHead.Header.Slot || (head.Header.Slot == oldHead.Header.Slot && signerCount <= oldHead.Signature.SignerCount()) {
return false, nil
}
sigOk, age, err := h.committeeChain.VerifySignedHeader(head)
if err != nil {
return false, err
}
if age < 0 {
log.Warn("Future signed head received", "age", age)
}
if age > time.Minute*2 {
log.Warn("Old signed head received", "age", age)
}
if !sigOk {
return false, errors.New("invalid header signature")
}
return true, nil
}
// PrefetchHead returns the latest known prefetch head's head info.
// This head can be used to start fetching related data hoping that it will be
// validated soon.
// Note that the prefetch head cannot be validated cryptographically so it should
// only be used as a performance optimization hint.
func (h *HeadTracker) PrefetchHead() types.HeadInfo {
h.lock.RLock()
defer h.lock.RUnlock()
return h.prefetchHead
}
// SetPrefetchHead sets the prefetch head info.
// Note that HeadTracker does not verify the prefetch head, just acts as a thread
// safe bulletin board.
func (h *HeadTracker) SetPrefetchHead(head types.HeadInfo) {
h.lock.Lock()
defer h.lock.Unlock()
if head == h.prefetchHead {
return
}
h.prefetchHead = head
h.changeCounter++
}
// ChangeCounter implements request.targetData
func (h *HeadTracker) ChangeCounter() uint64 {
h.lock.RLock()
defer h.lock.RUnlock()
return h.changeCounter
}

78
beacon/light/range.go Normal file
View File

@@ -0,0 +1,78 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package light
// periodRange represents a (possibly zero-length) range of integers (sync periods).
type periodRange struct {
Start, End uint64
}
// isEmpty returns true if the length of the range is zero.
func (a periodRange) isEmpty() bool {
return a.End == a.Start
}
// contains returns true if the range includes the given period.
func (a periodRange) contains(period uint64) bool {
return period >= a.Start && period < a.End
}
// canExpand returns true if the range includes or can be expanded with the given
// period (either the range is empty or the given period is inside, right before or
// right after the range).
func (a periodRange) canExpand(period uint64) bool {
return a.isEmpty() || (period+1 >= a.Start && period <= a.End)
}
// expand expands the range with the given period.
// This method assumes that canExpand returned true: otherwise this is a no-op.
func (a *periodRange) expand(period uint64) {
if a.isEmpty() {
a.Start, a.End = period, period+1
return
}
if a.Start == period+1 {
a.Start--
}
if a.End == period {
a.End++
}
}
// split splits the range into two ranges. The 'fromPeriod' will be the first
// element in the second range (if present).
// The original range is unchanged by this operation
func (a *periodRange) split(fromPeriod uint64) (periodRange, periodRange) {
if fromPeriod <= a.Start {
// First range empty, everything in second range,
return periodRange{}, *a
}
if fromPeriod >= a.End {
// Second range empty, everything in first range,
return *a, periodRange{}
}
x := periodRange{a.Start, fromPeriod}
y := periodRange{fromPeriod, a.End}
return x, y
}
// each invokes the supplied function fn once per period in range
func (a *periodRange) each(fn func(uint64)) {
for p := a.Start; p < a.End; p++ {
fn(p)
}
}

View File

@@ -0,0 +1,403 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package request
import (
"sync"
"github.com/ethereum/go-ethereum/log"
)
// Module represents a mechanism which is typically responsible for downloading
// and updating a passive data structure. It does not directly interact with the
// servers. It can start requests using the Requester interface, maintain its
// internal state by receiving and processing Events and update its target data
// structure based on the obtained data.
// It is the Scheduler's responsibility to feed events to the modules, call
// Process as long as there might be something to process and then generate request
// candidates using MakeRequest and start the best possible requests.
// Modules are called by Scheduler whenever a global trigger is fired. All events
// fire the trigger. Changing a target data structure also triggers a next
// processing round as it could make further actions possible either by the same
// or another Module.
type Module interface {
// Process is a non-blocking function responsible for starting requests,
// processing events and updating the target data structures(s) and the
// internal state of the module. Module state typically consists of information
// about pending requests and registered servers.
// Process is always called after an event is received or after a target data
// structure has been changed.
//
// Note: Process functions of different modules are never called concurrently;
// they are called by Scheduler in the same order of priority as they were
// registered in.
Process(Requester, []Event)
}
// Requester allows Modules to obtain the list of momentarily available servers,
// start new requests and report server failure when a response has been proven
// to be invalid in the processing phase.
// Note that all Requester functions should be safe to call from Module.Process.
type Requester interface {
CanSendTo() []Server
Send(Server, Request) ID
Fail(Server, string)
}
// Scheduler is a modular network data retrieval framework that coordinates multiple
// servers and retrieval mechanisms (modules). It implements a trigger mechanism
// that calls the Process function of registered modules whenever either the state
// of existing data structures or events coming from registered servers could
// allow new operations.
type Scheduler struct {
lock sync.Mutex
modules []Module // first has the highest priority
names map[Module]string
servers map[server]struct{}
targets map[targetData]uint64
requesterLock sync.RWMutex
serverOrder []server
pending map[ServerAndID]pendingRequest
// eventLock guards access to the events list. Note that eventLock can be
// locked either while lock is locked or unlocked but lock cannot be locked
// while eventLock is locked.
eventLock sync.Mutex
events []Event
stopCh chan chan struct{}
triggerCh chan struct{} // restarts waiting sync loop
// if trigger has already been fired then send to testWaitCh blocks until
// the triggered processing round is finished
testWaitCh chan struct{}
}
type (
// Server identifies a server without allowing any direct interaction.
// Note: server interface is used by Scheduler and Tracker but not used by
// the modules that do not interact with them directly.
// In order to make module testing easier, Server interface is used in
// events and modules.
Server interface {
Name() string
}
Request any
Response any
ID uint64
ServerAndID struct {
Server Server
ID ID
}
)
// targetData represents a registered target data structure that increases its
// ChangeCounter whenever it has been changed.
type targetData interface {
ChangeCounter() uint64
}
// pendingRequest keeps track of sent and not yet finalized requests and their
// sender modules.
type pendingRequest struct {
request Request
module Module
}
// NewScheduler creates a new Scheduler.
func NewScheduler() *Scheduler {
s := &Scheduler{
servers: make(map[server]struct{}),
names: make(map[Module]string),
pending: make(map[ServerAndID]pendingRequest),
targets: make(map[targetData]uint64),
stopCh: make(chan chan struct{}),
// Note: testWaitCh should not have capacity in order to ensure
// that after a trigger happens testWaitCh will block until the resulting
// processing round has been finished
triggerCh: make(chan struct{}, 1),
testWaitCh: make(chan struct{}),
}
return s
}
// RegisterTarget registers a target data structure, ensuring that any changes
// made to it trigger a new round of Module.Process calls, giving a chance to
// modules to react to the changes.
func (s *Scheduler) RegisterTarget(t targetData) {
s.lock.Lock()
defer s.lock.Unlock()
s.targets[t] = 0
}
// RegisterModule registers a module. Should be called before starting the scheduler.
// In each processing round the order of module processing depends on the order of
// registration.
func (s *Scheduler) RegisterModule(m Module, name string) {
s.lock.Lock()
defer s.lock.Unlock()
s.modules = append(s.modules, m)
s.names[m] = name
}
// RegisterServer registers a new server.
func (s *Scheduler) RegisterServer(server server) {
s.lock.Lock()
defer s.lock.Unlock()
s.addEvent(Event{Type: EvRegistered, Server: server})
server.subscribe(func(event Event) {
event.Server = server
s.addEvent(event)
})
}
// UnregisterServer removes a registered server.
func (s *Scheduler) UnregisterServer(server server) {
s.lock.Lock()
defer s.lock.Unlock()
server.unsubscribe()
s.addEvent(Event{Type: EvUnregistered, Server: server})
}
// Start starts the scheduler. It should be called after registering all modules
// and before registering any servers.
func (s *Scheduler) Start() {
go s.syncLoop()
}
// Stop stops the scheduler.
func (s *Scheduler) Stop() {
stop := make(chan struct{})
s.stopCh <- stop
<-stop
s.lock.Lock()
for server := range s.servers {
server.unsubscribe()
}
s.servers = nil
s.lock.Unlock()
}
// syncLoop is the main event loop responsible for event/data processing and
// sending new requests.
// A round of processing starts whenever the global trigger is fired. Triggers
// fired during a processing round ensure that there is going to be a next round.
func (s *Scheduler) syncLoop() {
for {
s.lock.Lock()
s.processRound()
s.lock.Unlock()
loop:
for {
select {
case stop := <-s.stopCh:
close(stop)
return
case <-s.triggerCh:
break loop
case <-s.testWaitCh:
}
}
}
}
// targetChanged returns true if a registered target data structure has been
// changed since the last call to this function.
func (s *Scheduler) targetChanged() (changed bool) {
for target, counter := range s.targets {
if newCounter := target.ChangeCounter(); newCounter != counter {
s.targets[target] = newCounter
changed = true
}
}
return
}
// processRound runs an entire processing round. It calls the Process functions
// of all modules, passing all relevant events and repeating Process calls as
// long as any changes have been made to the registered target data structures.
// Once all events have been processed and a stable state has been achieved,
// requests are generated and sent if necessary and possible.
func (s *Scheduler) processRound() {
for {
log.Trace("Processing modules")
filteredEvents := s.filterEvents()
for _, module := range s.modules {
log.Trace("Processing module", "name", s.names[module], "events", len(filteredEvents[module]))
module.Process(requester{s, module}, filteredEvents[module])
}
if !s.targetChanged() {
break
}
}
}
// Trigger starts a new processing round. If fired during processing, it ensures
// another full round of processing all modules.
func (s *Scheduler) Trigger() {
select {
case s.triggerCh <- struct{}{}:
default:
}
}
// addEvent adds an event to be processed in the next round. Note that it can be
// called regardless of the state of the lock mutex, making it safe for use in
// the server event callback.
func (s *Scheduler) addEvent(event Event) {
s.eventLock.Lock()
s.events = append(s.events, event)
s.eventLock.Unlock()
s.Trigger()
}
// filterEvent sorts each Event either as a request event or a server event,
// depending on its type. Request events are also sorted in a map based on the
// module that originally initiated the request. It also ensures that no events
// related to a server are returned before EvRegistered or after EvUnregistered.
// In case of an EvUnregistered server event it also closes all pending requests
// to the given server by adding a failed request event (EvFail), ensuring that
// all requests get finalized and thereby allowing the module logic to be safe
// and simple.
func (s *Scheduler) filterEvents() map[Module][]Event {
s.eventLock.Lock()
events := s.events
s.events = nil
s.eventLock.Unlock()
s.requesterLock.Lock()
defer s.requesterLock.Unlock()
filteredEvents := make(map[Module][]Event)
for _, event := range events {
server := event.Server.(server)
if _, ok := s.servers[server]; !ok && event.Type != EvRegistered {
continue // before EvRegister or after EvUnregister, discard
}
if event.IsRequestEvent() {
sid, _, _ := event.RequestInfo()
pending, ok := s.pending[sid]
if !ok {
continue // request already closed, ignore further events
}
if event.Type == EvResponse || event.Type == EvFail {
delete(s.pending, sid) // final event, close pending request
}
filteredEvents[pending.module] = append(filteredEvents[pending.module], event)
} else {
switch event.Type {
case EvRegistered:
s.servers[server] = struct{}{}
s.serverOrder = append(s.serverOrder, nil)
copy(s.serverOrder[1:], s.serverOrder[:len(s.serverOrder)-1])
s.serverOrder[0] = server
case EvUnregistered:
s.closePending(event.Server, filteredEvents)
delete(s.servers, server)
for i, srv := range s.serverOrder {
if srv == server {
copy(s.serverOrder[i:len(s.serverOrder)-1], s.serverOrder[i+1:])
s.serverOrder = s.serverOrder[:len(s.serverOrder)-1]
break
}
}
}
for _, module := range s.modules {
filteredEvents[module] = append(filteredEvents[module], event)
}
}
}
return filteredEvents
}
// closePending closes all pending requests to the given server and adds an EvFail
// event to properly finalize them
func (s *Scheduler) closePending(server Server, filteredEvents map[Module][]Event) {
for sid, pending := range s.pending {
if sid.Server == server {
filteredEvents[pending.module] = append(filteredEvents[pending.module], Event{
Type: EvFail,
Server: server,
Data: RequestResponse{
ID: sid.ID,
Request: pending.request,
},
})
delete(s.pending, sid)
}
}
}
// requester implements Requester. Note that while requester basically wraps
// Scheduler (with the added information of the currently processed Module), all
// functions are safe to call from Module.Process which is running while
// the Scheduler.lock mutex is held.
type requester struct {
*Scheduler
module Module
}
// CanSendTo returns the list of currently available servers. It also returns
// them in an order of least to most recently used, ensuring a round-robin usage
// of suitable servers if the module always chooses the first suitable one.
func (s requester) CanSendTo() []Server {
s.requesterLock.RLock()
defer s.requesterLock.RUnlock()
list := make([]Server, 0, len(s.serverOrder))
for _, server := range s.serverOrder {
if server.canRequestNow() {
list = append(list, server)
}
}
return list
}
// Send sends a request and adds an entry to Scheduler.pending map, ensuring that
// related request events will be delivered to the sender Module.
func (s requester) Send(srv Server, req Request) ID {
s.requesterLock.Lock()
defer s.requesterLock.Unlock()
server := srv.(server)
id := server.sendRequest(req)
sid := ServerAndID{Server: srv, ID: id}
s.pending[sid] = pendingRequest{request: req, module: s.module}
for i, ss := range s.serverOrder {
if ss == server {
copy(s.serverOrder[i:len(s.serverOrder)-1], s.serverOrder[i+1:])
s.serverOrder[len(s.serverOrder)-1] = server
return id
}
}
log.Error("Target server not found in ordered list of registered servers")
return id
}
// Fail should be called when a server delivers invalid or useless information.
// Calling Fail disables the given server for a period that is initially short
// but is exponentially growing if it happens frequently. This results in a
// somewhat fault tolerant operation that avoids hammering servers with requests
// that they cannot serve but still gives them a chance periodically.
func (s requester) Fail(srv Server, desc string) {
srv.(server).fail(desc)
}

View File

@@ -0,0 +1,126 @@
package request
import (
"reflect"
"testing"
)
func TestEventFilter(t *testing.T) {
s := NewScheduler()
module1 := &testModule{name: "module1"}
module2 := &testModule{name: "module2"}
s.RegisterModule(module1, "module1")
s.RegisterModule(module2, "module2")
s.Start()
// startup process round without events
s.testWaitCh <- struct{}{}
module1.expProcess(t, nil)
module2.expProcess(t, nil)
srv := &testServer{}
// register server; both modules should receive server event
s.RegisterServer(srv)
s.testWaitCh <- struct{}{}
module1.expProcess(t, []Event{
{Type: EvRegistered, Server: srv},
})
module2.expProcess(t, []Event{
{Type: EvRegistered, Server: srv},
})
// let module1 send a request
srv.canRequest = 1
module1.sendReq = testRequest
s.Trigger()
// in first triggered round module1 sends the request, no events yet
s.testWaitCh <- struct{}{}
module1.expProcess(t, nil)
module2.expProcess(t, nil)
// server emits EvTimeout; only module1 should receive it
srv.eventCb(Event{Type: EvTimeout, Data: RequestResponse{ID: 1, Request: testRequest}})
s.testWaitCh <- struct{}{}
module1.expProcess(t, []Event{
{Type: EvTimeout, Server: srv, Data: RequestResponse{ID: 1, Request: testRequest}},
})
module2.expProcess(t, nil)
// unregister server; both modules should receive server event
s.UnregisterServer(srv)
s.testWaitCh <- struct{}{}
module1.expProcess(t, []Event{
// module1 should also receive EvFail on its pending request
{Type: EvFail, Server: srv, Data: RequestResponse{ID: 1, Request: testRequest}},
{Type: EvUnregistered, Server: srv},
})
module2.expProcess(t, []Event{
{Type: EvUnregistered, Server: srv},
})
// response after server unregistered; should be discarded
srv.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
s.testWaitCh <- struct{}{}
module1.expProcess(t, nil)
module2.expProcess(t, nil)
// no more process rounds expected; shut down
s.testWaitCh <- struct{}{}
module1.expNoMoreProcess(t)
module2.expNoMoreProcess(t)
s.Stop()
}
type testServer struct {
eventCb func(Event)
lastID ID
canRequest int
}
func (s *testServer) Name() string {
return ""
}
func (s *testServer) subscribe(eventCb func(Event)) {
s.eventCb = eventCb
}
func (s *testServer) canRequestNow() bool {
return s.canRequest > 0
}
func (s *testServer) sendRequest(req Request) ID {
s.canRequest--
s.lastID++
return s.lastID
}
func (s *testServer) fail(string) {}
func (s *testServer) unsubscribe() {}
type testModule struct {
name string
processed [][]Event
sendReq Request
}
func (m *testModule) Process(requester Requester, events []Event) {
m.processed = append(m.processed, events)
if m.sendReq != nil {
if cs := requester.CanSendTo(); len(cs) > 0 {
requester.Send(cs[0], m.sendReq)
}
}
}
func (m *testModule) expProcess(t *testing.T, expEvents []Event) {
if len(m.processed) == 0 {
t.Errorf("Missing call to %s.Process", m.name)
return
}
events := m.processed[0]
m.processed = m.processed[1:]
if !reflect.DeepEqual(events, expEvents) {
t.Errorf("Call to %s.Process with wrong events (expected %v, got %v)", m.name, expEvents, events)
}
}
func (m *testModule) expNoMoreProcess(t *testing.T) {
for len(m.processed) > 0 {
t.Errorf("Unexpected call to %s.Process with events %v", m.name, m.processed[0])
m.processed = m.processed[1:]
}
}

View File

@@ -0,0 +1,451 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package request
import (
"math"
"sync"
"time"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/log"
)
var (
// request events
EvResponse = &EventType{Name: "response", requestEvent: true} // data: RequestResponse; sent by requestServer
EvFail = &EventType{Name: "fail", requestEvent: true} // data: RequestResponse; sent by requestServer
EvTimeout = &EventType{Name: "timeout", requestEvent: true} // data: RequestResponse; sent by serverWithTimeout
// server events
EvRegistered = &EventType{Name: "registered"} // data: nil; sent by Scheduler
EvUnregistered = &EventType{Name: "unregistered"} // data: nil; sent by Scheduler
EvCanRequestAgain = &EventType{Name: "canRequestAgain"} // data: nil; sent by serverWithLimits
)
const (
softRequestTimeout = time.Second // allow resending request to a different server but do not cancel yet
hardRequestTimeout = time.Second * 10 // cancel request
)
const (
// serverWithLimits parameters
parallelAdjustUp = 0.1 // adjust parallelLimit up in case of success under full load
parallelAdjustDown = 1 // adjust parallelLimit down in case of timeout/failure
minParallelLimit = 1 // parallelLimit lower bound
defaultParallelLimit = 3 // parallelLimit initial value
minFailureDelay = time.Millisecond * 100 // minimum disable time in case of request failure
maxFailureDelay = time.Minute // maximum disable time in case of request failure
maxServerEventBuffer = 5 // server event allowance buffer limit
maxServerEventRate = time.Second // server event allowance buffer recharge rate
)
// requestServer can send requests in a non-blocking way and feed back events
// through the event callback. After each request it should send back either
// EvResponse or EvFail. Additionally, it may also send application-defined
// events that the Modules can interpret.
type requestServer interface {
Name() string
Subscribe(eventCallback func(Event))
SendRequest(ID, Request)
Unsubscribe()
}
// server is implemented by a requestServer wrapped into serverWithTimeout and
// serverWithLimits and is used by Scheduler.
// In addition to requestServer functionality, server can also handle timeouts,
// limit the number of parallel in-flight requests and temporarily disable
// new requests based on timeouts and response failures.
type server interface {
Server
subscribe(eventCallback func(Event))
canRequestNow() bool
sendRequest(Request) ID
fail(string)
unsubscribe()
}
// NewServer wraps a requestServer and returns a server
func NewServer(rs requestServer, clock mclock.Clock) server {
s := &serverWithLimits{}
s.parent = rs
s.serverWithTimeout.init(clock)
s.init()
return s
}
// EventType identifies an event type, either related to a request or the server
// in general. Server events can also be externally defined.
type EventType struct {
Name string
requestEvent bool // all request events are pre-defined in request package
}
// Event describes an event where the type of Data depends on Type.
// Server field is not required when sent through the event callback; it is filled
// out when processed by the Scheduler. Note that the Scheduler can also create
// and send events (EvRegistered, EvUnregistered) directly.
type Event struct {
Type *EventType
Server Server // filled by Scheduler
Data any
}
// IsRequestEvent returns true if the event is a request event
func (e *Event) IsRequestEvent() bool {
return e.Type.requestEvent
}
// RequestInfo assumes that the event is a request event and returns its contents
// in a convenient form.
func (e *Event) RequestInfo() (ServerAndID, Request, Response) {
data := e.Data.(RequestResponse)
return ServerAndID{Server: e.Server, ID: data.ID}, data.Request, data.Response
}
// RequestResponse is the Data type of request events.
type RequestResponse struct {
ID ID
Request Request
Response Response
}
// serverWithTimeout wraps a requestServer and introduces timeouts.
// The request's lifecycle is concluded if EvResponse or EvFail emitted by the
// parent requestServer. If this does not happen until softRequestTimeout then
// EvTimeout is emitted, after which the final EvResponse or EvFail is still
// guaranteed to follow.
// If the parent fails to send this final event for hardRequestTimeout then
// serverWithTimeout emits EvFail and discards any further events from the
// parent related to the given request.
type serverWithTimeout struct {
parent requestServer
lock sync.Mutex
clock mclock.Clock
childEventCb func(event Event)
timeouts map[ID]mclock.Timer
lastID ID
}
// Name implements request.Server
func (s *serverWithTimeout) Name() string {
return s.parent.Name()
}
// init initializes serverWithTimeout
func (s *serverWithTimeout) init(clock mclock.Clock) {
s.clock = clock
s.timeouts = make(map[ID]mclock.Timer)
}
// subscribe subscribes to events which include parent (requestServer) events
// plus EvTimeout.
func (s *serverWithTimeout) subscribe(eventCallback func(event Event)) {
s.lock.Lock()
defer s.lock.Unlock()
s.childEventCb = eventCallback
s.parent.Subscribe(s.eventCallback)
}
// sendRequest generated a new request ID, emits EvRequest, sets up the timeout
// timer, then sends the request through the parent (requestServer).
func (s *serverWithTimeout) sendRequest(request Request) (reqId ID) {
s.lock.Lock()
s.lastID++
id := s.lastID
s.startTimeout(RequestResponse{ID: id, Request: request})
s.lock.Unlock()
s.parent.SendRequest(id, request)
return id
}
// eventCallback is called by parent (requestServer) event subscription.
func (s *serverWithTimeout) eventCallback(event Event) {
s.lock.Lock()
defer s.lock.Unlock()
switch event.Type {
case EvResponse, EvFail:
id := event.Data.(RequestResponse).ID
if timer, ok := s.timeouts[id]; ok {
// Note: if stopping the timer is unsuccessful then the resulting AfterFunc
// call will just do nothing
timer.Stop()
delete(s.timeouts, id)
if s.childEventCb != nil {
s.childEventCb(event)
}
}
default:
if s.childEventCb != nil {
s.childEventCb(event)
}
}
}
// startTimeout starts a timeout timer for the given request.
func (s *serverWithTimeout) startTimeout(reqData RequestResponse) {
id := reqData.ID
s.timeouts[id] = s.clock.AfterFunc(softRequestTimeout, func() {
s.lock.Lock()
if _, ok := s.timeouts[id]; !ok {
s.lock.Unlock()
return
}
s.timeouts[id] = s.clock.AfterFunc(hardRequestTimeout-softRequestTimeout, func() {
s.lock.Lock()
if _, ok := s.timeouts[id]; !ok {
s.lock.Unlock()
return
}
delete(s.timeouts, id)
childEventCb := s.childEventCb
s.lock.Unlock()
if childEventCb != nil {
childEventCb(Event{Type: EvFail, Data: reqData})
}
})
childEventCb := s.childEventCb
s.lock.Unlock()
if childEventCb != nil {
childEventCb(Event{Type: EvTimeout, Data: reqData})
}
})
}
// unsubscribe stops all goroutines associated with the server.
func (s *serverWithTimeout) unsubscribe() {
s.lock.Lock()
for _, timer := range s.timeouts {
if timer != nil {
timer.Stop()
}
}
s.lock.Unlock()
s.parent.Unsubscribe()
}
// serverWithLimits wraps serverWithTimeout and implements server. It limits the
// number of parallel in-flight requests and prevents sending new requests when a
// pending one has already timed out. Server events are also rate limited.
// It also implements a failure delay mechanism that adds an exponentially growing
// delay each time a request fails (wrong answer or hard timeout). This makes the
// syncing mechanism less brittle as temporary failures of the server might happen
// sometimes, but still avoids hammering a non-functional server with requests.
type serverWithLimits struct {
serverWithTimeout
lock sync.Mutex
childEventCb func(event Event)
softTimeouts map[ID]struct{}
pendingCount, timeoutCount int
parallelLimit float32
sendEvent bool
delayTimer mclock.Timer
delayCounter int
failureDelayEnd mclock.AbsTime
failureDelay float64
serverEventBuffer int
eventBufferUpdated mclock.AbsTime
}
// init initializes serverWithLimits
func (s *serverWithLimits) init() {
s.softTimeouts = make(map[ID]struct{})
s.parallelLimit = defaultParallelLimit
s.serverEventBuffer = maxServerEventBuffer
}
// subscribe subscribes to events which include parent (serverWithTimeout) events
// plus EvCanRequestAgain.
func (s *serverWithLimits) subscribe(eventCallback func(event Event)) {
s.lock.Lock()
defer s.lock.Unlock()
s.childEventCb = eventCallback
s.serverWithTimeout.subscribe(s.eventCallback)
}
// eventCallback is called by parent (serverWithTimeout) event subscription.
func (s *serverWithLimits) eventCallback(event Event) {
s.lock.Lock()
var sendCanRequestAgain bool
passEvent := true
switch event.Type {
case EvTimeout:
id := event.Data.(RequestResponse).ID
s.softTimeouts[id] = struct{}{}
s.timeoutCount++
s.parallelLimit -= parallelAdjustDown
if s.parallelLimit < minParallelLimit {
s.parallelLimit = minParallelLimit
}
log.Debug("Server timeout", "count", s.timeoutCount, "parallelLimit", s.parallelLimit)
case EvResponse, EvFail:
id := event.Data.(RequestResponse).ID
if _, ok := s.softTimeouts[id]; ok {
delete(s.softTimeouts, id)
s.timeoutCount--
log.Debug("Server timeout finalized", "count", s.timeoutCount, "parallelLimit", s.parallelLimit)
}
if event.Type == EvResponse && s.pendingCount >= int(s.parallelLimit) {
s.parallelLimit += parallelAdjustUp
}
s.pendingCount--
if s.canRequest() {
sendCanRequestAgain = s.sendEvent
s.sendEvent = false
}
if event.Type == EvFail {
s.failLocked("failed request")
}
default:
// server event; check rate limit
if s.serverEventBuffer < maxServerEventBuffer {
now := s.clock.Now()
sinceUpdate := time.Duration(now - s.eventBufferUpdated)
if sinceUpdate >= maxServerEventRate*time.Duration(maxServerEventBuffer-s.serverEventBuffer) {
s.serverEventBuffer = maxServerEventBuffer
s.eventBufferUpdated = now
} else {
addBuffer := int(sinceUpdate / maxServerEventRate)
s.serverEventBuffer += addBuffer
s.eventBufferUpdated += mclock.AbsTime(maxServerEventRate * time.Duration(addBuffer))
}
}
if s.serverEventBuffer > 0 {
s.serverEventBuffer--
} else {
passEvent = false
}
}
childEventCb := s.childEventCb
s.lock.Unlock()
if passEvent && childEventCb != nil {
childEventCb(event)
}
if sendCanRequestAgain && childEventCb != nil {
childEventCb(Event{Type: EvCanRequestAgain})
}
}
// sendRequest sends a request through the parent (serverWithTimeout).
func (s *serverWithLimits) sendRequest(request Request) (reqId ID) {
s.lock.Lock()
s.pendingCount++
s.lock.Unlock()
return s.serverWithTimeout.sendRequest(request)
}
// unsubscribe stops all goroutines associated with the server.
func (s *serverWithLimits) unsubscribe() {
s.lock.Lock()
if s.delayTimer != nil {
s.delayTimer.Stop()
s.delayTimer = nil
}
s.childEventCb = nil
s.lock.Unlock()
s.serverWithTimeout.unsubscribe()
}
// canRequest checks whether a new request can be started.
func (s *serverWithLimits) canRequest() bool {
if s.delayTimer != nil || s.pendingCount >= int(s.parallelLimit) || s.timeoutCount > 0 {
return false
}
if s.parallelLimit < minParallelLimit {
s.parallelLimit = minParallelLimit
}
return true
}
// canRequestNow checks whether a new request can be started, according to the
// current in-flight request count and parallelLimit, and also the failure delay
// timer.
// If it returns false then it is guaranteed that an EvCanRequestAgain will be
// sent whenever the server becomes available for requesting again.
func (s *serverWithLimits) canRequestNow() bool {
var sendCanRequestAgain bool
s.lock.Lock()
canRequest := s.canRequest()
if canRequest {
sendCanRequestAgain = s.sendEvent
s.sendEvent = false
}
childEventCb := s.childEventCb
s.lock.Unlock()
if sendCanRequestAgain && childEventCb != nil {
childEventCb(Event{Type: EvCanRequestAgain})
}
return canRequest
}
// delay sets the delay timer to the given duration, disabling new requests for
// the given period.
func (s *serverWithLimits) delay(delay time.Duration) {
if s.delayTimer != nil {
// Note: if stopping the timer is unsuccessful then the resulting AfterFunc
// call will just do nothing
s.delayTimer.Stop()
s.delayTimer = nil
}
s.delayCounter++
delayCounter := s.delayCounter
log.Debug("Server delay started", "length", delay)
s.delayTimer = s.clock.AfterFunc(delay, func() {
log.Debug("Server delay ended", "length", delay)
var sendCanRequestAgain bool
s.lock.Lock()
if s.delayTimer != nil && s.delayCounter == delayCounter { // do nothing if there is a new timer now
s.delayTimer = nil
if s.canRequest() {
sendCanRequestAgain = s.sendEvent
s.sendEvent = false
}
}
childEventCb := s.childEventCb
s.lock.Unlock()
if sendCanRequestAgain && childEventCb != nil {
childEventCb(Event{Type: EvCanRequestAgain})
}
})
}
// fail reports that a response from the server was found invalid by the processing
// Module, disabling new requests for a dynamically adjusted time period.
func (s *serverWithLimits) fail(desc string) {
s.lock.Lock()
defer s.lock.Unlock()
s.failLocked(desc)
}
// failLocked calculates the dynamic failure delay and applies it.
func (s *serverWithLimits) failLocked(desc string) {
log.Debug("Server error", "description", desc)
s.failureDelay *= 2
now := s.clock.Now()
if now > s.failureDelayEnd {
s.failureDelay *= math.Pow(2, -float64(now-s.failureDelayEnd)/float64(maxFailureDelay))
}
if s.failureDelay < float64(minFailureDelay) {
s.failureDelay = float64(minFailureDelay)
}
s.failureDelayEnd = now + mclock.AbsTime(s.failureDelay)
s.delay(time.Duration(s.failureDelay))
}

View File

@@ -0,0 +1,182 @@
package request
import (
"testing"
"github.com/ethereum/go-ethereum/common/mclock"
)
const (
testRequest = "Life, the Universe, and Everything"
testResponse = 42
)
var testEventType = &EventType{Name: "testEvent"}
func TestServerEvents(t *testing.T) {
rs := &testRequestServer{}
clock := &mclock.Simulated{}
srv := NewServer(rs, clock)
var lastEventType *EventType
srv.subscribe(func(event Event) { lastEventType = event.Type })
evTypeName := func(evType *EventType) string {
if evType == nil {
return "none"
}
return evType.Name
}
expEvent := func(expType *EventType) {
if lastEventType != expType {
t.Errorf("Wrong event type (expected %s, got %s)", evTypeName(expType), evTypeName(lastEventType))
}
lastEventType = nil
}
// user events should simply be passed through
rs.eventCb(Event{Type: testEventType})
expEvent(testEventType)
// send request, soft timeout, then valid response
srv.sendRequest(testRequest)
clock.WaitForTimers(1)
clock.Run(softRequestTimeout)
expEvent(EvTimeout)
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
expEvent(EvResponse)
// send request, hard timeout (response after hard timeout should be ignored)
srv.sendRequest(testRequest)
clock.WaitForTimers(1)
clock.Run(softRequestTimeout)
expEvent(EvTimeout)
clock.WaitForTimers(1)
clock.Run(hardRequestTimeout)
expEvent(EvFail)
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
expEvent(nil)
srv.unsubscribe()
}
func TestServerParallel(t *testing.T) {
rs := &testRequestServer{}
srv := NewServer(rs, &mclock.Simulated{})
srv.subscribe(func(event Event) {})
expSend := func(expSent int) {
var sent int
for sent <= expSent {
if !srv.canRequestNow() {
break
}
sent++
srv.sendRequest(testRequest)
}
if sent != expSent {
t.Errorf("Wrong number of parallel requests accepted (expected %d, got %d)", expSent, sent)
}
}
// max out parallel allowance
expSend(defaultParallelLimit)
// 1 answered, should accept 1 more
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
expSend(1)
// 2 answered, should accept 2 more
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 2, Request: testRequest, Response: testResponse}})
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 3, Request: testRequest, Response: testResponse}})
expSend(2)
// failed request, should decrease allowance and not accept more
rs.eventCb(Event{Type: EvFail, Data: RequestResponse{ID: 4, Request: testRequest}})
expSend(0)
srv.unsubscribe()
}
func TestServerFail(t *testing.T) {
rs := &testRequestServer{}
clock := &mclock.Simulated{}
srv := NewServer(rs, clock)
srv.subscribe(func(event Event) {})
expCanRequest := func(expCanRequest bool) {
if canRequest := srv.canRequestNow(); canRequest != expCanRequest {
t.Errorf("Wrong result for canRequestNow (expected %v, got %v)", expCanRequest, canRequest)
}
}
// timed out request
expCanRequest(true)
srv.sendRequest(testRequest)
clock.WaitForTimers(1)
expCanRequest(true)
clock.Run(softRequestTimeout)
expCanRequest(false) // cannot request when there is a timed out request
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
expCanRequest(true)
// explicit server.Fail
srv.fail("")
clock.WaitForTimers(1)
expCanRequest(false) // cannot request for a while after a failure
clock.Run(minFailureDelay)
expCanRequest(true)
// request returned with EvFail
srv.sendRequest(testRequest)
rs.eventCb(Event{Type: EvFail, Data: RequestResponse{ID: 2, Request: testRequest}})
clock.WaitForTimers(1)
expCanRequest(false) // EvFail should also start failure delay
clock.Run(minFailureDelay)
expCanRequest(false) // second failure delay is longer, should still be disabled
clock.Run(minFailureDelay)
expCanRequest(true)
srv.unsubscribe()
}
func TestServerEventRateLimit(t *testing.T) {
rs := &testRequestServer{}
clock := &mclock.Simulated{}
srv := NewServer(rs, clock)
var eventCount int
srv.subscribe(func(event Event) {
eventCount++
})
expEvents := func(send, expAllowed int) {
eventCount = 0
for sent := 0; sent < send; sent++ {
rs.eventCb(Event{Type: testEventType})
}
if eventCount != expAllowed {
t.Errorf("Wrong number of server events passing rate limitation (sent %d, expected %d, got %d)", send, expAllowed, eventCount)
}
}
expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
clock.Run(maxServerEventRate)
expEvents(5, 1)
clock.Run(maxServerEventRate * maxServerEventBuffer * 2)
expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
srv.unsubscribe()
}
func TestServerUnsubscribe(t *testing.T) {
rs := &testRequestServer{}
clock := &mclock.Simulated{}
srv := NewServer(rs, clock)
var eventCount int
srv.subscribe(func(event Event) {
eventCount++
})
eventCb := rs.eventCb
eventCb(Event{Type: testEventType})
if eventCount != 1 {
t.Errorf("Server event callback not called before unsubscribe")
}
srv.unsubscribe()
if rs.eventCb != nil {
t.Errorf("Server event callback not removed after unsubscribe")
}
eventCb(Event{Type: testEventType})
if eventCount != 1 {
t.Errorf("Server event callback called after unsubscribe")
}
}
type testRequestServer struct {
eventCb func(Event)
}
func (rs *testRequestServer) Name() string { return "" }
func (rs *testRequestServer) Subscribe(eventCb func(Event)) { rs.eventCb = eventCb }
func (rs *testRequestServer) SendRequest(ID, Request) {}
func (rs *testRequestServer) Unsubscribe() { rs.eventCb = nil }

View File

@@ -0,0 +1,202 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package sync
import (
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/log"
)
type headTracker interface {
ValidateOptimistic(update types.OptimisticUpdate) (bool, error)
ValidateFinality(head types.FinalityUpdate) (bool, error)
ValidatedFinality() (types.FinalityUpdate, bool)
SetPrefetchHead(head types.HeadInfo)
}
// HeadSync implements request.Module; it updates the validated and prefetch
// heads of HeadTracker based on the EvHead and EvSignedHead events coming from
// registered servers.
// It can also postpone the validation of the latest announced signed head
// until the committee chain is synced up to at least the required period.
type HeadSync struct {
headTracker headTracker
chain committeeChain
nextSyncPeriod uint64
chainInit bool
unvalidatedOptimistic map[request.Server]types.OptimisticUpdate
unvalidatedFinality map[request.Server]types.FinalityUpdate
serverHeads map[request.Server]types.HeadInfo
reqFinalityEpoch map[request.Server]uint64 // next epoch to request finality update
headServerCount map[types.HeadInfo]headServerCount
headCounter uint64
prefetchHead types.HeadInfo
}
// headServerCount is associated with most recently seen head infos; it counts
// the number of servers currently having the given head info as their announced
// head and a counter signaling how recent that head is.
// This data is used for selecting the prefetch head.
type headServerCount struct {
serverCount int
headCounter uint64
}
// NewHeadSync creates a new HeadSync.
func NewHeadSync(headTracker headTracker, chain committeeChain) *HeadSync {
s := &HeadSync{
headTracker: headTracker,
chain: chain,
unvalidatedOptimistic: make(map[request.Server]types.OptimisticUpdate),
unvalidatedFinality: make(map[request.Server]types.FinalityUpdate),
serverHeads: make(map[request.Server]types.HeadInfo),
headServerCount: make(map[types.HeadInfo]headServerCount),
reqFinalityEpoch: make(map[request.Server]uint64),
}
return s
}
// Process implements request.Module.
func (s *HeadSync) Process(requester request.Requester, events []request.Event) {
nextPeriod, chainInit := s.chain.NextSyncPeriod()
if nextPeriod != s.nextSyncPeriod || chainInit != s.chainInit {
s.nextSyncPeriod, s.chainInit = nextPeriod, chainInit
s.processUnvalidatedUpdates()
}
for _, event := range events {
switch event.Type {
case EvNewHead:
s.setServerHead(event.Server, event.Data.(types.HeadInfo))
case EvNewOptimisticUpdate:
update := event.Data.(types.OptimisticUpdate)
s.newOptimisticUpdate(event.Server, update)
epoch := update.Attested.Epoch()
if epoch < s.reqFinalityEpoch[event.Server] {
continue
}
if finality, ok := s.headTracker.ValidatedFinality(); ok && finality.Attested.Header.Epoch() >= epoch {
continue
}
requester.Send(event.Server, ReqFinality{})
s.reqFinalityEpoch[event.Server] = epoch + 1
case EvNewFinalityUpdate:
s.newFinalityUpdate(event.Server, event.Data.(types.FinalityUpdate))
case request.EvResponse:
_, _, resp := event.RequestInfo()
s.newFinalityUpdate(event.Server, resp.(types.FinalityUpdate))
case request.EvUnregistered:
s.setServerHead(event.Server, types.HeadInfo{})
delete(s.serverHeads, event.Server)
delete(s.unvalidatedOptimistic, event.Server)
delete(s.unvalidatedFinality, event.Server)
}
}
}
// newOptimisticUpdate handles received optimistic update; either validates it if
// the chain is properly synced or stores it for further validation.
func (s *HeadSync) newOptimisticUpdate(server request.Server, optimisticUpdate types.OptimisticUpdate) {
if !s.chainInit || types.SyncPeriod(optimisticUpdate.SignatureSlot) > s.nextSyncPeriod {
s.unvalidatedOptimistic[server] = optimisticUpdate
return
}
if _, err := s.headTracker.ValidateOptimistic(optimisticUpdate); err != nil {
log.Debug("Error validating optimistic update", "error", err)
}
}
// newFinalityUpdate handles received finality update; either validates it if
// the chain is properly synced or stores it for further validation.
func (s *HeadSync) newFinalityUpdate(server request.Server, finalityUpdate types.FinalityUpdate) {
if !s.chainInit || types.SyncPeriod(finalityUpdate.SignatureSlot) > s.nextSyncPeriod {
s.unvalidatedFinality[server] = finalityUpdate
return
}
if _, err := s.headTracker.ValidateFinality(finalityUpdate); err != nil {
log.Debug("Error validating finality update", "error", err)
}
}
// processUnvalidatedUpdates iterates the list of unvalidated updates and validates
// those which can be validated.
func (s *HeadSync) processUnvalidatedUpdates() {
if !s.chainInit {
return
}
for server, optimisticUpdate := range s.unvalidatedOptimistic {
if types.SyncPeriod(optimisticUpdate.SignatureSlot) <= s.nextSyncPeriod {
if _, err := s.headTracker.ValidateOptimistic(optimisticUpdate); err != nil {
log.Debug("Error validating deferred optimistic update", "error", err)
}
delete(s.unvalidatedOptimistic, server)
}
}
for server, finalityUpdate := range s.unvalidatedFinality {
if types.SyncPeriod(finalityUpdate.SignatureSlot) <= s.nextSyncPeriod {
if _, err := s.headTracker.ValidateFinality(finalityUpdate); err != nil {
log.Debug("Error validating deferred finality update", "error", err)
}
delete(s.unvalidatedFinality, server)
}
}
}
// setServerHead processes non-validated server head announcements and updates
// the prefetch head if necessary.
func (s *HeadSync) setServerHead(server request.Server, head types.HeadInfo) bool {
if oldHead, ok := s.serverHeads[server]; ok {
if head == oldHead {
return false
}
h := s.headServerCount[oldHead]
if h.serverCount--; h.serverCount > 0 {
s.headServerCount[oldHead] = h
} else {
delete(s.headServerCount, oldHead)
}
}
if head != (types.HeadInfo{}) {
h, ok := s.headServerCount[head]
if !ok {
s.headCounter++
h.headCounter = s.headCounter
}
h.serverCount++
s.headServerCount[head] = h
s.serverHeads[server] = head
} else {
delete(s.serverHeads, server)
}
var (
bestHead types.HeadInfo
bestHeadInfo headServerCount
)
for head, headServerCount := range s.headServerCount {
if headServerCount.serverCount > bestHeadInfo.serverCount ||
(headServerCount.serverCount == bestHeadInfo.serverCount && headServerCount.headCounter > bestHeadInfo.headCounter) {
bestHead, bestHeadInfo = head, headServerCount
}
}
if bestHead == s.prefetchHead {
return false
}
s.prefetchHead = bestHead
s.headTracker.SetPrefetchHead(bestHead)
return true
}

View File

@@ -0,0 +1,183 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package sync
import (
"testing"
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/types"
"github.com/ethereum/go-ethereum/common"
)
var (
testServer1 = testServer("testServer1")
testServer2 = testServer("testServer2")
testServer3 = testServer("testServer3")
testServer4 = testServer("testServer4")
testServer5 = testServer("testServer5")
testHead0 = types.HeadInfo{}
testHead1 = types.HeadInfo{Slot: 123, BlockRoot: common.Hash{1}}
testHead2 = types.HeadInfo{Slot: 124, BlockRoot: common.Hash{2}}
testHead3 = types.HeadInfo{Slot: 124, BlockRoot: common.Hash{3}}
testHead4 = types.HeadInfo{Slot: 125, BlockRoot: common.Hash{4}}
testOptUpdate1 = types.OptimisticUpdate{SignatureSlot: 0x0124, Attested: types.HeaderWithExecProof{Header: types.Header{Slot: 0x0123, StateRoot: common.Hash{1}}}}
testOptUpdate2 = types.OptimisticUpdate{SignatureSlot: 0x2010, Attested: types.HeaderWithExecProof{Header: types.Header{Slot: 0x200e, StateRoot: common.Hash{2}}}}
// testOptUpdate3 is at the end of period 1 but signed in period 2
testOptUpdate3 = types.OptimisticUpdate{SignatureSlot: 0x4000, Attested: types.HeaderWithExecProof{Header: types.Header{Slot: 0x3fff, StateRoot: common.Hash{3}}}}
testOptUpdate4 = types.OptimisticUpdate{SignatureSlot: 0x6444, Attested: types.HeaderWithExecProof{Header: types.Header{Slot: 0x6443, StateRoot: common.Hash{4}}}}
)
func finality(opt types.OptimisticUpdate) types.FinalityUpdate {
return types.FinalityUpdate{
SignatureSlot: opt.SignatureSlot,
Attested: opt.Attested,
Finalized: types.HeaderWithExecProof{Header: types.Header{Slot: (opt.Attested.Header.Slot - 64) & uint64(0xffffffffffffffe0)}},
}
}
type testServer string
func (t testServer) Name() string {
return string(t)
}
func TestValidatedHead(t *testing.T) {
chain := &TestCommitteeChain{}
ht := &TestHeadTracker{}
headSync := NewHeadSync(ht, chain)
ts := NewTestScheduler(t, headSync)
ht.ExpValidated(t, 0, nil)
ts.AddServer(testServer1, 1)
ts.ServerEvent(EvNewOptimisticUpdate, testServer1, testOptUpdate1)
ts.Run(1, testServer1, ReqFinality{})
// announced head should be queued because of uninitialized chain
ht.ExpValidated(t, 1, nil)
chain.SetNextSyncPeriod(0) // initialize chain
ts.Run(2)
// expect previously queued head to be validated
ht.ExpValidated(t, 2, []types.OptimisticUpdate{testOptUpdate1})
chain.SetNextSyncPeriod(1)
ts.ServerEvent(EvNewFinalityUpdate, testServer1, finality(testOptUpdate2))
ts.ServerEvent(EvNewOptimisticUpdate, testServer1, testOptUpdate2)
ts.AddServer(testServer2, 1)
ts.ServerEvent(EvNewOptimisticUpdate, testServer2, testOptUpdate2)
ts.Run(3)
// expect both head announcements to be validated instantly
ht.ExpValidated(t, 3, []types.OptimisticUpdate{testOptUpdate2, testOptUpdate2})
ts.ServerEvent(EvNewOptimisticUpdate, testServer1, testOptUpdate3)
ts.AddServer(testServer3, 1)
ts.ServerEvent(EvNewOptimisticUpdate, testServer3, testOptUpdate4)
// finality should be requested from both servers
ts.Run(4, testServer1, ReqFinality{}, testServer3, ReqFinality{})
// future period announced heads should be queued
ht.ExpValidated(t, 4, nil)
chain.SetNextSyncPeriod(2)
ts.Run(5)
// testOptUpdate3 can be validated now but not testOptUpdate4
ht.ExpValidated(t, 5, []types.OptimisticUpdate{testOptUpdate3})
ts.AddServer(testServer4, 1)
ts.ServerEvent(EvNewOptimisticUpdate, testServer4, testOptUpdate3)
// new server joined with recent optimistic update but still no finality; should be requested
ts.Run(6, testServer4, ReqFinality{})
ht.ExpValidated(t, 6, []types.OptimisticUpdate{testOptUpdate3})
ts.AddServer(testServer5, 1)
ts.RequestEvent(request.EvResponse, ts.Request(6, 1), finality(testOptUpdate3))
ts.ServerEvent(EvNewOptimisticUpdate, testServer5, testOptUpdate3)
// finality update request answered; new server should not be requested
ts.Run(7)
ht.ExpValidated(t, 7, []types.OptimisticUpdate{testOptUpdate3})
// server 3 disconnected without proving period 3, its announced head should be dropped
ts.RemoveServer(testServer3)
ts.Run(8)
ht.ExpValidated(t, 8, nil)
chain.SetNextSyncPeriod(3)
ts.Run(9)
// testOptUpdate4 could be validated now but it's not queued by any registered server
ht.ExpValidated(t, 9, nil)
ts.ServerEvent(EvNewFinalityUpdate, testServer2, finality(testOptUpdate4))
ts.ServerEvent(EvNewOptimisticUpdate, testServer2, testOptUpdate4)
ts.Run(10)
// now testOptUpdate4 should be validated
ht.ExpValidated(t, 10, []types.OptimisticUpdate{testOptUpdate4})
}
func TestPrefetchHead(t *testing.T) {
chain := &TestCommitteeChain{}
ht := &TestHeadTracker{}
headSync := NewHeadSync(ht, chain)
ts := NewTestScheduler(t, headSync)
ht.ExpPrefetch(t, 0, testHead0) // no servers registered
ts.AddServer(testServer1, 1)
ts.ServerEvent(EvNewHead, testServer1, testHead1)
ts.Run(1)
ht.ExpPrefetch(t, 1, testHead1) // s1: h1
ts.AddServer(testServer2, 1)
ts.ServerEvent(EvNewHead, testServer2, testHead2)
ts.Run(2)
ht.ExpPrefetch(t, 2, testHead2) // s1: h1, s2: h2
ts.ServerEvent(EvNewHead, testServer1, testHead2)
ts.Run(3)
ht.ExpPrefetch(t, 3, testHead2) // s1: h2, s2: h2
ts.AddServer(testServer3, 1)
ts.ServerEvent(EvNewHead, testServer3, testHead3)
ts.Run(4)
ht.ExpPrefetch(t, 4, testHead2) // s1: h2, s2: h2, s3: h3
ts.AddServer(testServer4, 1)
ts.ServerEvent(EvNewHead, testServer4, testHead4)
ts.Run(5)
ht.ExpPrefetch(t, 5, testHead2) // s1: h2, s2: h2, s3: h3, s4: h4
ts.ServerEvent(EvNewHead, testServer2, testHead3)
ts.Run(6)
ht.ExpPrefetch(t, 6, testHead3) // s1: h2, s2: h3, s3: h3, s4: h4
ts.RemoveServer(testServer3)
ts.Run(7)
ht.ExpPrefetch(t, 7, testHead4) // s1: h2, s2: h3, s4: h4
ts.RemoveServer(testServer1)
ts.Run(8)
ht.ExpPrefetch(t, 8, testHead4) // s2: h3, s4: h4
ts.RemoveServer(testServer4)
ts.Run(9)
ht.ExpPrefetch(t, 9, testHead3) // s2: h3
ts.RemoveServer(testServer2)
ts.Run(10)
ht.ExpPrefetch(t, 10, testHead0) // no servers registered
}

View File

@@ -0,0 +1,259 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package sync
import (
"reflect"
"testing"
"github.com/ethereum/go-ethereum/beacon/light"
"github.com/ethereum/go-ethereum/beacon/light/request"
"github.com/ethereum/go-ethereum/beacon/types"
)
type requestWithID struct {
sid request.ServerAndID
request request.Request
}
type TestScheduler struct {
t *testing.T
module request.Module
events []request.Event
servers []request.Server
allowance map[request.Server]int
sent map[int][]requestWithID
testIndex int
expFail map[request.Server]int // expected Server.Fail calls during next Run
lastId request.ID
}
func NewTestScheduler(t *testing.T, module request.Module) *TestScheduler {
return &TestScheduler{
t: t,
module: module,
allowance: make(map[request.Server]int),
expFail: make(map[request.Server]int),
sent: make(map[int][]requestWithID),
}
}
func (ts *TestScheduler) Run(testIndex int, exp ...any) {
expReqs := make([]requestWithID, len(exp)/2)
id := ts.lastId
for i := range expReqs {
id++
expReqs[i] = requestWithID{
sid: request.ServerAndID{Server: exp[i*2].(request.Server), ID: id},
request: exp[i*2+1].(request.Request),
}
}
if len(expReqs) == 0 {
expReqs = nil
}
ts.testIndex = testIndex
ts.module.Process(ts, ts.events)
ts.events = nil
for server, count := range ts.expFail {
delete(ts.expFail, server)
if count == 0 {
continue
}
ts.t.Errorf("Missing %d Server.Fail(s) from server %s in test case #%d", count, server.Name(), testIndex)
}
if !reflect.DeepEqual(ts.sent[testIndex], expReqs) {
ts.t.Errorf("Wrong sent requests in test case #%d (expected %v, got %v)", testIndex, expReqs, ts.sent[testIndex])
}
}
func (ts *TestScheduler) CanSendTo() (cs []request.Server) {
for _, server := range ts.servers {
if ts.allowance[server] > 0 {
cs = append(cs, server)
}
}
return
}
func (ts *TestScheduler) Send(server request.Server, req request.Request) request.ID {
ts.lastId++
ts.sent[ts.testIndex] = append(ts.sent[ts.testIndex], requestWithID{
sid: request.ServerAndID{Server: server, ID: ts.lastId},
request: req,
})
ts.allowance[server]--
return ts.lastId
}
func (ts *TestScheduler) Fail(server request.Server, desc string) {
if ts.expFail[server] == 0 {
ts.t.Errorf("Unexpected Fail from server %s in test case #%d: %s", server.Name(), ts.testIndex, desc)
return
}
ts.expFail[server]--
}
func (ts *TestScheduler) Request(testIndex, reqIndex int) requestWithID {
if len(ts.sent[testIndex]) < reqIndex {
ts.t.Errorf("Missing request from test case %d index %d", testIndex, reqIndex)
return requestWithID{}
}
return ts.sent[testIndex][reqIndex-1]
}
func (ts *TestScheduler) ServerEvent(evType *request.EventType, server request.Server, data any) {
ts.events = append(ts.events, request.Event{
Type: evType,
Server: server,
Data: data,
})
}
func (ts *TestScheduler) RequestEvent(evType *request.EventType, req requestWithID, resp request.Response) {
if req.request == nil {
return
}
ts.events = append(ts.events, request.Event{
Type: evType,
Server: req.sid.Server,
Data: request.RequestResponse{
ID: req.sid.ID,
Request: req.request,
Response: resp,
},
})
}
func (ts *TestScheduler) AddServer(server request.Server, allowance int) {
ts.servers = append(ts.servers, server)
ts.allowance[server] = allowance
ts.ServerEvent(request.EvRegistered, server, nil)
}
func (ts *TestScheduler) RemoveServer(server request.Server) {
ts.servers = append(ts.servers, server)
for i, s := range ts.servers {
if s == server {
copy(ts.servers[i:len(ts.servers)-1], ts.servers[i+1:])
ts.servers = ts.servers[:len(ts.servers)-1]
break
}
}
delete(ts.allowance, server)
ts.ServerEvent(request.EvUnregistered, server, nil)
}
func (ts *TestScheduler) AddAllowance(server request.Server, allowance int) {
ts.allowance[server] += allowance
}
func (ts *TestScheduler) ExpFail(server request.Server) {
ts.expFail[server]++
}
type TestCommitteeChain struct {
fsp, nsp uint64
init bool
}
func (tc *TestCommitteeChain) CheckpointInit(bootstrap types.BootstrapData) error {
tc.fsp, tc.nsp, tc.init = bootstrap.Header.SyncPeriod(), bootstrap.Header.SyncPeriod()+2, true
return nil
}
func (tc *TestCommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommittee *types.SerializedSyncCommittee) error {
period := update.AttestedHeader.Header.SyncPeriod()
if period < tc.fsp || period > tc.nsp || !tc.init {
return light.ErrInvalidPeriod
}
if period == tc.nsp {
tc.nsp++
}
return nil
}
func (tc *TestCommitteeChain) NextSyncPeriod() (uint64, bool) {
return tc.nsp, tc.init
}
func (tc *TestCommitteeChain) ExpInit(t *testing.T, ExpInit bool) {
if tc.init != ExpInit {
t.Errorf("Incorrect init flag (expected %v, got %v)", ExpInit, tc.init)
}
}
func (tc *TestCommitteeChain) SetNextSyncPeriod(nsp uint64) {
tc.init, tc.nsp = true, nsp
}
func (tc *TestCommitteeChain) ExpNextSyncPeriod(t *testing.T, expNsp uint64) {
tc.ExpInit(t, true)
if tc.nsp != expNsp {
t.Errorf("Incorrect NextSyncPeriod (expected %d, got %d)", expNsp, tc.nsp)
}
}
type TestHeadTracker struct {
phead types.HeadInfo
validated []types.OptimisticUpdate
finality types.FinalityUpdate
}
func (ht *TestHeadTracker) ValidateOptimistic(update types.OptimisticUpdate) (bool, error) {
ht.validated = append(ht.validated, update)
return true, nil
}
func (ht *TestHeadTracker) ValidateFinality(update types.FinalityUpdate) (bool, error) {
ht.finality = update
return true, nil
}
func (ht *TestHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
return ht.finality, ht.finality.Attested.Header != (types.Header{})
}
func (ht *TestHeadTracker) ExpValidated(t *testing.T, tci int, expHeads []types.OptimisticUpdate) {
for i, expHead := range expHeads {
if i >= len(ht.validated) {
t.Errorf("Missing validated head in test case #%d index #%d (expected {slot %d blockRoot %x}, got none)", tci, i, expHead.Attested.Header.Slot, expHead.Attested.Header.Hash())
continue
}
if !reflect.DeepEqual(ht.validated[i], expHead) {
vhead := ht.validated[i].Attested.Header
t.Errorf("Wrong validated head in test case #%d index #%d (expected {slot %d blockRoot %x}, got {slot %d blockRoot %x})", tci, i, expHead.Attested.Header.Slot, expHead.Attested.Header.Hash(), vhead.Slot, vhead.Hash())
}
}
for i := len(expHeads); i < len(ht.validated); i++ {
vhead := ht.validated[i].Attested.Header
t.Errorf("Unexpected validated head in test case #%d index #%d (expected none, got {slot %d blockRoot %x})", tci, i, vhead.Slot, vhead.Hash())
}
ht.validated = nil
}
func (ht *TestHeadTracker) SetPrefetchHead(head types.HeadInfo) {
ht.phead = head
}
func (ht *TestHeadTracker) ExpPrefetch(t *testing.T, tci int, exp types.HeadInfo) {
if ht.phead != exp {
t.Errorf("Wrong prefetch head in test case #%d (expected {slot %d blockRoot %x}, got {slot %d blockRoot %x})", tci, exp.Slot, exp.BlockRoot, ht.phead.Slot, ht.phead.BlockRoot)
}
}

Some files were not shown because too many files have changed in this diff Show More