Merge branch 'ethereum:master' into portal

This commit is contained in:
Chen Kai 2023-11-14 13:40:27 +08:00 committed by GitHub
commit 915ab84d3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 116 additions and 42 deletions

View file

@ -5,22 +5,22 @@
# https://github.com/ethereum/execution-spec-tests/releases/download/v1.0.6/
485af7b66cf41eb3a8c1bd46632913b8eb95995df867cf665617bbc9b4beedd1 fixtures_develop.tar.gz
# version:golang 1.21.3
# version:golang 1.21.4
# https://go.dev/dl/
186f2b6f8c8b704e696821b09ab2041a5c1ee13dcbc3156a13adcf75931ee488 go1.21.3.src.tar.gz
27014fc69e301d7588a169ca239b3cc609f0aa1abf38528bf0d20d3b259211eb go1.21.3.darwin-amd64.tar.gz
65302a7a9f7a4834932b3a7a14cb8be51beddda757b567a2f9e0cbd0d7b5a6ab go1.21.3.darwin-arm64.tar.gz
8e0cd2f66cf1bde9d07b4aee01e3d7c3cfdd14e20650488e1683da4b8492594a go1.21.3.freebsd-386.tar.gz
6e74f65f586e93d1f3947894766f69e9b2ebda488592a09df61f36f06bfe58a8 go1.21.3.freebsd-amd64.tar.gz
fb209fd070db500a84291c5a95251cceeb1723e8f6142de9baca5af70a927c0e go1.21.3.linux-386.tar.gz
1241381b2843fae5a9707eec1f8fb2ef94d827990582c7c7c32f5bdfbfd420c8 go1.21.3.linux-amd64.tar.gz
fc90fa48ae97ba6368eecb914343590bbb61b388089510d0c56c2dde52987ef3 go1.21.3.linux-arm64.tar.gz
a1ddcaaf0821a12a800884c14cb4268ce1c1f5a0301e9060646f1e15e611c6c7 go1.21.3.linux-armv6l.tar.gz
3b0e10a3704f164a6e85e0377728ec5fd21524fabe4c925610e34076586d5826 go1.21.3.linux-ppc64le.tar.gz
4c78e2e6f4c684a3d5a9bdc97202729053f44eb7be188206f0627ef3e18716b6 go1.21.3.linux-s390x.tar.gz
e36737f4f2fadb4d2f919ec4ce517133a56e06064cca6e82fc883bb000c4d56c go1.21.3.windows-386.zip
27c8daf157493f288d42a6f38debc6a2cb391f6543139eba9152fceca0be2a10 go1.21.3.windows-amd64.zip
bfb7a5c56f9ded07d8ae0e0b3702ac07b65e68fa8f33da24ed6df4ce01fe2c5c go1.21.3.windows-arm64.zip
47b26a83d2b65a3c1c1bcace273b69bee49a7a7b5168a7604ded3d26a37bd787 go1.21.4.src.tar.gz
cd3bdcc802b759b70e8418bc7afbc4a65ca73a3fe576060af9fc8a2a5e71c3b8 go1.21.4.darwin-amd64.tar.gz
8b7caf2ac60bdff457dba7d4ff2a01def889592b834453431ae3caecf884f6a5 go1.21.4.darwin-arm64.tar.gz
f1e685d086eb36f4be5b8b953b52baf7752bc6235400d84bb7d87e500b65f03e go1.21.4.freebsd-386.tar.gz
59f9b32187efb98d344a3818a631d3815ebb5c7bbefc367bab6515caaca544e9 go1.21.4.freebsd-amd64.tar.gz
64d3e5d295806e137c9e39d1e1f10b00a30fcd5c2f230d72b3298f579bb3c89a go1.21.4.linux-386.tar.gz
73cac0215254d0c7d1241fa40837851f3b9a8a742d0b54714cbdfb3feaf8f0af go1.21.4.linux-amd64.tar.gz
ce1983a7289856c3a918e1fd26d41e072cc39f928adfb11ba1896440849b95da go1.21.4.linux-arm64.tar.gz
6c62e89113750cc77c498194d13a03fadfda22bd2c7d44e8a826fd354db60252 go1.21.4.linux-armv6l.tar.gz
2c63b36d2adcfb22013102a2ee730f058ec2f93b9f27479793c80b2e3641783f go1.21.4.linux-ppc64le.tar.gz
7a75ba4afc7a96058ca65903d994cd862381825d7dca12b2183f087c757c26c0 go1.21.4.linux-s390x.tar.gz
870a0e462b94671dc2d6cac707e9e19f7524fdc3c90711e6cd4450c3713a8ce0 go1.21.4.windows-386.zip
79e5428e068c912d9cfa6cd115c13549856ec689c1332eac17f5d6122e19d595 go1.21.4.windows-amd64.zip
58bc7c6f4d4c72da2df4d2650c8222fe03c9978070eb3c66be8bbaa2a4757ac1 go1.21.4.windows-arm64.zip
# version:golangci 1.51.1
# https://github.com/golangci/golangci-lint/releases/

View file

@ -108,13 +108,14 @@ func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error {
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
}
}
// Dump any state to aid debugging
if dump {
dump := state.RawDump(nil)
result.State = &dump
}
if err != nil {
// Test failed, mark as so and dump any state to aid debugging
// Test failed, mark as so
result.Pass, result.Error = false, err.Error()
if dump {
dump := state.RawDump(nil)
result.State = &dump
}
}
})
results = append(results, *result)

View file

@ -108,7 +108,7 @@ a data corruption.`,
utils.CacheFlag,
utils.CacheDatabaseFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: `This command performs a database compaction.
Description: `This command performs a database compaction.
WARNING: This operation may take a very long time to finish, and may cause database
corruption if it is aborted during execution'!`,
}
@ -130,7 +130,7 @@ corruption if it is aborted during execution'!`,
Flags: flags.Merge([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: `This command deletes the specified database key from the database.
Description: `This command deletes the specified database key from the database.
WARNING: This is a low-level operation which may cause database corruption!`,
}
dbPutCmd = &cli.Command{
@ -141,7 +141,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Flags: flags.Merge([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: `This command sets a given database key to the given value.
Description: `This command sets a given database key to the given value.
WARNING: This is a low-level operation which may cause database corruption!`,
}
dbGetSlotsCmd = &cli.Command{

View file

@ -84,8 +84,8 @@ In other words, this command does the snapshot to trie conversion.
Action: checkDanglingStorage,
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth snapshot check-dangling-storage <state-root> traverses the snap storage
data, and verifies that all snapshot storage data has a corresponding account.
geth snapshot check-dangling-storage <state-root> traverses the snap storage
data, and verifies that all snapshot storage data has a corresponding account.
`,
},
{
@ -96,7 +96,7 @@ data, and verifies that all snapshot storage data has a corresponding account.
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
Description: `
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
information about the specified address.
information about the specified address.
`,
},
{
@ -125,7 +125,7 @@ geth snapshot traverse-rawstate <state-root>
will traverse the whole state from the given root and will abort if any referenced
trie node or contract code is missing. This command can be used for state integrity
verification. The default checking target is the HEAD state. It's basically identical
to traverse-state, but the check granularity is smaller.
to traverse-state, but the check granularity is smaller.
It's also usable without snapshot enabled.
`,
@ -143,7 +143,7 @@ It's also usable without snapshot enabled.
}, utils.NetworkFlags, utils.DatabaseFlags),
Description: `
This command is semantically equivalent to 'geth dump', but uses the snapshots
as the backend data source, making this command a lot faster.
as the backend data source, making this command a lot faster.
The argument is interpreted as block number or hash. If none is provided, the latest
block is used.

View file

@ -2045,12 +2045,11 @@ func SplitTagsFlag(tagsFlag string) map[string]string {
return tagsMap
}
// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
// MakeChainDatabase opens a database using the flags passed to the client and will hard crash if it fails.
func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database {
var (
cache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100
handles = MakeDatabaseHandles(ctx.Int(FDLimitFlag.Name))
err error
chainDb ethdb.Database
)

View file

@ -18,6 +18,7 @@ package rawdb
import (
"fmt"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
@ -126,6 +127,8 @@ func InspectFreezerTable(ancient string, freezerName string, tableName string, s
switch freezerName {
case chainFreezerName:
path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy
case stateFreezerName:
path, tables = filepath.Join(ancient, freezerName), stateFreezerNoSnappy
default:
return fmt.Errorf("unknown freezer, supported ones: %v", freezers)
}

View file

@ -182,19 +182,27 @@ func (batch *freezerTableBatch) maybeCommit() error {
// commit writes the batched items to the backing freezerTable.
func (batch *freezerTableBatch) commit() error {
// Write data.
// Write data. The head file is fsync'd after write to ensure the
// data is truly transferred to disk.
_, err := batch.t.head.Write(batch.dataBuffer)
if err != nil {
return err
}
if err := batch.t.head.Sync(); err != nil {
return err
}
dataSize := int64(len(batch.dataBuffer))
batch.dataBuffer = batch.dataBuffer[:0]
// Write indices.
// Write indices. The index file is fsync'd after write to ensure the
// data indexes are truly transferred to disk.
_, err = batch.t.index.Write(batch.indexBuffer)
if err != nil {
return err
}
if err := batch.t.index.Sync(); err != nil {
return err
}
indexSize := int64(len(batch.indexBuffer))
batch.indexBuffer = batch.indexBuffer[:0]

View file

@ -215,7 +215,9 @@ func (t *freezerTable) repair() error {
if t.readonly {
return fmt.Errorf("index file(path: %s, name: %s) size is not a multiple of %d", t.path, t.name, indexEntrySize)
}
truncateFreezerFile(t.index, stat.Size()-overflow) // New file can't trigger this path
if err := truncateFreezerFile(t.index, stat.Size()-overflow); err != nil {
return err
} // New file can't trigger this path
}
// Retrieve the file sizes and prepare for truncation
if stat, err = t.index.Stat(); err != nil {
@ -260,8 +262,8 @@ func (t *freezerTable) repair() error {
// Print an error log if the index is corrupted due to an incorrect
// last index item. While it is theoretically possible to have a zero offset
// by storing all zero-size items, it is highly unlikely to occur in practice.
if lastIndex.offset == 0 && offsetsSize%indexEntrySize > 1 {
log.Error("Corrupted index file detected", "lastOffset", lastIndex.offset, "items", offsetsSize%indexEntrySize-1)
if lastIndex.offset == 0 && offsetsSize/indexEntrySize > 1 {
log.Error("Corrupted index file detected", "lastOffset", lastIndex.offset, "indexes", offsetsSize/indexEntrySize)
}
if t.readonly {
t.head, err = t.openFile(lastIndex.filenum, openFreezerFileForReadOnly)
@ -416,6 +418,9 @@ func (t *freezerTable) truncateHead(items uint64) error {
if err := truncateFreezerFile(t.index, int64(length+1)*indexEntrySize); err != nil {
return err
}
if err := t.index.Sync(); err != nil {
return err
}
// Calculate the new expected size of the data file and truncate it
var expected indexEntry
if length == 0 {
@ -438,6 +443,7 @@ func (t *freezerTable) truncateHead(items uint64) error {
// Release any files _after the current head -- both the previous head
// and any files which may have been opened for reading
t.releaseFilesAfter(expected.filenum, true)
// Set back the historic head
t.head = newHead
t.headId = expected.filenum
@ -445,6 +451,9 @@ func (t *freezerTable) truncateHead(items uint64) error {
if err := truncateFreezerFile(t.head, int64(expected.offset)); err != nil {
return err
}
if err := t.head.Sync(); err != nil {
return err
}
// All data files truncated, set internal counters and return
t.headBytes = int64(expected.offset)
t.items.Store(items)
@ -589,10 +598,12 @@ func (t *freezerTable) Close() error {
// error on Windows.
doClose(t.index, true, true)
doClose(t.meta, true, true)
// The preopened non-head data-files are all opened in readonly.
// The head is opened in rw-mode, so we sync it here - but since it's also
// part of t.files, it will be closed in the loop below.
doClose(t.head, true, false) // sync but do not close
for _, f := range t.files {
doClose(f, false, true) // close but do not sync
}

View file

@ -73,11 +73,7 @@ func copyFrom(srcPath, destPath string, offset uint64, before func(f *os.File) e
return err
}
f = nil
if err := os.Rename(fname, destPath); err != nil {
return err
}
return nil
return os.Rename(fname, destPath)
}
// openFreezerFileForAppend opens a freezer table file and seeks to the end

View file

@ -37,8 +37,12 @@ var (
errInvalidTopic = errors.New("invalid topic(s)")
errFilterNotFound = errors.New("filter not found")
errInvalidBlockRange = errors.New("invalid block range params")
errExceedMaxTopics = errors.New("exceed max topics")
)
// The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0
const maxTopics = 4
// filter is a helper struct that holds meta information over the filter type
// and associated subscription in the event system.
type filter struct {
@ -334,6 +338,9 @@ func (api *FilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) {
// GetLogs returns logs matching the given argument that are stored within the state.
func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) {
if len(crit.Topics) > maxTopics {
return nil, errExceedMaxTopics
}
var filter *Filter
if crit.BlockHash != nil {
// Block filter requested, construct a single-shot filter

View file

@ -299,6 +299,9 @@ func (es *EventSystem) subscribe(sub *subscription) *Subscription {
// given criteria to the given logs channel. Default value for the from and to
// block is "latest". If the fromBlock > toBlock an error is returned.
func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) (*Subscription, error) {
if len(crit.Topics) > maxTopics {
return nil, errExceedMaxTopics
}
var from, to rpc.BlockNumber
if crit.FromBlock == nil {
from = rpc.LatestBlockNumber

View file

@ -386,6 +386,8 @@ func TestLogFilterCreation(t *testing.T) {
{FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false},
// from block "higher" than to block
{FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, false},
// topics more then 4
{FilterCriteria{Topics: [][]common.Hash{{}, {}, {}, {}, {}}}, false},
}
)
@ -420,6 +422,7 @@ func TestInvalidLogFilterCreation(t *testing.T) {
0: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
1: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)},
2: {FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)},
3: {Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
}
for i, test := range testCases {
@ -445,6 +448,7 @@ func TestInvalidGetLogsRequest(t *testing.T) {
0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)},
1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)},
2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
3: {BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
}
for i, test := range testCases {

View file

@ -42,6 +42,7 @@ var (
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
testContract = common.HexToAddress("0xbeef")
testEmpty = common.HexToAddress("0xeeee")
testSlot = common.HexToHash("0xdeadbeef")
testValue = crypto.Keccak256Hash(testSlot[:])
testBalance = big.NewInt(2e15)
@ -80,8 +81,11 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
func generateTestChain() (*core.Genesis, []*types.Block) {
genesis := &core.Genesis{
Config: params.AllEthashProtocolChanges,
Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}},
testContract: {Nonce: 1, Code: []byte{0x13, 0x37}}},
Alloc: core.GenesisAlloc{
testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}},
testContract: {Nonce: 1, Code: []byte{0x13, 0x37}},
testEmpty: {Balance: big.NewInt(1)},
},
ExtraData: []byte("test genesis"),
Timestamp: 9000,
}
@ -110,6 +114,12 @@ func TestGethClient(t *testing.T) {
}, {
"TestGetProof2",
func(t *testing.T) { testGetProof(t, client, testContract) },
}, {
"TestGetProofEmpty",
func(t *testing.T) { testGetProof(t, client, testEmpty) },
}, {
"TestGetProofNonExistent",
func(t *testing.T) { testGetProofNonExistent(t, client) },
}, {
"TestGetProofCanonicalizeKeys",
func(t *testing.T) { testGetProofCanonicalizeKeys(t, client) },
@ -274,6 +284,38 @@ func testGetProofCanonicalizeKeys(t *testing.T, client *rpc.Client) {
}
}
func testGetProofNonExistent(t *testing.T, client *rpc.Client) {
addr := common.HexToAddress("0x0001")
ec := New(client)
result, err := ec.GetProof(context.Background(), addr, nil, nil)
if err != nil {
t.Fatal(err)
}
if result.Address != addr {
t.Fatalf("unexpected address, have: %v want: %v", result.Address, addr)
}
// test nonce
if result.Nonce != 0 {
t.Fatalf("invalid nonce, want: %v got: %v", 0, result.Nonce)
}
// test balance
if result.Balance.Cmp(big.NewInt(0)) != 0 {
t.Fatalf("invalid balance, want: %v got: %v", 0, result.Balance)
}
// test storage
if have := len(result.StorageProof); have != 0 {
t.Fatalf("invalid storage proof, want 0 proof, got %v proof(s)", have)
}
// test codeHash
if have, want := result.CodeHash, (common.Hash{}); have != want {
t.Fatalf("codehash wrong, have %v want %v ", have, want)
}
// test codeHash
if have, want := result.StorageHash, (common.Hash{}); have != want {
t.Fatalf("storagehash wrong, have %v want %v ", have, want)
}
}
func testGCStats(t *testing.T, client *rpc.Client) {
ec := New(client)
_, err := ec.GCStats(context.Background())