mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
resolve conflict
This commit is contained in:
commit
222566d48e
62 changed files with 586 additions and 347 deletions
|
|
@ -3,9 +3,6 @@
|
||||||
run:
|
run:
|
||||||
timeout: 20m
|
timeout: 20m
|
||||||
tests: true
|
tests: true
|
||||||
# default is true. Enables skipping of directories:
|
|
||||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
|
||||||
skip-dirs-use-default: true
|
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
disable-all: true
|
disable-all: true
|
||||||
|
|
@ -54,6 +51,9 @@ linters-settings:
|
||||||
exclude: [""]
|
exclude: [""]
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
|
# default is true. Enables skipping of directories:
|
||||||
|
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||||
|
exclude-dirs-use-default: true
|
||||||
exclude-files:
|
exclude-files:
|
||||||
- core/genesis_alloc.go
|
- core/genesis_alloc.go
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,9 @@ const (
|
||||||
// of starting any background processes such as automatic key derivation.
|
// of starting any background processes such as automatic key derivation.
|
||||||
WalletOpened
|
WalletOpened
|
||||||
|
|
||||||
// WalletDropped
|
// WalletDropped is fired when a wallet is removed or disconnected, either via USB
|
||||||
|
// or due to a filesystem event in the keystore. This event indicates that the wallet
|
||||||
|
// is no longer available for operations.
|
||||||
WalletDropped
|
WalletDropped
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,37 +56,37 @@ fc77c0531406d092c5356167e45c05a22d16bea84e3fa555e0f03af085c11763 go1.23.4.windo
|
||||||
8347c1aa4e1e67954d12830f88dbe44bd7ac0ec134bb472783dbfb5a3a8865d0 go1.23.4.windows-arm64.msi
|
8347c1aa4e1e67954d12830f88dbe44bd7ac0ec134bb472783dbfb5a3a8865d0 go1.23.4.windows-arm64.msi
|
||||||
db69cae5006753c785345c3215ad941f8b6224e2f81fec471c42d6857bee0e6f go1.23.4.windows-arm64.zip
|
db69cae5006753c785345c3215ad941f8b6224e2f81fec471c42d6857bee0e6f go1.23.4.windows-arm64.zip
|
||||||
|
|
||||||
# version:golangci 1.61.0
|
# version:golangci 1.63.4
|
||||||
# https://github.com/golangci/golangci-lint/releases/
|
# https://github.com/golangci/golangci-lint/releases/
|
||||||
# https://github.com/golangci/golangci-lint/releases/download/v1.61.0/
|
# https://github.com/golangci/golangci-lint/releases/download/v1.63.4/
|
||||||
5c280ef3284f80c54fd90d73dc39ca276953949da1db03eb9dd0fbf868cc6e55 golangci-lint-1.61.0-darwin-amd64.tar.gz
|
878d017cc360e4fb19510d39852c8189852e3c48e7ce0337577df73507c97d68 golangci-lint-1.63.4-darwin-amd64.tar.gz
|
||||||
544334890701e4e04a6e574bc010bea8945205c08c44cced73745a6378012d36 golangci-lint-1.61.0-darwin-arm64.tar.gz
|
a2b630c2ac8466393f0ccbbede4462387b6c190697a70bc2298c6d2123f21bbf golangci-lint-1.63.4-darwin-arm64.tar.gz
|
||||||
e885a6f561092055930ebd298914d80e8fd2e10d2b1e9942836c2c6a115301fa golangci-lint-1.61.0-freebsd-386.tar.gz
|
8938b74aa92888e561a1c5a4c175110b92f84e7d24733703e6d9ebc39e9cd5f8 golangci-lint-1.63.4-freebsd-386.tar.gz
|
||||||
b13f6a3f11f65e7ff66b734d7554df3bbae0f485768848424e7554ed289e19c2 golangci-lint-1.61.0-freebsd-amd64.tar.gz
|
054903339d620df2e760b978920100986e3b03bcb058f669d520a71dac9c34ed golangci-lint-1.63.4-freebsd-amd64.tar.gz
|
||||||
cd8e7bbe5b8f33ed1597aa1cc588da96a3b9f22e1b9ae60d93511eae1a0ee8c5 golangci-lint-1.61.0-freebsd-armv6.tar.gz
|
a19d499f961a02608348e8b626537a88edfaab6e1b6534f1eff742b5d6d750e4 golangci-lint-1.63.4-freebsd-armv6.tar.gz
|
||||||
7ade524dbd88bd250968f45e190af90e151fa5ee63dd6aa7f7bb90e8155db61d golangci-lint-1.61.0-freebsd-armv7.tar.gz
|
00d616f0fb275b780ce4d26604bdd7fdbfe6bc9c63acd5a0b31498e1f7511108 golangci-lint-1.63.4-freebsd-armv7.tar.gz
|
||||||
0fe3cd8a1ed8d9f54f48670a5af3df056d6040d94017057f0f4d65c930660ad9 golangci-lint-1.61.0-illumos-amd64.tar.gz
|
d453688e0eabded3c1a97ff5a2777bb0df5a18851efdaaaf6b472e3e5713c33e golangci-lint-1.63.4-illumos-amd64.tar.gz
|
||||||
b463fc5053a612abd26393ebaff1d85d7d56058946f4f0f7bf25ed44ea899415 golangci-lint-1.61.0-linux-386.tar.gz
|
6b1bec847fc9f347d53712d05606a49d55d0e3b5c1bacadfed2393f3503de0e9 golangci-lint-1.63.4-linux-386.tar.gz
|
||||||
77cb0af99379d9a21d5dc8c38364d060e864a01bd2f3e30b5e8cc550c3a54111 golangci-lint-1.61.0-linux-amd64.tar.gz
|
01abb14a4df47b5ca585eff3c34b105023cba92ec34ff17212dbb83855581690 golangci-lint-1.63.4-linux-amd64.tar.gz
|
||||||
af60ac05566d9351615cb31b4cc070185c25bf8cbd9b09c1873aa5ec6f3cc17e golangci-lint-1.61.0-linux-arm64.tar.gz
|
51f0c79d19a92353e0465fb30a4901a0644a975d34e6f399ad2eebc0160bbb24 golangci-lint-1.63.4-linux-arm64.tar.gz
|
||||||
1f307f2fcc5d7d674062a967a0d83a7091e300529aa237ec6ad2b3dd14c897f5 golangci-lint-1.61.0-linux-armv6.tar.gz
|
8d0a43f41e8424fbae10f7aa2dc29999f98112817c6dba63d7dc76832940a673 golangci-lint-1.63.4-linux-armv6.tar.gz
|
||||||
3ad8cbaae75a547450844811300f99c4cd290277398e43d22b9eb1792d15af4c golangci-lint-1.61.0-linux-armv7.tar.gz
|
1045a047b31e9302c9160c7b0f199f4ac1bd02a1b221a2d9521bd3507f0cf671 golangci-lint-1.63.4-linux-armv7.tar.gz
|
||||||
9be2ca67d961d7699079739cf6f7c8291c5183d57e34d1677de21ca19d0bd3ed golangci-lint-1.61.0-linux-loong64.tar.gz
|
933fe10ab50ce3bb0806e15a4ae69fe20f0549abf91dea0161236000ca706e67 golangci-lint-1.63.4-linux-loong64.tar.gz
|
||||||
90d005e1648115ebf0861b408eab9c936079a24763e883058b0a227cd3135d31 golangci-lint-1.61.0-linux-mips64.tar.gz
|
45798630cbad5642862766051199fa862ef3c33d569cab12f01cac4f68e2ddd5 golangci-lint-1.63.4-linux-mips64.tar.gz
|
||||||
6d2ed4f49407115460b8c10ccfc40fd177e0887a48864a2879dd16e84ba2a48c golangci-lint-1.61.0-linux-mips64le.tar.gz
|
86ae25335ddb24975d2c915c1af0c7fad70dce99d0b4614fa4bee392de714aa2 golangci-lint-1.63.4-linux-mips64le.tar.gz
|
||||||
633089589af5a58b7430afb6eee107d4e9c99e8d91711ddc219eb13a07e8d3b8 golangci-lint-1.61.0-linux-ppc64le.tar.gz
|
33dabd11aaba4b602938da98bcf49aabab55019557e0115cdc3dbcc3009768fa golangci-lint-1.63.4-linux-ppc64le.tar.gz
|
||||||
4c1a097d9e0d1b4a8144dae6a1f5583a38d662f3bdc1498c4e954b6ed856be98 golangci-lint-1.61.0-linux-riscv64.tar.gz
|
4e7a81230a663bcdf30bba5689ce96040abc76994dbc2003dce32c8dca8c06f3 golangci-lint-1.63.4-linux-riscv64.tar.gz
|
||||||
30581d3c987d287b7064617f1a2694143e10dffc40bc25be6636006ee82d7e1c golangci-lint-1.61.0-linux-s390x.tar.gz
|
21370b49c7c47f4d9b8f982c952f940b01e65710174c3b4dad7b6452d58f92ec golangci-lint-1.63.4-linux-s390x.tar.gz
|
||||||
42530bf8100bd43c07f5efe6d92148ba6c5a7a712d510c6f24be85af6571d5eb golangci-lint-1.61.0-netbsd-386.tar.gz
|
255866a6464c7e11bb7edd8e6e6ad54f11e1f01b82ba9ca229698ac788cd9724 golangci-lint-1.63.4-netbsd-386.tar.gz
|
||||||
b8bb07c920f6601edf718d5e82ec0784fd590b0992b42b6ec18da99f26013ed4 golangci-lint-1.61.0-netbsd-amd64.tar.gz
|
2798c040ac658bda97224f204795199c81ac97bb207b21c02b664aaed380d5d2 golangci-lint-1.63.4-netbsd-amd64.tar.gz
|
||||||
353a51527c60bd0776b0891b03f247c791986f625fca689d121972c624e54198 golangci-lint-1.61.0-netbsd-arm64.tar.gz
|
b910eecffd0064103837e7e1abe870deb8ade22331e6dffe319f430d49399c8e golangci-lint-1.63.4-netbsd-arm64.tar.gz
|
||||||
957a6272c3137910514225704c5dac0723b9c65eb7d9587366a997736e2d7580 golangci-lint-1.61.0-netbsd-armv6.tar.gz
|
df2693ef37147b457c3e2089614537dd2ae2e18e53641e756a5b404f4c72d3fa golangci-lint-1.63.4-netbsd-armv6.tar.gz
|
||||||
a89eb28ff7f18f5cd52b914739360fa95cf2f643de4adeca46e26bec3a07e8d8 golangci-lint-1.61.0-netbsd-armv7.tar.gz
|
a28a533366974bd7834c4516cd6075bff3419a508d1ed7aa63ae8182768b352e golangci-lint-1.63.4-netbsd-armv7.tar.gz
|
||||||
d8d74c43600b271393000717a4ed157d7a15bb85bab7db2efad9b63a694d4634 golangci-lint-1.61.0-windows-386.zip
|
368932775fb5c620b324dabf018155f3365f5e33c5af5b26e9321db373f96eea golangci-lint-1.63.4-windows-386.zip
|
||||||
e7bc2a81929a50f830244d6d2e657cce4f19a59aff49fa9000176ff34fda64ce golangci-lint-1.61.0-windows-amd64.zip
|
184d13c2b8f5441576bec2a0d8ba7b2d45445595cf796b879a73bcc98c39f8c1 golangci-lint-1.63.4-windows-amd64.zip
|
||||||
ed97c221596dd771e3dd9344872c140340bee2e819cd7a90afa1de752f1f2e0f golangci-lint-1.61.0-windows-arm64.zip
|
4fabf175d5b05ef0858ded49527948eebac50e9093814979fd84555a75fb80a6 golangci-lint-1.63.4-windows-arm64.zip
|
||||||
4b365233948b13d02d45928a5c390045e00945e919747b9887b5f260247541ae golangci-lint-1.61.0-windows-armv6.zip
|
e92be3f3ff30d4a849fb4b9a4c8d56837dee45269cb405a3ecad52fa034c781b golangci-lint-1.63.4-windows-armv6.zip
|
||||||
595538fb64d152173959d28f6235227f9cd969a828e5af0c4e960d02af4ffd0e golangci-lint-1.61.0-windows-armv7.zip
|
c71d348653b8f7fbb109bb10c1a481722bc6b0b2b6e731b897f99ac869f7653e golangci-lint-1.63.4-windows-armv7.zip
|
||||||
|
|
||||||
# This is the builder on PPA that will build Go itself (inception-y), don't modify!
|
# This is the builder on PPA that will build Go itself (inception-y), don't modify!
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -41,6 +40,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Chain is a lightweight blockchain-like store which can read a hivechain
|
// Chain is a lightweight blockchain-like store which can read a hivechain
|
||||||
|
|
@ -166,11 +166,8 @@ func (c *Chain) RootAt(height int) common.Hash {
|
||||||
// GetSender returns the address associated with account at the index in the
|
// GetSender returns the address associated with account at the index in the
|
||||||
// pre-funded accounts list.
|
// pre-funded accounts list.
|
||||||
func (c *Chain) GetSender(idx int) (common.Address, uint64) {
|
func (c *Chain) GetSender(idx int) (common.Address, uint64) {
|
||||||
var accounts Addresses
|
accounts := maps.Keys(c.senders)
|
||||||
for addr := range c.senders {
|
slices.SortFunc(accounts, common.Address.Cmp)
|
||||||
accounts = append(accounts, addr)
|
|
||||||
}
|
|
||||||
sort.Sort(accounts)
|
|
||||||
addr := accounts[idx]
|
addr := accounts[idx]
|
||||||
return addr, c.senders[addr].Nonce
|
return addr, c.senders[addr].Nonce
|
||||||
}
|
}
|
||||||
|
|
@ -260,22 +257,6 @@ func loadGenesis(genesisFile string) (core.Genesis, error) {
|
||||||
return gen, nil
|
return gen, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Addresses []common.Address
|
|
||||||
|
|
||||||
func (a Addresses) Len() int {
|
|
||||||
return len(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a Addresses) Less(i, j int) bool {
|
|
||||||
return bytes.Compare(a[i][:], a[j][:]) < 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a Addresses) Swap(i, j int) {
|
|
||||||
tmp := a[i]
|
|
||||||
a[i] = a[j]
|
|
||||||
a[j] = tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
func blocksFromFile(chainfile string, gblock *types.Block) ([]*types.Block, error) {
|
func blocksFromFile(chainfile string, gblock *types.Block) ([]*types.Block, error) {
|
||||||
// Load chain.rlp.
|
// Load chain.rlp.
|
||||||
fh, err := os.Open(chainfile)
|
fh, err := os.Open(chainfile)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package ethtest
|
package ethtest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ func PingExtraData(t *utesting.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sends a PING packet with additional data and wrong 'from' field
|
// PingExtraDataWrongFrom sends a PING packet with additional data and wrong 'from' field
|
||||||
// and expects a PONG response.
|
// and expects a PONG response.
|
||||||
func PingExtraDataWrongFrom(t *utesting.T) {
|
func PingExtraDataWrongFrom(t *utesting.T) {
|
||||||
te := newTestEnv(Remote, Listen1, Listen2)
|
te := newTestEnv(Remote, Listen1, Listen2)
|
||||||
|
|
@ -215,7 +215,7 @@ func PingExtraDataWrongFrom(t *utesting.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sends a PING packet with an expiration in the past.
|
// PingPastExpiration sends a PING packet with an expiration in the past.
|
||||||
// The remote node should not respond.
|
// The remote node should not respond.
|
||||||
func PingPastExpiration(t *utesting.T) {
|
func PingPastExpiration(t *utesting.T) {
|
||||||
te := newTestEnv(Remote, Listen1, Listen2)
|
te := newTestEnv(Remote, Listen1, Listen2)
|
||||||
|
|
@ -234,7 +234,7 @@ func PingPastExpiration(t *utesting.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sends an invalid packet. The remote node should not respond.
|
// WrongPacketType sends an invalid packet. The remote node should not respond.
|
||||||
func WrongPacketType(t *utesting.T) {
|
func WrongPacketType(t *utesting.T) {
|
||||||
te := newTestEnv(Remote, Listen1, Listen2)
|
te := newTestEnv(Remote, Listen1, Listen2)
|
||||||
defer te.close()
|
defer te.close()
|
||||||
|
|
@ -252,7 +252,7 @@ func WrongPacketType(t *utesting.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test verifies that the default behaviour of ignoring 'from' fields is unaffected by
|
// BondThenPingWithWrongFrom verifies that the default behaviour of ignoring 'from' fields is unaffected by
|
||||||
// the bonding process. After bonding, it pings the target with a different from endpoint.
|
// the bonding process. After bonding, it pings the target with a different from endpoint.
|
||||||
func BondThenPingWithWrongFrom(t *utesting.T) {
|
func BondThenPingWithWrongFrom(t *utesting.T) {
|
||||||
te := newTestEnv(Remote, Listen1, Listen2)
|
te := newTestEnv(Remote, Listen1, Listen2)
|
||||||
|
|
@ -289,7 +289,7 @@ waitForPong:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test just sends FINDNODE. The remote node should not reply
|
// FindnodeWithoutEndpointProof sends FINDNODE. The remote node should not reply
|
||||||
// because the endpoint proof has not completed.
|
// because the endpoint proof has not completed.
|
||||||
func FindnodeWithoutEndpointProof(t *utesting.T) {
|
func FindnodeWithoutEndpointProof(t *utesting.T) {
|
||||||
te := newTestEnv(Remote, Listen1, Listen2)
|
te := newTestEnv(Remote, Listen1, Listen2)
|
||||||
|
|
@ -332,7 +332,7 @@ func BasicFindnode(t *utesting.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sends an unsolicited NEIGHBORS packet after the endpoint proof, then sends
|
// UnsolicitedNeighbors sends an unsolicited NEIGHBORS packet after the endpoint proof, then sends
|
||||||
// FINDNODE to read the remote table. The remote node should not return the node contained
|
// FINDNODE to read the remote table. The remote node should not return the node contained
|
||||||
// in the unsolicited NEIGHBORS packet.
|
// in the unsolicited NEIGHBORS packet.
|
||||||
func UnsolicitedNeighbors(t *utesting.T) {
|
func UnsolicitedNeighbors(t *utesting.T) {
|
||||||
|
|
@ -373,7 +373,7 @@ func UnsolicitedNeighbors(t *utesting.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sends FINDNODE with an expiration timestamp in the past.
|
// FindnodePastExpiration sends FINDNODE with an expiration timestamp in the past.
|
||||||
// The remote node should not respond.
|
// The remote node should not respond.
|
||||||
func FindnodePastExpiration(t *utesting.T) {
|
func FindnodePastExpiration(t *utesting.T) {
|
||||||
te := newTestEnv(Remote, Listen1, Listen2)
|
te := newTestEnv(Remote, Listen1, Listen2)
|
||||||
|
|
@ -426,7 +426,7 @@ func bond(t *utesting.T, te *testenv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test attempts to perform a traffic amplification attack against a
|
// FindnodeAmplificationInvalidPongHash attempts to perform a traffic amplification attack against a
|
||||||
// 'victim' endpoint using FINDNODE. In this attack scenario, the attacker
|
// 'victim' endpoint using FINDNODE. In this attack scenario, the attacker
|
||||||
// attempts to complete the endpoint proof non-interactively by sending a PONG
|
// attempts to complete the endpoint proof non-interactively by sending a PONG
|
||||||
// with mismatching reply token from the 'victim' endpoint. The attack works if
|
// with mismatching reply token from the 'victim' endpoint. The attack works if
|
||||||
|
|
@ -478,7 +478,7 @@ func FindnodeAmplificationInvalidPongHash(t *utesting.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test attempts to perform a traffic amplification attack using FINDNODE.
|
// FindnodeAmplificationWrongIP attempts to perform a traffic amplification attack using FINDNODE.
|
||||||
// The attack works if the remote node does not verify the IP address of FINDNODE
|
// The attack works if the remote node does not verify the IP address of FINDNODE
|
||||||
// against the endpoint verification proof done by PING/PONG.
|
// against the endpoint verification proof done by PING/PONG.
|
||||||
func FindnodeAmplificationWrongIP(t *utesting.T) {
|
func FindnodeAmplificationWrongIP(t *utesting.T) {
|
||||||
|
|
|
||||||
|
|
@ -230,11 +230,10 @@ func initGenesis(ctx *cli.Context) error {
|
||||||
triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
_, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides)
|
_, hash, _, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to write genesis block: %v", err)
|
utils.Fatalf("Failed to write genesis block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash)
|
log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
||||||
db2.Close()
|
db2.Close()
|
||||||
})
|
})
|
||||||
|
|
||||||
genesis.MustCommit(db2, triedb.NewDatabase(db, triedb.HashDefaults))
|
genesis.MustCommit(db2, triedb.NewDatabase(db2, triedb.HashDefaults))
|
||||||
imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
|
imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize chain: %v", err)
|
t.Fatalf("unable to initialize chain: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -467,7 +467,6 @@ func (tt *cliqueTest) run(t *testing.T) {
|
||||||
for j := 0; j < len(batches)-1; j++ {
|
for j := 0; j < len(batches)-1; j++ {
|
||||||
if k, err := chain.InsertChain(batches[j]); err != nil {
|
if k, err := chain.InsertChain(batches[j]); err != nil {
|
||||||
t.Fatalf("failed to import batch %d, block %d: %v", j, k, err)
|
t.Fatalf("failed to import batch %d, block %d: %v", j, k, err)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, err = chain.InsertChain(batches[len(batches)-1]); err != tt.failure {
|
if _, err = chain.InsertChain(batches[len(batches)-1]); err != tt.failure {
|
||||||
|
|
|
||||||
|
|
@ -269,14 +269,19 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
cacheConfig = defaultCacheConfig
|
cacheConfig = defaultCacheConfig
|
||||||
}
|
}
|
||||||
// Open trie database with provided config
|
// Open trie database with provided config
|
||||||
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(genesis != nil && genesis.IsVerkle()))
|
enableVerkle, err := EnableVerkleAtGenesis(db, genesis)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(enableVerkle))
|
||||||
|
|
||||||
// Setup the genesis block, commit the provided genesis specification
|
// Write the supplied genesis to the database if it has not been initialized
|
||||||
// to database if the genesis block is not present yet, or load the
|
// yet. The corresponding chain config will be returned, either from the
|
||||||
// stored one from database.
|
// provided genesis or from the locally stored configuration if the genesis
|
||||||
chainConfig, genesisHash, genesisErr := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides)
|
// has already been initialized.
|
||||||
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides)
|
||||||
return nil, genesisErr
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Info("")
|
log.Info("")
|
||||||
log.Info(strings.Repeat("-", 153))
|
log.Info(strings.Repeat("-", 153))
|
||||||
|
|
@ -303,7 +308,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
vmConfig: vmConfig,
|
vmConfig: vmConfig,
|
||||||
logger: vmConfig.Tracer,
|
logger: vmConfig.Tracer,
|
||||||
}
|
}
|
||||||
var err error
|
|
||||||
bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped)
|
bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -453,16 +457,15 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewind the chain in case of an incompatible config upgrade.
|
// Rewind the chain in case of an incompatible config upgrade.
|
||||||
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
if compatErr != nil {
|
||||||
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
log.Warn("Rewinding chain to upgrade configuration", "err", compatErr)
|
||||||
if compat.RewindToTime > 0 {
|
if compatErr.RewindToTime > 0 {
|
||||||
bc.SetHeadWithTimestamp(compat.RewindToTime)
|
bc.SetHeadWithTimestamp(compatErr.RewindToTime)
|
||||||
} else {
|
} else {
|
||||||
bc.SetHead(compat.RewindToBlock)
|
bc.SetHead(compatErr.RewindToBlock)
|
||||||
}
|
}
|
||||||
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
|
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start tx indexer if it's enabled.
|
// Start tx indexer if it's enabled.
|
||||||
if txLookupLimit != nil {
|
if txLookupLimit != nil {
|
||||||
bc.txIndexer = newTxIndexer(*txLookupLimit, bc)
|
bc.txIndexer = newTxIndexer(*txLookupLimit, bc)
|
||||||
|
|
@ -1616,7 +1619,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
|
||||||
return nil, 0, nil
|
return nil, 0, nil
|
||||||
}
|
}
|
||||||
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
|
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
|
||||||
SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain)
|
SenderCacher().RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
stats = insertStats{startTime: mclock.Now()}
|
stats = insertStats{startTime: mclock.Now()}
|
||||||
|
|
|
||||||
|
|
@ -2535,7 +2535,7 @@ func testReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T, scheme strin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Benchmarks large blocks with value transfers to non-existing accounts
|
// Benchmarks large blocks with value transfers to non-existing accounts
|
||||||
func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
|
func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address) {
|
||||||
var (
|
var (
|
||||||
signer = types.HomesteadSigner{}
|
signer = types.HomesteadSigner{}
|
||||||
testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
|
|
@ -2598,10 +2598,7 @@ func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
|
||||||
recipientFn := func(nonce uint64) common.Address {
|
recipientFn := func(nonce uint64) common.Address {
|
||||||
return common.BigToAddress(new(big.Int).SetUint64(1337 + nonce))
|
return common.BigToAddress(new(big.Int).SetUint64(1337 + nonce))
|
||||||
}
|
}
|
||||||
dataFn := func(nonce uint64) []byte {
|
benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
|
func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
|
||||||
|
|
@ -2615,10 +2612,7 @@ func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
|
||||||
recipientFn := func(nonce uint64) common.Address {
|
recipientFn := func(nonce uint64) common.Address {
|
||||||
return common.BigToAddress(new(big.Int).SetUint64(1337))
|
return common.BigToAddress(new(big.Int).SetUint64(1337))
|
||||||
}
|
}
|
||||||
dataFn := func(nonce uint64) []byte {
|
benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
|
func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
|
||||||
|
|
@ -2632,10 +2626,7 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
|
||||||
recipientFn := func(nonce uint64) common.Address {
|
recipientFn := func(nonce uint64) common.Address {
|
||||||
return common.BigToAddress(new(big.Int).SetUint64(0xc0de))
|
return common.BigToAddress(new(big.Int).SetUint64(0xc0de))
|
||||||
}
|
}
|
||||||
dataFn := func(nonce uint64) []byte {
|
benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that importing a some old blocks, where all blocks are before the
|
// Tests that importing a some old blocks, where all blocks are before the
|
||||||
|
|
@ -4274,12 +4265,11 @@ func TestEIP7702(t *testing.T) {
|
||||||
// 2. addr1:0xaaaa calls into addr2:0xbbbb
|
// 2. addr1:0xaaaa calls into addr2:0xbbbb
|
||||||
// 3. addr2:0xbbbb writes to storage
|
// 3. addr2:0xbbbb writes to storage
|
||||||
auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{
|
auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{
|
||||||
ChainID: gspec.Config.ChainID.Uint64(),
|
ChainID: *uint256.MustFromBig(gspec.Config.ChainID),
|
||||||
Address: aa,
|
Address: aa,
|
||||||
Nonce: 1,
|
Nonce: 1,
|
||||||
})
|
})
|
||||||
auth2, _ := types.SignSetCode(key2, types.SetCodeAuthorization{
|
auth2, _ := types.SignSetCode(key2, types.SetCodeAuthorization{
|
||||||
ChainID: 0,
|
|
||||||
Address: bb,
|
Address: bb,
|
||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
})
|
})
|
||||||
|
|
@ -4287,7 +4277,7 @@ func TestEIP7702(t *testing.T) {
|
||||||
_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
|
_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
|
||||||
b.SetCoinbase(aa)
|
b.SetCoinbase(aa)
|
||||||
txdata := &types.SetCodeTx{
|
txdata := &types.SetCodeTx{
|
||||||
ChainID: gspec.Config.ChainID.Uint64(),
|
ChainID: uint256.MustFromBig(gspec.Config.ChainID),
|
||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
To: addr1,
|
To: addr1,
|
||||||
Gas: 500000,
|
Gas: 500000,
|
||||||
|
|
|
||||||
200
core/genesis.go
200
core/genesis.go
|
|
@ -247,6 +247,24 @@ type ChainOverrides struct {
|
||||||
OverrideVerkle *uint64
|
OverrideVerkle *uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply applies the chain overrides on the supplied chain config.
|
||||||
|
func (o *ChainOverrides) apply(cfg *params.ChainConfig) (*params.ChainConfig, error) {
|
||||||
|
if o == nil || cfg == nil {
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
cpy := *cfg
|
||||||
|
if o.OverrideCancun != nil {
|
||||||
|
cpy.CancunTime = o.OverrideCancun
|
||||||
|
}
|
||||||
|
if o.OverrideVerkle != nil {
|
||||||
|
cpy.VerkleTime = o.OverrideVerkle
|
||||||
|
}
|
||||||
|
if err := cpy.CheckConfigForkOrder(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &cpy, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetupGenesisBlock writes or updates the genesis block in db.
|
// SetupGenesisBlock writes or updates the genesis block in db.
|
||||||
// The block that will be used is:
|
// The block that will be used is:
|
||||||
//
|
//
|
||||||
|
|
@ -258,109 +276,102 @@ type ChainOverrides struct {
|
||||||
// The stored chain configuration will be updated if it is compatible (i.e. does not
|
// The stored chain configuration will be updated if it is compatible (i.e. does not
|
||||||
// specify a fork block below the local head block). In case of a conflict, the
|
// specify a fork block below the local head block). In case of a conflict, the
|
||||||
// error is a *params.ConfigCompatError and the new, unwritten config is returned.
|
// error is a *params.ConfigCompatError and the new, unwritten config is returned.
|
||||||
//
|
func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
// The returned chain configuration is never nil.
|
|
||||||
func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
|
|
||||||
return SetupGenesisBlockWithOverride(db, triedb, genesis, nil)
|
return SetupGenesisBlockWithOverride(db, triedb, genesis, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, error) {
|
func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
|
// Sanitize the supplied genesis, ensuring it has the associated chain
|
||||||
|
// config attached.
|
||||||
if genesis != nil && genesis.Config == nil {
|
if genesis != nil && genesis.Config == nil {
|
||||||
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
|
return nil, common.Hash{}, nil, errGenesisNoConfig
|
||||||
}
|
}
|
||||||
applyOverrides := func(config *params.ChainConfig) {
|
// Commit the genesis if the database is empty
|
||||||
if config != nil {
|
ghash := rawdb.ReadCanonicalHash(db, 0)
|
||||||
if overrides != nil && overrides.OverrideCancun != nil {
|
if (ghash == common.Hash{}) {
|
||||||
config.CancunTime = overrides.OverrideCancun
|
|
||||||
}
|
|
||||||
if overrides != nil && overrides.OverrideVerkle != nil {
|
|
||||||
config.VerkleTime = overrides.OverrideVerkle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Just commit the new block if there is no stored genesis block.
|
|
||||||
stored := rawdb.ReadCanonicalHash(db, 0)
|
|
||||||
if (stored == common.Hash{}) {
|
|
||||||
if genesis == nil {
|
if genesis == nil {
|
||||||
log.Info("Writing default main-net genesis block")
|
log.Info("Writing default main-net genesis block")
|
||||||
genesis = DefaultGenesisBlock()
|
genesis = DefaultGenesisBlock()
|
||||||
} else {
|
} else {
|
||||||
log.Info("Writing custom genesis block")
|
log.Info("Writing custom genesis block")
|
||||||
}
|
}
|
||||||
|
chainCfg, err := overrides.apply(genesis.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, common.Hash{}, nil, err
|
||||||
|
}
|
||||||
|
genesis.Config = chainCfg
|
||||||
|
|
||||||
applyOverrides(genesis.Config)
|
|
||||||
block, err := genesis.Commit(db, triedb)
|
block, err := genesis.Commit(db, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return genesis.Config, common.Hash{}, err
|
return nil, common.Hash{}, nil, err
|
||||||
}
|
}
|
||||||
return genesis.Config, block.Hash(), nil
|
return chainCfg, block.Hash(), nil, nil
|
||||||
}
|
}
|
||||||
// The genesis block is present(perhaps in ancient database) while the
|
// Commit the genesis if the genesis block exists in the ancient database
|
||||||
// state database is not initialized yet. It can happen that the node
|
// but the key-value database is empty without initializing the genesis
|
||||||
// is initialized with an external ancient store. Commit genesis state
|
// fields. This scenario can occur when the node is created from scratch
|
||||||
// in this case.
|
// with an existing ancient store.
|
||||||
header := rawdb.ReadHeader(db, stored, 0)
|
storedCfg := rawdb.ReadChainConfig(db, ghash)
|
||||||
if header.Root != types.EmptyRootHash && !triedb.Initialized(header.Root) {
|
if storedCfg == nil {
|
||||||
|
// Ensure the stored genesis block matches with the given genesis. Private
|
||||||
|
// networks must explicitly specify the genesis in the config file, mainnet
|
||||||
|
// genesis will be used as default and the initialization will always fail.
|
||||||
if genesis == nil {
|
if genesis == nil {
|
||||||
|
log.Info("Writing default main-net genesis block")
|
||||||
genesis = DefaultGenesisBlock()
|
genesis = DefaultGenesisBlock()
|
||||||
|
} else {
|
||||||
|
log.Info("Writing custom genesis block")
|
||||||
}
|
}
|
||||||
applyOverrides(genesis.Config)
|
chainCfg, err := overrides.apply(genesis.Config)
|
||||||
// Ensure the stored genesis matches with the given one.
|
if err != nil {
|
||||||
hash := genesis.ToBlock().Hash()
|
return nil, common.Hash{}, nil, err
|
||||||
if hash != stored {
|
}
|
||||||
return genesis.Config, hash, &GenesisMismatchError{stored, hash}
|
genesis.Config = chainCfg
|
||||||
|
|
||||||
|
if hash := genesis.ToBlock().Hash(); hash != ghash {
|
||||||
|
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
|
||||||
}
|
}
|
||||||
block, err := genesis.Commit(db, triedb)
|
block, err := genesis.Commit(db, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return genesis.Config, hash, err
|
return nil, common.Hash{}, nil, err
|
||||||
}
|
}
|
||||||
return genesis.Config, block.Hash(), nil
|
return chainCfg, block.Hash(), nil, nil
|
||||||
}
|
}
|
||||||
// Check whether the genesis block is already written.
|
// The genesis block has already been committed previously. Verify that the
|
||||||
|
// provided genesis with chain overrides matches the existing one, and update
|
||||||
|
// the stored chain config if necessary.
|
||||||
if genesis != nil {
|
if genesis != nil {
|
||||||
applyOverrides(genesis.Config)
|
chainCfg, err := overrides.apply(genesis.Config)
|
||||||
hash := genesis.ToBlock().Hash()
|
if err != nil {
|
||||||
if hash != stored {
|
return nil, common.Hash{}, nil, err
|
||||||
return genesis.Config, hash, &GenesisMismatchError{stored, hash}
|
|
||||||
}
|
}
|
||||||
|
genesis.Config = chainCfg
|
||||||
|
|
||||||
|
if hash := genesis.ToBlock().Hash(); hash != ghash {
|
||||||
|
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
|
||||||
}
|
}
|
||||||
// Get the existing chain configuration.
|
|
||||||
newcfg := genesis.configOrDefault(stored)
|
|
||||||
applyOverrides(newcfg)
|
|
||||||
if err := newcfg.CheckConfigForkOrder(); err != nil {
|
|
||||||
return newcfg, common.Hash{}, err
|
|
||||||
}
|
|
||||||
storedcfg := rawdb.ReadChainConfig(db, stored)
|
|
||||||
if storedcfg == nil {
|
|
||||||
log.Warn("Found genesis block without chain config")
|
|
||||||
rawdb.WriteChainConfig(db, stored, newcfg)
|
|
||||||
return newcfg, stored, nil
|
|
||||||
}
|
|
||||||
storedData, _ := json.Marshal(storedcfg)
|
|
||||||
// Special case: if a private network is being used (no genesis and also no
|
|
||||||
// mainnet hash in the database), we must not apply the `configOrDefault`
|
|
||||||
// chain config as that would be AllProtocolChanges (applying any new fork
|
|
||||||
// on top of an existing private network genesis block). In that case, only
|
|
||||||
// apply the overrides.
|
|
||||||
if genesis == nil && stored != params.MainnetGenesisHash {
|
|
||||||
newcfg = storedcfg
|
|
||||||
applyOverrides(newcfg)
|
|
||||||
}
|
}
|
||||||
// Check config compatibility and write the config. Compatibility errors
|
// Check config compatibility and write the config. Compatibility errors
|
||||||
// are returned to the caller unless we're already at block zero.
|
// are returned to the caller unless we're already at block zero.
|
||||||
head := rawdb.ReadHeadHeader(db)
|
head := rawdb.ReadHeadHeader(db)
|
||||||
if head == nil {
|
if head == nil {
|
||||||
return newcfg, stored, errors.New("missing head header")
|
return nil, common.Hash{}, nil, errors.New("missing head header")
|
||||||
}
|
}
|
||||||
compatErr := storedcfg.CheckCompatible(newcfg, head.Number.Uint64(), head.Time)
|
newCfg := genesis.chainConfigOrDefault(ghash, storedCfg)
|
||||||
|
|
||||||
|
// TODO(rjl493456442) better to define the comparator of chain config
|
||||||
|
// and short circuit if the chain config is not changed.
|
||||||
|
compatErr := storedCfg.CheckCompatible(newCfg, head.Number.Uint64(), head.Time)
|
||||||
if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) {
|
if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) {
|
||||||
return newcfg, stored, compatErr
|
return newCfg, ghash, compatErr, nil
|
||||||
}
|
}
|
||||||
// Don't overwrite if the old is identical to the new
|
// Don't overwrite if the old is identical to the new. It's useful
|
||||||
if newData, _ := json.Marshal(newcfg); !bytes.Equal(storedData, newData) {
|
// for the scenarios that database is opened in the read-only mode.
|
||||||
rawdb.WriteChainConfig(db, stored, newcfg)
|
storedData, _ := json.Marshal(storedCfg)
|
||||||
|
if newData, _ := json.Marshal(newCfg); !bytes.Equal(storedData, newData) {
|
||||||
|
rawdb.WriteChainConfig(db, ghash, newCfg)
|
||||||
}
|
}
|
||||||
return newcfg, stored, nil
|
return newCfg, ghash, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadChainConfig loads the stored chain config if it is already present in
|
// LoadChainConfig loads the stored chain config if it is already present in
|
||||||
|
|
@ -396,7 +407,10 @@ func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig,
|
||||||
return params.MainnetChainConfig, nil
|
return params.MainnetChainConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
// chainConfigOrDefault retrieves the attached chain configuration. If the genesis
|
||||||
|
// object is null, it returns the default chain configuration based on the given
|
||||||
|
// genesis hash, or the locally stored config if it's not a pre-defined network.
|
||||||
|
func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainConfig) *params.ChainConfig {
|
||||||
switch {
|
switch {
|
||||||
case g != nil:
|
case g != nil:
|
||||||
return g.Config
|
return g.Config
|
||||||
|
|
@ -407,14 +421,14 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
||||||
case ghash == params.SepoliaGenesisHash:
|
case ghash == params.SepoliaGenesisHash:
|
||||||
return params.SepoliaChainConfig
|
return params.SepoliaChainConfig
|
||||||
default:
|
default:
|
||||||
return params.AllEthashProtocolChanges
|
return stored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVerkle indicates whether the state is already stored in a verkle
|
// IsVerkle indicates whether the state is already stored in a verkle
|
||||||
// tree at genesis time.
|
// tree at genesis time.
|
||||||
func (g *Genesis) IsVerkle() bool {
|
func (g *Genesis) IsVerkle() bool {
|
||||||
return g.Config.IsVerkle(new(big.Int).SetUint64(g.Number), g.Timestamp)
|
return g.Config.IsVerkleGenesis()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToBlock returns the genesis block according to genesis specification.
|
// ToBlock returns the genesis block according to genesis specification.
|
||||||
|
|
@ -494,7 +508,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
|
||||||
}
|
}
|
||||||
config := g.Config
|
config := g.Config
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = params.AllEthashProtocolChanges
|
return nil, errors.New("invalid genesis without chain config")
|
||||||
}
|
}
|
||||||
if err := config.CheckConfigForkOrder(); err != nil {
|
if err := config.CheckConfigForkOrder(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -514,16 +528,17 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rawdb.WriteGenesisStateSpec(db, block.Hash(), blob)
|
batch := db.NewBatch()
|
||||||
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty())
|
rawdb.WriteGenesisStateSpec(batch, block.Hash(), blob)
|
||||||
rawdb.WriteBlock(db, block)
|
rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), block.Difficulty())
|
||||||
rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
|
rawdb.WriteBlock(batch, block)
|
||||||
rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
|
rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), nil)
|
||||||
rawdb.WriteHeadBlockHash(db, block.Hash())
|
rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
|
||||||
rawdb.WriteHeadFastBlockHash(db, block.Hash())
|
rawdb.WriteHeadBlockHash(batch, block.Hash())
|
||||||
rawdb.WriteHeadHeaderHash(db, block.Hash())
|
rawdb.WriteHeadFastBlockHash(batch, block.Hash())
|
||||||
rawdb.WriteChainConfig(db, block.Hash(), config)
|
rawdb.WriteHeadHeaderHash(batch, block.Hash())
|
||||||
return block, nil
|
rawdb.WriteChainConfig(batch, block.Hash(), config)
|
||||||
|
return block, batch.Write()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustCommit writes the genesis block and state to db, panicking on error.
|
// MustCommit writes the genesis block and state to db, panicking on error.
|
||||||
|
|
@ -536,6 +551,29 @@ func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types.
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnableVerkleAtGenesis indicates whether the verkle fork should be activated
|
||||||
|
// at genesis. This is a temporary solution only for verkle devnet testing, where
|
||||||
|
// verkle fork is activated at genesis, and the configured activation date has
|
||||||
|
// already passed.
|
||||||
|
//
|
||||||
|
// In production networks (mainnet and public testnets), verkle activation always
|
||||||
|
// occurs after the genesis block, making this function irrelevant in those cases.
|
||||||
|
func EnableVerkleAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) {
|
||||||
|
if genesis != nil {
|
||||||
|
if genesis.Config == nil {
|
||||||
|
return false, errGenesisNoConfig
|
||||||
|
}
|
||||||
|
return genesis.Config.EnableVerkleAtGenesis, nil
|
||||||
|
}
|
||||||
|
if ghash := rawdb.ReadCanonicalHash(db, 0); ghash != (common.Hash{}) {
|
||||||
|
chainCfg := rawdb.ReadChainConfig(db, ghash)
|
||||||
|
if chainCfg != nil {
|
||||||
|
return chainCfg.EnableVerkleAtGenesis, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultGenesisBlock returns the Ethereum main net genesis block.
|
// DefaultGenesisBlock returns the Ethereum main net genesis block.
|
||||||
func DefaultGenesisBlock() *Genesis {
|
func DefaultGenesisBlock() *Genesis {
|
||||||
return &Genesis{
|
return &Genesis{
|
||||||
|
|
|
||||||
|
|
@ -55,22 +55,22 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fn func(ethdb.Database) (*params.ChainConfig, common.Hash, error)
|
fn func(ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error)
|
||||||
wantConfig *params.ChainConfig
|
wantConfig *params.ChainConfig
|
||||||
wantHash common.Hash
|
wantHash common.Hash
|
||||||
wantErr error
|
wantErr error
|
||||||
|
wantCompactErr *params.ConfigCompatError
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "genesis without ChainConfig",
|
name: "genesis without ChainConfig",
|
||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), new(Genesis))
|
return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), new(Genesis))
|
||||||
},
|
},
|
||||||
wantErr: errGenesisNoConfig,
|
wantErr: errGenesisNoConfig,
|
||||||
wantConfig: params.AllEthashProtocolChanges,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no block in DB, genesis == nil",
|
name: "no block in DB, genesis == nil",
|
||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil)
|
return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil)
|
||||||
},
|
},
|
||||||
wantHash: params.MainnetGenesisHash,
|
wantHash: params.MainnetGenesisHash,
|
||||||
|
|
@ -78,7 +78,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mainnet block in DB, genesis == nil",
|
name: "mainnet block in DB, genesis == nil",
|
||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
DefaultGenesisBlock().MustCommit(db, triedb.NewDatabase(db, newDbConfig(scheme)))
|
DefaultGenesisBlock().MustCommit(db, triedb.NewDatabase(db, newDbConfig(scheme)))
|
||||||
return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil)
|
return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil)
|
||||||
},
|
},
|
||||||
|
|
@ -87,7 +87,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "custom block in DB, genesis == nil",
|
name: "custom block in DB, genesis == nil",
|
||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
||||||
customg.Commit(db, tdb)
|
customg.Commit(db, tdb)
|
||||||
return SetupGenesisBlock(db, tdb, nil)
|
return SetupGenesisBlock(db, tdb, nil)
|
||||||
|
|
@ -97,18 +97,16 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "custom block in DB, genesis == sepolia",
|
name: "custom block in DB, genesis == sepolia",
|
||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
||||||
customg.Commit(db, tdb)
|
customg.Commit(db, tdb)
|
||||||
return SetupGenesisBlock(db, tdb, DefaultSepoliaGenesisBlock())
|
return SetupGenesisBlock(db, tdb, DefaultSepoliaGenesisBlock())
|
||||||
},
|
},
|
||||||
wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash},
|
wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash},
|
||||||
wantHash: params.SepoliaGenesisHash,
|
|
||||||
wantConfig: params.SepoliaChainConfig,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "compatible config in DB",
|
name: "compatible config in DB",
|
||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
||||||
oldcustomg.Commit(db, tdb)
|
oldcustomg.Commit(db, tdb)
|
||||||
return SetupGenesisBlock(db, tdb, &customg)
|
return SetupGenesisBlock(db, tdb, &customg)
|
||||||
|
|
@ -118,7 +116,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "incompatible config in DB",
|
name: "incompatible config in DB",
|
||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
// Commit the 'old' genesis block with Homestead transition at #2.
|
// Commit the 'old' genesis block with Homestead transition at #2.
|
||||||
// Advance to block #4, past the homestead transition block of customg.
|
// Advance to block #4, past the homestead transition block of customg.
|
||||||
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
|
||||||
|
|
@ -135,7 +133,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
||||||
},
|
},
|
||||||
wantHash: customghash,
|
wantHash: customghash,
|
||||||
wantConfig: customg.Config,
|
wantConfig: customg.Config,
|
||||||
wantErr: ¶ms.ConfigCompatError{
|
wantCompactErr: ¶ms.ConfigCompatError{
|
||||||
What: "Homestead fork block",
|
What: "Homestead fork block",
|
||||||
StoredBlock: big.NewInt(2),
|
StoredBlock: big.NewInt(2),
|
||||||
NewBlock: big.NewInt(3),
|
NewBlock: big.NewInt(3),
|
||||||
|
|
@ -146,12 +144,16 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
config, hash, err := test.fn(db)
|
config, hash, compatErr, err := test.fn(db)
|
||||||
// Check the return values.
|
// Check the return values.
|
||||||
if !reflect.DeepEqual(err, test.wantErr) {
|
if !reflect.DeepEqual(err, test.wantErr) {
|
||||||
spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true}
|
spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true}
|
||||||
t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr))
|
t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr))
|
||||||
}
|
}
|
||||||
|
if !reflect.DeepEqual(compatErr, test.wantCompactErr) {
|
||||||
|
spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true}
|
||||||
|
t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(compatErr), spew.NewFormatter(test.wantCompactErr))
|
||||||
|
}
|
||||||
if !reflect.DeepEqual(config, test.wantConfig) {
|
if !reflect.DeepEqual(config, test.wantConfig) {
|
||||||
t.Errorf("%s:\nreturned %v\nwant %v", test.name, config, test.wantConfig)
|
t.Errorf("%s:\nreturned %v\nwant %v", test.name, config, test.wantConfig)
|
||||||
}
|
}
|
||||||
|
|
@ -279,6 +281,7 @@ func TestVerkleGenesisCommit(t *testing.T) {
|
||||||
PragueTime: &verkleTime,
|
PragueTime: &verkleTime,
|
||||||
VerkleTime: &verkleTime,
|
VerkleTime: &verkleTime,
|
||||||
TerminalTotalDifficulty: big.NewInt(0),
|
TerminalTotalDifficulty: big.NewInt(0),
|
||||||
|
EnableVerkleAtGenesis: true,
|
||||||
Ethash: nil,
|
Ethash: nil,
|
||||||
Clique: nil,
|
Clique: nil,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,21 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SenderCacher is a concurrent transaction sender recoverer and cacher.
|
// senderCacherOnce is used to ensure that the SenderCacher is initialized only once.
|
||||||
var SenderCacher = newTxSenderCacher(runtime.NumCPU())
|
var senderCacherOnce = sync.OnceValue(func() *txSenderCacher {
|
||||||
|
return newTxSenderCacher(runtime.NumCPU())
|
||||||
|
})
|
||||||
|
|
||||||
|
// SenderCacher returns the singleton instance of SenderCacher, initializing it if called for the first time.
|
||||||
|
// This function is thread-safe and ensures that initialization happens only once.
|
||||||
|
func SenderCacher() *txSenderCacher {
|
||||||
|
return senderCacherOnce()
|
||||||
|
}
|
||||||
|
|
||||||
// txSenderCacherRequest is a request for recovering transaction senders with a
|
// txSenderCacherRequest is a request for recovering transaction senders with a
|
||||||
// specific signature scheme and caching it into the transactions themselves.
|
// specific signature scheme and caching it into the transactions themselves.
|
||||||
|
|
|
||||||
|
|
@ -470,7 +470,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
if msg.SetCodeAuthorizations != nil {
|
if msg.SetCodeAuthorizations != nil {
|
||||||
for _, auth := range msg.SetCodeAuthorizations {
|
for _, auth := range msg.SetCodeAuthorizations {
|
||||||
// Note errors are ignored, we simply skip invalid authorizations here.
|
// Note errors are ignored, we simply skip invalid authorizations here.
|
||||||
st.applyAuthorization(msg, &auth)
|
st.applyAuthorization(&auth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,8 +529,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
|
|
||||||
// validateAuthorization validates an EIP-7702 authorization against the state.
|
// validateAuthorization validates an EIP-7702 authorization against the state.
|
||||||
func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) {
|
func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) {
|
||||||
// Verify chain ID is 0 or equal to current chain ID.
|
// Verify chain ID is null or equal to current chain ID.
|
||||||
if auth.ChainID != 0 && st.evm.ChainConfig().ChainID.Uint64() != auth.ChainID {
|
if !auth.ChainID.IsZero() && auth.ChainID.CmpBig(st.evm.ChainConfig().ChainID) != 0 {
|
||||||
return authority, ErrAuthorizationWrongChainID
|
return authority, ErrAuthorizationWrongChainID
|
||||||
}
|
}
|
||||||
// Limit nonce to 2^64-1 per EIP-2681.
|
// Limit nonce to 2^64-1 per EIP-2681.
|
||||||
|
|
@ -559,7 +559,7 @@ func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorizatio
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyAuthorization applies an EIP-7702 code delegation to the state.
|
// applyAuthorization applies an EIP-7702 code delegation to the state.
|
||||||
func (st *stateTransition) applyAuthorization(msg *Message, auth *types.SetCodeAuthorization) error {
|
func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization) error {
|
||||||
authority, err := st.validateAuthorization(auth)
|
authority, err := st.validateAuthorization(auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,14 @@ All notable changes to the tracing interface will be documented in this file.
|
||||||
- `GasChangeReason` has been extended with the following reasons which will be enabled only post-Verkle. There shouldn't be any gas changes with those reasons prior to the fork.
|
- `GasChangeReason` has been extended with the following reasons which will be enabled only post-Verkle. There shouldn't be any gas changes with those reasons prior to the fork.
|
||||||
- `GasChangeWitnessContractCollisionCheck` flags the event of adding to the witness when checking for contract address collision.
|
- `GasChangeWitnessContractCollisionCheck` flags the event of adding to the witness when checking for contract address collision.
|
||||||
|
|
||||||
|
## [v1.14.12]
|
||||||
|
|
||||||
|
This release contains a change in behavior for `OnCodeChange` hook.
|
||||||
|
|
||||||
|
### `OnCodeChange` change
|
||||||
|
|
||||||
|
The `OnCodeChange` hook is now called when the code of a contract is removed due to a selfdestruct. Previously, no code change was emitted on such occasions.
|
||||||
|
|
||||||
## [v1.14.4]
|
## [v1.14.4]
|
||||||
|
|
||||||
This release contained only minor extensions to the tracing interface.
|
This release contained only minor extensions to the tracing interface.
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ const (
|
||||||
GasChangeCallLeftOverRefunded GasChangeReason = 7
|
GasChangeCallLeftOverRefunded GasChangeReason = 7
|
||||||
// GasChangeCallContractCreation is the amount of gas that will be burned for a CREATE.
|
// GasChangeCallContractCreation is the amount of gas that will be burned for a CREATE.
|
||||||
GasChangeCallContractCreation GasChangeReason = 8
|
GasChangeCallContractCreation GasChangeReason = 8
|
||||||
// GasChangeContractCreation is the amount of gas that will be burned for a CREATE2.
|
// GasChangeCallContractCreation2 is the amount of gas that will be burned for a CREATE2.
|
||||||
GasChangeCallContractCreation2 GasChangeReason = 9
|
GasChangeCallContractCreation2 GasChangeReason = 9
|
||||||
// GasChangeCallCodeStorage is the amount of gas that will be charged for code storage.
|
// GasChangeCallCodeStorage is the amount of gas that will be charged for code storage.
|
||||||
GasChangeCallCodeStorage GasChangeReason = 10
|
GasChangeCallCodeStorage GasChangeReason = 10
|
||||||
|
|
|
||||||
|
|
@ -1751,7 +1751,7 @@ func (p *BlobPool) Clear() {
|
||||||
// The transaction addition may attempt to reserve the sender addr which
|
// The transaction addition may attempt to reserve the sender addr which
|
||||||
// can't happen until Clear releases the reservation lock. Clear cannot
|
// can't happen until Clear releases the reservation lock. Clear cannot
|
||||||
// acquire the subpool lock until the transaction addition is completed.
|
// acquire the subpool lock until the transaction addition is completed.
|
||||||
for acct, _ := range p.index {
|
for acct := range p.index {
|
||||||
p.reserve(acct, false)
|
p.reserve(acct, false)
|
||||||
}
|
}
|
||||||
p.lookup = newLookup()
|
p.lookup = newLookup()
|
||||||
|
|
|
||||||
|
|
@ -1440,7 +1440,7 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {
|
||||||
|
|
||||||
// Inject any transactions discarded due to reorgs
|
// Inject any transactions discarded due to reorgs
|
||||||
log.Debug("Reinjecting stale transactions", "count", len(reinject))
|
log.Debug("Reinjecting stale transactions", "count", len(reinject))
|
||||||
core.SenderCacher.Recover(pool.signer, reinject)
|
core.SenderCacher().Recover(pool.signer, reinject)
|
||||||
pool.addTxsLocked(reinject, false)
|
pool.addTxsLocked(reinject, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1986,7 +1986,7 @@ func (pool *LegacyPool) Clear() {
|
||||||
senderAddr, _ := types.Sender(pool.signer, tx)
|
senderAddr, _ := types.Sender(pool.signer, tx)
|
||||||
pool.reserve(senderAddr, false)
|
pool.reserve(senderAddr, false)
|
||||||
}
|
}
|
||||||
for localSender, _ := range pool.locals.accounts {
|
for localSender := range pool.locals.accounts {
|
||||||
pool.reserve(localSender, false)
|
pool.reserve(localSender, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1994,6 +1994,7 @@ func (pool *LegacyPool) Clear() {
|
||||||
pool.priced = newPricedList(pool.all)
|
pool.priced = newPricedList(pool.all)
|
||||||
pool.pending = make(map[common.Address]*list)
|
pool.pending = make(map[common.Address]*list)
|
||||||
pool.queue = make(map[common.Address]*list)
|
pool.queue = make(map[common.Address]*list)
|
||||||
|
pool.pendingNonces = newNoncer(pool.currentState)
|
||||||
|
|
||||||
if !pool.config.NoLocals && pool.config.Journal != "" {
|
if !pool.config.NoLocals && pool.config.Journal != "" {
|
||||||
pool.journal = newTxJournal(pool.config.Journal)
|
pool.journal = newTxJournal(pool.config.Journal)
|
||||||
|
|
|
||||||
|
|
@ -162,12 +162,12 @@ func TestTransactionZAttack(t *testing.T) {
|
||||||
var ivpendingNum int
|
var ivpendingNum int
|
||||||
pendingtxs, _ := pool.Content()
|
pendingtxs, _ := pool.Content()
|
||||||
for account, txs := range pendingtxs {
|
for account, txs := range pendingtxs {
|
||||||
cur_balance := new(big.Int).Set(pool.currentState.GetBalance(account).ToBig())
|
curBalance := new(big.Int).Set(pool.currentState.GetBalance(account).ToBig())
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
if cur_balance.Cmp(tx.Value()) <= 0 {
|
if curBalance.Cmp(tx.Value()) <= 0 {
|
||||||
ivpendingNum++
|
ivpendingNum++
|
||||||
} else {
|
} else {
|
||||||
cur_balance.Sub(cur_balance, tx.Value())
|
curBalance.Sub(curBalance, tx.Value())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1243,33 +1243,28 @@ func TestAllowedTxSize(t *testing.T) {
|
||||||
account := crypto.PubkeyToAddress(key.PublicKey)
|
account := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
testAddBalance(pool, account, big.NewInt(1000000000))
|
testAddBalance(pool, account, big.NewInt(1000000000))
|
||||||
|
|
||||||
// Compute maximal data size for transactions (lower bound).
|
// Find the maximum data length for the kind of transaction which will
|
||||||
//
|
// be generated in the pool.addRemoteSync calls below.
|
||||||
// It is assumed the fields in the transaction (except of the data) are:
|
const largeDataLength = txMaxSize - 200 // enough to have a 5 bytes RLP encoding of the data length number
|
||||||
// - nonce <= 32 bytes
|
txWithLargeData := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, largeDataLength)
|
||||||
// - gasTip <= 32 bytes
|
maxTxLengthWithoutData := txWithLargeData.Size() - largeDataLength // 103 bytes
|
||||||
// - gasLimit <= 32 bytes
|
maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130953 bytes
|
||||||
// - recipient == 20 bytes
|
|
||||||
// - value <= 32 bytes
|
|
||||||
// - signature == 65 bytes
|
|
||||||
// All those fields are summed up to at most 213 bytes.
|
|
||||||
baseSize := uint64(213)
|
|
||||||
dataSize := txMaxSize - baseSize
|
|
||||||
// Try adding a transaction with maximal allowed size
|
// Try adding a transaction with maximal allowed size
|
||||||
tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize)
|
tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength)
|
||||||
if err := pool.addRemoteSync(tx); err != nil {
|
if err := pool.addRemoteSync(tx); err != nil {
|
||||||
t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err)
|
t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err)
|
||||||
}
|
}
|
||||||
// Try adding a transaction with random allowed size
|
// Try adding a transaction with random allowed size
|
||||||
if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.Intn(int(dataSize))))); err != nil {
|
if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.Intn(int(maxTxDataLength+1))))); err != nil {
|
||||||
t.Fatalf("failed to add transaction of random allowed size: %v", err)
|
t.Fatalf("failed to add transaction of random allowed size: %v", err)
|
||||||
}
|
}
|
||||||
// Try adding a transaction of minimal not allowed size
|
// Try adding a transaction above maximum size by one
|
||||||
if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, txMaxSize)); err == nil {
|
if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength+1)); err == nil {
|
||||||
t.Fatalf("expected rejection on slightly oversize transaction")
|
t.Fatalf("expected rejection on slightly oversize transaction")
|
||||||
}
|
}
|
||||||
// Try adding a transaction of random not allowed size
|
// Try adding a transaction above maximum size by more than one
|
||||||
if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize+1+uint64(rand.Intn(10*txMaxSize)))); err == nil {
|
if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength+1+uint64(rand.Intn(10*txMaxSize)))); err == nil {
|
||||||
t.Fatalf("expected rejection on oversize transaction")
|
t.Fatalf("expected rejection on oversize transaction")
|
||||||
}
|
}
|
||||||
// Run some sanity checks on the pool internals
|
// Run some sanity checks on the pool internals
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const (
|
||||||
depositRequestSize = 192
|
depositRequestSize = 192
|
||||||
)
|
)
|
||||||
|
|
||||||
// UnpackIntoDeposit unpacks a serialized DepositEvent.
|
// DepositLogToRequest unpacks a serialized DepositEvent.
|
||||||
func DepositLogToRequest(data []byte) ([]byte, error) {
|
func DepositLogToRequest(data []byte) ([]byte, error) {
|
||||||
if len(data) != 576 {
|
if len(data) != 576 {
|
||||||
return nil, fmt.Errorf("deposit wrong length: want 576, have %d", len(data))
|
return nil, fmt.Errorf("deposit wrong length: want 576, have %d", len(data))
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ var _ = (*authorizationMarshaling)(nil)
|
||||||
// MarshalJSON marshals as JSON.
|
// MarshalJSON marshals as JSON.
|
||||||
func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) {
|
func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) {
|
||||||
type SetCodeAuthorization struct {
|
type SetCodeAuthorization struct {
|
||||||
ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"`
|
ChainID hexutil.U256 `json:"chainId" gencodec:"required"`
|
||||||
Address common.Address `json:"address" gencodec:"required"`
|
Address common.Address `json:"address" gencodec:"required"`
|
||||||
Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||||
V hexutil.Uint64 `json:"yParity" gencodec:"required"`
|
V hexutil.Uint64 `json:"yParity" gencodec:"required"`
|
||||||
|
|
@ -24,7 +24,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) {
|
||||||
S hexutil.U256 `json:"s" gencodec:"required"`
|
S hexutil.U256 `json:"s" gencodec:"required"`
|
||||||
}
|
}
|
||||||
var enc SetCodeAuthorization
|
var enc SetCodeAuthorization
|
||||||
enc.ChainID = hexutil.Uint64(s.ChainID)
|
enc.ChainID = hexutil.U256(s.ChainID)
|
||||||
enc.Address = s.Address
|
enc.Address = s.Address
|
||||||
enc.Nonce = hexutil.Uint64(s.Nonce)
|
enc.Nonce = hexutil.Uint64(s.Nonce)
|
||||||
enc.V = hexutil.Uint64(s.V)
|
enc.V = hexutil.Uint64(s.V)
|
||||||
|
|
@ -36,7 +36,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) {
|
||||||
// UnmarshalJSON unmarshals from JSON.
|
// UnmarshalJSON unmarshals from JSON.
|
||||||
func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error {
|
func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error {
|
||||||
type SetCodeAuthorization struct {
|
type SetCodeAuthorization struct {
|
||||||
ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"`
|
ChainID *hexutil.U256 `json:"chainId" gencodec:"required"`
|
||||||
Address *common.Address `json:"address" gencodec:"required"`
|
Address *common.Address `json:"address" gencodec:"required"`
|
||||||
Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||||
V *hexutil.Uint64 `json:"yParity" gencodec:"required"`
|
V *hexutil.Uint64 `json:"yParity" gencodec:"required"`
|
||||||
|
|
@ -50,7 +50,7 @@ func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error {
|
||||||
if dec.ChainID == nil {
|
if dec.ChainID == nil {
|
||||||
return errors.New("missing required field 'chainId' for SetCodeAuthorization")
|
return errors.New("missing required field 'chainId' for SetCodeAuthorization")
|
||||||
}
|
}
|
||||||
s.ChainID = uint64(*dec.ChainID)
|
s.ChainID = uint256.Int(*dec.ChainID)
|
||||||
if dec.Address == nil {
|
if dec.Address == nil {
|
||||||
return errors.New("missing required field 'address' for SetCodeAuthorization")
|
return errors.New("missing required field 'address' for SetCodeAuthorization")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) {
|
||||||
enc.Proofs = itx.Sidecar.Proofs
|
enc.Proofs = itx.Sidecar.Proofs
|
||||||
}
|
}
|
||||||
case *SetCodeTx:
|
case *SetCodeTx:
|
||||||
enc.ChainID = (*hexutil.Big)(new(big.Int).SetUint64(itx.ChainID))
|
enc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig())
|
||||||
enc.Nonce = (*hexutil.Uint64)(&itx.Nonce)
|
enc.Nonce = (*hexutil.Uint64)(&itx.Nonce)
|
||||||
enc.To = tx.To()
|
enc.To = tx.To()
|
||||||
enc.Gas = (*hexutil.Uint64)(&itx.Gas)
|
enc.Gas = (*hexutil.Uint64)(&itx.Gas)
|
||||||
|
|
@ -353,7 +353,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
||||||
if dec.ChainID == nil {
|
if dec.ChainID == nil {
|
||||||
return errors.New("missing required field 'chainId' in transaction")
|
return errors.New("missing required field 'chainId' in transaction")
|
||||||
}
|
}
|
||||||
itx.ChainID = uint256.MustFromBig((*big.Int)(dec.ChainID))
|
var overflow bool
|
||||||
|
itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt())
|
||||||
|
if overflow {
|
||||||
|
return errors.New("'chainId' value overflows uint256")
|
||||||
|
}
|
||||||
if dec.Nonce == nil {
|
if dec.Nonce == nil {
|
||||||
return errors.New("missing required field 'nonce' in transaction")
|
return errors.New("missing required field 'nonce' in transaction")
|
||||||
}
|
}
|
||||||
|
|
@ -395,7 +399,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
||||||
itx.BlobHashes = dec.BlobVersionedHashes
|
itx.BlobHashes = dec.BlobVersionedHashes
|
||||||
|
|
||||||
// signature R
|
// signature R
|
||||||
var overflow bool
|
|
||||||
if dec.R == nil {
|
if dec.R == nil {
|
||||||
return errors.New("missing required field 'r' in transaction")
|
return errors.New("missing required field 'r' in transaction")
|
||||||
}
|
}
|
||||||
|
|
@ -432,7 +435,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
||||||
if dec.ChainID == nil {
|
if dec.ChainID == nil {
|
||||||
return errors.New("missing required field 'chainId' in transaction")
|
return errors.New("missing required field 'chainId' in transaction")
|
||||||
}
|
}
|
||||||
itx.ChainID = dec.ChainID.ToInt().Uint64()
|
var overflow bool
|
||||||
|
itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt())
|
||||||
|
if overflow {
|
||||||
|
return errors.New("'chainId' value overflows uint256")
|
||||||
|
}
|
||||||
if dec.Nonce == nil {
|
if dec.Nonce == nil {
|
||||||
return errors.New("missing required field 'nonce' in transaction")
|
return errors.New("missing required field 'nonce' in transaction")
|
||||||
}
|
}
|
||||||
|
|
@ -470,7 +477,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
||||||
itx.AuthList = dec.AuthorizationList
|
itx.AuthList = dec.AuthorizationList
|
||||||
|
|
||||||
// signature R
|
// signature R
|
||||||
var overflow bool
|
|
||||||
if dec.R == nil {
|
if dec.R == nil {
|
||||||
return errors.New("missing required field 'r' in transaction")
|
return errors.New("missing required field 'r' in transaction")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big
|
||||||
}
|
}
|
||||||
// Check that chain ID of tx matches the signer. We also accept ID zero here,
|
// Check that chain ID of tx matches the signer. We also accept ID zero here,
|
||||||
// because it indicates that the chain ID was not specified in the tx.
|
// because it indicates that the chain ID was not specified in the tx.
|
||||||
if txdata.ChainID != 0 && new(big.Int).SetUint64(txdata.ChainID).Cmp(s.chainId) != 0 {
|
if txdata.ChainID != nil && txdata.ChainID.CmpBig(s.chainId) != 0 {
|
||||||
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
|
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
|
||||||
}
|
}
|
||||||
R, S, _ = decodeSignature(sig)
|
R, S, _ = decodeSignature(sig)
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ type BlobTx struct {
|
||||||
Sidecar *BlobTxSidecar `rlp:"-"`
|
Sidecar *BlobTxSidecar `rlp:"-"`
|
||||||
|
|
||||||
// Signature values
|
// Signature values
|
||||||
V *uint256.Int `json:"v" gencodec:"required"`
|
V *uint256.Int
|
||||||
R *uint256.Int `json:"r" gencodec:"required"`
|
R *uint256.Int
|
||||||
S *uint256.Int `json:"s" gencodec:"required"`
|
S *uint256.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlobTxSidecar contains the blobs of a blob transaction.
|
// BlobTxSidecar contains the blobs of a blob transaction.
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,9 @@ type DynamicFeeTx struct {
|
||||||
AccessList AccessList
|
AccessList AccessList
|
||||||
|
|
||||||
// Signature values
|
// Signature values
|
||||||
V *big.Int `json:"v" gencodec:"required"`
|
V *big.Int
|
||||||
R *big.Int `json:"r" gencodec:"required"`
|
R *big.Int
|
||||||
S *big.Int `json:"s" gencodec:"required"`
|
S *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy creates a deep copy of the transaction data and initializes all fields.
|
// copy creates a deep copy of the transaction data and initializes all fields.
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func AddressToDelegation(addr common.Address) []byte {
|
||||||
// SetCodeTx implements the EIP-7702 transaction type which temporarily installs
|
// SetCodeTx implements the EIP-7702 transaction type which temporarily installs
|
||||||
// the code at the signer's address.
|
// the code at the signer's address.
|
||||||
type SetCodeTx struct {
|
type SetCodeTx struct {
|
||||||
ChainID uint64
|
ChainID *uint256.Int
|
||||||
Nonce uint64
|
Nonce uint64
|
||||||
GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas
|
GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas
|
||||||
GasFeeCap *uint256.Int // a.k.a. maxFeePerGas
|
GasFeeCap *uint256.Int // a.k.a. maxFeePerGas
|
||||||
|
|
@ -61,16 +61,16 @@ type SetCodeTx struct {
|
||||||
AuthList []SetCodeAuthorization
|
AuthList []SetCodeAuthorization
|
||||||
|
|
||||||
// Signature values
|
// Signature values
|
||||||
V *uint256.Int `json:"v" gencodec:"required"`
|
V *uint256.Int
|
||||||
R *uint256.Int `json:"r" gencodec:"required"`
|
R *uint256.Int
|
||||||
S *uint256.Int `json:"s" gencodec:"required"`
|
S *uint256.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go
|
//go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go
|
||||||
|
|
||||||
// SetCodeAuthorization is an authorization from an account to deploy code at its address.
|
// SetCodeAuthorization is an authorization from an account to deploy code at its address.
|
||||||
type SetCodeAuthorization struct {
|
type SetCodeAuthorization struct {
|
||||||
ChainID uint64 `json:"chainId" gencodec:"required"`
|
ChainID uint256.Int `json:"chainId" gencodec:"required"`
|
||||||
Address common.Address `json:"address" gencodec:"required"`
|
Address common.Address `json:"address" gencodec:"required"`
|
||||||
Nonce uint64 `json:"nonce" gencodec:"required"`
|
Nonce uint64 `json:"nonce" gencodec:"required"`
|
||||||
V uint8 `json:"yParity" gencodec:"required"`
|
V uint8 `json:"yParity" gencodec:"required"`
|
||||||
|
|
@ -80,7 +80,7 @@ type SetCodeAuthorization struct {
|
||||||
|
|
||||||
// field type overrides for gencodec
|
// field type overrides for gencodec
|
||||||
type authorizationMarshaling struct {
|
type authorizationMarshaling struct {
|
||||||
ChainID hexutil.Uint64
|
ChainID hexutil.U256
|
||||||
Nonce hexutil.Uint64
|
Nonce hexutil.Uint64
|
||||||
V hexutil.Uint64
|
V hexutil.Uint64
|
||||||
R hexutil.U256
|
R hexutil.U256
|
||||||
|
|
@ -180,7 +180,7 @@ func (tx *SetCodeTx) copy() TxData {
|
||||||
|
|
||||||
// accessors for innerTx.
|
// accessors for innerTx.
|
||||||
func (tx *SetCodeTx) txType() byte { return SetCodeTxType }
|
func (tx *SetCodeTx) txType() byte { return SetCodeTxType }
|
||||||
func (tx *SetCodeTx) chainID() *big.Int { return big.NewInt(int64(tx.ChainID)) }
|
func (tx *SetCodeTx) chainID() *big.Int { return tx.ChainID.ToBig() }
|
||||||
func (tx *SetCodeTx) accessList() AccessList { return tx.AccessList }
|
func (tx *SetCodeTx) accessList() AccessList { return tx.AccessList }
|
||||||
func (tx *SetCodeTx) data() []byte { return tx.Data }
|
func (tx *SetCodeTx) data() []byte { return tx.Data }
|
||||||
func (tx *SetCodeTx) gas() uint64 { return tx.Gas }
|
func (tx *SetCodeTx) gas() uint64 { return tx.Gas }
|
||||||
|
|
@ -207,7 +207,7 @@ func (tx *SetCodeTx) rawSignatureValues() (v, r, s *big.Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *SetCodeTx) setSignatureValues(chainID, v, r, s *big.Int) {
|
func (tx *SetCodeTx) setSignatureValues(chainID, v, r, s *big.Int) {
|
||||||
tx.ChainID = chainID.Uint64()
|
tx.ChainID = uint256.MustFromBig(chainID)
|
||||||
tx.V.SetFromBig(v)
|
tx.V.SetFromBig(v)
|
||||||
tx.R.SetFromBig(r)
|
tx.R.SetFromBig(r)
|
||||||
tx.S.SetFromBig(s)
|
tx.S.SetFromBig(s)
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ var (
|
||||||
ShanghaiTime: u64(0),
|
ShanghaiTime: u64(0),
|
||||||
VerkleTime: u64(0),
|
VerkleTime: u64(0),
|
||||||
TerminalTotalDifficulty: common.Big0,
|
TerminalTotalDifficulty: common.Big0,
|
||||||
|
EnableVerkleAtGenesis: true,
|
||||||
// TODO uncomment when proof generation is merged
|
// TODO uncomment when proof generation is merged
|
||||||
// ProofInBlocks: true,
|
// ProofInBlocks: true,
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +78,7 @@ var (
|
||||||
ShanghaiTime: u64(0),
|
ShanghaiTime: u64(0),
|
||||||
VerkleTime: u64(0),
|
VerkleTime: u64(0),
|
||||||
TerminalTotalDifficulty: common.Big0,
|
TerminalTotalDifficulty: common.Big0,
|
||||||
|
EnableVerkleAtGenesis: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,8 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case RJUMPV:
|
case RJUMPV:
|
||||||
max_size := int(code[i+1])
|
maxSize := int(code[i+1])
|
||||||
length := max_size + 1
|
length := maxSize + 1
|
||||||
if len(code) <= i+length {
|
if len(code) <= i+length {
|
||||||
return nil, fmt.Errorf("%w: jump table truncated, op %s, pos %d", errTruncatedImmediate, op, i)
|
return nil, fmt.Errorf("%w: jump table truncated, op %s, pos %d", errTruncatedImmediate, op, i)
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +120,7 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i += 2 * max_size
|
i += 2 * maxSize
|
||||||
case CALLF:
|
case CALLF:
|
||||||
arg, _ := parseUint16(code[i+1:])
|
arg, _ := parseUint16(code[i+1:])
|
||||||
if arg >= len(container.types) {
|
if arg >= len(container.types) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
// - There are not package guarantees. We might iterate heavily on this package, and do backwards-incompatible changes without warning
|
// - There are not package guarantees. We might iterate heavily on this package, and do backwards-incompatible changes without warning
|
||||||
// - There are no quality-guarantees. These utilities may produce evm-code that is non-functional. YMMV.
|
// - There are no quality-guarantees. These utilities may produce evm-code that is non-functional. YMMV.
|
||||||
// - There are no stability-guarantees. The utility will `panic` if the inputs do not align / make sense.
|
// - There are no stability-guarantees. The utility will `panic` if the inputs do not align / make sense.
|
||||||
|
|
||||||
package program
|
package program
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -204,7 +205,7 @@ func (p *Program) StaticCall(gas *uint256.Int, address, inOffset, inSize, outOff
|
||||||
return p.Op(vm.STATICCALL)
|
return p.Op(vm.STATICCALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StaticCall is a convenience function to make a callcode. If 'gas' is nil, the opcode GAS will
|
// CallCode is a convenience function to make a callcode. If 'gas' is nil, the opcode GAS will
|
||||||
// be used to provide all gas.
|
// be used to provide all gas.
|
||||||
func (p *Program) CallCode(gas *uint256.Int, address, value, inOffset, inSize, outOffset, outSize any) *Program {
|
func (p *Program) CallCode(gas *uint256.Int, address, value, inOffset, inSize, outOffset, outSize any) *Program {
|
||||||
if outOffset == outSize && inSize == outSize && inOffset == outSize {
|
if outOffset == outSize && inSize == outSize && inOffset == outSize {
|
||||||
|
|
@ -263,7 +264,7 @@ func (p *Program) InputAddressToStack(inputOffset uint32) *Program {
|
||||||
return p.Op(vm.AND)
|
return p.Op(vm.AND)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MStore stores the provided data (into the memory area starting at memStart).
|
// Mstore stores the provided data (into the memory area starting at memStart).
|
||||||
func (p *Program) Mstore(data []byte, memStart uint32) *Program {
|
func (p *Program) Mstore(data []byte, memStart uint32) *Program {
|
||||||
var idx = 0
|
var idx = 0
|
||||||
// We need to store it in chunks of 32 bytes
|
// We need to store it in chunks of 32 bytes
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// The blocksize of BLAKE2b in bytes.
|
// BlockSize the blocksize of BLAKE2b in bytes.
|
||||||
BlockSize = 128
|
BlockSize = 128
|
||||||
// The hash size of BLAKE2b-512 in bytes.
|
// Size the hash size of BLAKE2b-512 in bytes.
|
||||||
Size = 64
|
Size = 64
|
||||||
// The hash size of BLAKE2b-384 in bytes.
|
// Size384 the hash size of BLAKE2b-384 in bytes.
|
||||||
Size384 = 48
|
Size384 = 48
|
||||||
// The hash size of BLAKE2b-256 in bytes.
|
// Size256 the hash size of BLAKE2b-256 in bytes.
|
||||||
Size256 = 32
|
Size256 = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"github.com/consensys/gnark-crypto/ecc/bn254"
|
"github.com/consensys/gnark-crypto/ecc/bn254"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1
|
// PairingCheck computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1
|
||||||
//
|
//
|
||||||
// To explain why gnark returns a (bool, error):
|
// To explain why gnark returns a (bool, error):
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,12 @@ type PublicKey struct {
|
||||||
Params *ECIESParams
|
Params *ECIESParams
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export an ECIES public key as an ECDSA public key.
|
// ExportECDSA exports an ECIES public key as an ECDSA public key.
|
||||||
func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey {
|
func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey {
|
||||||
return &ecdsa.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y}
|
return &ecdsa.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import an ECDSA public key as an ECIES public key.
|
// ImportECDSAPublic imports an ECDSA public key as an ECIES public key.
|
||||||
func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey {
|
func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey {
|
||||||
return &PublicKey{
|
return &PublicKey{
|
||||||
X: pub.X,
|
X: pub.X,
|
||||||
|
|
@ -81,20 +81,20 @@ type PrivateKey struct {
|
||||||
D *big.Int
|
D *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export an ECIES private key as an ECDSA private key.
|
// ExportECDSA exports an ECIES private key as an ECDSA private key.
|
||||||
func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey {
|
func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey {
|
||||||
pub := &prv.PublicKey
|
pub := &prv.PublicKey
|
||||||
pubECDSA := pub.ExportECDSA()
|
pubECDSA := pub.ExportECDSA()
|
||||||
return &ecdsa.PrivateKey{PublicKey: *pubECDSA, D: prv.D}
|
return &ecdsa.PrivateKey{PublicKey: *pubECDSA, D: prv.D}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import an ECDSA private key as an ECIES private key.
|
// ImportECDSA imports an ECDSA private key as an ECIES private key.
|
||||||
func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey {
|
func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey {
|
||||||
pub := ImportECDSAPublic(&prv.PublicKey)
|
pub := ImportECDSAPublic(&prv.PublicKey)
|
||||||
return &PrivateKey{*pub, prv.D}
|
return &PrivateKey{*pub, prv.D}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate an elliptic curve public / private keypair. If params is nil,
|
// GenerateKey generates an elliptic curve public / private keypair. If params is nil,
|
||||||
// the recommended default parameters for the key will be chosen.
|
// the recommended default parameters for the key will be chosen.
|
||||||
func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) {
|
func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) {
|
||||||
sk, err := ecdsa.GenerateKey(curve, rand)
|
sk, err := ecdsa.GenerateKey(curve, rand)
|
||||||
|
|
@ -119,7 +119,7 @@ func MaxSharedKeyLength(pub *PublicKey) int {
|
||||||
return (pub.Curve.Params().BitSize + 7) / 8
|
return (pub.Curve.Params().BitSize + 7) / 8
|
||||||
}
|
}
|
||||||
|
|
||||||
// ECDH key agreement method used to establish secret keys for encryption.
|
// GenerateShared ECDH key agreement method used to establish secret keys for encryption.
|
||||||
func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) {
|
func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) {
|
||||||
if prv.PublicKey.Curve != pub.Curve {
|
if prv.PublicKey.Curve != pub.Curve {
|
||||||
return nil, ErrInvalidCurve
|
return nil, ErrInvalidCurve
|
||||||
|
|
|
||||||
|
|
@ -638,6 +638,9 @@ func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHas
|
||||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV4 must only be called for prague payloads"))
|
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV4 must only be called for prague payloads"))
|
||||||
}
|
}
|
||||||
requests := convertRequests(executionRequests)
|
requests := convertRequests(executionRequests)
|
||||||
|
if err := validateRequests(requests); err != nil {
|
||||||
|
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err)
|
||||||
|
}
|
||||||
return api.newPayload(params, versionedHashes, beaconRoot, requests, false)
|
return api.newPayload(params, versionedHashes, beaconRoot, requests, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -727,6 +730,9 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV4(params engine.ExecutableData, v
|
||||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadWithWitnessV4 must only be called for prague payloads"))
|
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadWithWitnessV4 must only be called for prague payloads"))
|
||||||
}
|
}
|
||||||
requests := convertRequests(executionRequests)
|
requests := convertRequests(executionRequests)
|
||||||
|
if err := validateRequests(requests); err != nil {
|
||||||
|
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err)
|
||||||
|
}
|
||||||
return api.newPayload(params, versionedHashes, beaconRoot, requests, true)
|
return api.newPayload(params, versionedHashes, beaconRoot, requests, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1287,3 +1293,20 @@ func convertRequests(hex []hexutil.Bytes) [][]byte {
|
||||||
}
|
}
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateRequests checks that requests are ordered by their type and are not empty.
|
||||||
|
func validateRequests(requests [][]byte) error {
|
||||||
|
var last byte
|
||||||
|
for _, req := range requests {
|
||||||
|
// No empty requests.
|
||||||
|
if len(req) < 2 {
|
||||||
|
return fmt.Errorf("empty request: %v", req)
|
||||||
|
}
|
||||||
|
// Check that requests are ordered by their type.
|
||||||
|
if req[0] < last {
|
||||||
|
return fmt.Errorf("invalid request order: %v", req)
|
||||||
|
}
|
||||||
|
last = req[0]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,16 +120,23 @@ func NewOracle(backend OracleBackend, params Config, startPrice *big.Int) *Oracl
|
||||||
|
|
||||||
cache := lru.NewCache[cacheKey, processedFees](2048)
|
cache := lru.NewCache[cacheKey, processedFees](2048)
|
||||||
headEvent := make(chan core.ChainHeadEvent, 1)
|
headEvent := make(chan core.ChainHeadEvent, 1)
|
||||||
backend.SubscribeChainHeadEvent(headEvent)
|
sub := backend.SubscribeChainHeadEvent(headEvent)
|
||||||
|
if sub != nil { // the gasprice testBackend doesn't support subscribing to head events
|
||||||
go func() {
|
go func() {
|
||||||
var lastHead common.Hash
|
var lastHead common.Hash
|
||||||
for ev := range headEvent {
|
for {
|
||||||
|
select {
|
||||||
|
case ev := <-headEvent:
|
||||||
if ev.Header.ParentHash != lastHead {
|
if ev.Header.ParentHash != lastHead {
|
||||||
cache.Purge()
|
cache.Purge()
|
||||||
}
|
}
|
||||||
lastHead = ev.Header.Hash()
|
lastHead = ev.Header.Hash()
|
||||||
|
case <-sub.Err():
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
return &Oracle{
|
return &Oracle{
|
||||||
backend: backend,
|
backend: backend,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type Context struct {
|
||||||
TxHash common.Hash // Hash of the transaction being traced (zero if dangling call)
|
TxHash common.Hash // Hash of the transaction being traced (zero if dangling call)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The set of methods that must be exposed by a tracer
|
// Tracer represents the set of methods that must be exposed by a tracer
|
||||||
// for it to be available through the RPC interface.
|
// for it to be available through the RPC interface.
|
||||||
// This involves a method to retrieve results and one to
|
// This involves a method to retrieve results and one to
|
||||||
// stop tracing.
|
// stop tracing.
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// 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/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package logger
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"maps"
|
"maps"
|
||||||
|
|
@ -350,7 +351,7 @@ func (l *StructLogger) GetResult() (json.RawMessage, error) {
|
||||||
returnData := common.CopyBytes(l.output)
|
returnData := common.CopyBytes(l.output)
|
||||||
// Return data when successful and revert reason when reverted, otherwise empty.
|
// Return data when successful and revert reason when reverted, otherwise empty.
|
||||||
returnVal := fmt.Sprintf("%x", returnData)
|
returnVal := fmt.Sprintf("%x", returnData)
|
||||||
if failed && l.err != vm.ErrExecutionReverted {
|
if failed && !errors.Is(l.err, vm.ErrExecutionReverted) {
|
||||||
returnVal = ""
|
returnVal = ""
|
||||||
}
|
}
|
||||||
return json.Marshal(&ExecutionResult{
|
return json.Marshal(&ExecutionResult{
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,15 @@ package simulated
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"crypto/sha256"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -36,6 +40,8 @@ var _ bind.ContractBackend = (Client)(nil)
|
||||||
var (
|
var (
|
||||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
|
testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||||
|
testKey2, _ = crypto.HexToECDSA("7ee346e3f7efc685250053bfbafbfc880d58dc6145247053d4fb3cb0f66dfcb2")
|
||||||
|
testAddr2 = crypto.PubkeyToAddress(testKey2.PublicKey)
|
||||||
)
|
)
|
||||||
|
|
||||||
func simTestBackend(testAddr common.Address) *Backend {
|
func simTestBackend(testAddr common.Address) *Backend {
|
||||||
|
|
@ -46,6 +52,46 @@ func simTestBackend(testAddr common.Address) *Backend {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newBlobTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) {
|
||||||
|
client := sim.Client()
|
||||||
|
|
||||||
|
testBlob := &kzg4844.Blob{0x00}
|
||||||
|
testBlobCommit, _ := kzg4844.BlobToCommitment(testBlob)
|
||||||
|
testBlobProof, _ := kzg4844.ComputeBlobProof(testBlob, testBlobCommit)
|
||||||
|
testBlobVHash := kzg4844.CalcBlobHashV1(sha256.New(), &testBlobCommit)
|
||||||
|
|
||||||
|
head, _ := client.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
|
||||||
|
gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei))
|
||||||
|
gasPriceU256, _ := uint256.FromBig(gasPrice)
|
||||||
|
gasTipCapU256, _ := uint256.FromBig(big.NewInt(params.GWei))
|
||||||
|
|
||||||
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
chainid, _ := client.ChainID(context.Background())
|
||||||
|
nonce, err := client.PendingNonceAt(context.Background(), addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
chainidU256, _ := uint256.FromBig(chainid)
|
||||||
|
tx := types.NewTx(&types.BlobTx{
|
||||||
|
ChainID: chainidU256,
|
||||||
|
GasTipCap: gasTipCapU256,
|
||||||
|
GasFeeCap: gasPriceU256,
|
||||||
|
BlobFeeCap: uint256.NewInt(1),
|
||||||
|
Gas: 21000,
|
||||||
|
Nonce: nonce,
|
||||||
|
To: addr,
|
||||||
|
AccessList: nil,
|
||||||
|
BlobHashes: []common.Hash{testBlobVHash},
|
||||||
|
Sidecar: &types.BlobTxSidecar{
|
||||||
|
Blobs: []kzg4844.Blob{*testBlob},
|
||||||
|
Commitments: []kzg4844.Commitment{testBlobCommit},
|
||||||
|
Proofs: []kzg4844.Proof{testBlobProof},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return types.SignTx(tx, types.LatestSignerForChainID(chainid), key)
|
||||||
|
}
|
||||||
|
|
||||||
func newTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) {
|
func newTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) {
|
||||||
client := sim.Client()
|
client := sim.Client()
|
||||||
|
|
||||||
|
|
@ -66,6 +112,7 @@ func newTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) {
|
||||||
Gas: 21000,
|
Gas: 21000,
|
||||||
To: &addr,
|
To: &addr,
|
||||||
})
|
})
|
||||||
|
|
||||||
return types.SignTx(tx, types.LatestSignerForChainID(chainid), key)
|
return types.SignTx(tx, types.LatestSignerForChainID(chainid), key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
102
ethclient/simulated/rollback_test.go
Normal file
102
ethclient/simulated/rollback_test.go
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
package simulated
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestTransactionRollbackBehavior tests that calling Rollback on the simulated backend doesn't prevent subsequent
|
||||||
|
// addition of new transactions
|
||||||
|
func TestTransactionRollbackBehavior(t *testing.T) {
|
||||||
|
sim := NewBackend(
|
||||||
|
types.GenesisAlloc{
|
||||||
|
testAddr: {Balance: big.NewInt(10000000000000000)},
|
||||||
|
testAddr2: {Balance: big.NewInt(10000000000000000)},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer sim.Close()
|
||||||
|
client := sim.Client()
|
||||||
|
|
||||||
|
btx0 := testSendSignedTx(t, testKey, sim, true)
|
||||||
|
tx0 := testSendSignedTx(t, testKey2, sim, false)
|
||||||
|
tx1 := testSendSignedTx(t, testKey2, sim, false)
|
||||||
|
|
||||||
|
sim.Rollback()
|
||||||
|
|
||||||
|
if pendingStateHasTx(client, btx0) || pendingStateHasTx(client, tx0) || pendingStateHasTx(client, tx1) {
|
||||||
|
t.Fatalf("all transactions were not rolled back")
|
||||||
|
}
|
||||||
|
|
||||||
|
btx2 := testSendSignedTx(t, testKey, sim, true)
|
||||||
|
tx2 := testSendSignedTx(t, testKey2, sim, false)
|
||||||
|
tx3 := testSendSignedTx(t, testKey2, sim, false)
|
||||||
|
|
||||||
|
sim.Commit()
|
||||||
|
|
||||||
|
if !pendingStateHasTx(client, btx2) || !pendingStateHasTx(client, tx2) || !pendingStateHasTx(client, tx3) {
|
||||||
|
t.Fatalf("all post-rollback transactions were not included")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// testSendSignedTx sends a signed transaction to the simulated backend.
|
||||||
|
// It does not commit the block.
|
||||||
|
func testSendSignedTx(t *testing.T, key *ecdsa.PrivateKey, sim *Backend, isBlobTx bool) *types.Transaction {
|
||||||
|
t.Helper()
|
||||||
|
client := sim.Client()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
signedTx *types.Transaction
|
||||||
|
)
|
||||||
|
if isBlobTx {
|
||||||
|
signedTx, err = newBlobTx(sim, key)
|
||||||
|
} else {
|
||||||
|
signedTx, err = newTx(sim, key)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create transaction: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = client.SendTransaction(ctx, signedTx); err != nil {
|
||||||
|
t.Fatalf("failed to send transaction: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedTx
|
||||||
|
}
|
||||||
|
|
||||||
|
// pendingStateHasTx returns true if a given transaction was successfully included as of the latest pending state.
|
||||||
|
func pendingStateHasTx(client Client, tx *types.Transaction) bool {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var (
|
||||||
|
receipt *types.Receipt
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// Poll for receipt with timeout
|
||||||
|
deadline := time.Now().Add(2 * time.Second)
|
||||||
|
for time.Now().Before(deadline) {
|
||||||
|
receipt, err = client.TransactionReceipt(ctx, tx.Hash())
|
||||||
|
if err == nil && receipt != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if receipt == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if receipt.Status != types.ReceiptStatusSuccessful {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with go-ethereum. If not, see <http//www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package era
|
package era
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -503,7 +503,7 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction {
|
||||||
}
|
}
|
||||||
data = &types.SetCodeTx{
|
data = &types.SetCodeTx{
|
||||||
To: *args.To,
|
To: *args.To,
|
||||||
ChainID: args.ChainID.ToInt().Uint64(),
|
ChainID: uint256.MustFromBig(args.ChainID.ToInt()),
|
||||||
Nonce: uint64(*args.Nonce),
|
Nonce: uint64(*args.Nonce),
|
||||||
Gas: uint64(*args.Gas),
|
Gas: uint64(*args.Gas),
|
||||||
GasFeeCap: uint256.MustFromBig((*big.Int)(args.MaxFeePerGas)),
|
GasFeeCap: uint256.MustFromBig((*big.Int)(args.MaxFeePerGas)),
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,19 @@ type evalReq struct {
|
||||||
done chan bool
|
done chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtime must be stopped with Stop() after use and cannot be used after stopping
|
// New creates and initializes a new JavaScript runtime environment (JSRE).
|
||||||
|
// The runtime is configured with the provided assetPath for loading scripts and
|
||||||
|
// an output writer for logging or printing results.
|
||||||
|
//
|
||||||
|
// The returned JSRE must be stopped by calling Stop() after use to release resources.
|
||||||
|
// Attempting to use the JSRE after stopping it will result in undefined behavior.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - assetPath: The path to the directory containing script assets.
|
||||||
|
// - output: The writer used for logging or printing runtime output.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - A pointer to the newly created JSRE instance.
|
||||||
func New(assetPath string, output io.Writer) *JSRE {
|
func New(assetPath string, output io.Writer) *JSRE {
|
||||||
re := &JSRE{
|
re := &JSRE{
|
||||||
assetPath: assetPath,
|
assetPath: assetPath,
|
||||||
|
|
@ -251,8 +263,15 @@ func (re *JSRE) Stop(waitForCallbacks bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec(file) loads and runs the contents of a file
|
// Exec loads and executes the contents of a JavaScript file.
|
||||||
// if a relative path is given, the jsre's assetPath is used
|
// If a relative path is provided, the file is resolved relative to the JSRE's assetPath.
|
||||||
|
// The file is read, compiled, and executed in the JSRE's runtime environment.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - file: The path to the JavaScript file to execute. Can be an absolute path or relative to assetPath.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: An error if the file cannot be read, compiled, or executed.
|
||||||
func (re *JSRE) Exec(file string) error {
|
func (re *JSRE) Exec(file string) error {
|
||||||
code, err := os.ReadFile(common.AbsolutePath(re.assetPath, file))
|
code, err := os.ReadFile(common.AbsolutePath(re.assetPath, file))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
// we require because of the forking limitations of using Go. Handlers can be
|
// we require because of the forking limitations of using Go. Handlers can be
|
||||||
// registered with a name and the argv 0 of the exec of the binary will be used
|
// registered with a name and the argv 0 of the exec of the binary will be used
|
||||||
// to find and execute custom init paths.
|
// to find and execute custom init paths.
|
||||||
|
|
||||||
package reexec
|
package reexec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// Hook go-metrics into expvar
|
// Hook go-metrics into expvar
|
||||||
// on any /debug/metrics request, load all vars from the registry into expvar, and execute regular expvar handler
|
// on any /debug/metrics request, load all vars from the registry into expvar, and execute regular expvar handler
|
||||||
|
|
||||||
package exp
|
package exp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ func NewRegisteredGaugeInfo(name string, r Registry) *GaugeInfo {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// gaugeInfoSnapshot is a read-only copy of another GaugeInfo.
|
// GaugeInfoSnapshot is a read-only copy of another GaugeInfo.
|
||||||
type GaugeInfoSnapshot GaugeInfoValue
|
type GaugeInfoSnapshot GaugeInfoValue
|
||||||
|
|
||||||
// Value returns the value at the time the snapshot was taken.
|
// Value returns the value at the time the snapshot was taken.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ func Log(r Registry, freq time.Duration, l Logger) {
|
||||||
LogScaled(r, freq, time.Nanosecond, l)
|
LogScaled(r, freq, time.Nanosecond, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output each metric in the given registry periodically using the given
|
// LogScaled outputs each metric in the given registry periodically using the given
|
||||||
// logger. Print timings in `scale` units (eg time.Millisecond) rather than nanos.
|
// logger. Print timings in `scale` units (eg time.Millisecond) rather than nanos.
|
||||||
func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) {
|
func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) {
|
||||||
du := float64(scale)
|
du := float64(scale)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// <https://github.com/rcrowley/go-metrics>
|
// <https://github.com/rcrowley/go-metrics>
|
||||||
//
|
//
|
||||||
// Coda Hale's original work: <https://github.com/codahale/metrics>
|
// Coda Hale's original work: <https://github.com/codahale/metrics>
|
||||||
|
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -53,14 +53,14 @@ func (t *ResettingTimer) Snapshot() *ResettingTimerSnapshot {
|
||||||
return snapshot
|
return snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of the execution of the given function.
|
// Time records the duration of the execution of the given function.
|
||||||
func (t *ResettingTimer) Time(f func()) {
|
func (t *ResettingTimer) Time(f func()) {
|
||||||
ts := time.Now()
|
ts := time.Now()
|
||||||
f()
|
f()
|
||||||
t.Update(time.Since(ts))
|
t.Update(time.Since(ts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of an event.
|
// Update records the duration of an event.
|
||||||
func (t *ResettingTimer) Update(d time.Duration) {
|
func (t *ResettingTimer) Update(d time.Duration) {
|
||||||
if !metricsEnabled {
|
if !metricsEnabled {
|
||||||
return
|
return
|
||||||
|
|
@ -71,7 +71,7 @@ func (t *ResettingTimer) Update(d time.Duration) {
|
||||||
t.sum += int64(d)
|
t.sum += int64(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of an event that started at a time and ends now.
|
// UpdateSince records the duration of an event that started at a time and ends now.
|
||||||
func (t *ResettingTimer) UpdateSince(ts time.Time) {
|
func (t *ResettingTimer) UpdateSince(ts time.Time) {
|
||||||
t.Update(time.Since(ts))
|
t.Update(time.Since(ts))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Output each metric in the given registry to syslog periodically using
|
// Syslog outputs each metric in the given registry to syslog periodically using
|
||||||
// the given syslogger.
|
// the given syslogger.
|
||||||
func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
|
func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
|
||||||
for range time.Tick(d) {
|
for range time.Tick(d) {
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ func createMiner(t *testing.T) *Miner {
|
||||||
chainDB := rawdb.NewMemoryDatabase()
|
chainDB := rawdb.NewMemoryDatabase()
|
||||||
triedb := triedb.NewDatabase(chainDB, nil)
|
triedb := triedb.NewDatabase(chainDB, nil)
|
||||||
genesis := minerTestGenesisBlock(15, 11_500_000, common.HexToAddress("12345"))
|
genesis := minerTestGenesisBlock(15, 11_500_000, common.HexToAddress("12345"))
|
||||||
chainConfig, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis)
|
chainConfig, _, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't create new chain config: %v", err)
|
t.Fatalf("can't create new chain config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -249,20 +249,20 @@ func TestHandshake_BadHandshakeAttack(t *testing.T) {
|
||||||
net.nodeA.expectDecode(t, WhoareyouPacket, whoareyou)
|
net.nodeA.expectDecode(t, WhoareyouPacket, whoareyou)
|
||||||
|
|
||||||
// A -> B FINDNODE
|
// A -> B FINDNODE
|
||||||
incorrect_challenge := &Whoareyou{
|
incorrectChallenge := &Whoareyou{
|
||||||
IDNonce: [16]byte{5, 6, 7, 8, 9, 6, 11, 12},
|
IDNonce: [16]byte{5, 6, 7, 8, 9, 6, 11, 12},
|
||||||
RecordSeq: challenge.RecordSeq,
|
RecordSeq: challenge.RecordSeq,
|
||||||
Node: challenge.Node,
|
Node: challenge.Node,
|
||||||
sent: challenge.sent,
|
sent: challenge.sent,
|
||||||
}
|
}
|
||||||
incorrect_findnode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, incorrect_challenge, &Findnode{})
|
incorrectFindNode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, incorrectChallenge, &Findnode{})
|
||||||
incorrect_findnode2 := make([]byte, len(incorrect_findnode))
|
incorrectFindNode2 := make([]byte, len(incorrectFindNode))
|
||||||
copy(incorrect_findnode2, incorrect_findnode)
|
copy(incorrectFindNode2, incorrectFindNode)
|
||||||
|
|
||||||
net.nodeB.expectDecodeErr(t, errInvalidNonceSig, incorrect_findnode)
|
net.nodeB.expectDecodeErr(t, errInvalidNonceSig, incorrectFindNode)
|
||||||
|
|
||||||
// Reject new findnode as previous handshake is now deleted.
|
// Reject new findnode as previous handshake is now deleted.
|
||||||
net.nodeB.expectDecodeErr(t, errUnexpectedHandshake, incorrect_findnode2)
|
net.nodeB.expectDecodeErr(t, errUnexpectedHandshake, incorrectFindNode2)
|
||||||
|
|
||||||
// The findnode packet is again rejected even with a valid challenge this time.
|
// The findnode packet is again rejected even with a valid challenge this time.
|
||||||
findnode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, challenge, &Findnode{})
|
findnode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, challenge, &Findnode{})
|
||||||
|
|
|
||||||
|
|
@ -326,6 +326,19 @@ type ChainConfig struct {
|
||||||
|
|
||||||
DepositContractAddress common.Address `json:"depositContractAddress,omitempty"`
|
DepositContractAddress common.Address `json:"depositContractAddress,omitempty"`
|
||||||
|
|
||||||
|
// EnableVerkleAtGenesis is a flag that specifies whether the network uses
|
||||||
|
// the Verkle tree starting from the genesis block. If set to true, the
|
||||||
|
// genesis state will be committed using the Verkle tree, eliminating the
|
||||||
|
// need for any Verkle transition later.
|
||||||
|
//
|
||||||
|
// This is a temporary flag only for verkle devnet testing, where verkle is
|
||||||
|
// activated at genesis, and the configured activation date has already passed.
|
||||||
|
//
|
||||||
|
// In production networks (mainnet and public testnets), verkle activation
|
||||||
|
// always occurs after the genesis block, making this flag irrelevant in
|
||||||
|
// those cases.
|
||||||
|
EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"`
|
||||||
|
|
||||||
// Various consensus engines
|
// Various consensus engines
|
||||||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||||
Clique *CliqueConfig `json:"clique,omitempty"`
|
Clique *CliqueConfig `json:"clique,omitempty"`
|
||||||
|
|
@ -525,6 +538,20 @@ func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
|
||||||
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
|
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsVerkleGenesis checks whether the verkle fork is activated at the genesis block.
|
||||||
|
//
|
||||||
|
// Verkle mode is considered enabled if the verkle fork time is configured,
|
||||||
|
// regardless of whether the local time has surpassed the fork activation time.
|
||||||
|
// This is a temporary workaround for verkle devnet testing, where verkle is
|
||||||
|
// activated at genesis, and the configured activation date has already passed.
|
||||||
|
//
|
||||||
|
// In production networks (mainnet and public testnets), verkle activation
|
||||||
|
// always occurs after the genesis block, making this function irrelevant in
|
||||||
|
// those cases.
|
||||||
|
func (c *ChainConfig) IsVerkleGenesis() bool {
|
||||||
|
return c.EnableVerkleAtGenesis
|
||||||
|
}
|
||||||
|
|
||||||
// IsEIP4762 returns whether eip 4762 has been activated at given block.
|
// IsEIP4762 returns whether eip 4762 has been activated at given block.
|
||||||
func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool {
|
func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool {
|
||||||
return c.IsVerkle(num, time)
|
return c.IsVerkle(num, time)
|
||||||
|
|
|
||||||
|
|
@ -179,10 +179,10 @@ const (
|
||||||
HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935.
|
HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935.
|
||||||
)
|
)
|
||||||
|
|
||||||
// Gas discount table for BLS12-381 G1 multi exponentiation operation
|
// Bls12381G1MultiExpDiscountTable is the gas discount table for BLS12-381 G1 multi exponentiation operation
|
||||||
var Bls12381G1MultiExpDiscountTable = [128]uint64{1000, 949, 848, 797, 764, 750, 738, 728, 719, 712, 705, 698, 692, 687, 682, 677, 673, 669, 665, 661, 658, 654, 651, 648, 645, 642, 640, 637, 635, 632, 630, 627, 625, 623, 621, 619, 617, 615, 613, 611, 609, 608, 606, 604, 603, 601, 599, 598, 596, 595, 593, 592, 591, 589, 588, 586, 585, 584, 582, 581, 580, 579, 577, 576, 575, 574, 573, 572, 570, 569, 568, 567, 566, 565, 564, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 547, 546, 545, 544, 543, 542, 541, 540, 540, 539, 538, 537, 536, 536, 535, 534, 533, 532, 532, 531, 530, 529, 528, 528, 527, 526, 525, 525, 524, 523, 522, 522, 521, 520, 520, 519}
|
var Bls12381G1MultiExpDiscountTable = [128]uint64{1000, 949, 848, 797, 764, 750, 738, 728, 719, 712, 705, 698, 692, 687, 682, 677, 673, 669, 665, 661, 658, 654, 651, 648, 645, 642, 640, 637, 635, 632, 630, 627, 625, 623, 621, 619, 617, 615, 613, 611, 609, 608, 606, 604, 603, 601, 599, 598, 596, 595, 593, 592, 591, 589, 588, 586, 585, 584, 582, 581, 580, 579, 577, 576, 575, 574, 573, 572, 570, 569, 568, 567, 566, 565, 564, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 547, 546, 545, 544, 543, 542, 541, 540, 540, 539, 538, 537, 536, 536, 535, 534, 533, 532, 532, 531, 530, 529, 528, 528, 527, 526, 525, 525, 524, 523, 522, 522, 521, 520, 520, 519}
|
||||||
|
|
||||||
// Gas discount table for BLS12-381 G2 multi exponentiation operation
|
// Bls12381G2MultiExpDiscountTable is the gas discount table for BLS12-381 G2 multi exponentiation operation
|
||||||
var Bls12381G2MultiExpDiscountTable = [128]uint64{1000, 1000, 923, 884, 855, 832, 812, 796, 782, 770, 759, 749, 740, 732, 724, 717, 711, 704, 699, 693, 688, 683, 679, 674, 670, 666, 663, 659, 655, 652, 649, 646, 643, 640, 637, 634, 632, 629, 627, 624, 622, 620, 618, 615, 613, 611, 609, 607, 606, 604, 602, 600, 598, 597, 595, 593, 592, 590, 589, 587, 586, 584, 583, 582, 580, 579, 578, 576, 575, 574, 573, 571, 570, 569, 568, 567, 566, 565, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 552, 551, 550, 549, 548, 547, 546, 545, 545, 544, 543, 542, 541, 541, 540, 539, 538, 537, 537, 536, 535, 535, 534, 533, 532, 532, 531, 530, 530, 529, 528, 528, 527, 526, 526, 525, 524, 524}
|
var Bls12381G2MultiExpDiscountTable = [128]uint64{1000, 1000, 923, 884, 855, 832, 812, 796, 782, 770, 759, 749, 740, 732, 724, 717, 711, 704, 699, 693, 688, 683, 679, 674, 670, 666, 663, 659, 655, 652, 649, 646, 643, 640, 637, 634, 632, 629, 627, 624, 622, 620, 618, 615, 613, 611, 609, 607, 606, 604, 602, 600, 598, 597, 595, 593, 592, 590, 589, 587, 586, 584, 583, 582, 580, 579, 578, 576, 575, 574, 573, 571, 570, 569, 568, 567, 566, 565, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 552, 551, 550, 549, 548, 547, 546, 545, 545, 544, 543, 542, 541, 541, 540, 539, 538, 537, 537, 536, 535, 535, 534, 533, 532, 532, 531, 530, 530, 529, 528, 528, 527, 526, 526, 525, 524, 524}
|
||||||
|
|
||||||
// Difficulty parameters.
|
// Difficulty parameters.
|
||||||
|
|
|
||||||
|
|
@ -664,7 +664,7 @@ func (api *SignerAPI) SignGnosisSafeTx(ctx context.Context, signerAddress common
|
||||||
return &gnosisTx, nil
|
return &gnosisTx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the external api version. This method does not require user acceptance. Available methods are
|
// Version returns the external api version. This method does not require user acceptance. Available methods are
|
||||||
// available via enumeration anyway, and this info does not contain user-specific data
|
// available via enumeration anyway, and this info does not contain user-specific data
|
||||||
func (api *SignerAPI) Version(ctx context.Context) (string, error) {
|
func (api *SignerAPI) Version(ctx context.Context) (string, error) {
|
||||||
return ExternalAPIVersion, nil
|
return ExternalAPIVersion, nil
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ func NewUIServerAPI(extapi *SignerAPI) *UIServerAPI {
|
||||||
return &UIServerAPI{extapi, extapi.am}
|
return &UIServerAPI{extapi, extapi.am}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List available accounts. As opposed to the external API definition, this method delivers
|
// ListAccounts lists available accounts. As opposed to the external API definition, this method delivers
|
||||||
// the full Account object and not only Address.
|
// the full Account object and not only Address.
|
||||||
// Example call
|
// Example call
|
||||||
// {"jsonrpc":"2.0","method":"clef_listAccounts","params":[], "id":4}
|
// {"jsonrpc":"2.0","method":"clef_listAccounts","params":[], "id":4}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ var _ = (*stAuthorizationMarshaling)(nil)
|
||||||
// MarshalJSON marshals as JSON.
|
// MarshalJSON marshals as JSON.
|
||||||
func (s stAuthorization) MarshalJSON() ([]byte, error) {
|
func (s stAuthorization) MarshalJSON() ([]byte, error) {
|
||||||
type stAuthorization struct {
|
type stAuthorization struct {
|
||||||
ChainID math.HexOrDecimal64
|
ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"`
|
||||||
Address common.Address `json:"address" gencodec:"required"`
|
Address common.Address `json:"address" gencodec:"required"`
|
||||||
Nonce math.HexOrDecimal64 `json:"nonce" gencodec:"required"`
|
Nonce math.HexOrDecimal64 `json:"nonce" gencodec:"required"`
|
||||||
V math.HexOrDecimal64 `json:"v" gencodec:"required"`
|
V math.HexOrDecimal64 `json:"v" gencodec:"required"`
|
||||||
|
|
@ -24,7 +24,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) {
|
||||||
S *math.HexOrDecimal256 `json:"s" gencodec:"required"`
|
S *math.HexOrDecimal256 `json:"s" gencodec:"required"`
|
||||||
}
|
}
|
||||||
var enc stAuthorization
|
var enc stAuthorization
|
||||||
enc.ChainID = math.HexOrDecimal64(s.ChainID)
|
enc.ChainID = (*math.HexOrDecimal256)(s.ChainID)
|
||||||
enc.Address = s.Address
|
enc.Address = s.Address
|
||||||
enc.Nonce = math.HexOrDecimal64(s.Nonce)
|
enc.Nonce = math.HexOrDecimal64(s.Nonce)
|
||||||
enc.V = math.HexOrDecimal64(s.V)
|
enc.V = math.HexOrDecimal64(s.V)
|
||||||
|
|
@ -36,7 +36,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) {
|
||||||
// UnmarshalJSON unmarshals from JSON.
|
// UnmarshalJSON unmarshals from JSON.
|
||||||
func (s *stAuthorization) UnmarshalJSON(input []byte) error {
|
func (s *stAuthorization) UnmarshalJSON(input []byte) error {
|
||||||
type stAuthorization struct {
|
type stAuthorization struct {
|
||||||
ChainID *math.HexOrDecimal64
|
ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"`
|
||||||
Address *common.Address `json:"address" gencodec:"required"`
|
Address *common.Address `json:"address" gencodec:"required"`
|
||||||
Nonce *math.HexOrDecimal64 `json:"nonce" gencodec:"required"`
|
Nonce *math.HexOrDecimal64 `json:"nonce" gencodec:"required"`
|
||||||
V *math.HexOrDecimal64 `json:"v" gencodec:"required"`
|
V *math.HexOrDecimal64 `json:"v" gencodec:"required"`
|
||||||
|
|
@ -47,9 +47,10 @@ func (s *stAuthorization) UnmarshalJSON(input []byte) error {
|
||||||
if err := json.Unmarshal(input, &dec); err != nil {
|
if err := json.Unmarshal(input, &dec); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dec.ChainID != nil {
|
if dec.ChainID == nil {
|
||||||
s.ChainID = uint64(*dec.ChainID)
|
return errors.New("missing required field 'chainId' for stAuthorization")
|
||||||
}
|
}
|
||||||
|
s.ChainID = (*big.Int)(dec.ChainID)
|
||||||
if dec.Address == nil {
|
if dec.Address == nil {
|
||||||
return errors.New("missing required field 'address' for stAuthorization")
|
return errors.New("missing required field 'address' for stAuthorization")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ type stTransactionMarshaling struct {
|
||||||
|
|
||||||
// Authorization is an authorization from an account to deploy code at it's address.
|
// Authorization is an authorization from an account to deploy code at it's address.
|
||||||
type stAuthorization struct {
|
type stAuthorization struct {
|
||||||
ChainID uint64
|
ChainID *big.Int `json:"chainId" gencodec:"required"`
|
||||||
Address common.Address `json:"address" gencodec:"required"`
|
Address common.Address `json:"address" gencodec:"required"`
|
||||||
Nonce uint64 `json:"nonce" gencodec:"required"`
|
Nonce uint64 `json:"nonce" gencodec:"required"`
|
||||||
V uint8 `json:"v" gencodec:"required"`
|
V uint8 `json:"v" gencodec:"required"`
|
||||||
|
|
@ -150,7 +150,7 @@ type stAuthorization struct {
|
||||||
|
|
||||||
// field type overrides for gencodec
|
// field type overrides for gencodec
|
||||||
type stAuthorizationMarshaling struct {
|
type stAuthorizationMarshaling struct {
|
||||||
ChainID math.HexOrDecimal64
|
ChainID *math.HexOrDecimal256
|
||||||
Nonce math.HexOrDecimal64
|
Nonce math.HexOrDecimal64
|
||||||
V math.HexOrDecimal64
|
V math.HexOrDecimal64
|
||||||
R *math.HexOrDecimal256
|
R *math.HexOrDecimal256
|
||||||
|
|
@ -446,7 +446,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess
|
||||||
authList = make([]types.SetCodeAuthorization, len(tx.AuthorizationList))
|
authList = make([]types.SetCodeAuthorization, len(tx.AuthorizationList))
|
||||||
for i, auth := range tx.AuthorizationList {
|
for i, auth := range tx.AuthorizationList {
|
||||||
authList[i] = types.SetCodeAuthorization{
|
authList[i] = types.SetCodeAuthorization{
|
||||||
ChainID: auth.ChainID,
|
ChainID: *uint256.MustFromBig(auth.ChainID),
|
||||||
Address: auth.Address,
|
Address: auth.Address,
|
||||||
Nonce: auth.Nonce,
|
Nonce: auth.Nonce,
|
||||||
V: auth.V,
|
V: auth.V,
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,6 @@ type backend interface {
|
||||||
// state. An error will be returned if the specified state is not available.
|
// state. An error will be returned if the specified state is not available.
|
||||||
StateReader(root common.Hash) (database.StateReader, error)
|
StateReader(root common.Hash) (database.StateReader, error)
|
||||||
|
|
||||||
// Initialized returns an indicator if the state data is already initialized
|
|
||||||
// according to the state scheme.
|
|
||||||
Initialized(genesisRoot common.Hash) bool
|
|
||||||
|
|
||||||
// Size returns the current storage size of the diff layers on top of the
|
// Size returns the current storage size of the diff layers on top of the
|
||||||
// disk layer and the storage size of the nodes cached in the disk layer.
|
// disk layer and the storage size of the nodes cached in the disk layer.
|
||||||
//
|
//
|
||||||
|
|
@ -178,12 +174,6 @@ func (db *Database) Size() (common.StorageSize, common.StorageSize, common.Stora
|
||||||
return diffs, nodes, preimages
|
return diffs, nodes, preimages
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialized returns an indicator if the state data is already initialized
|
|
||||||
// according to the state scheme.
|
|
||||||
func (db *Database) Initialized(genesisRoot common.Hash) bool {
|
|
||||||
return db.backend.Initialized(genesisRoot)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scheme returns the node scheme used in the database.
|
// Scheme returns the node scheme used in the database.
|
||||||
func (db *Database) Scheme() string {
|
func (db *Database) Scheme() string {
|
||||||
if db.config.PathDB != nil {
|
if db.config.PathDB != nil {
|
||||||
|
|
|
||||||
|
|
@ -532,12 +532,6 @@ func (c *cleaner) Delete(key []byte) error {
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialized returns an indicator if state data is already initialized
|
|
||||||
// in hash-based scheme by checking the presence of genesis state.
|
|
||||||
func (db *Database) Initialized(genesisRoot common.Hash) bool {
|
|
||||||
return rawdb.HasLegacyTrieNode(db.diskdb, genesisRoot)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update inserts the dirty nodes in provided nodeset into database and link the
|
// Update inserts the dirty nodes in provided nodeset into database and link the
|
||||||
// account trie with multiple storage tries if necessary.
|
// account trie with multiple storage tries if necessary.
|
||||||
func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet) error {
|
func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet) error {
|
||||||
|
|
|
||||||
|
|
@ -529,21 +529,6 @@ func (db *Database) Size() (diffs common.StorageSize, nodes common.StorageSize)
|
||||||
return diffs, nodes
|
return diffs, nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialized returns an indicator if the state data is already
|
|
||||||
// initialized in path-based scheme.
|
|
||||||
func (db *Database) Initialized(genesisRoot common.Hash) bool {
|
|
||||||
var inited bool
|
|
||||||
db.tree.forEach(func(layer layer) {
|
|
||||||
if layer.rootHash() != types.EmptyRootHash {
|
|
||||||
inited = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if !inited {
|
|
||||||
inited = rawdb.ReadSnapSyncStatusFlag(db.diskdb) != rawdb.StateSyncUnknown
|
|
||||||
}
|
|
||||||
return inited
|
|
||||||
}
|
|
||||||
|
|
||||||
// modifyAllowed returns the indicator if mutation is allowed. This function
|
// modifyAllowed returns the indicator if mutation is allowed. This function
|
||||||
// assumes the db.lock is already held.
|
// assumes the db.lock is already held.
|
||||||
func (db *Database) modifyAllowed() error {
|
func (db *Database) modifyAllowed() error {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue