From 09c69b60766595d13ebdca8c4918f3bdbaf90449 Mon Sep 17 00:00:00 2001 From: Nazarii Denha Date: Thu, 20 Apr 2023 11:39:19 +0200 Subject: [PATCH 01/12] implement PUSH0 (#273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Péter Garamvölgyi --- core/vm/eips.go | 18 ++++++++++++++++++ core/vm/opcodes.go | 3 +++ 2 files changed, 21 insertions(+) diff --git a/core/vm/eips.go b/core/vm/eips.go index a3acfbe99..c40ae1af3 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -26,6 +26,7 @@ import ( ) var activators = map[int]func(*JumpTable){ + 3855: enable3855, 3529: enable3529, 3198: enable3198, 2929: enable2929, @@ -176,3 +177,20 @@ func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] scope.Stack.push(baseFee) return nil, nil } + +// enable3855 applies EIP-3855 (PUSH0 opcode) +func enable3855(jt *JumpTable) { + // New opcode + jt[PUSH0] = &operation{ + execute: opPush0, + constantGas: GasQuickStep, + minStack: minStack(0, 1), + maxStack: maxStack(0, 1), + } +} + +// opPush0 implements the PUSH0 opcode +func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + scope.Stack.push(new(uint256.Int)) + return nil, nil +} diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 9c207636b..cf9a26231 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -120,6 +120,7 @@ const ( MSIZE OpCode = 0x59 GAS OpCode = 0x5a JUMPDEST OpCode = 0x5b + PUSH0 OpCode = 0x5f ) // 0x60 range - pushes. @@ -308,6 +309,7 @@ var opCodeToString = map[OpCode]string{ MSIZE: "MSIZE", GAS: "GAS", JUMPDEST: "JUMPDEST", + PUSH0: "PUSH0", // 0x60 range - push. PUSH1: "PUSH1", @@ -475,6 +477,7 @@ var stringToOp = map[string]OpCode{ "MSIZE": MSIZE, "GAS": GAS, "JUMPDEST": JUMPDEST, + "PUSH0": PUSH0, "PUSH1": PUSH1, "PUSH2": PUSH2, "PUSH3": PUSH3, From 32aacc3fd6aabc075bc8354c95ab8b63b965c252 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:49:35 +0800 Subject: [PATCH 02/12] style: revert some formatting (#294) Revert "style: remove blank line & white space formatting" This reverts commit 349def8d5d78f83c19e899d5d80b1d9f6a5d18c6. --- accounts/abi/abi_test.go | 34 ++- accounts/abi/bind/backends/simulated_test.go | 33 ++- accounts/abi/reflect.go | 22 +- accounts/accounts.go | 6 +- accounts/hd.go | 2 +- accounts/scwallet/wallet.go | 3 - accounts/url.go | 7 +- accounts/usbwallet/ledger.go | 162 ++++++------- accounts/usbwallet/trezor.go | 18 +- .../usbwallet/trezor/messages-common.pb.go | 26 +-- .../usbwallet/trezor/messages-ethereum.pb.go | 20 +- .../trezor/messages-management.pb.go | 48 ++-- accounts/usbwallet/trezor/messages.pb.go | 2 +- build/ci.go | 21 +- cmd/devp2p/internal/ethtest/transaction.go | 2 +- cmd/ethkey/utils.go | 3 +- cmd/evm/internal/t8ntool/transition.go | 5 +- cmd/faucet/website.go | 12 +- cmd/p2psim/main.go | 21 +- common/hexutil/hexutil.go | 2 +- common/math/big.go | 8 +- common/prque/lazyqueue.go | 7 +- consensus/ethash/api.go | 9 +- consensus/ethash/sealer.go | 9 +- consensus/misc/dao.go | 9 +- core/blockchain_test.go | 44 ++-- core/genesis.go | 8 +- core/mkalloc.go | 8 +- core/rawdb/freezer.go | 14 +- core/state/pruner/pruner.go | 6 +- core/state/snapshot/generate_test.go | 2 - core/state/snapshot/snapshot.go | 8 +- core/state/statedb.go | 4 +- core/state_transition.go | 20 +- core/vm/contracts.go | 7 +- core/vm/gas_table.go | 18 +- core/vm/instructions.go | 19 +- crypto/crypto.go | 2 +- eth/downloader/downloader.go | 40 ++-- eth/downloader/queue.go | 7 +- eth/downloader/resultstore.go | 9 +- eth/gasprice/feehistory.go | 9 +- eth/protocols/snap/sync_test.go | 3 +- eth/state_accessor.go | 18 +- eth/tracers/js/internal/tracers/assets.go | 12 +- eth/tracers/native/4byte.go | 17 +- eth/tracers/native/tracer.go | 8 +- ethdb/leveldb/leveldb.go | 15 +- ethstats/ethstats.go | 15 +- internal/cmdtest/test_cmd.go | 2 +- internal/ethapi/api.go | 8 +- internal/jsre/deps/bindata.go | 12 +- les/api.go | 16 +- les/downloader/downloader.go | 40 ++-- les/downloader/queue.go | 7 +- les/downloader/resultstore.go | 9 +- les/fetcher.go | 21 +- light/txpool.go | 9 +- log/doc.go | 218 +++++++++--------- log/format.go | 6 +- log/handler.go | 38 +-- log/handler_glog.go | 12 +- metrics/influxdb/influxdbv2.go | 1 + mobile/big.go | 1 + mobile/discover.go | 6 +- mobile/doc.go | 2 +- node/doc.go | 64 ++--- node/node_example_test.go | 4 +- p2p/dial.go | 11 +- p2p/discover/v5wire/encoding_test.go | 3 +- p2p/dnsdisc/tree.go | 30 +-- p2p/enode/urlv4.go | 6 +- p2p/enr/enr.go | 2 +- p2p/message.go | 5 +- p2p/nat/nat.go | 12 +- p2p/simulations/adapters/types.go | 1 + p2p/simulations/mocker.go | 22 +- params/denomination.go | 3 +- params/version.go | 3 +- rlp/decode.go | 2 +- rlp/doc.go | 45 ++-- rpc/doc.go | 57 ++--- rpc/handler.go | 15 +- signer/core/api_test.go | 2 +- signer/core/apitypes/types.go | 2 +- signer/fourbyte/4byte.go | 12 +- signer/rules/rules_test.go | 4 +- tests/block_test_util.go | 17 +- tests/fuzzers/bls12381/precompile_fuzzer.go | 6 +- tests/fuzzers/difficulty/difficulty-fuzz.go | 6 +- tests/fuzzers/rangeproof/rangeproof-fuzzer.go | 6 +- tests/fuzzers/stacktrie/trie_fuzzer.go | 6 +- tests/fuzzers/trie/trie-fuzzer.go | 6 +- trie/proof.go | 20 +- trie/stacktrie.go | 9 +- 95 files changed, 775 insertions(+), 818 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 94d992882..34e1b068d 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -165,9 +165,8 @@ func TestInvalidABI(t *testing.T) { // TestConstructor tests a constructor function. // The test is based on the following contract: -// -// contract TestConstructor { -// constructor(uint256 a, uint256 b) public{} +// contract TestConstructor { +// constructor(uint256 a, uint256 b) public{} // } func TestConstructor(t *testing.T) { json := `[{ "inputs": [{"internalType": "uint256","name": "a","type": "uint256" },{ "internalType": "uint256","name": "b","type": "uint256"}],"stateMutability": "nonpayable","type": "constructor"}]` @@ -725,19 +724,16 @@ func TestBareEvents(t *testing.T) { } // TestUnpackEvent is based on this contract: -// -// contract T { -// event received(address sender, uint amount, bytes memo); -// event receivedAddr(address sender); -// function receive(bytes memo) external payable { -// received(msg.sender, msg.value, memo); -// receivedAddr(msg.sender); -// } -// } -// +// contract T { +// event received(address sender, uint amount, bytes memo); +// event receivedAddr(address sender); +// function receive(bytes memo) external payable { +// received(msg.sender, msg.value, memo); +// receivedAddr(msg.sender); +// } +// } // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: -// -// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} +// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} func TestUnpackEvent(t *testing.T) { const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` abi, err := JSON(strings.NewReader(abiJSON)) @@ -1084,9 +1080,8 @@ func TestDoubleDuplicateMethodNames(t *testing.T) { // TestDoubleDuplicateEventNames checks that if send0 already exists, there won't be a name // conflict and that the second send event will be renamed send1. // The test runs the abi of the following contract. -// -// contract DuplicateEvent { -// event send(uint256 a); +// contract DuplicateEvent { +// event send(uint256 a); // event send0(); // event send(); // } @@ -1113,8 +1108,7 @@ func TestDoubleDuplicateEventNames(t *testing.T) { // TestUnnamedEventParam checks that an event with unnamed parameters is // correctly handled. // The test runs the abi of the following contract. -// -// contract TestEvent { +// contract TestEvent { // event send(uint256, uint256); // } func TestUnnamedEventParam(t *testing.T) { diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 57eda514c..182e67855 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -93,17 +93,17 @@ func TestSimulatedBackend(t *testing.T) { var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") -// the following is based on this contract: -// contract T { -// event received(address sender, uint amount, bytes memo); -// event receivedAddr(address sender); +// the following is based on this contract: +// contract T { +// event received(address sender, uint amount, bytes memo); +// event receivedAddr(address sender); // -// function receive(bytes calldata memo) external payable returns (string memory res) { -// emit received(msg.sender, msg.value, memo); -// emit receivedAddr(msg.sender); -// return "hello world"; -// } -// } +// function receive(bytes calldata memo) external payable returns (string memory res) { +// emit received(msg.sender, msg.value, memo); +// emit receivedAddr(msg.sender); +// return "hello world"; +// } +// } const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]` const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` const deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` @@ -1015,8 +1015,7 @@ func TestCodeAt(t *testing.T) { } // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: -// -// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} +// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} func TestPendingAndCallContract(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -1227,11 +1226,10 @@ func TestFork(t *testing.T) { Example contract to test event emission: pragma solidity >=0.7.0 <0.9.0; - - contract Callable { - event Called(); - function Call() public { emit Called(); } - } +contract Callable { + event Called(); + function Call() public { emit Called(); } +} */ const callableAbi = "[{\"anonymous\":false,\"inputs\":[],\"name\":\"Called\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" @@ -1249,7 +1247,6 @@ const callableBin = "6080604052348015600f57600080fd5b5060998061001e6000396000f3f // 7. Mine two blocks to trigger a reorg. // 8. Check that the event was removed. // 9. Re-send the transaction and mine a block. -// // 10. Check that the event was reborn. func TestForkLogsReborn(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 285d34944..35e5556d2 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -28,13 +28,11 @@ import ( // given type // e.g. turn // var fields []reflect.StructField -// -// fields = append(fields, reflect.StructField{ -// Name: "X", -// Type: reflect.TypeOf(new(big.Int)), -// Tag: reflect.StructTag("json:\"" + "x" + "\""), -// } -// +// fields = append(fields, reflect.StructField{ +// Name: "X", +// Type: reflect.TypeOf(new(big.Int)), +// Tag: reflect.StructTag("json:\"" + "x" + "\""), +// } // into // type TupleT struct { X *big.Int } func ConvertType(in interface{}, proto interface{}) interface{} { @@ -173,14 +171,10 @@ func setStruct(dst, src reflect.Value) error { // mapArgNamesToStructFields maps a slice of argument names to struct fields. // first round: for each Exportable field that contains a `abi:""` tag -// -// and this field name exists in the given argument name list, pair them together. -// +// and this field name exists in the given argument name list, pair them together. // second round: for each argument name that has not been already linked, -// -// find what variable is expected to be mapped into, if it exists and has not been -// used, pair them. -// +// find what variable is expected to be mapped into, if it exists and has not been +// used, pair them. // Note this function assumes the given value is a struct value. func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[string]string, error) { typ := value.Type() diff --git a/accounts/accounts.go b/accounts/accounts.go index 87d37da47..bfc9f9d2d 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -178,8 +178,7 @@ type Backend interface { // safely used to calculate a signature from. // // The hash is calulcated as -// -// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). +// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). // // This gives context to the signed message and prevents signing of transactions. func TextHash(data []byte) []byte { @@ -191,8 +190,7 @@ func TextHash(data []byte) []byte { // safely used to calculate a signature from. // // The hash is calulcated as -// -// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). +// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). // // This gives context to the signed message and prevents signing of transactions. func TextAndHash(data []byte) ([]byte, string) { diff --git a/accounts/hd.go b/accounts/hd.go index e4fb0543d..54acea3b2 100644 --- a/accounts/hd.go +++ b/accounts/hd.go @@ -46,7 +46,7 @@ var LegacyLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 // The BIP-32 spec https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki // defines derivation paths to be of the form: // -// m / purpose' / coin_type' / account' / change / address_index +// m / purpose' / coin_type' / account' / change / address_index // // The BIP-44 spec https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki // defines that the `purpose` be 44' (or 0x8000002C) for crypto currencies, and diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index c70b331d8..01b8bb019 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -880,7 +880,6 @@ func (s *Session) walletStatus() (*walletStatus, error) { } // derivationPath fetches the wallet's current derivation path from the card. -// //lint:ignore U1000 needs to be added to the console interface func (s *Session) derivationPath() (accounts.DerivationPath, error) { response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1Path, 0, nil) @@ -996,7 +995,6 @@ func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error) } // keyExport contains information on an exported keypair. -// //lint:ignore U1000 needs to be added to the console interface type keyExport struct { PublicKey []byte `asn1:"tag:0"` @@ -1004,7 +1002,6 @@ type keyExport struct { } // publicKey returns the public key for the current derivation path. -// //lint:ignore U1000 needs to be added to the console interface func (s *Session) publicKey() ([]byte, error) { response, err := s.Channel.transmitEncrypted(claSCWallet, insExportKey, exportP1Any, exportP2Pubkey, nil) diff --git a/accounts/url.go b/accounts/url.go index 39b00e5b4..12a84414a 100644 --- a/accounts/url.go +++ b/accounts/url.go @@ -92,9 +92,10 @@ func (u *URL) UnmarshalJSON(input []byte) error { // Cmp compares x and y and returns: // -// -1 if x < y -// 0 if x == y -// +1 if x > y +// -1 if x < y +// 0 if x == y +// +1 if x > y +// func (u URL) Cmp(url URL) int { if u.Scheme == url.Scheme { return strings.Compare(u.Path, url.Path) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index ebaaf2800..175c76ad3 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -195,18 +195,18 @@ func (w *ledgerDriver) SignTypedMessage(path accounts.DerivationPath, domainHash // // The version retrieval protocol is defined as follows: // -// CLA | INS | P1 | P2 | Lc | Le -// ----+-----+----+----+----+--- -// E0 | 06 | 00 | 00 | 00 | 04 +// CLA | INS | P1 | P2 | Lc | Le +// ----+-----+----+----+----+--- +// E0 | 06 | 00 | 00 | 00 | 04 // // With no input data, and the output data being: // -// Description | Length -// ---------------------------------------------------+-------- -// Flags 01: arbitrary data signature enabled by user | 1 byte -// Application major version | 1 byte -// Application minor version | 1 byte -// Application patch version | 1 byte +// Description | Length +// ---------------------------------------------------+-------- +// Flags 01: arbitrary data signature enabled by user | 1 byte +// Application major version | 1 byte +// Application minor version | 1 byte +// Application patch version | 1 byte func (w *ledgerDriver) ledgerVersion() ([3]byte, error) { // Send the request and wait for the response reply, err := w.ledgerExchange(ledgerOpGetConfiguration, 0, 0, nil) @@ -227,32 +227,32 @@ func (w *ledgerDriver) ledgerVersion() ([3]byte, error) { // // The address derivation protocol is defined as follows: // -// CLA | INS | P1 | P2 | Lc | Le -// ----+-----+----+----+-----+--- -// E0 | 02 | 00 return address -// 01 display address and confirm before returning -// | 00: do not return the chain code -// | 01: return the chain code -// | var | 00 +// CLA | INS | P1 | P2 | Lc | Le +// ----+-----+----+----+-----+--- +// E0 | 02 | 00 return address +// 01 display address and confirm before returning +// | 00: do not return the chain code +// | 01: return the chain code +// | var | 00 // // Where the input data is: // -// Description | Length -// -------------------------------------------------+-------- -// Number of BIP 32 derivations to perform (max 10) | 1 byte -// First derivation index (big endian) | 4 bytes -// ... | 4 bytes -// Last derivation index (big endian) | 4 bytes +// Description | Length +// -------------------------------------------------+-------- +// Number of BIP 32 derivations to perform (max 10) | 1 byte +// First derivation index (big endian) | 4 bytes +// ... | 4 bytes +// Last derivation index (big endian) | 4 bytes // // And the output data is: // -// Description | Length -// ------------------------+------------------- -// Public Key length | 1 byte -// Uncompressed Public Key | arbitrary -// Ethereum address length | 1 byte -// Ethereum address | 40 bytes hex ascii -// Chain code if requested | 32 bytes +// Description | Length +// ------------------------+------------------- +// Public Key length | 1 byte +// Uncompressed Public Key | arbitrary +// Ethereum address length | 1 byte +// Ethereum address | 40 bytes hex ascii +// Chain code if requested | 32 bytes func (w *ledgerDriver) ledgerDerive(derivationPath []uint32) (common.Address, error) { // Flatten the derivation path into the Ledger request path := make([]byte, 1+4*len(derivationPath)) @@ -290,35 +290,35 @@ func (w *ledgerDriver) ledgerDerive(derivationPath []uint32) (common.Address, er // // The transaction signing protocol is defined as follows: // -// CLA | INS | P1 | P2 | Lc | Le -// ----+-----+----+----+-----+--- -// E0 | 04 | 00: first transaction data block -// 80: subsequent transaction data block -// | 00 | variable | variable +// CLA | INS | P1 | P2 | Lc | Le +// ----+-----+----+----+-----+--- +// E0 | 04 | 00: first transaction data block +// 80: subsequent transaction data block +// | 00 | variable | variable // // Where the input for the first transaction block (first 255 bytes) is: // -// Description | Length -// -------------------------------------------------+---------- -// Number of BIP 32 derivations to perform (max 10) | 1 byte -// First derivation index (big endian) | 4 bytes -// ... | 4 bytes -// Last derivation index (big endian) | 4 bytes -// RLP transaction chunk | arbitrary +// Description | Length +// -------------------------------------------------+---------- +// Number of BIP 32 derivations to perform (max 10) | 1 byte +// First derivation index (big endian) | 4 bytes +// ... | 4 bytes +// Last derivation index (big endian) | 4 bytes +// RLP transaction chunk | arbitrary // // And the input for subsequent transaction blocks (first 255 bytes) are: // -// Description | Length -// ----------------------+---------- -// RLP transaction chunk | arbitrary +// Description | Length +// ----------------------+---------- +// RLP transaction chunk | arbitrary // // And the output data is: // -// Description | Length -// ------------+--------- -// signature V | 1 byte -// signature R | 32 bytes -// signature S | 32 bytes +// Description | Length +// ------------+--------- +// signature V | 1 byte +// signature R | 32 bytes +// signature S | 32 bytes func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) { // Flatten the derivation path into the Ledger request path := make([]byte, 1+4*len(derivationPath)) @@ -392,28 +392,30 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction // // The signing protocol is defined as follows: // -// CLA | INS | P1 | P2 | Lc | Le -// ----+-----+----+-----------------------------+-----+--- -// E0 | 0C | 00 | implementation version : 00 | variable | variable +// CLA | INS | P1 | P2 | Lc | Le +// ----+-----+----+-----------------------------+-----+--- +// E0 | 0C | 00 | implementation version : 00 | variable | variable // // Where the input is: // -// Description | Length -// -------------------------------------------------+---------- -// Number of BIP 32 derivations to perform (max 10) | 1 byte -// First derivation index (big endian) | 4 bytes -// ... | 4 bytes -// Last derivation index (big endian) | 4 bytes -// domain hash | 32 bytes -// message hash | 32 bytes +// Description | Length +// -------------------------------------------------+---------- +// Number of BIP 32 derivations to perform (max 10) | 1 byte +// First derivation index (big endian) | 4 bytes +// ... | 4 bytes +// Last derivation index (big endian) | 4 bytes +// domain hash | 32 bytes +// message hash | 32 bytes +// +// // // And the output data is: // -// Description | Length -// ------------+--------- -// signature V | 1 byte -// signature R | 32 bytes -// signature S | 32 bytes +// Description | Length +// ------------+--------- +// signature V | 1 byte +// signature R | 32 bytes +// signature S | 32 bytes func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHash []byte, messageHash []byte) ([]byte, error) { // Flatten the derivation path into the Ledger request path := make([]byte, 1+4*len(derivationPath)) @@ -452,12 +454,12 @@ func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHas // // The common transport header is defined as follows: // -// Description | Length -// --------------------------------------+---------- -// Communication channel ID (big endian) | 2 bytes -// Command tag | 1 byte -// Packet sequence index (big endian) | 2 bytes -// Payload | arbitrary +// Description | Length +// --------------------------------------+---------- +// Communication channel ID (big endian) | 2 bytes +// Command tag | 1 byte +// Packet sequence index (big endian) | 2 bytes +// Payload | arbitrary // // The Communication channel ID allows commands multiplexing over the same // physical link. It is not used for the time being, and should be set to 0101 @@ -471,15 +473,15 @@ func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHas // // APDU Command payloads are encoded as follows: // -// Description | Length -// ----------------------------------- -// APDU length (big endian) | 2 bytes -// APDU CLA | 1 byte -// APDU INS | 1 byte -// APDU P1 | 1 byte -// APDU P2 | 1 byte -// APDU length | 1 byte -// Optional APDU data | arbitrary +// Description | Length +// ----------------------------------- +// APDU length (big endian) | 2 bytes +// APDU CLA | 1 byte +// APDU INS | 1 byte +// APDU P1 | 1 byte +// APDU P2 | 1 byte +// APDU length | 1 byte +// Optional APDU data | arbitrary func (w *ledgerDriver) ledgerExchange(opcode ledgerOpcode, p1 ledgerParam1, p2 ledgerParam2, data []byte) ([]byte, error) { // Construct the message payload, possibly split into multiple chunks apdu := make([]byte, 2, 7+len(data)) diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 579307eff..28fc9f352 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -85,15 +85,15 @@ func (w *trezorDriver) Status() (string, error) { // Open implements usbwallet.driver, attempting to initialize the connection to // the Trezor hardware wallet. Initializing the Trezor is a two or three phase operation: -// - The first phase is to initialize the connection and read the wallet's -// features. This phase is invoked if the provided passphrase is empty. The -// device will display the pinpad as a result and will return an appropriate -// error to notify the user that a second open phase is needed. -// - The second phase is to unlock access to the Trezor, which is done by the -// user actually providing a passphrase mapping a keyboard keypad to the pin -// number of the user (shuffled according to the pinpad displayed). -// - If needed the device will ask for passphrase which will require calling -// open again with the actual passphrase (3rd phase) +// * The first phase is to initialize the connection and read the wallet's +// features. This phase is invoked if the provided passphrase is empty. The +// device will display the pinpad as a result and will return an appropriate +// error to notify the user that a second open phase is needed. +// * The second phase is to unlock access to the Trezor, which is done by the +// user actually providing a passphrase mapping a keyboard keypad to the pin +// number of the user (shuffled according to the pinpad displayed). +// * If needed the device will ask for passphrase which will require calling +// open again with the actual passphrase (3rd phase) func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error { w.device, w.failure = device, nil diff --git a/accounts/usbwallet/trezor/messages-common.pb.go b/accounts/usbwallet/trezor/messages-common.pb.go index b396c6d8b..304bec0e3 100644 --- a/accounts/usbwallet/trezor/messages-common.pb.go +++ b/accounts/usbwallet/trezor/messages-common.pb.go @@ -94,7 +94,7 @@ func (Failure_FailureType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_aaf30d059fdbc38d, []int{1, 0} } -// * +//* // Type of button request type ButtonRequest_ButtonRequestType int32 @@ -175,7 +175,7 @@ func (ButtonRequest_ButtonRequestType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_aaf30d059fdbc38d, []int{2, 0} } -// * +//* // Type of PIN request type PinMatrixRequest_PinMatrixRequestType int32 @@ -220,7 +220,7 @@ func (PinMatrixRequest_PinMatrixRequestType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_aaf30d059fdbc38d, []int{4, 0} } -// * +//* // Response: Success of the previous request // @end type Success struct { @@ -262,7 +262,7 @@ func (m *Success) GetMessage() string { return "" } -// * +//* // Response: Failure of the previous request // @end type Failure struct { @@ -312,7 +312,7 @@ func (m *Failure) GetMessage() string { return "" } -// * +//* // Response: Device is waiting for HW button press. // @auxstart // @next ButtonAck @@ -363,7 +363,7 @@ func (m *ButtonRequest) GetData() string { return "" } -// * +//* // Request: Computer agrees to wait for HW button press // @auxend type ButtonAck struct { @@ -397,7 +397,7 @@ func (m *ButtonAck) XXX_DiscardUnknown() { var xxx_messageInfo_ButtonAck proto.InternalMessageInfo -// * +//* // Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme // @auxstart // @next PinMatrixAck @@ -440,7 +440,7 @@ func (m *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { return PinMatrixRequest_PinMatrixRequestType_Current } -// * +//* // Request: Computer responds with encoded PIN // @auxend type PinMatrixAck struct { @@ -482,7 +482,7 @@ func (m *PinMatrixAck) GetPin() string { return "" } -// * +//* // Response: Device awaits encryption passphrase // @auxstart // @next PassphraseAck @@ -525,7 +525,7 @@ func (m *PassphraseRequest) GetOnDevice() bool { return false } -// * +//* // Request: Send passphrase back // @next PassphraseStateRequest type PassphraseAck struct { @@ -575,7 +575,7 @@ func (m *PassphraseAck) GetState() []byte { return nil } -// * +//* // Response: Device awaits passphrase state // @next PassphraseStateAck type PassphraseStateRequest struct { @@ -617,7 +617,7 @@ func (m *PassphraseStateRequest) GetState() []byte { return nil } -// * +//* // Request: Send passphrase state back // @auxend type PassphraseStateAck struct { @@ -651,7 +651,7 @@ func (m *PassphraseStateAck) XXX_DiscardUnknown() { var xxx_messageInfo_PassphraseStateAck proto.InternalMessageInfo -// * +//* // Structure representing BIP32 (hierarchical deterministic) node // Used for imports of private key into the device and exporting public key out of device // @embed diff --git a/accounts/usbwallet/trezor/messages-ethereum.pb.go b/accounts/usbwallet/trezor/messages-ethereum.pb.go index 230a48279..5d664f5ba 100644 --- a/accounts/usbwallet/trezor/messages-ethereum.pb.go +++ b/accounts/usbwallet/trezor/messages-ethereum.pb.go @@ -21,7 +21,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package -// * +//* // Request: Ask device for public key corresponding to address_n path // @start // @next EthereumPublicKey @@ -73,7 +73,7 @@ func (m *EthereumGetPublicKey) GetShowDisplay() bool { return false } -// * +//* // Response: Contains public key derived from device private seed // @end type EthereumPublicKey struct { @@ -123,7 +123,7 @@ func (m *EthereumPublicKey) GetXpub() string { return "" } -// * +//* // Request: Ask device for Ethereum address corresponding to address_n path // @start // @next EthereumAddress @@ -175,7 +175,7 @@ func (m *EthereumGetAddress) GetShowDisplay() bool { return false } -// * +//* // Response: Contains an Ethereum address derived from device private seed // @end type EthereumAddress struct { @@ -225,7 +225,7 @@ func (m *EthereumAddress) GetAddressHex() string { return "" } -// * +//* // Request: Ask device to sign transaction // All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. // Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. @@ -351,7 +351,7 @@ func (m *EthereumSignTx) GetTxType() uint32 { return 0 } -// * +//* // Response: Device asks for more data from transaction payload, or returns the signature. // If data_length is set, device awaits that many more bytes of payload. // Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. @@ -420,7 +420,7 @@ func (m *EthereumTxRequest) GetSignatureS() []byte { return nil } -// * +//* // Request: Transaction payload data. // @next EthereumTxRequest type EthereumTxAck struct { @@ -462,7 +462,7 @@ func (m *EthereumTxAck) GetDataChunk() []byte { return nil } -// * +//* // Request: Ask device to sign message // @start // @next EthereumMessageSignature @@ -514,7 +514,7 @@ func (m *EthereumSignMessage) GetMessage() []byte { return nil } -// * +//* // Response: Signed message // @end type EthereumMessageSignature struct { @@ -572,7 +572,7 @@ func (m *EthereumMessageSignature) GetAddressHex() string { return "" } -// * +//* // Request: Ask device to verify message // @start // @next Success diff --git a/accounts/usbwallet/trezor/messages-management.pb.go b/accounts/usbwallet/trezor/messages-management.pb.go index 91bfca1e3..f5c872f1f 100644 --- a/accounts/usbwallet/trezor/messages-management.pb.go +++ b/accounts/usbwallet/trezor/messages-management.pb.go @@ -21,7 +21,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package -// * +//* // Structure representing passphrase source type ApplySettings_PassphraseSourceType int32 @@ -66,7 +66,7 @@ func (ApplySettings_PassphraseSourceType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_0c720c20d27aa029, []int{4, 0} } -// * +//* // Type of recovery procedure. These should be used as bitmask, e.g., // `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` // listing every method supported by the host computer. @@ -114,7 +114,7 @@ func (RecoveryDevice_RecoveryDeviceType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_0c720c20d27aa029, []int{17, 0} } -// * +//* // Type of Recovery Word request type WordRequest_WordRequestType int32 @@ -159,7 +159,7 @@ func (WordRequest_WordRequestType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_0c720c20d27aa029, []int{18, 0} } -// * +//* // Request: Reset device to default state and ask for device details // @start // @next Features @@ -210,7 +210,7 @@ func (m *Initialize) GetSkipPassphrase() bool { return false } -// * +//* // Request: Ask for device details (no device reset) // @start // @next Features @@ -245,7 +245,7 @@ func (m *GetFeatures) XXX_DiscardUnknown() { var xxx_messageInfo_GetFeatures proto.InternalMessageInfo -// * +//* // Response: Reports various information about the device // @end type Features struct { @@ -495,7 +495,7 @@ func (m *Features) GetNoBackup() bool { return false } -// * +//* // Request: clear session (removes cached PIN, passphrase, etc). // @start // @next Success @@ -530,7 +530,7 @@ func (m *ClearSession) XXX_DiscardUnknown() { var xxx_messageInfo_ClearSession proto.InternalMessageInfo -// * +//* // Request: change language and/or label of the device // @start // @next Success @@ -622,7 +622,7 @@ func (m *ApplySettings) GetDisplayRotation() uint32 { return 0 } -// * +//* // Request: set flags of the device // @start // @next Success @@ -666,7 +666,7 @@ func (m *ApplyFlags) GetFlags() uint32 { return 0 } -// * +//* // Request: Starts workflow for setting/changing/removing the PIN // @start // @next Success @@ -710,7 +710,7 @@ func (m *ChangePin) GetRemove() bool { return false } -// * +//* // Request: Test if the device is alive, device sends back the message in Success response // @start // @next Success @@ -777,7 +777,7 @@ func (m *Ping) GetPassphraseProtection() bool { return false } -// * +//* // Request: Abort last operation that required user interaction // @start // @next Failure @@ -812,7 +812,7 @@ func (m *Cancel) XXX_DiscardUnknown() { var xxx_messageInfo_Cancel proto.InternalMessageInfo -// * +//* // Request: Request a sample of random data generated by hardware RNG. May be used for testing. // @start // @next Entropy @@ -856,7 +856,7 @@ func (m *GetEntropy) GetSize() uint32 { return 0 } -// * +//* // Response: Reply with random data generated by internal RNG // @end type Entropy struct { @@ -898,7 +898,7 @@ func (m *Entropy) GetEntropy() []byte { return nil } -// * +//* // Request: Request device to wipe all sensitive data and settings // @start // @next Success @@ -934,7 +934,7 @@ func (m *WipeDevice) XXX_DiscardUnknown() { var xxx_messageInfo_WipeDevice proto.InternalMessageInfo -// * +//* // Request: Load seed and related internal settings from the computer // @start // @next Success @@ -1036,7 +1036,7 @@ func (m *LoadDevice) GetU2FCounter() uint32 { return 0 } -// * +//* // Request: Ask device to do initialization involving user interaction // @start // @next EntropyRequest @@ -1147,7 +1147,7 @@ func (m *ResetDevice) GetNoBackup() bool { return false } -// * +//* // Request: Perform backup of the device seed if not backed up using ResetDevice // @start // @next Success @@ -1182,7 +1182,7 @@ func (m *BackupDevice) XXX_DiscardUnknown() { var xxx_messageInfo_BackupDevice proto.InternalMessageInfo -// * +//* // Response: Ask for additional entropy from host computer // @next EntropyAck type EntropyRequest struct { @@ -1216,7 +1216,7 @@ func (m *EntropyRequest) XXX_DiscardUnknown() { var xxx_messageInfo_EntropyRequest proto.InternalMessageInfo -// * +//* // Request: Provide additional entropy for seed generation function // @next Success type EntropyAck struct { @@ -1258,7 +1258,7 @@ func (m *EntropyAck) GetEntropy() []byte { return nil } -// * +//* // Request: Start recovery workflow asking user for specific words of mnemonic // Used to recovery device safely even on untrusted computer. // @start @@ -1369,7 +1369,7 @@ func (m *RecoveryDevice) GetDryRun() bool { return false } -// * +//* // Response: Device is waiting for user to enter word of the mnemonic // Its position is shown only on device's internal display. // @next WordAck @@ -1412,7 +1412,7 @@ func (m *WordRequest) GetType() WordRequest_WordRequestType { return WordRequest_WordRequestType_Plain } -// * +//* // Request: Computer replies with word from the mnemonic // @next WordRequest // @next Success @@ -1456,7 +1456,7 @@ func (m *WordAck) GetWord() string { return "" } -// * +//* // Request: Set U2F counter // @start // @next Success diff --git a/accounts/usbwallet/trezor/messages.pb.go b/accounts/usbwallet/trezor/messages.pb.go index af0c95714..6278bd8ee 100644 --- a/accounts/usbwallet/trezor/messages.pb.go +++ b/accounts/usbwallet/trezor/messages.pb.go @@ -22,7 +22,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package -// * +//* // Mapping between TREZOR wire identifier (uint) and a protobuf message type MessageType int32 diff --git a/build/ci.go b/build/ci.go index 7ffa19e77..a7a15ac0a 100644 --- a/build/ci.go +++ b/build/ci.go @@ -24,18 +24,19 @@ Usage: go run build/ci.go Available commands are: - install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables - test [ -coverage ] [ packages... ] -- runs the tests - lint -- runs certain pre-selected linters - archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts - importkeys -- imports signing keys from env - debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package - nsis -- creates a Windows NSIS installer - aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive - xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework - purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore + install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables + test [ -coverage ] [ packages... ] -- runs the tests + lint -- runs certain pre-selected linters + archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts + importkeys -- imports signing keys from env + debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package + nsis -- creates a Windows NSIS installer + aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive + xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework + purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore For all commands, -n prevents execution of external programs (dry run mode). + */ package main diff --git a/cmd/devp2p/internal/ethtest/transaction.go b/cmd/devp2p/internal/ethtest/transaction.go index 0628fe4ca..128b272f0 100644 --- a/cmd/devp2p/internal/ethtest/transaction.go +++ b/cmd/devp2p/internal/ethtest/transaction.go @@ -29,7 +29,7 @@ import ( "github.com/scroll-tech/go-ethereum/params" ) -// var faucetAddr = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") +//var faucetAddr = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") var faucetKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") func (s *Suite) sendSuccessfulTxs(t *utesting.T, isEth66 bool) error { diff --git a/cmd/ethkey/utils.go b/cmd/ethkey/utils.go index d121ce056..689877f12 100644 --- a/cmd/ethkey/utils.go +++ b/cmd/ethkey/utils.go @@ -51,8 +51,7 @@ func getPassphrase(ctx *cli.Context, confirmation bool) string { // that can be safely used to calculate a signature from. // // The hash is calulcated as -// -// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). +// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). // // This gives context to the signed message and prevents signing of transactions. func signHash(data []byte) []byte { diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index ef020a85e..8520dfb7f 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -321,9 +321,8 @@ func (t *txWithKey) UnmarshalJSON(input []byte) error { // signUnsignedTransactions converts the input txs to canonical transactions. // // The transactions can have two forms, either -// 1. unsigned or -// 2. signed -// +// 1. unsigned or +// 2. signed // For (1), r, s, v, need so be zero, and the `secretKey` needs to be set. // If so, we sign it here and now, with the given `secretKey` // If the condition above is not met, then it's considered a signed transaction. diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go index 16e430233..aed067893 100644 --- a/cmd/faucet/website.go +++ b/cmd/faucet/website.go @@ -187,13 +187,11 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// +// data/ +// foo.txt +// img/ +// a.png +// b.png // then AssetDir("data") would return []string{"foo.txt", "img"}, // AssetDir("data/img") would return []string{"a.png", "b.png"}, // AssetDir("foo.txt") and AssetDir("notexist") would return an error, and diff --git a/cmd/p2psim/main.go b/cmd/p2psim/main.go index dcfdea21b..2119d3d43 100644 --- a/cmd/p2psim/main.go +++ b/cmd/p2psim/main.go @@ -19,20 +19,21 @@ // Here is an example of creating a 2 node network with the first node // connected to the second: // -// $ p2psim node create -// Created node01 +// $ p2psim node create +// Created node01 // -// $ p2psim node start node01 -// Started node01 +// $ p2psim node start node01 +// Started node01 // -// $ p2psim node create -// Created node02 +// $ p2psim node create +// Created node02 // -// $ p2psim node start node02 -// Started node02 +// $ p2psim node start node02 +// Started node02 +// +// $ p2psim node connect node01 node02 +// Connected node01 to node02 // -// $ p2psim node connect node01 node02 -// Connected node01 to node02 package main import ( diff --git a/common/hexutil/hexutil.go b/common/hexutil/hexutil.go index 71d9206a0..8d15ab48d 100644 --- a/common/hexutil/hexutil.go +++ b/common/hexutil/hexutil.go @@ -18,7 +18,7 @@ Package hexutil implements hex encoding with 0x prefix. This encoding is used by the Ethereum RPC API to transport binary data in JSON payloads. -# Encoding Rules +Encoding Rules All hex data must have prefix "0x". diff --git a/common/math/big.go b/common/math/big.go index 48427810e..1af5b4d87 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -227,10 +227,10 @@ func U256Bytes(n *big.Int) []byte { // S256 interprets x as a two's complement number. // x must not exceed 256 bits (the result is undefined if it does) and is not modified. // -// S256(0) = 0 -// S256(1) = 1 -// S256(2**255) = -2**255 -// S256(2**256-1) = -1 +// S256(0) = 0 +// S256(1) = 1 +// S256(2**255) = -2**255 +// S256(2**256-1) = -1 func S256(x *big.Int) *big.Int { if x.Cmp(tt255) < 0 { return x diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index 976ecff61..90dabe532 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -26,10 +26,9 @@ import ( // LazyQueue is a priority queue data structure where priorities can change over // time and are only evaluated on demand. // Two callbacks are required: -// - priority evaluates the actual priority of an item -// - maxPriority gives an upper estimate for the priority in any moment between -// now and the given absolute time -// +// - priority evaluates the actual priority of an item +// - maxPriority gives an upper estimate for the priority in any moment between +// now and the given absolute time // If the upper estimate is exceeded then Update should be called for that item. // A global Refresh function should also be called periodically. type LazyQueue struct { diff --git a/consensus/ethash/api.go b/consensus/ethash/api.go index 18b2548c6..240b077f6 100644 --- a/consensus/ethash/api.go +++ b/consensus/ethash/api.go @@ -34,11 +34,10 @@ type API struct { // GetWork returns a work package for external miner. // // The work package consists of 3 strings: -// -// result[0] - 32 bytes hex encoded current block header pow-hash -// result[1] - 32 bytes hex encoded seed hash used for DAG -// result[2] - 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty -// result[3] - hex encoded block number +// result[0] - 32 bytes hex encoded current block header pow-hash +// result[1] - 32 bytes hex encoded seed hash used for DAG +// result[2] - 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty +// result[3] - hex encoded block number func (api *API) GetWork() ([4]string, error) { if api.ethash.remote == nil { return [4]string{}, errors.New("not supported") diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go index 84b5b1a20..a65888031 100644 --- a/consensus/ethash/sealer.go +++ b/consensus/ethash/sealer.go @@ -339,11 +339,10 @@ func (s *remoteSealer) loop() { // makeWork creates a work package for external miner. // // The work package consists of 3 strings: -// -// result[0], 32 bytes hex encoded current block header pow-hash -// result[1], 32 bytes hex encoded seed hash used for DAG -// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty -// result[3], hex encoded block number +// result[0], 32 bytes hex encoded current block header pow-hash +// result[1], 32 bytes hex encoded seed hash used for DAG +// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty +// result[3], hex encoded block number func (s *remoteSealer) makeWork(block *types.Block) { hash := s.ethash.SealHash(block.Header()) s.currentWork[0] = hash.Hex() diff --git a/consensus/misc/dao.go b/consensus/misc/dao.go index 0a72863d0..3824b3bad 100644 --- a/consensus/misc/dao.go +++ b/consensus/misc/dao.go @@ -40,11 +40,10 @@ var ( // ensure it conforms to DAO hard-fork rules. // // DAO hard-fork extension to the header validity: -// -// a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range -// with the fork specific extra-data set -// b) if the node is pro-fork, require blocks in the specific range to have the -// unique extra-data set. +// a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range +// with the fork specific extra-data set +// b) if the node is pro-fork, require blocks in the specific range to have the +// unique extra-data set. func VerifyDAOHeaderExtraData(config *params.ChainConfig, header *types.Header) error { // Short circuit validation if the node doesn't care about the DAO fork if config.DAOForkBlock == nil { diff --git a/core/blockchain_test.go b/core/blockchain_test.go index aece102ef..9c7e7ec77 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -1747,8 +1747,8 @@ func TestInsertReceiptChainRollback(t *testing.T) { // overtake the 'canon' chain until after it's passed canon by about 200 blocks. // // Details at: -// - https://github.com/scroll-tech/go-ethereum/issues/18977 -// - https://github.com/scroll-tech/go-ethereum/pull/18988 +// - https://github.com/scroll-tech/go-ethereum/issues/18977 +// - https://github.com/scroll-tech/go-ethereum/pull/18988 func TestLowDiffLongChain(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() @@ -1867,8 +1867,7 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon // That is: the sidechain for import contains some blocks already present in canon chain. // So the blocks are // [ Cn, Cn+1, Cc, Sn+3 ... Sm] -// -// ^ ^ ^ pruned +// ^ ^ ^ pruned func TestPrunedImportSide(t *testing.T) { //glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) //glogger.Verbosity(3) @@ -2473,9 +2472,9 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) { // This internally leads to a sidechain import, since the blocks trigger an // ErrPrunedAncestor error. // This may e.g. happen if -// 1. Downloader rollbacks a batch of inserted blocks and exits -// 2. Downloader starts to sync again -// 3. The blocks fetched are all known and canonical blocks +// 1. Downloader rollbacks a batch of inserted blocks and exits +// 2. Downloader starts to sync again +// 3. The blocks fetched are all known and canonical blocks func TestSideImportPrunedBlocks(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() @@ -2637,19 +2636,20 @@ func TestDeleteCreateRevert(t *testing.T) { // TestInitThenFailCreateContract tests a pretty notorious case that happened // on mainnet over blocks 7338108, 7338110 and 7338115. -// - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated -// with 0.001 ether (thus created but no code) -// - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on -// the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the -// deployment fails due to OOG during initcode execution -// - Block 7338115: another tx checks the balance of -// e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as -// zero. +// - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated +// with 0.001 ether (thus created but no code) +// - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on +// the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the +// deployment fails due to OOG during initcode execution +// - Block 7338115: another tx checks the balance of +// e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as +// zero. // // The problem being that the snapshotter maintains a destructset, and adds items // to the destructset in case something is created "onto" an existing item. // We need to either roll back the snapDestructs, or not place it into snapDestructs // in the first place. +// func TestInitThenFailCreateContract(t *testing.T) { var ( // Generate a canonical chain to act as the main dataset @@ -2838,13 +2838,13 @@ func TestEIP2718Transition(t *testing.T) { // TestEIP1559Transition tests the following: // -// 1. A transaction whose gasFeeCap is greater than the baseFee is valid. -// 2. Gas accounting for access lists on EIP-1559 transactions is correct. -// 3. Only the transaction's tip will be received by the coinbase. -// 4. The transaction sender pays for both the tip and baseFee. -// 5. The coinbase receives only the partially realized tip when -// gasFeeCap - gasTipCap < baseFee. -// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap). +// 1. A transaction whose gasFeeCap is greater than the baseFee is valid. +// 2. Gas accounting for access lists on EIP-1559 transactions is correct. +// 3. Only the transaction's tip will be received by the coinbase. +// 4. The transaction sender pays for both the tip and baseFee. +// 5. The coinbase receives only the partially realized tip when +// gasFeeCap - gasTipCap < baseFee. +// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap). func TestEIP1559Transition(t *testing.T) { var ( aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") diff --git a/core/genesis.go b/core/genesis.go index 07c8a9ea0..bcdb84654 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -144,10 +144,10 @@ func (e *GenesisMismatchError) Error() string { // SetupGenesisBlock writes or updates the genesis block in db. // The block that will be used is: // -// genesis == nil genesis != nil -// +------------------------------------------ -// db has no genesis | main-net default | genesis -// db has genesis | from DB | genesis (if compatible) +// genesis == nil genesis != nil +// +------------------------------------------ +// db has no genesis | main-net default | genesis +// db has genesis | from DB | genesis (if compatible) // // 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 diff --git a/core/mkalloc.go b/core/mkalloc.go index 8e928565e..32149d118 100644 --- a/core/mkalloc.go +++ b/core/mkalloc.go @@ -18,10 +18,12 @@ // +build none /* -The mkalloc tool creates the genesis allocation constants in genesis_alloc.go -It outputs a const declaration that contains an RLP-encoded list of (address, balance) tuples. - go run mkalloc.go genesis.json + The mkalloc tool creates the genesis allocation constants in genesis_alloc.go + It outputs a const declaration that contains an RLP-encoded list of (address, balance) tuples. + + go run mkalloc.go genesis.json + */ package main diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index bdb6b22b8..ab0510a78 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -70,10 +70,10 @@ const ( // freezer is an memory mapped append-only database to store immutable chain data // into flat files: // -// - The append only nature ensures that disk writes are minimized. -// - The memory mapping ensures we can max out system memory for caching without -// reserving it for go-ethereum. This would also reduce the memory requirements -// of Geth, and thus also GC overhead. +// - The append only nature ensures that disk writes are minimized. +// - The memory mapping ensures we can max out system memory for caching without +// reserving it for go-ethereum. This would also reduce the memory requirements +// of Geth, and thus also GC overhead. type freezer struct { // WARNING: The `frozen` field is accessed atomically. On 32 bit platforms, only // 64-bit aligned fields can be atomic. The struct is guaranteed to be so aligned, @@ -205,9 +205,9 @@ func (f *freezer) Ancient(kind string, number uint64) ([]byte, error) { // AncientRange retrieves multiple items in sequence, starting from the index 'start'. // It will return -// - at most 'max' items, -// - at least 1 item (even if exceeding the maxByteSize), but will otherwise -// return as many items as fit into maxByteSize. +// - at most 'max' items, +// - at least 1 item (even if exceeding the maxByteSize), but will otherwise +// return as many items as fit into maxByteSize. func (f *freezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { if table := f.tables[kind]; table != nil { return table.RetrieveItems(start, count, maxBytes) diff --git a/core/state/pruner/pruner.go b/core/state/pruner/pruner.go index 726d38a5f..4d3845ca0 100644 --- a/core/state/pruner/pruner.go +++ b/core/state/pruner/pruner.go @@ -66,9 +66,9 @@ var ( // Pruner is an offline tool to prune the stale state with the // help of the snapshot. The workflow of pruner is very simple: // -// - iterate the snapshot, reconstruct the relevant state -// - iterate the database, delete all other state entries which -// don't belong to the target state and the genesis state +// - iterate the snapshot, reconstruct the relevant state +// - iterate the database, delete all other state entries which +// don't belong to the target state and the genesis state // // It can take several hours(around 2 hours for mainnet) to finish // the whole pruning work. It's recommended to run this offline tool diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go index fa9ad6522..43a6946fc 100644 --- a/core/state/snapshot/generate_test.go +++ b/core/state/snapshot/generate_test.go @@ -235,12 +235,10 @@ func (t *testHelper) Generate() (common.Hash, *diskLayer) { // - miss in the beginning // - miss in the middle // - miss in the end -// // - the contract(non-empty storage) has wrong storage slots // - wrong slots in the beginning // - wrong slots in the middle // - wrong slots in the end -// // - the contract(non-empty storage) has extra storage slots // - extra slots in the beginning // - extra slots in the middle diff --git a/core/state/snapshot/snapshot.go b/core/state/snapshot/snapshot.go index 89d8df035..417e742d9 100644 --- a/core/state/snapshot/snapshot.go +++ b/core/state/snapshot/snapshot.go @@ -179,10 +179,10 @@ type Tree struct { // If the memory layers in the journal do not match the disk layer (e.g. there is // a gap) or the journal is missing, there are two repair cases: // -// - if the 'recovery' parameter is true, all memory diff-layers will be discarded. -// This case happens when the snapshot is 'ahead' of the state trie. -// - otherwise, the entire snapshot is considered invalid and will be recreated on -// a background thread. +// - if the 'recovery' parameter is true, all memory diff-layers will be discarded. +// This case happens when the snapshot is 'ahead' of the state trie. +// - otherwise, the entire snapshot is considered invalid and will be recreated on +// a background thread. func New(diskdb ethdb.KeyValueStore, triedb *trie.Database, cache int, root common.Hash, async bool, rebuild bool, recovery bool) (*Tree, error) { // Create a new, empty snapshot tree if triedb.Zktrie { diff --git a/core/state/statedb.go b/core/state/statedb.go index 8dc4cc8ab..60189beb5 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -677,8 +677,8 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) // CreateAccount is called during the EVM CREATE operation. The situation might arise that // a contract does the following: // -// 1. sends funds to sha(account ++ (nonce + 1)) -// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) +// 1. sends funds to sha(account ++ (nonce + 1)) +// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) // // Carrying over the balance ensures that Ether doesn't disappear. func (s *StateDB) CreateAccount(addr common.Address) { diff --git a/core/state_transition.go b/core/state_transition.go index 8e5c4a8e0..2c3a2ad0b 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -44,10 +44,8 @@ The state transitioning model does all the necessary work to work out a valid ne 3) Create a new state object if the recipient is \0*32 4) Value transfer == If contract creation == - - 4a) Attempt to run transaction data - 4b) If valid, use result as code for the new state object - + 4a) Attempt to run transaction data + 4b) If valid, use result as code for the new state object == end == 5) Run Script section 6) Derive new state root @@ -291,13 +289,13 @@ func (st *StateTransition) preCheck() error { // TransitionDb will transition the state by applying the current message and // returning the evm execution result with following fields. // -// - used gas: -// total gas used (including gas being refunded) -// - returndata: -// the returned data from evm -// - concrete execution error: -// various **EVM** error which aborts the execution, -// e.g. ErrOutOfGas, ErrExecutionReverted +// - used gas: +// total gas used (including gas being refunded) +// - returndata: +// the returned data from evm +// - concrete execution error: +// various **EVM** error which aborts the execution, +// e.g. ErrOutOfGas, ErrExecutionReverted // // However if any consensus issue encountered, return the error directly with // nil evm execution result. diff --git a/core/vm/contracts.go b/core/vm/contracts.go index d33b19416..6fb771580 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -266,10 +266,9 @@ var ( // modexpMultComplexity implements bigModexp multComplexity formula, as defined in EIP-198 // // def mult_complexity(x): -// -// if x <= 64: return x ** 2 -// elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072 -// else: return x ** 2 // 16 + 480 * x - 199680 +// if x <= 64: return x ** 2 +// elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072 +// else: return x ** 2 // 16 + 480 * x - 199680 // // where is x is max(length_of_MODULUS, length_of_BASE) func modexpMultComplexity(x *big.Int) *big.Int { diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 355cf20c0..8d985e3ac 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -162,19 +162,19 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi return params.NetSstoreDirtyGas, nil } -// 0. If *gasleft* is less than or equal to 2300, fail the current call. -// 1. If current value equals new value (this is a no-op), SLOAD_GAS is deducted. -// 2. If current value does not equal new value: -// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context): +// 0. If *gasleft* is less than or equal to 2300, fail the current call. +// 1. If current value equals new value (this is a no-op), SLOAD_GAS is deducted. +// 2. If current value does not equal new value: +// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context): // 2.1.1. If original value is 0, SSTORE_SET_GAS (20K) gas is deducted. // 2.1.2. Otherwise, SSTORE_RESET_GAS gas is deducted. If new value is 0, add SSTORE_CLEARS_SCHEDULE to refund counter. -// 2.2. If original value does not equal current value (this storage slot is dirty), SLOAD_GAS gas is deducted. Apply both of the following clauses: +// 2.2. If original value does not equal current value (this storage slot is dirty), SLOAD_GAS gas is deducted. Apply both of the following clauses: // 2.2.1. If original value is not 0: -// 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEARS_SCHEDULE gas from refund counter. -// 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEARS_SCHEDULE gas to refund counter. +// 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEARS_SCHEDULE gas from refund counter. +// 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEARS_SCHEDULE gas to refund counter. // 2.2.2. If original value equals new value (this storage slot is reset): -// 2.2.2.1. If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter. -// 2.2.2.2. Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter. +// 2.2.2.1. If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter. +// 2.2.2.2. Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter. func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { // If we fail the minimum gas availability invariant, fail (0) if contract.Gas <= params.SstoreSentryGasEIP2200 { diff --git a/core/vm/instructions.go b/core/vm/instructions.go index b51df87f0..09097b79b 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -391,21 +391,16 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // opExtCodeHash returns the code hash of a specified account. // There are several cases when the function is called, while we can relay everything // to `state.GetCodeHash` function to ensure the correctness. -// -// (1) Caller tries to get the code hash of a normal contract account, state -// +// (1) Caller tries to get the code hash of a normal contract account, state // should return the relative code hash and set it as the result. // -// (2) Caller tries to get the code hash of a non-existent account, state should -// +// (2) Caller tries to get the code hash of a non-existent account, state should // return common.Hash{} and zero will be set as the result. // -// (3) Caller tries to get the code hash for an account without contract code, -// +// (3) Caller tries to get the code hash for an account without contract code, // state should return emptyCodeHash(0xc5d246...) as the result. // -// (4) Caller tries to get the code hash of a precompiled account, the result -// +// (4) Caller tries to get the code hash of a precompiled account, the result // should be zero or emptyCodeHash. // // It is worth noting that in order to avoid unnecessary create and clean, @@ -414,12 +409,10 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // If the precompile account is not transferred any amount on a private or // customized chain, the return value will be zero. // -// (5) Caller tries to get the code hash for an account which is marked as suicided -// +// (5) Caller tries to get the code hash for an account which is marked as suicided // in the current transaction, the code hash of this account should be returned. // -// (6) Caller tries to get the code hash for an account which is marked as deleted, -// +// (6) Caller tries to get the code hash for an account which is marked as deleted, // this account should be regarded as a non-existent account and zero should be returned. func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() diff --git a/crypto/crypto.go b/crypto/crypto.go index 7b1e2f5b4..f1ccf3754 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -37,7 +37,7 @@ import ( "github.com/scroll-tech/go-ethereum/rlp" ) -// SignatureLength indicates the byte length required to carry a signature with recovery id. +//SignatureLength indicates the byte length required to carry a signature with recovery id. const SignatureLength = 64 + 1 // 64 bytes ECDSA signature + 1 byte recovery id // RecoveryIDOffset points to the byte offset within the signature that contains the recovery id. diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 6afb3a852..839ebe733 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -702,11 +702,9 @@ func (d *Downloader) fetchHead(p *peerConnection) (head *types.Header, pivot *ty // calculateRequestSpan calculates what headers to request from a peer when trying to determine the // common ancestor. // It returns parameters to be used for peer.RequestHeadersByNumber: -// -// from - starting block number -// count - number of headers to request -// skip - number of headers to skip -// +// from - starting block number +// count - number of headers to request +// skip - number of headers to skip // and also returns 'max', the last block which is expected to be returned by the remote peers, // given the (from,count,skip) func calculateRequestSpan(remoteHeight, localHeight uint64) (int64, int, int, uint64) { @@ -1321,22 +1319,22 @@ func (d *Downloader) fetchReceipts(from uint64) error { // various callbacks to handle the slight differences between processing them. // // The instrumentation parameters: -// - errCancel: error type to return if the fetch operation is cancelled (mostly makes logging nicer) -// - deliveryCh: channel from which to retrieve downloaded data packets (merged from all concurrent peers) -// - deliver: processing callback to deliver data packets into type specific download queues (usually within `queue`) -// - wakeCh: notification channel for waking the fetcher when new tasks are available (or sync completed) -// - expire: task callback method to abort requests that took too long and return the faulty peers (traffic shaping) -// - pending: task callback for the number of requests still needing download (detect completion/non-completability) -// - inFlight: task callback for the number of in-progress requests (wait for all active downloads to finish) -// - throttle: task callback to check if the processing queue is full and activate throttling (bound memory use) -// - reserve: task callback to reserve new download tasks to a particular peer (also signals partial completions) -// - fetchHook: tester callback to notify of new tasks being initiated (allows testing the scheduling logic) -// - fetch: network callback to actually send a particular download request to a physical remote peer -// - cancel: task callback to abort an in-flight download request and allow rescheduling it (in case of lost peer) -// - capacity: network callback to retrieve the estimated type-specific bandwidth capacity of a peer (traffic shaping) -// - idle: network callback to retrieve the currently (type specific) idle peers that can be assigned tasks -// - setIdle: network callback to set a peer back to idle and update its estimated capacity (traffic shaping) -// - kind: textual label of the type being downloaded to display in log messages +// - errCancel: error type to return if the fetch operation is cancelled (mostly makes logging nicer) +// - deliveryCh: channel from which to retrieve downloaded data packets (merged from all concurrent peers) +// - deliver: processing callback to deliver data packets into type specific download queues (usually within `queue`) +// - wakeCh: notification channel for waking the fetcher when new tasks are available (or sync completed) +// - expire: task callback method to abort requests that took too long and return the faulty peers (traffic shaping) +// - pending: task callback for the number of requests still needing download (detect completion/non-completability) +// - inFlight: task callback for the number of in-progress requests (wait for all active downloads to finish) +// - throttle: task callback to check if the processing queue is full and activate throttling (bound memory use) +// - reserve: task callback to reserve new download tasks to a particular peer (also signals partial completions) +// - fetchHook: tester callback to notify of new tasks being initiated (allows testing the scheduling logic) +// - fetch: network callback to actually send a particular download request to a physical remote peer +// - cancel: task callback to abort an in-flight download request and allow rescheduling it (in case of lost peer) +// - capacity: network callback to retrieve the estimated type-specific bandwidth capacity of a peer (traffic shaping) +// - idle: network callback to retrieve the currently (type specific) idle peers that can be assigned tasks +// - setIdle: network callback to set a peer back to idle and update its estimated capacity (traffic shaping) +// - kind: textual label of the type being downloaded to display in log messages func (d *Downloader) fetchParts(deliveryCh chan dataPack, deliver func(dataPack) (int, error), wakeCh chan bool, expire func() map[string]int, pending func() int, inFlight func() bool, reserve func(*peerConnection, int) (*fetchRequest, bool, bool), fetchHook func([]*types.Header), fetch func(*peerConnection, *fetchRequest) error, cancel func(*fetchRequest), capacity func(*peerConnection) int, diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index c6fa78729..158608ccd 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -477,10 +477,9 @@ func (q *queue) ReserveReceipts(p *peerConnection, count int) (*fetchRequest, bo // to access the queue, so they already need a lock anyway. // // Returns: -// -// item - the fetchRequest -// progress - whether any progress was made -// throttle - if the caller should throttle for a while +// item - the fetchRequest +// progress - whether any progress was made +// throttle - if the caller should throttle for a while func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque, pendPool map[string]*fetchRequest, kind uint) (*fetchRequest, bool, bool) { // Short circuit if the pool has been depleted, or if the peer's already diff --git a/eth/downloader/resultstore.go b/eth/downloader/resultstore.go index 4a40e0ebd..8075f507d 100644 --- a/eth/downloader/resultstore.go +++ b/eth/downloader/resultstore.go @@ -71,11 +71,10 @@ func (r *resultStore) SetThrottleThreshold(threshold uint64) uint64 { // wants to reserve headers for fetching. // // It returns the following: -// -// stale - if true, this item is already passed, and should not be requested again -// throttled - if true, the store is at capacity, this particular header is not prio now -// item - the result to store data into -// err - any error that occurred +// stale - if true, this item is already passed, and should not be requested again +// throttled - if true, the store is at capacity, this particular header is not prio now +// item - the result to store data into +// err - any error that occurred func (r *resultStore) AddFetch(header *types.Header, fastSync bool) (stale, throttled bool, item *fetchResult, err error) { r.lock.Lock() defer r.lock.Unlock() diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 87676e8f8..c99e69c1e 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -184,11 +184,10 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.Block // actually processed range is returned to avoid ambiguity when parts of the requested range // are not available or when the head has changed during processing this request. // Three arrays are returned based on the processed blocks: -// - reward: the requested percentiles of effective priority fees per gas of transactions in each -// block, sorted in ascending order and weighted by gas used. -// - baseFee: base fee per gas in the given block -// - gasUsedRatio: gasUsed/gasLimit in the given block -// +// - reward: the requested percentiles of effective priority fees per gas of transactions in each +// block, sorted in ascending order and weighted by gas used. +// - baseFee: base fee per gas in the given block +// - gasUsedRatio: gasUsed/gasLimit in the given block // Note: baseFee includes the next block after the newest of the returned range, because this // value can be derived from the newest block. func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) { diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go index 2aa668542..db898241e 100644 --- a/eth/protocols/snap/sync_test.go +++ b/eth/protocols/snap/sync_test.go @@ -369,8 +369,7 @@ func createStorageRequestResponse(t *testPeer, root common.Hash, accounts []comm return hashes, slots, proofs } -// the createStorageRequestResponseAlwaysProve tests a cornercase, where it always -// +// the createStorageRequestResponseAlwaysProve tests a cornercase, where it always // supplies the proof for the last account, even if it is 'complete'.h func createStorageRequestResponseAlwaysProve(t *testPeer, root common.Hash, accounts []common.Hash, bOrigin, bLimit []byte, max uint64) (hashes [][]common.Hash, slots [][][]byte, proofs [][]byte) { var size uint64 diff --git a/eth/state_accessor.go b/eth/state_accessor.go index e5c166221..bac31fe7f 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -36,15 +36,15 @@ import ( // base layer statedb can be passed then it's regarded as the statedb of the // parent block. // Parameters: -// - block: The block for which we want the state (== state at the stateRoot of the parent) -// - reexec: The maximum number of blocks to reprocess trying to obtain the desired state -// - base: If the caller is tracing multiple blocks, the caller can provide the parent state -// continuously from the callsite. -// - checklive: if true, then the live 'blockchain' state database is used. If the caller want to -// perform Commit or other 'save-to-disk' changes, this should be set to false to avoid -// storing trash persistently -// - preferDisk: this arg can be used by the caller to signal that even though the 'base' is provided, -// it would be preferrable to start from a fresh state, if we have it on disk. +// - block: The block for which we want the state (== state at the stateRoot of the parent) +// - reexec: The maximum number of blocks to reprocess trying to obtain the desired state +// - base: If the caller is tracing multiple blocks, the caller can provide the parent state +// continuously from the callsite. +// - checklive: if true, then the live 'blockchain' state database is used. If the caller want to +// perform Commit or other 'save-to-disk' changes, this should be set to false to avoid +// storing trash persistently +// - preferDisk: this arg can be used by the caller to signal that even though the 'base' is provided, +// it would be preferrable to start from a fresh state, if we have it on disk. func (eth *Ethereum) stateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) { var ( current *types.Block diff --git a/eth/tracers/js/internal/tracers/assets.go b/eth/tracers/js/internal/tracers/assets.go index 15e7757a7..caeccb7f3 100644 --- a/eth/tracers/js/internal/tracers/assets.go +++ b/eth/tracers/js/internal/tracers/assets.go @@ -388,13 +388,11 @@ const AssetDebug = false // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// +// data/ +// foo.txt +// img/ +// a.png +// b.png // then AssetDir("data") would return []string{"foo.txt", "img"}, // AssetDir("data/img") would return []string{"a.png", "b.png"}, // AssetDir("foo.txt") and AssetDir("notexist") would return an error, and diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 27bfa73c5..8f94bb975 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -37,15 +37,14 @@ func init() { // a reversed signature can be matched against the size of the data. // // Example: -// -// > debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"}) -// { -// 0x27dc297e-128: 1, -// 0x38cc4831-0: 2, -// 0x524f3889-96: 1, -// 0xadf59f99-288: 1, -// 0xc281d19e-0: 1 -// } +// > debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"}) +// { +// 0x27dc297e-128: 1, +// 0x38cc4831-0: 2, +// 0x524f3889-96: 1, +// 0xadf59f99-288: 1, +// 0xc281d19e-0: 1 +// } type fourByteTracer struct { env *vm.EVM ids map[string]int // ids aggregates the 4byte ids found diff --git a/eth/tracers/native/tracer.go b/eth/tracers/native/tracer.go index 370732b08..b1061d243 100644 --- a/eth/tracers/native/tracer.go +++ b/eth/tracers/native/tracer.go @@ -27,11 +27,9 @@ Aside from implementing the tracer, it also needs to register itself, using the Example: ```golang - - func init() { - register("noopTracerNative", newNoopTracer) - } - +func init() { + register("noopTracerNative", newNoopTracer) +} ``` */ package native diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index 302b8b532..33ff84b54 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -246,14 +246,13 @@ func (db *Database) Path() string { // the metrics subsystem. // // This is how a LevelDB stats table looks like (currently): -// -// Compactions -// Level | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB) -// -------+------------+---------------+---------------+---------------+--------------- -// 0 | 0 | 0.00000 | 1.27969 | 0.00000 | 12.31098 -// 1 | 85 | 109.27913 | 28.09293 | 213.92493 | 214.26294 -// 2 | 523 | 1000.37159 | 7.26059 | 66.86342 | 66.77884 -// 3 | 570 | 1113.18458 | 0.00000 | 0.00000 | 0.00000 +// Compactions +// Level | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB) +// -------+------------+---------------+---------------+---------------+--------------- +// 0 | 0 | 0.00000 | 1.27969 | 0.00000 | 12.31098 +// 1 | 85 | 109.27913 | 28.09293 | 213.92493 | 214.26294 +// 2 | 523 | 1000.37159 | 7.26059 | 66.86342 | 66.77884 +// 3 | 570 | 1113.18458 | 0.00000 | 0.00000 | 0.00000 // // This is how the write delay look like (currently): // DelayN:5 Delay:406.604657ms Paused: false diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index 28f9794b5..d0533be8f 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -103,14 +103,13 @@ type Service struct { // websocket. // // From Gorilla websocket docs: -// -// Connections support one concurrent reader and one concurrent writer. -// Applications are responsible for ensuring that no more than one goroutine calls the write methods -// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel -// concurrently and that no more than one goroutine calls the read methods -// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler -// concurrently. -// The Close and WriteControl methods can be called concurrently with all other methods. +// Connections support one concurrent reader and one concurrent writer. +// Applications are responsible for ensuring that no more than one goroutine calls the write methods +// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel +// concurrently and that no more than one goroutine calls the read methods +// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler +// concurrently. +// The Close and WriteControl methods can be called concurrently with all other methods. type connWrapper struct { conn *websocket.Conn diff --git a/internal/cmdtest/test_cmd.go b/internal/cmdtest/test_cmd.go index 1772459e7..6c7cb3a7c 100644 --- a/internal/cmdtest/test_cmd.go +++ b/internal/cmdtest/test_cmd.go @@ -87,7 +87,7 @@ func (tt *TestCmd) Run(name string, args ...string) { // InputLine writes the given text to the child's stdin. // This method can also be called from an expect template, e.g.: // -// geth.expect(`Passphrase: {{.InputLine "password"}}`) +// geth.expect(`Passphrase: {{.InputLine "password"}}`) func (tt *TestCmd) InputLine(s string) string { io.WriteString(tt.stdin, s+"\n") return "" diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 25fc673f7..d6e2591a1 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -741,10 +741,10 @@ func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.H } // GetBlockByNumber returns the requested canonical block. -// - When blockNr is -1 the chain head is returned. -// - When blockNr is -2 the pending chain head is returned. -// - When fullTx is true all transactions in the block are returned, otherwise -// only the transaction hash is returned. +// * When blockNr is -1 the chain head is returned. +// * When blockNr is -2 the pending chain head is returned. +// * When fullTx is true all transactions in the block are returned, otherwise +// only the transaction hash is returned. func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { block, err := s.b.BlockByNumber(ctx, number) if block != nil && err == nil { diff --git a/internal/jsre/deps/bindata.go b/internal/jsre/deps/bindata.go index 5b575c372..6f079c2ba 100644 --- a/internal/jsre/deps/bindata.go +++ b/internal/jsre/deps/bindata.go @@ -212,13 +212,11 @@ const AssetDebug = false // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// +// data/ +// foo.txt +// img/ +// a.png +// b.png // then AssetDir("data") would return []string{"foo.txt", "img"}, // AssetDir("data/img") would return []string{"a.png", "b.png"}, // AssetDir("foo.txt") and AssetDir("notexist") would return an error, and diff --git a/les/api.go b/les/api.go index 521a7d6ba..45ff05b99 100644 --- a/les/api.go +++ b/les/api.go @@ -366,11 +366,10 @@ func NewPrivateLightAPI(backend *lesCommons) *PrivateLightAPI { // LatestCheckpoint returns the latest local checkpoint package. // // The checkpoint package consists of 4 strings: -// -// result[0], hex encoded latest section index -// result[1], 32 bytes hex encoded latest section head hash -// result[2], 32 bytes hex encoded latest section canonical hash trie root hash -// result[3], 32 bytes hex encoded latest section bloom trie root hash +// result[0], hex encoded latest section index +// result[1], 32 bytes hex encoded latest section head hash +// result[2], 32 bytes hex encoded latest section canonical hash trie root hash +// result[3], 32 bytes hex encoded latest section bloom trie root hash func (api *PrivateLightAPI) LatestCheckpoint() ([4]string, error) { var res [4]string cp := api.backend.latestLocalCheckpoint() @@ -385,10 +384,9 @@ func (api *PrivateLightAPI) LatestCheckpoint() ([4]string, error) { // GetLocalCheckpoint returns the specific local checkpoint package. // // The checkpoint package consists of 3 strings: -// -// result[0], 32 bytes hex encoded latest section head hash -// result[1], 32 bytes hex encoded latest section canonical hash trie root hash -// result[2], 32 bytes hex encoded latest section bloom trie root hash +// result[0], 32 bytes hex encoded latest section head hash +// result[1], 32 bytes hex encoded latest section canonical hash trie root hash +// result[2], 32 bytes hex encoded latest section bloom trie root hash func (api *PrivateLightAPI) GetCheckpoint(index uint64) ([3]string, error) { var res [3]string cp := api.backend.localCheckpoint(index) diff --git a/les/downloader/downloader.go b/les/downloader/downloader.go index 7ff6eda9a..d02d91b2a 100644 --- a/les/downloader/downloader.go +++ b/les/downloader/downloader.go @@ -705,11 +705,9 @@ func (d *Downloader) fetchHead(p *peerConnection) (head *types.Header, pivot *ty // calculateRequestSpan calculates what headers to request from a peer when trying to determine the // common ancestor. // It returns parameters to be used for peer.RequestHeadersByNumber: -// -// from - starting block number -// count - number of headers to request -// skip - number of headers to skip -// +// from - starting block number +// count - number of headers to request +// skip - number of headers to skip // and also returns 'max', the last block which is expected to be returned by the remote peers, // given the (from,count,skip) func calculateRequestSpan(remoteHeight, localHeight uint64) (int64, int, int, uint64) { @@ -1324,22 +1322,22 @@ func (d *Downloader) fetchReceipts(from uint64) error { // various callbacks to handle the slight differences between processing them. // // The instrumentation parameters: -// - errCancel: error type to return if the fetch operation is cancelled (mostly makes logging nicer) -// - deliveryCh: channel from which to retrieve downloaded data packets (merged from all concurrent peers) -// - deliver: processing callback to deliver data packets into type specific download queues (usually within `queue`) -// - wakeCh: notification channel for waking the fetcher when new tasks are available (or sync completed) -// - expire: task callback method to abort requests that took too long and return the faulty peers (traffic shaping) -// - pending: task callback for the number of requests still needing download (detect completion/non-completability) -// - inFlight: task callback for the number of in-progress requests (wait for all active downloads to finish) -// - throttle: task callback to check if the processing queue is full and activate throttling (bound memory use) -// - reserve: task callback to reserve new download tasks to a particular peer (also signals partial completions) -// - fetchHook: tester callback to notify of new tasks being initiated (allows testing the scheduling logic) -// - fetch: network callback to actually send a particular download request to a physical remote peer -// - cancel: task callback to abort an in-flight download request and allow rescheduling it (in case of lost peer) -// - capacity: network callback to retrieve the estimated type-specific bandwidth capacity of a peer (traffic shaping) -// - idle: network callback to retrieve the currently (type specific) idle peers that can be assigned tasks -// - setIdle: network callback to set a peer back to idle and update its estimated capacity (traffic shaping) -// - kind: textual label of the type being downloaded to display in log messages +// - errCancel: error type to return if the fetch operation is cancelled (mostly makes logging nicer) +// - deliveryCh: channel from which to retrieve downloaded data packets (merged from all concurrent peers) +// - deliver: processing callback to deliver data packets into type specific download queues (usually within `queue`) +// - wakeCh: notification channel for waking the fetcher when new tasks are available (or sync completed) +// - expire: task callback method to abort requests that took too long and return the faulty peers (traffic shaping) +// - pending: task callback for the number of requests still needing download (detect completion/non-completability) +// - inFlight: task callback for the number of in-progress requests (wait for all active downloads to finish) +// - throttle: task callback to check if the processing queue is full and activate throttling (bound memory use) +// - reserve: task callback to reserve new download tasks to a particular peer (also signals partial completions) +// - fetchHook: tester callback to notify of new tasks being initiated (allows testing the scheduling logic) +// - fetch: network callback to actually send a particular download request to a physical remote peer +// - cancel: task callback to abort an in-flight download request and allow rescheduling it (in case of lost peer) +// - capacity: network callback to retrieve the estimated type-specific bandwidth capacity of a peer (traffic shaping) +// - idle: network callback to retrieve the currently (type specific) idle peers that can be assigned tasks +// - setIdle: network callback to set a peer back to idle and update its estimated capacity (traffic shaping) +// - kind: textual label of the type being downloaded to display in log messages func (d *Downloader) fetchParts(deliveryCh chan dataPack, deliver func(dataPack) (int, error), wakeCh chan bool, expire func() map[string]int, pending func() int, inFlight func() bool, reserve func(*peerConnection, int) (*fetchRequest, bool, bool), fetchHook func([]*types.Header), fetch func(*peerConnection, *fetchRequest) error, cancel func(*fetchRequest), capacity func(*peerConnection) int, diff --git a/les/downloader/queue.go b/les/downloader/queue.go index c6fa78729..158608ccd 100644 --- a/les/downloader/queue.go +++ b/les/downloader/queue.go @@ -477,10 +477,9 @@ func (q *queue) ReserveReceipts(p *peerConnection, count int) (*fetchRequest, bo // to access the queue, so they already need a lock anyway. // // Returns: -// -// item - the fetchRequest -// progress - whether any progress was made -// throttle - if the caller should throttle for a while +// item - the fetchRequest +// progress - whether any progress was made +// throttle - if the caller should throttle for a while func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque, pendPool map[string]*fetchRequest, kind uint) (*fetchRequest, bool, bool) { // Short circuit if the pool has been depleted, or if the peer's already diff --git a/les/downloader/resultstore.go b/les/downloader/resultstore.go index 4a40e0ebd..8075f507d 100644 --- a/les/downloader/resultstore.go +++ b/les/downloader/resultstore.go @@ -71,11 +71,10 @@ func (r *resultStore) SetThrottleThreshold(threshold uint64) uint64 { // wants to reserve headers for fetching. // // It returns the following: -// -// stale - if true, this item is already passed, and should not be requested again -// throttled - if true, the store is at capacity, this particular header is not prio now -// item - the result to store data into -// err - any error that occurred +// stale - if true, this item is already passed, and should not be requested again +// throttled - if true, the store is at capacity, this particular header is not prio now +// item - the result to store data into +// err - any error that occurred func (r *resultStore) AddFetch(header *types.Header, fastSync bool) (stale, throttled bool, item *fetchResult, err error) { r.lock.Lock() defer r.lock.Unlock() diff --git a/les/fetcher.go b/les/fetcher.go index b92d89c9e..0ba54e5d9 100644 --- a/les/fetcher.go +++ b/les/fetcher.go @@ -242,19 +242,18 @@ func (f *lightFetcher) forEachPeer(check func(id enode.ID, p *fetcherPeer) bool) } // mainloop is the main event loop of the light fetcher, which is responsible for +// - announcement maintenance(ulc) +// If we are running in ultra light client mode, then all announcements from +// the trusted servers are maintained. If the same announcements from trusted +// servers reach the threshold, then the relevant header is requested for retrieval. // -// - announcement maintenance(ulc) -// If we are running in ultra light client mode, then all announcements from -// the trusted servers are maintained. If the same announcements from trusted -// servers reach the threshold, then the relevant header is requested for retrieval. +// - block header retrieval +// Whenever we receive announce with higher td compared with local chain, the +// request will be made for header retrieval. // -// - block header retrieval -// Whenever we receive announce with higher td compared with local chain, the -// request will be made for header retrieval. -// -// - re-sync trigger -// If the local chain lags too much, then the fetcher will enter "synnchronise" -// mode to retrieve missing headers in batch. +// - re-sync trigger +// If the local chain lags too much, then the fetcher will enter "synnchronise" +// mode to retrieve missing headers in batch. func (f *lightFetcher) mainloop() { defer f.wg.Done() diff --git a/light/txpool.go b/light/txpool.go index 8b9d2a150..db791f405 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -77,13 +77,10 @@ type TxPool struct { // // Send instructs backend to forward new transactions // NewHead notifies backend about a new head after processed by the tx pool, -// -// including mined and rolled back transactions since the last event -// +// including mined and rolled back transactions since the last event // Discard notifies backend about transactions that should be discarded either -// -// because they have been replaced by a re-send or because they have been mined -// long ago and no rollback is expected +// because they have been replaced by a re-send or because they have been mined +// long ago and no rollback is expected type TxRelayBackend interface { Send(txs types.Transactions) NewHead(head common.Hash, mined []common.Hash, rollback []common.Hash) diff --git a/log/doc.go b/log/doc.go index d2e15140e..993743c0f 100644 --- a/log/doc.go +++ b/log/doc.go @@ -7,25 +7,27 @@ This package enforces you to only log key/value pairs. Keys must be strings. Val any type that you like. The default output format is logfmt, but you may also choose to use JSON instead if that suits you. Here's how you log: - log.Info("page accessed", "path", r.URL.Path, "user_id", user.id) + log.Info("page accessed", "path", r.URL.Path, "user_id", user.id) This will output a line that looks like: - lvl=info t=2014-05-02T16:07:23-0700 msg="page accessed" path=/org/71/profile user_id=9 + lvl=info t=2014-05-02T16:07:23-0700 msg="page accessed" path=/org/71/profile user_id=9 -# Getting Started +Getting Started To get started, you'll want to import the library: - import log "github.com/inconshreveable/log15" + import log "github.com/inconshreveable/log15" + Now you're ready to start logging: - func main() { - log.Info("Program starting", "args", os.Args()) - } + func main() { + log.Info("Program starting", "args", os.Args()) + } + -# Convention +Convention Because recording a human-meaningful message is common and good practice, the first argument to every logging method is the value to the *implicit* key 'msg'. @@ -38,35 +40,38 @@ you to favor terseness, ordering, and speed over safety. This is a reasonable tr logging functions. You don't need to explicitly state keys/values, log15 understands that they alternate in the variadic argument list: - log.Warn("size out of bounds", "low", lowBound, "high", highBound, "val", val) + log.Warn("size out of bounds", "low", lowBound, "high", highBound, "val", val) If you really do favor your type-safety, you may choose to pass a log.Ctx instead: - log.Warn("size out of bounds", log.Ctx{"low": lowBound, "high": highBound, "val": val}) + log.Warn("size out of bounds", log.Ctx{"low": lowBound, "high": highBound, "val": val}) + -# Context loggers +Context loggers Frequently, you want to add context to a logger so that you can track actions associated with it. An http request is a good example. You can easily create new loggers that have context that is automatically included with each log line: - requestlogger := log.New("path", r.URL.Path) + requestlogger := log.New("path", r.URL.Path) - // later - requestlogger.Debug("db txn commit", "duration", txnTimer.Finish()) + // later + requestlogger.Debug("db txn commit", "duration", txnTimer.Finish()) This will output a log line that includes the path context that is attached to the logger: - lvl=dbug t=2014-05-02T16:07:23-0700 path=/repo/12/add_hook msg="db txn commit" duration=0.12 + lvl=dbug t=2014-05-02T16:07:23-0700 path=/repo/12/add_hook msg="db txn commit" duration=0.12 -# Handlers + +Handlers The Handler interface defines where log lines are printed to and how they are formatted. Handler is a single interface that is inspired by net/http's handler interface: - type Handler interface { - Log(r *Record) error - } + type Handler interface { + Log(r *Record) error + } + Handlers can filter records, format them, or dispatch to multiple other Handlers. This package implements a number of Handlers for common logging patterns that are @@ -74,49 +79,49 @@ easily composed to create flexible, custom logging structures. Here's an example handler that prints logfmt output to Stdout: - handler := log.StreamHandler(os.Stdout, log.LogfmtFormat()) + handler := log.StreamHandler(os.Stdout, log.LogfmtFormat()) Here's an example handler that defers to two other handlers. One handler only prints records from the rpc package in logfmt to standard out. The other prints records at Error level or above in JSON formatted output to the file /var/log/service.json - handler := log.MultiHandler( - log.LvlFilterHandler(log.LvlError, log.Must.FileHandler("/var/log/service.json", log.JSONFormat())), - log.MatchFilterHandler("pkg", "app/rpc" log.StdoutHandler()) - ) + handler := log.MultiHandler( + log.LvlFilterHandler(log.LvlError, log.Must.FileHandler("/var/log/service.json", log.JSONFormat())), + log.MatchFilterHandler("pkg", "app/rpc" log.StdoutHandler()) + ) -# Logging File Names and Line Numbers +Logging File Names and Line Numbers This package implements three Handlers that add debugging information to the context, CallerFileHandler, CallerFuncHandler and CallerStackHandler. Here's an example that adds the source file and line number of each logging call to the context. - h := log.CallerFileHandler(log.StdoutHandler) - log.Root().SetHandler(h) - ... - log.Error("open file", "err", err) + h := log.CallerFileHandler(log.StdoutHandler) + log.Root().SetHandler(h) + ... + log.Error("open file", "err", err) This will output a line that looks like: - lvl=eror t=2014-05-02T16:07:23-0700 msg="open file" err="file not found" caller=data.go:42 + lvl=eror t=2014-05-02T16:07:23-0700 msg="open file" err="file not found" caller=data.go:42 Here's an example that logs the call stack rather than just the call site. - h := log.CallerStackHandler("%+v", log.StdoutHandler) - log.Root().SetHandler(h) - ... - log.Error("open file", "err", err) + h := log.CallerStackHandler("%+v", log.StdoutHandler) + log.Root().SetHandler(h) + ... + log.Error("open file", "err", err) This will output a line that looks like: - lvl=eror t=2014-05-02T16:07:23-0700 msg="open file" err="file not found" stack="[pkg/data.go:42 pkg/cmd/main.go]" + lvl=eror t=2014-05-02T16:07:23-0700 msg="open file" err="file not found" stack="[pkg/data.go:42 pkg/cmd/main.go]" The "%+v" format instructs the handler to include the path of the source file relative to the compile time GOPATH. The github.com/go-stack/stack package documents the full list of formatting verbs and modifiers available. -# Custom Handlers +Custom Handlers The Handler interface is so simple that it's also trivial to write your own. Let's create an example handler which tries to write to one handler, but if that fails it falls back to @@ -124,24 +129,24 @@ writing to another handler and includes the error that it encountered when tryin to the primary. This might be useful when trying to log over a network socket, but if that fails you want to log those records to a file on disk. - type BackupHandler struct { - Primary Handler - Secondary Handler - } + type BackupHandler struct { + Primary Handler + Secondary Handler + } - func (h *BackupHandler) Log (r *Record) error { - err := h.Primary.Log(r) - if err != nil { - r.Ctx = append(ctx, "primary_err", err) - return h.Secondary.Log(r) - } - return nil - } + func (h *BackupHandler) Log (r *Record) error { + err := h.Primary.Log(r) + if err != nil { + r.Ctx = append(ctx, "primary_err", err) + return h.Secondary.Log(r) + } + return nil + } This pattern is so useful that a generic version that handles an arbitrary number of Handlers is included as part of this library called FailoverHandler. -# Logging Expensive Operations +Logging Expensive Operations Sometimes, you want to log values that are extremely expensive to compute, but you don't want to pay the price of computing them if you haven't turned up your logging level to a high level of detail. @@ -150,50 +155,50 @@ This package provides a simple type to annotate a logging operation that you wan lazily, just when it is about to be logged, so that it would not be evaluated if an upstream Handler filters it out. Just wrap any function which takes no arguments with the log.Lazy type. For example: - func factorRSAKey() (factors []int) { - // return the factors of a very large number - } + func factorRSAKey() (factors []int) { + // return the factors of a very large number + } - log.Debug("factors", log.Lazy{factorRSAKey}) + log.Debug("factors", log.Lazy{factorRSAKey}) If this message is not logged for any reason (like logging at the Error level), then factorRSAKey is never evaluated. -# Dynamic context values +Dynamic context values The same log.Lazy mechanism can be used to attach context to a logger which you want to be evaluated when the message is logged, but not when the logger is created. For example, let's imagine a game where you have Player objects: - type Player struct { - name string - alive bool - log.Logger - } + type Player struct { + name string + alive bool + log.Logger + } You always want to log a player's name and whether they're alive or dead, so when you create the player object, you might do: - p := &Player{name: name, alive: true} - p.Logger = log.New("name", p.name, "alive", p.alive) + p := &Player{name: name, alive: true} + p.Logger = log.New("name", p.name, "alive", p.alive) Only now, even after a player has died, the logger will still report they are alive because the logging context is evaluated when the logger was created. By using the Lazy wrapper, we can defer the evaluation of whether the player is alive or not to each log message, so that the log records will reflect the player's current state no matter when the log message is written: - p := &Player{name: name, alive: true} - isAlive := func() bool { return p.alive } - player.Logger = log.New("name", p.name, "alive", log.Lazy{isAlive}) + p := &Player{name: name, alive: true} + isAlive := func() bool { return p.alive } + player.Logger = log.New("name", p.name, "alive", log.Lazy{isAlive}) -# Terminal Format +Terminal Format If log15 detects that stdout is a terminal, it will configure the default handler for it (which is log.StdoutHandler) to use TerminalFormat. This format logs records nicely for your terminal, including color-coded output based on log level. -# Error Handling +Error Handling Becasuse log15 allows you to step around the type system, there are a few ways you can specify invalid arguments to the logging functions. You could, for example, wrap something that is not @@ -211,61 +216,61 @@ are encouraged to return errors only if they fail to write their log records out syslog daemon is not responding. This allows the construction of useful handlers which cope with those failures like the FailoverHandler. -# Library Use +Library Use log15 is intended to be useful for library authors as a way to provide configurable logging to users of their library. Best practice for use in a library is to always disable all output for your logger by default and to provide a public Logger instance that consumers of your library can configure. Like so: - package yourlib + package yourlib - import "github.com/inconshreveable/log15" + import "github.com/inconshreveable/log15" - var Log = log.New() + var Log = log.New() - func init() { - Log.SetHandler(log.DiscardHandler()) - } + func init() { + Log.SetHandler(log.DiscardHandler()) + } Users of your library may then enable it if they like: - import "github.com/inconshreveable/log15" - import "example.com/yourlib" + import "github.com/inconshreveable/log15" + import "example.com/yourlib" - func main() { - handler := // custom handler setup - yourlib.Log.SetHandler(handler) - } + func main() { + handler := // custom handler setup + yourlib.Log.SetHandler(handler) + } -# Best practices attaching logger context +Best practices attaching logger context The ability to attach context to a logger is a powerful one. Where should you do it and why? I favor embedding a Logger directly into any persistent object in my application and adding unique, tracing context keys to it. For instance, imagine I am writing a web browser: - type Tab struct { - url string - render *RenderingContext - // ... + type Tab struct { + url string + render *RenderingContext + // ... - Logger - } + Logger + } - func NewTab(url string) *Tab { - return &Tab { - // ... - url: url, + func NewTab(url string) *Tab { + return &Tab { + // ... + url: url, - Logger: log.New("url", url), - } - } + Logger: log.New("url", url), + } + } When a new tab is created, I assign a logger to it with the url of the tab as context so it can easily be traced through the logs. Now, whenever we perform any operation with the tab, we'll log with its embedded logger and it will include the tab title automatically: - tab.Debug("moved position", "idx", tab.idx) + tab.Debug("moved position", "idx", tab.idx) There's only one problem. What if the tab url changes? We could use log.Lazy to make sure the current url is always written, but that @@ -280,29 +285,29 @@ function to let you generate what you might call "surrogate keys" They're just random hex identifiers to use for tracing. Back to our Tab example, we would prefer to set up our Logger like so: - import logext "github.com/inconshreveable/log15/ext" + import logext "github.com/inconshreveable/log15/ext" - t := &Tab { - // ... - url: url, - } + t := &Tab { + // ... + url: url, + } - t.Logger = log.New("id", logext.RandId(8), "url", log.Lazy{t.getUrl}) - return t + t.Logger = log.New("id", logext.RandId(8), "url", log.Lazy{t.getUrl}) + return t Now we'll have a unique traceable identifier even across loading new urls, but we'll still be able to see the tab's current url in the log messages. -# Must +Must For all Handler functions which can return an error, there is a version of that function which will return no error but panics on failure. They are all available on the Must object. For example: - log.Must.FileHandler("/path", log.JSONFormat) - log.Must.NetHandler("tcp", ":1234", log.JSONFormat) + log.Must.FileHandler("/path", log.JSONFormat) + log.Must.NetHandler("tcp", ":1234", log.JSONFormat) -# Inspiration and Credit +Inspiration and Credit All of the following excellent projects inspired the design of this library: @@ -320,8 +325,9 @@ github.com/spacemonkeygo/spacelog golang's stdlib, notably io and net/http -# The Name +The Name https://xkcd.com/927/ + */ package log diff --git a/log/format.go b/log/format.go index 924738181..9e2476f85 100644 --- a/log/format.go +++ b/log/format.go @@ -79,11 +79,12 @@ type TerminalStringer interface { // a terminal with color-coded level output and terser human friendly timestamp. // This format should only be used for interactive programs or while developing. // -// [LEVEL] [TIME] MESSAGE key=value key=value ... +// [LEVEL] [TIME] MESSAGE key=value key=value ... // // Example: // -// [DBUG] [May 16 20:58:45] remove route ns=haproxy addr=127.0.0.1:50002 +// [DBUG] [May 16 20:58:45] remove route ns=haproxy addr=127.0.0.1:50002 +// func TerminalFormat(usecolor bool) Format { return FormatFunc(func(r *Record) []byte { var color = 0 @@ -148,6 +149,7 @@ func TerminalFormat(usecolor bool) Format { // format for key/value pairs. // // For more details see: http://godoc.org/github.com/kr/logfmt +// func LogfmtFormat() Format { return FormatFunc(func(r *Record) []byte { common := []interface{}{r.KeyNames.Time, r.Time, r.KeyNames.Lvl, r.Lvl, r.KeyNames.Msg, r.Msg} diff --git a/log/handler.go b/log/handler.go index 5fc727d02..4ad433334 100644 --- a/log/handler.go +++ b/log/handler.go @@ -135,14 +135,15 @@ func CallerStackHandler(format string, h Handler) Handler { // wrapped Handler if the given function evaluates true. For example, // to only log records where the 'err' key is not nil: // -// logger.SetHandler(FilterHandler(func(r *Record) bool { -// for i := 0; i < len(r.Ctx); i += 2 { -// if r.Ctx[i] == "err" { -// return r.Ctx[i+1] != nil -// } -// } -// return false -// }, h)) +// logger.SetHandler(FilterHandler(func(r *Record) bool { +// for i := 0; i < len(r.Ctx); i += 2 { +// if r.Ctx[i] == "err" { +// return r.Ctx[i+1] != nil +// } +// } +// return false +// }, h)) +// func FilterHandler(fn func(r *Record) bool, h Handler) Handler { return FuncHandler(func(r *Record) error { if fn(r) { @@ -157,7 +158,8 @@ func FilterHandler(fn func(r *Record) bool, h Handler) Handler { // context matches the value. For example, to only log records // from your ui package: // -// log.MatchFilterHandler("pkg", "app/ui", log.StdoutHandler) +// log.MatchFilterHandler("pkg", "app/ui", log.StdoutHandler) +// func MatchFilterHandler(key string, value interface{}, h Handler) Handler { return FilterHandler(func(r *Record) (pass bool) { switch key { @@ -183,7 +185,8 @@ func MatchFilterHandler(key string, value interface{}, h Handler) Handler { // level to the wrapped Handler. For example, to only // log Error/Crit records: // -// log.LvlFilterHandler(log.LvlError, log.StdoutHandler) +// log.LvlFilterHandler(log.LvlError, log.StdoutHandler) +// func LvlFilterHandler(maxLvl Lvl, h Handler) Handler { return FilterHandler(func(r *Record) (pass bool) { return r.Lvl <= maxLvl @@ -195,9 +198,10 @@ func LvlFilterHandler(maxLvl Lvl, h Handler) Handler { // to different locations. For example, to log to a file and // standard error: // -// log.MultiHandler( -// log.Must.FileHandler("/var/log/app.log", log.LogfmtFormat()), -// log.StderrHandler) +// log.MultiHandler( +// log.Must.FileHandler("/var/log/app.log", log.LogfmtFormat()), +// log.StderrHandler) +// func MultiHandler(hs ...Handler) Handler { return FuncHandler(func(r *Record) error { for _, h := range hs { @@ -215,10 +219,10 @@ func MultiHandler(hs ...Handler) Handler { // to writing to a file if the network fails, and then to // standard out if the file write fails: // -// log.FailoverHandler( -// log.Must.NetHandler("tcp", ":9090", log.JSONFormat()), -// log.Must.FileHandler("/var/log/app.log", log.LogfmtFormat()), -// log.StdoutHandler) +// log.FailoverHandler( +// log.Must.NetHandler("tcp", ":9090", log.JSONFormat()), +// log.Must.FileHandler("/var/log/app.log", log.LogfmtFormat()), +// log.StdoutHandler) // // All writes that do not go to the first handler will add context with keys of // the form "failover_err_{idx}" which explain the error encountered while diff --git a/log/handler_glog.go b/log/handler_glog.go index b5186d4b2..9b1d4efaf 100644 --- a/log/handler_glog.go +++ b/log/handler_glog.go @@ -82,14 +82,14 @@ func (h *GlogHandler) Verbosity(level Lvl) { // // For instance: // -// pattern="gopher.go=3" -// sets the V level to 3 in all Go files named "gopher.go" +// pattern="gopher.go=3" +// sets the V level to 3 in all Go files named "gopher.go" // -// pattern="foo=3" -// sets V to 3 in all files of any packages whose import path ends in "foo" +// pattern="foo=3" +// sets V to 3 in all files of any packages whose import path ends in "foo" // -// pattern="foo/*=3" -// sets V to 3 in all files of any packages whose import path contains "foo" +// pattern="foo/*=3" +// sets V to 3 in all files of any packages whose import path contains "foo" func (h *GlogHandler) Vmodule(ruleset string) error { var filter []pattern for _, rule := range strings.Split(ruleset, ",") { diff --git a/metrics/influxdb/influxdbv2.go b/metrics/influxdb/influxdbv2.go index fb13d5081..24808791a 100644 --- a/metrics/influxdb/influxdbv2.go +++ b/metrics/influxdb/influxdbv2.go @@ -1,3 +1,4 @@ +// // The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the diff --git a/mobile/big.go b/mobile/big.go index 01c013df5..b8895c95c 100644 --- a/mobile/big.go +++ b/mobile/big.go @@ -77,6 +77,7 @@ func (bi *BigInt) SetInt64(x int64) { // -1 if x < 0 // 0 if x == 0 // +1 if x > 0 +// func (bi *BigInt) Sign() int { return bi.bigint.Sign() } diff --git a/mobile/discover.go b/mobile/discover.go index d87dabf69..f9b31ad9b 100644 --- a/mobile/discover.go +++ b/mobile/discover.go @@ -38,8 +38,8 @@ type Enode struct { // // For incomplete nodes, the designator must look like one of these // -// enode:// -// +// enode:// +// // // For complete nodes, the node ID is encoded in the username portion // of the URL, separated from the host by an @ sign. The hostname can @@ -52,7 +52,7 @@ type Enode struct { // a node with IP address 10.3.58.6, TCP listening port 30303 // and UDP discovery port 30301. // -// enode://@10.3.58.6:30303?discport=30301 +// enode://@10.3.58.6:30303?discport=30301 func NewEnode(rawurl string) (*Enode, error) { node, err := enode.Parse(enode.ValidSchemes, rawurl) if err != nil { diff --git a/mobile/doc.go b/mobile/doc.go index a4d4949ee..20131afc2 100644 --- a/mobile/doc.go +++ b/mobile/doc.go @@ -20,7 +20,7 @@ // with pieces plucked from go-ethereum, rather to allow writing native dapps on // mobile platforms. Keep this in mind when using or extending this package! // -// # API limitations +// API limitations // // Since gomobile cannot bridge arbitrary types between Go and Android/iOS, the // exposed APIs need to be manually wrapped into simplified types, with custom diff --git a/node/doc.go b/node/doc.go index 9d6dd18cd..b257f412f 100644 --- a/node/doc.go +++ b/node/doc.go @@ -21,22 +21,25 @@ In the model exposed by this package, a node is a collection of services which u resources to provide RPC APIs. Services can also offer devp2p protocols, which are wired up to the devp2p network when the node instance is started. -# Node Lifecycle + +Node Lifecycle The Node object has a lifecycle consisting of three basic states, INITIALIZING, RUNNING and CLOSED. - ●───────┐ - New() - │ - ▼ - INITIALIZING ────Start()─┐ - │ │ - │ ▼ - Close() RUNNING - │ │ - ▼ │ - CLOSED ◀──────Close()─┘ + + ●───────┐ + New() + │ + ▼ + INITIALIZING ────Start()─┐ + │ │ + │ ▼ + Close() RUNNING + │ │ + ▼ │ + CLOSED ◀──────Close()─┘ + Creating a Node allocates basic resources such as the data directory and returns the node in its INITIALIZING state. Lifecycle objects, RPC APIs and peer-to-peer networking @@ -55,7 +58,8 @@ objects and shuts down RPC and peer-to-peer networking. You must always call Close on Node, even if the node was not started. -# Resources Managed By Node + +Resources Managed By Node All file-system resources used by a node instance are located in a directory called the data directory. The location of each resource can be overridden through additional node @@ -79,7 +83,8 @@ without a data directory, databases are opened in memory instead. Node also creates the shared store of encrypted Ethereum account keys. Services can access the account manager through the service context. -# Sharing Data Directory Among Instances + +Sharing Data Directory Among Instances Multiple node instances can share a single data directory if they have distinct instance names (set through the Name config option). Sharing behaviour depends on the type of @@ -97,25 +102,26 @@ create one database for each instance. The account key store is shared among all node instances using the same data directory unless its location is changed through the KeyStoreDir configuration option. -# Data Directory Sharing Example + +Data Directory Sharing Example In this example, two node instances named A and B are started with the same data directory. Node instance A opens the database "db", node instance B opens the databases "db" and "db-2". The following files will be created in the data directory: - data-directory/ - A/ - nodekey -- devp2p node key of instance A - nodes/ -- devp2p discovery knowledge database of instance A - db/ -- LevelDB content for "db" - A.ipc -- JSON-RPC UNIX domain socket endpoint of instance A - B/ - nodekey -- devp2p node key of node B - nodes/ -- devp2p discovery knowledge database of instance B - static-nodes.json -- devp2p static node list of instance B - db/ -- LevelDB content for "db" - db-2/ -- LevelDB content for "db-2" - B.ipc -- JSON-RPC UNIX domain socket endpoint of instance B - keystore/ -- account key store, used by both instances + data-directory/ + A/ + nodekey -- devp2p node key of instance A + nodes/ -- devp2p discovery knowledge database of instance A + db/ -- LevelDB content for "db" + A.ipc -- JSON-RPC UNIX domain socket endpoint of instance A + B/ + nodekey -- devp2p node key of node B + nodes/ -- devp2p discovery knowledge database of instance B + static-nodes.json -- devp2p static node list of instance B + db/ -- LevelDB content for "db" + db-2/ -- LevelDB content for "db-2" + B.ipc -- JSON-RPC UNIX domain socket endpoint of instance B + keystore/ -- account key store, used by both instances */ package node diff --git a/node/node_example_test.go b/node/node_example_test.go index 9ae2ae6d5..ccf7b7eb6 100644 --- a/node/node_example_test.go +++ b/node/node_example_test.go @@ -27,8 +27,8 @@ import ( // life cycle management. // // The following methods are needed to implement a node.Lifecycle: -// - Start() error - method invoked when the node is ready to start the service -// - Stop() error - method invoked when the node terminates the service +// - Start() error - method invoked when the node is ready to start the service +// - Stop() error - method invoked when the node terminates the service type SampleLifecycle struct{} func (s *SampleLifecycle) Start() error { fmt.Println("Service starting..."); return nil } diff --git a/p2p/dial.go b/p2p/dial.go index 6be9508e7..1005e9687 100644 --- a/p2p/dial.go +++ b/p2p/dial.go @@ -84,12 +84,13 @@ var ( // dialer creates outbound connections and submits them into Server. // Two types of peer connections can be created: // -// - static dials are pre-configured connections. The dialer attempts -// keep these nodes connected at all times. +// - static dials are pre-configured connections. The dialer attempts +// keep these nodes connected at all times. +// +// - dynamic dials are created from node discovery results. The dialer +// continuously reads candidate nodes from its input iterator and attempts +// to create peer connections to nodes arriving through the iterator. // -// - dynamic dials are created from node discovery results. The dialer -// continuously reads candidate nodes from its input iterator and attempts -// to create peer connections to nodes arriving through the iterator. type dialScheduler struct { dialConfig setupFunc dialSetupFunc diff --git a/p2p/discover/v5wire/encoding_test.go b/p2p/discover/v5wire/encoding_test.go index f5a153ad4..b32e9a325 100644 --- a/p2p/discover/v5wire/encoding_test.go +++ b/p2p/discover/v5wire/encoding_test.go @@ -40,7 +40,8 @@ import ( // To regenerate discv5 test vectors, run // -// go test -run TestVectors -write-test-vectors +// go test -run TestVectors -write-test-vectors +// var writeTestVectorsFlag = flag.Bool("write-test-vectors", false, "Overwrite discv5 test vectors in testdata/") var ( diff --git a/p2p/dnsdisc/tree.go b/p2p/dnsdisc/tree.go index 71efd9a3a..a80257610 100644 --- a/p2p/dnsdisc/tree.go +++ b/p2p/dnsdisc/tree.go @@ -118,21 +118,21 @@ func (t *Tree) Nodes() []*enode.Node { We want to keep the UDP size below 512 bytes. The UDP size is roughly: UDP length = 8 + UDP payload length ( 229 ) UPD Payload length: - - dns.id 2 - - dns.flags 2 - - dns.count.queries 2 - - dns.count.answers 2 - - dns.count.auth_rr 2 - - dns.count.add_rr 2 - - queries (query-size + 6) - - answers : - - dns.resp.name 2 - - dns.resp.type 2 - - dns.resp.class 2 - - dns.resp.ttl 4 - - dns.resp.len 2 - - dns.txt.length 1 - - dns.txt resp_data_size + - dns.id 2 + - dns.flags 2 + - dns.count.queries 2 + - dns.count.answers 2 + - dns.count.auth_rr 2 + - dns.count.add_rr 2 + - queries (query-size + 6) + - answers : + - dns.resp.name 2 + - dns.resp.type 2 + - dns.resp.class 2 + - dns.resp.ttl 4 + - dns.resp.len 2 + - dns.txt.length 1 + - dns.txt resp_data_size So the total size is roughly a fixed overhead of `39`, and the size of the query (domain name) and response. diff --git a/p2p/enode/urlv4.go b/p2p/enode/urlv4.go index 2c5a47e70..6095fb94e 100644 --- a/p2p/enode/urlv4.go +++ b/p2p/enode/urlv4.go @@ -54,8 +54,8 @@ func MustParseV4(rawurl string) *Node { // // For incomplete nodes, the designator must look like one of these // -// enode:// -// +// enode:// +// // // For complete nodes, the node ID is encoded in the username portion // of the URL, separated from the host by an @ sign. The hostname can @@ -68,7 +68,7 @@ func MustParseV4(rawurl string) *Node { // a node with IP address 10.3.58.6, TCP listening port 30303 // and UDP discovery port 30301. // -// enode://@10.3.58.6:30303?discport=30301 +// enode://@10.3.58.6:30303?discport=30301 func ParseV4(rawurl string) (*Node, error) { if m := incompleteNodeURL.FindStringSubmatch(rawurl); m != nil { id, err := parsePubkey(m[1]) diff --git a/p2p/enr/enr.go b/p2p/enr/enr.go index b0dcfdc09..cb737e270 100644 --- a/p2p/enr/enr.go +++ b/p2p/enr/enr.go @@ -19,7 +19,7 @@ // stored in key/value pairs. To store and retrieve key/values in a record, use the Entry // interface. // -// # Signature Handling +// Signature Handling // // Records must be signed before transmitting them to another node. // diff --git a/p2p/message.go b/p2p/message.go index 89545c343..42fdd73e6 100644 --- a/p2p/message.go +++ b/p2p/message.go @@ -108,11 +108,12 @@ func Send(w MsgWriter, msgcode uint64, data interface{}) error { // SendItems writes an RLP with the given code and data elements. // For a call such as: // -// SendItems(w, code, e1, e2, e3) +// SendItems(w, code, e1, e2, e3) // // the message payload will be an RLP list containing the items: // -// [e1, e2, e3] +// [e1, e2, e3] +// func SendItems(w MsgWriter, msgcode uint64, elems ...interface{}) error { return Send(w, msgcode, elems) } diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index cb64158c3..a66e319de 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -54,12 +54,12 @@ type Interface interface { // The following formats are currently accepted. // Note that mechanism names are not case-sensitive. // -// "" or "none" return nil -// "extip:77.12.33.4" will assume the local machine is reachable on the given IP -// "any" uses the first auto-detected mechanism -// "upnp" uses the Universal Plug and Play protocol -// "pmp" uses NAT-PMP with an auto-detected gateway address -// "pmp:192.168.0.1" uses NAT-PMP with the given gateway address +// "" or "none" return nil +// "extip:77.12.33.4" will assume the local machine is reachable on the given IP +// "any" uses the first auto-detected mechanism +// "upnp" uses the Universal Plug and Play protocol +// "pmp" uses NAT-PMP with an auto-detected gateway address +// "pmp:192.168.0.1" uses NAT-PMP with the given gateway address func Parse(spec string) (Interface, error) { var ( parts = strings.SplitN(spec, ":", 2) diff --git a/p2p/simulations/adapters/types.go b/p2p/simulations/adapters/types.go index d9eb9f1c0..40a937628 100644 --- a/p2p/simulations/adapters/types.go +++ b/p2p/simulations/adapters/types.go @@ -43,6 +43,7 @@ import ( // * SimNode - An in-memory node // * ExecNode - A child process node // * DockerNode - A Docker container node +// type Node interface { // Addr returns the node's address (e.g. an Enode URL) Addr() []byte diff --git a/p2p/simulations/mocker.go b/p2p/simulations/mocker.go index 8515b7348..e168cb12f 100644 --- a/p2p/simulations/mocker.go +++ b/p2p/simulations/mocker.go @@ -29,20 +29,20 @@ import ( "github.com/scroll-tech/go-ethereum/p2p/simulations/adapters" ) -// a map of mocker names to its function +//a map of mocker names to its function var mockerList = map[string]func(net *Network, quit chan struct{}, nodeCount int){ "startStop": startStop, "probabilistic": probabilistic, "boot": boot, } -// Lookup a mocker by its name, returns the mockerFn +//Lookup a mocker by its name, returns the mockerFn func LookupMocker(mockerType string) func(net *Network, quit chan struct{}, nodeCount int) { return mockerList[mockerType] } -// Get a list of mockers (keys of the map) -// Useful for frontend to build available mocker selection +//Get a list of mockers (keys of the map) +//Useful for frontend to build available mocker selection func GetMockerList() []string { list := make([]string, 0, len(mockerList)) for k := range mockerList { @@ -51,7 +51,7 @@ func GetMockerList() []string { return list } -// The boot mockerFn only connects the node in a ring and doesn't do anything else +//The boot mockerFn only connects the node in a ring and doesn't do anything else func boot(net *Network, quit chan struct{}, nodeCount int) { _, err := connectNodesInRing(net, nodeCount) if err != nil { @@ -59,7 +59,7 @@ func boot(net *Network, quit chan struct{}, nodeCount int) { } } -// The startStop mockerFn stops and starts nodes in a defined period (ticker) +//The startStop mockerFn stops and starts nodes in a defined period (ticker) func startStop(net *Network, quit chan struct{}, nodeCount int) { nodes, err := connectNodesInRing(net, nodeCount) if err != nil { @@ -96,10 +96,10 @@ func startStop(net *Network, quit chan struct{}, nodeCount int) { } } -// The probabilistic mocker func has a more probabilistic pattern -// (the implementation could probably be improved): -// nodes are connected in a ring, then a varying number of random nodes is selected, -// mocker then stops and starts them in random intervals, and continues the loop +//The probabilistic mocker func has a more probabilistic pattern +//(the implementation could probably be improved): +//nodes are connected in a ring, then a varying number of random nodes is selected, +//mocker then stops and starts them in random intervals, and continues the loop func probabilistic(net *Network, quit chan struct{}, nodeCount int) { nodes, err := connectNodesInRing(net, nodeCount) if err != nil { @@ -160,7 +160,7 @@ func probabilistic(net *Network, quit chan struct{}, nodeCount int) { } -// connect nodeCount number of nodes in a ring +//connect nodeCount number of nodes in a ring func connectNodesInRing(net *Network, nodeCount int) ([]enode.ID, error) { ids := make([]enode.ID, nodeCount) for i := 0; i < nodeCount; i++ { diff --git a/params/denomination.go b/params/denomination.go index bcedd271e..fb4da7f41 100644 --- a/params/denomination.go +++ b/params/denomination.go @@ -19,7 +19,8 @@ package params // These are the multipliers for ether denominations. // Example: To get the wei value of an amount in 'gwei', use // -// new(big.Int).Mul(value, big.NewInt(params.GWei)) +// new(big.Int).Mul(value, big.NewInt(params.GWei)) +// const ( Wei = 1 GWei = 1e9 diff --git a/params/version.go b/params/version.go index a681346c6..2cd828f96 100644 --- a/params/version.go +++ b/params/version.go @@ -44,8 +44,7 @@ var VersionWithMeta = func() string { // ArchiveVersion holds the textual version string used for Geth archives. // e.g. "1.8.11-dea1ce05" for stable releases, or -// -// "1.8.13-unstable-21c059b6" for unstable releases +// "1.8.13-unstable-21c059b6" for unstable releases func ArchiveVersion(gitCommit string) string { vsn := Version if VersionMeta != "stable" { diff --git a/rlp/decode.go b/rlp/decode.go index 540cc407f..5f2e5ad5f 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -74,7 +74,7 @@ type Decoder interface { // Note that Decode does not set an input limit for all readers and may be vulnerable to // panics cause by huge value sizes. If you need an input limit, use // -// NewStream(r, limit).Decode(val) +// NewStream(r, limit).Decode(val) func Decode(r io.Reader, val interface{}) error { stream := streamPool.Get().(*Stream) defer streamPool.Put(stream) diff --git a/rlp/doc.go b/rlp/doc.go index 8dd5c89b8..113828e39 100644 --- a/rlp/doc.go +++ b/rlp/doc.go @@ -27,7 +27,8 @@ value zero equivalent to the empty string). RLP values are distinguished by a type tag. The type tag precedes the value in the input stream and defines the size and kind of the bytes that follow. -# Encoding Rules + +Encoding Rules Package rlp uses reflection and encodes RLP based on the Go type of the value. @@ -57,7 +58,8 @@ An interface value encodes as the value contained in the interface. Floating point numbers, maps, channels and functions are not supported. -# Decoding Rules + +Decoding Rules Decoding uses the following type-dependent rules: @@ -91,29 +93,30 @@ or one (true). To decode into an interface value, one of these types is stored in the value: - []interface{}, for RLP lists - []byte, for RLP strings + []interface{}, for RLP lists + []byte, for RLP strings Non-empty interface types are not supported when decoding. Signed integers, floating point numbers, maps, channels and functions cannot be decoded into. -# Struct Tags + +Struct Tags As with other encoding packages, the "-" tag ignores fields. - type StructWithIgnoredField struct{ - Ignored uint `rlp:"-"` - Field uint - } + type StructWithIgnoredField struct{ + Ignored uint `rlp:"-"` + Field uint + } Go struct values encode/decode as RLP lists. There are two ways of influencing the mapping of fields to list elements. The "tail" tag, which may only be used on the last exported struct field, allows slurping up any excess list elements into a slice. - type StructWithTail struct{ - Field uint - Tail []string `rlp:"tail"` - } + type StructWithTail struct{ + Field uint + Tail []string `rlp:"tail"` + } The "optional" tag says that the field may be omitted if it is zero-valued. If this tag is used on a struct field, all subsequent public fields must also be declared optional. @@ -125,11 +128,11 @@ When decoding into a struct, optional fields may be omitted from the end of the list. For the example below, this means input lists of one, two, or three elements are accepted. - type StructWithOptionalFields struct{ - Required uint - Optional1 uint `rlp:"optional"` - Optional2 uint `rlp:"optional"` - } + type StructWithOptionalFields struct{ + Required uint + Optional1 uint `rlp:"optional"` + Optional2 uint `rlp:"optional"` + } The "nil", "nilList" and "nilString" tags apply to pointer-typed fields only, and change the decoding rules for the field type. For regular pointer fields without the "nil" tag, @@ -137,9 +140,9 @@ input values must always match the required input length exactly and the decoder produce nil values. When the "nil" tag is set, input values of size zero decode as a nil pointer. This is especially useful for recursive types. - type StructWithNilField struct { - Field *[3]byte `rlp:"nil"` - } + type StructWithNilField struct { + Field *[3]byte `rlp:"nil"` + } In the example above, Field allows two possible input sizes. For input 0xC180 (a list containing an empty string) Field is set to nil after decoding. For input 0xC483000000 (a diff --git a/rpc/doc.go b/rpc/doc.go index 33c41895e..fc175f2ae 100644 --- a/rpc/doc.go +++ b/rpc/doc.go @@ -15,6 +15,7 @@ // along with the go-ethereum library. If not, see . /* + Package rpc implements bi-directional JSON-RPC 2.0 on multiple transports. It provides access to the exported methods of an object across a network or other I/O @@ -22,16 +23,16 @@ connection. After creating a server or client instance, objects can be registere them visible as 'services'. Exported methods that follow specific conventions can be called remotely. It also has support for the publish/subscribe pattern. -# RPC Methods +RPC Methods Methods that satisfy the following criteria are made available for remote access: - - method must be exported - - method returns 0, 1 (response or error) or 2 (response and error) values + - method must be exported + - method returns 0, 1 (response or error) or 2 (response and error) values An example method: - func (s *CalcService) Add(a, b int) (int, error) + func (s *CalcService) Add(a, b int) (int, error) When the returned error isn't nil the returned integer is ignored and the error is sent back to the client. Otherwise the returned integer is sent back to the client. @@ -40,7 +41,7 @@ Optional arguments are supported by accepting pointer values as arguments. E.g. to do the addition in an optional finite field we can accept a mod argument as pointer value. - func (s *CalcService) Add(a, b int, mod *int) (int, error) + func (s *CalcService) Add(a, b int, mod *int) (int, error) This RPC method can be called with 2 integers and a null value as third argument. In that case the mod argument will be nil. Or it can be called with 3 integers, in that case mod @@ -55,40 +56,40 @@ to the client out of order. An example server which uses the JSON codec: - type CalculatorService struct {} + type CalculatorService struct {} - func (s *CalculatorService) Add(a, b int) int { - return a + b - } + func (s *CalculatorService) Add(a, b int) int { + return a + b + } - func (s *CalculatorService) Div(a, b int) (int, error) { - if b == 0 { - return 0, errors.New("divide by zero") - } - return a/b, nil - } + func (s *CalculatorService) Div(a, b int) (int, error) { + if b == 0 { + return 0, errors.New("divide by zero") + } + return a/b, nil + } - calculator := new(CalculatorService) - server := NewServer() - server.RegisterName("calculator", calculator) - l, _ := net.ListenUnix("unix", &net.UnixAddr{Net: "unix", Name: "/tmp/calculator.sock"}) - server.ServeListener(l) + calculator := new(CalculatorService) + server := NewServer() + server.RegisterName("calculator", calculator) + l, _ := net.ListenUnix("unix", &net.UnixAddr{Net: "unix", Name: "/tmp/calculator.sock"}) + server.ServeListener(l) -# Subscriptions +Subscriptions The package also supports the publish subscribe pattern through the use of subscriptions. A method that is considered eligible for notifications must satisfy the following criteria: - - method must be exported - - first method argument type must be context.Context - - method must have return types (rpc.Subscription, error) + - method must be exported + - first method argument type must be context.Context + - method must have return types (rpc.Subscription, error) An example method: - func (s *BlockChainService) NewBlocks(ctx context.Context) (rpc.Subscription, error) { - ... - } + func (s *BlockChainService) NewBlocks(ctx context.Context) (rpc.Subscription, error) { + ... + } When the service containing the subscription method is registered to the server, for example under the "blockchain" namespace, a subscription is created by calling the @@ -100,7 +101,7 @@ the client and server. The server will close the connection for any write error. For more information about subscriptions, see https://github.com/scroll-tech/go-ethereum/wiki/RPC-PUB-SUB. -# Reverse Calls +Reverse Calls In any method handler, an instance of rpc.Client can be accessed through the ClientFromContext method. Using this client instance, server-to-client method calls can be diff --git a/rpc/handler.go b/rpc/handler.go index 68d969575..28f92effc 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -34,20 +34,21 @@ import ( // // The entry points for incoming messages are: // -// h.handleMsg(message) -// h.handleBatch(message) +// h.handleMsg(message) +// h.handleBatch(message) // // Outgoing calls use the requestOp struct. Register the request before sending it // on the connection: // -// op := &requestOp{ids: ...} -// h.addRequestOp(op) +// op := &requestOp{ids: ...} +// h.addRequestOp(op) // // Now send the request, then wait for the reply to be delivered through handleMsg: // -// if err := op.wait(...); err != nil { -// h.removeRequestOp(op) // timeout, etc. -// } +// if err := op.wait(...); err != nil { +// h.removeRequestOp(op) // timeout, etc. +// } +// type handler struct { reg *serviceRegistry unsubscribeCb *callback diff --git a/signer/core/api_test.go b/signer/core/api_test.go index ff5eb6df6..7e76ca190 100644 --- a/signer/core/api_test.go +++ b/signer/core/api_test.go @@ -40,7 +40,7 @@ import ( "github.com/scroll-tech/go-ethereum/signer/storage" ) -// Used for testing +//Used for testing type headlessUi struct { approveCh chan string // to send approve/deny inputCh chan string // to send password diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go index 59ddcb5c2..869d66201 100644 --- a/signer/core/apitypes/types.go +++ b/signer/core/apitypes/types.go @@ -51,7 +51,7 @@ func (vs *ValidationMessages) Info(msg string) { vs.Messages = append(vs.Messages, ValidationInfo{INFO, msg}) } -// / getWarnings returns an error with all messages of type WARN of above, or nil if no warnings were present +/// getWarnings returns an error with all messages of type WARN of above, or nil if no warnings were present func (v *ValidationMessages) GetWarnings() error { var messages []string for _, msg := range v.Messages { diff --git a/signer/fourbyte/4byte.go b/signer/fourbyte/4byte.go index 0d655da77..2f7b24795 100644 --- a/signer/fourbyte/4byte.go +++ b/signer/fourbyte/4byte.go @@ -147004,13 +147004,11 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// +// data/ +// foo.txt +// img/ +// a.png +// b.png // then AssetDir("data") would return []string{"foo.txt", "img"}, // AssetDir("data/img") would return []string{"a.png", "b.png"}, // AssetDir("foo.txt") and AssetDir("notexist") would return an error, and diff --git a/signer/rules/rules_test.go b/signer/rules/rules_test.go index 1dc040670..b2d1130de 100644 --- a/signer/rules/rules_test.go +++ b/signer/rules/rules_test.go @@ -243,7 +243,7 @@ func (d *dummyUI) OnApprovedTx(tx ethapi.SignTransactionResult) { func (d *dummyUI) OnSignerStartup(info core.StartupInfo) { } -// TestForwarding tests that the rule-engine correctly dispatches requests to the next caller +//TestForwarding tests that the rule-engine correctly dispatches requests to the next caller func TestForwarding(t *testing.T) { js := "" @@ -544,7 +544,7 @@ func (d *dontCallMe) OnApprovedTx(tx ethapi.SignTransactionResult) { d.t.Fatalf("Did not expect next-handler to be called") } -// TestContextIsCleared tests that the rule-engine does not retain variables over several requests. +//TestContextIsCleared tests that the rule-engine does not retain variables over several requests. // if it does, that would be bad since developers may rely on that to store data, // instead of using the disk-based data storage func TestContextIsCleared(t *testing.T) { diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 93aeaec91..b03452354 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -174,18 +174,17 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { } } -/* -See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II +/* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II - Whether a block is valid or not is a bit subtle, it's defined by presence of - blockHeader, transactions and uncleHeaders fields. If they are missing, the block is - invalid and we must verify that we do not accept it. + Whether a block is valid or not is a bit subtle, it's defined by presence of + blockHeader, transactions and uncleHeaders fields. If they are missing, the block is + invalid and we must verify that we do not accept it. - Since some tests mix valid and invalid blocks we need to check this for every block. + Since some tests mix valid and invalid blocks we need to check this for every block. - If a block is invalid it does not necessarily fail the test, if it's invalidness is - expected we are expected to ignore it and continue processing and then validate the - post state. + If a block is invalid it does not necessarily fail the test, if it's invalidness is + expected we are expected to ignore it and continue processing and then validate the + post state. */ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) { validBlocks := make([]btBlock, 0) diff --git a/tests/fuzzers/bls12381/precompile_fuzzer.go b/tests/fuzzers/bls12381/precompile_fuzzer.go index 4ed681e23..648138a95 100644 --- a/tests/fuzzers/bls12381/precompile_fuzzer.go +++ b/tests/fuzzers/bls12381/precompile_fuzzer.go @@ -72,10 +72,8 @@ func checkInput(id byte, inputLen int) bool { // The fuzzer functions must return // 1 if the fuzzer should increase priority of the -// -// given input during subsequent fuzzing (for example, the input is lexically -// correct and was parsed successfully); -// +// given input during subsequent fuzzing (for example, the input is lexically +// correct and was parsed successfully); // -1 if the input must not be added to corpus even if gives new coverage; and // 0 otherwise // other values are reserved for future use. diff --git a/tests/fuzzers/difficulty/difficulty-fuzz.go b/tests/fuzzers/difficulty/difficulty-fuzz.go index daa0d2fdd..a62406447 100644 --- a/tests/fuzzers/difficulty/difficulty-fuzz.go +++ b/tests/fuzzers/difficulty/difficulty-fuzz.go @@ -69,10 +69,8 @@ func (f *fuzzer) readBool() bool { // The function must return // 1 if the fuzzer should increase priority of the -// -// given input during subsequent fuzzing (for example, the input is lexically -// correct and was parsed successfully); -// +// given input during subsequent fuzzing (for example, the input is lexically +// correct and was parsed successfully); // -1 if the input must not be added to corpus even if gives new coverage; and // 0 otherwise // other values are reserved for future use. diff --git a/tests/fuzzers/rangeproof/rangeproof-fuzzer.go b/tests/fuzzers/rangeproof/rangeproof-fuzzer.go index fb2438dbc..cdbfa98e3 100644 --- a/tests/fuzzers/rangeproof/rangeproof-fuzzer.go +++ b/tests/fuzzers/rangeproof/rangeproof-fuzzer.go @@ -182,10 +182,8 @@ func (f *fuzzer) fuzz() int { // The function must return // 1 if the fuzzer should increase priority of the -// -// given input during subsequent fuzzing (for example, the input is lexically -// correct and was parsed successfully); -// +// given input during subsequent fuzzing (for example, the input is lexically +// correct and was parsed successfully); // -1 if the input must not be added to corpus even if gives new coverage; and // 0 otherwise; other values are reserved for future use. func Fuzz(input []byte) int { diff --git a/tests/fuzzers/stacktrie/trie_fuzzer.go b/tests/fuzzers/stacktrie/trie_fuzzer.go index 5f96ee32f..3fba704c7 100644 --- a/tests/fuzzers/stacktrie/trie_fuzzer.go +++ b/tests/fuzzers/stacktrie/trie_fuzzer.go @@ -115,10 +115,8 @@ func (k kvs) Swap(i, j int) { // The function must return // 1 if the fuzzer should increase priority of the -// -// given input during subsequent fuzzing (for example, the input is lexically -// correct and was parsed successfully); -// +// given input during subsequent fuzzing (for example, the input is lexically +// correct and was parsed successfully); // -1 if the input must not be added to corpus even if gives new coverage; and // 0 otherwise // other values are reserved for future use. diff --git a/tests/fuzzers/trie/trie-fuzzer.go b/tests/fuzzers/trie/trie-fuzzer.go index ff2ec75c1..aca71ff45 100644 --- a/tests/fuzzers/trie/trie-fuzzer.go +++ b/tests/fuzzers/trie/trie-fuzzer.go @@ -124,10 +124,8 @@ func Generate(input []byte) randTest { // The function must return // 1 if the fuzzer should increase priority of the -// -// given input during subsequent fuzzing (for example, the input is lexically -// correct and was parsed successfully); -// +// given input during subsequent fuzzing (for example, the input is lexically +// correct and was parsed successfully); // -1 if the input must not be added to corpus even if gives new coverage; and // 0 otherwise // other values are reserved for future use. diff --git a/trie/proof.go b/trie/proof.go index f3470b9cc..58fb4c3cc 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -341,9 +341,9 @@ findFork: // unset removes all internal node references either the left most or right most. // It can meet these scenarios: // -// - The given path is existent in the trie, unset the associated nodes with the -// specific direction -// - The given path is non-existent in the trie +// - The given path is existent in the trie, unset the associated nodes with the +// specific direction +// - The given path is non-existent in the trie // - the fork point is a fullnode, the corresponding child pointed by path // is nil, return // - the fork point is a shortnode, the shortnode is included in the range, @@ -458,15 +458,15 @@ func hasRightElement(node node, key []byte) bool { // Expect the normal case, this function can also be used to verify the following // range proofs: // -// - All elements proof. In this case the proof can be nil, but the range should -// be all the leaves in the trie. +// - All elements proof. In this case the proof can be nil, but the range should +// be all the leaves in the trie. // -// - One element proof. In this case no matter the edge proof is a non-existent -// proof or not, we can always verify the correctness of the proof. +// - One element proof. In this case no matter the edge proof is a non-existent +// proof or not, we can always verify the correctness of the proof. // -// - Zero element proof. In this case a single non-existent proof is enough to prove. -// Besides, if there are still some other leaves available on the right side, then -// an error will be returned. +// - Zero element proof. In this case a single non-existent proof is enough to prove. +// Besides, if there are still some other leaves available on the right side, then +// an error will be returned. // // Except returning the error to indicate the proof is valid or not, the function will // also return a flag to indicate whether there exists more accounts/slots in the trie. diff --git a/trie/stacktrie.go b/trie/stacktrie.go index 8665c7073..2e9f98bac 100644 --- a/trie/stacktrie.go +++ b/trie/stacktrie.go @@ -363,12 +363,11 @@ func (st *StackTrie) insert(key, value []byte) { // hash() hashes the node 'st' and converts it into 'hashedNode', if possible. // Possible outcomes: // 1. The rlp-encoded value was >= 32 bytes: -// - Then the 32-byte `hash` will be accessible in `st.val`. -// - And the 'st.type' will be 'hashedNode' -// +// - Then the 32-byte `hash` will be accessible in `st.val`. +// - And the 'st.type' will be 'hashedNode' // 2. The rlp-encoded value was < 32 bytes -// - Then the <32 byte rlp-encoded value will be accessible in 'st.val'. -// - And the 'st.type' will be 'hashedNode' AGAIN +// - Then the <32 byte rlp-encoded value will be accessible in 'st.val'. +// - And the 'st.type' will be 'hashedNode' AGAIN // // This method will also: // set 'st.type' to hashedNode From 60ced6cf4debc14c1d23808e015027f787314458 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:12:46 +0800 Subject: [PATCH 03/12] build: remove jenkins scripts (#295) * update github workflow * update github workflow * update github workflow --- .github/workflows/l2geth_ci.yml | 49 ++++++++++++++--- build/jenkins/Jenkinsfile | 65 ----------------------- build/jenkins/push-docker-tag.Jenkinsfile | 61 --------------------- 3 files changed, 41 insertions(+), 134 deletions(-) delete mode 100644 build/jenkins/Jenkinsfile delete mode 100644 build/jenkins/push-docker-tag.Jenkinsfile diff --git a/.github/workflows/l2geth_ci.yml b/.github/workflows/l2geth_ci.yml index be75afce6..127aa2a7b 100644 --- a/.github/workflows/l2geth_ci.yml +++ b/.github/workflows/l2geth_ci.yml @@ -1,6 +1,30 @@ -on: [pull_request] -name: Continuous Integration +on: + push: + branches: + - main + - staging + - develop + - alpha + pull_request: + branches: + - main + - staging + - develop + - alpha +name: CI jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.18.x + - name: Checkout code + uses: actions/checkout@v2 + - name: Build + run: | + make geth check: runs-on: ubuntu-latest steps: @@ -14,12 +38,6 @@ jobs: run: | rm -rf $HOME/.cache/golangci-lint make lint - - name: Test - run: | - go get ./... - make test - - name: Upload coverage report - run: bash <(curl -s https://codecov.io/bash) goimports-lint: runs-on: ubuntu-latest steps: @@ -39,3 +57,18 @@ jobs: if [ -n "$(git status --porcelain)" ]; then exit 1 fi + test: + runs-on: ubuntu-latest + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.18.x + - name: Checkout code + uses: actions/checkout@v2 + - name: Test + run: | + go get ./... + make test + - name: Upload coverage report + run: bash <(curl -s https://codecov.io/bash) diff --git a/build/jenkins/Jenkinsfile b/build/jenkins/Jenkinsfile deleted file mode 100644 index e58ff57dc..000000000 --- a/build/jenkins/Jenkinsfile +++ /dev/null @@ -1,65 +0,0 @@ -pipeline { - agent any - tools { - go 'go-1.18' - } - environment { - GO111MODULE = 'on' - } - stages { - stage('Build') { - steps { - // Get some code from a GitHub repository - - // git branch: 'zkrollup', - // credentialsId: 'testgitchuhan1', - // url: 'git@github.com:scroll-tech/go-ethereum.git' - - // Build the app. - sh 'go build' - - } - - } - stage('Test') { - // Use golang. - steps { - // Remove cached test results. - sh 'go clean -cache' - // Run Unit Tests. - sh 'make test' - } - } - - stage('Docker') { - environment { - // Extract the username and password of our credentials into "DOCKER_CREDENTIALS_USR" and "DOCKER_CREDENTIALS_PSW". - // (NOTE 1: DOCKER_CREDENTIALS will be set to "your_username:your_password".) - // The new variables will always be YOUR_VARIABLE_NAME + _USR and _PSW. - // (NOTE 2: You can't print credentials in the pipeline for security reasons.) - DOCKER_CREDENTIALS = credentials('dockerhub') - } - - steps { - // Use a scripted pipeline. - script { - def app - // stage('Initialize') { - // def dockerHome = tool 'myDocker' - // env.PATH = "${dockerHome}/bin:${env.PATH}" - // } - - stage('Build image') { - app = docker.build("${env.DOCKER_CREDENTIALS_USR}/l2geth-img") - } - - } - } - } - } - post { - always { - cleanWs() - } - } -} \ No newline at end of file diff --git a/build/jenkins/push-docker-tag.Jenkinsfile b/build/jenkins/push-docker-tag.Jenkinsfile deleted file mode 100644 index 78d3abeac..000000000 --- a/build/jenkins/push-docker-tag.Jenkinsfile +++ /dev/null @@ -1,61 +0,0 @@ -credentialDocker = 'dockerhub' - -pipeline { - agent any - options { - timeout (20) - } - tools { - go 'go-1.18' - nodejs "nodejs" - } - environment { - GO111MODULE = 'on' - PATH="/home/ubuntu/.cargo/bin:$PATH" - // LOG_DOCKER = 'true' - } - stages { - stage('Tag') { - steps { - script { - TAGNAME = sh(returnStdout: true, script: 'git tag -l --points-at HEAD') - sh "echo ${TAGNAME}" - // ... - } - } - } - stage('Build') { - environment { - DOCKER_CREDENTIALS = credentials('dockerhub') - } - steps { - withCredentials([usernamePassword(credentialsId: "${credentialDocker}", passwordVariable: 'dockerPassword', usernameVariable: 'dockerUser')]) { - // Use a scripted pipeline. - script { - stage('Push image') { - if (TAGNAME == ""){ - return; - } - sh "docker login --username=${dockerUser} --password=${dockerPassword}" - sh "docker build -t scrolltech/l2geth:latest ." - sh "docker tag scrolltech/l2geth:latest scrolltech/l2geth:${TAGNAME}" - sh "docker push scrolltech/l2geth:${TAGNAME}" - } - } - } - } - } - } - post { - success { - slackSend(message: "l2geth tag ${TAGNAME} build dockersSuccessed") - } - // triggered when red sign - failure { - slackSend(message: "l2geth tag ${TAGNAME} build docker failed") - } - always { - cleanWs() - } - } -} From 1abf51a719ed680a69bde23817f0ea1e2cec3e95 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:21:46 +0800 Subject: [PATCH 04/12] style: revert Dockerfile format (#296) --- .gitignore | 1 - Dockerfile | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index fef885502..1ee8b8302 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,3 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log - diff --git a/Dockerfile b/Dockerfile index c07e7d1f3..ec46f6077 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,15 +6,15 @@ ARG BUILDNUM="" # Build Geth in a stock Go builder container FROM golang:1.18-alpine as builder -ENV GOPROXY https://proxy.golang.org,direct +RUN apk add --no-cache gcc musl-dev linux-headers git ADD . /go-ethereum -RUN apk add --no-cache gcc musl-dev linux-headers git ca-certificates \ - && cd /go-ethereum && go run build/ci.go install ./cmd/geth +RUN cd /go-ethereum && go run build/ci.go install ./cmd/geth # Pull Geth into a second stage deploy alpine container FROM alpine:latest +RUN apk add --no-cache ca-certificates COPY --from=builder /go-ethereum/build/bin/geth /usr/local/bin/ EXPOSE 8545 8546 30303 30303/udp From dfdd0160e77e56755fa4f264ade4014e14621a30 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:58:25 +0800 Subject: [PATCH 05/12] chore: remove outdated genesis.json (#297) --- README.md | 7 ++----- cmd/geth/genesis_test.go | 37 ------------------------------------- genesis.json | 37 ------------------------------------- genesis_zktrie.json | 37 ------------------------------------- 4 files changed, 2 insertions(+), 116 deletions(-) delete mode 100644 genesis.json delete mode 100644 genesis_zktrie.json diff --git a/README.md b/README.md index c0e7849bb..34a4c537e 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,7 @@ ZK-Rollup adapts the Go Ethereum to run as Layer 2 Sequencer. The codebase is ba ### ZKTrie Storage -Another implement for storage trie, base on patricia merkle tree, has been induced. It is feasible to zk proving in the storage part. It is specified as a flag -in gensis, set `config.zktrie` to true for enabling it. Using `genesis_zktrie.json` as an example to create a L2 chain with zktrie sotrage: - -> geth init \/genesis_zktrie.json +Another implement for storage trie, base on patricia merkle tree, has been induced. It is feasible to zk proving in the storage part. It is specified as a flag in gensis, set `config.scroll.useZktrie` to true for enabling it. Notice current the snapshot would be disabled by the zktrie implement. @@ -78,7 +75,7 @@ This command will: causing it to download more data in exchange for avoiding processing the entire history of the Ethereum network, which is very CPU intensive. * Start up `geth`'s built-in interactive [JavaScript console](https://geth.ethereum.org/docs/interface/javascript-console), - (via the trailing `console` subcommand) through which you can interact using [`web3` methods](https://web3js.readthedocs.io/) + (via the trailing `console` subcommand) through which you can interact using [`web3` methods](https://web3js.readthedocs.io/) (note: the `web3` version bundled within `geth` is very old, and not up to date with official docs), as well as `geth`'s own [management APIs](https://geth.ethereum.org/docs/rpc/server). This tool is optional and if you leave it out you can always attach to an already running diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go index 3b077bae8..e86e1d7ee 100644 --- a/cmd/geth/genesis_test.go +++ b/cmd/geth/genesis_test.go @@ -17,15 +17,10 @@ package main import ( - "encoding/json" - "fmt" "io/ioutil" "os" "path/filepath" "testing" - - "github.com/scroll-tech/go-ethereum/common" - "github.com/scroll-tech/go-ethereum/core" ) var customGenesisTests = []struct { @@ -73,41 +68,9 @@ var customGenesisTests = []struct { }, } -func addCustomGenesis() error { - path, _ := os.Getwd() - buf, err := os.ReadFile(fmt.Sprintf("%s/%s", path[:len(path)-len("/cmd/geth")], "genesis.json")) - if err != nil { - return err - } - genesis := &core.Genesis{} - if err := json.Unmarshal(buf, genesis); err != nil { - return err - } - if len(genesis.Alloc) == 0 { - return nil - } - data := string(buf) - for addr, balance := range genesis.Alloc { - customGenesisTests = append(customGenesisTests, struct { - genesis string - query string - result string - }{ - genesis: data, - query: fmt.Sprintf("eth.getBalance('%s')", addr.String()), - result: common.Bytes2Hex(balance.Balance.Bytes()), - }) - } - - return nil -} - // Tests that initializing Geth with a custom genesis block and chain definitions // work properly. func TestCustomGenesis(t *testing.T) { - if err := addCustomGenesis(); err != nil { - t.Error(err) - } for i, tt := range customGenesisTests { // Create a temporary data directory to use and inspect later datadir := tmpdir(t) diff --git a/genesis.json b/genesis.json deleted file mode 100644 index 3e5e35ad3..000000000 --- a/genesis.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "config": { - "chainId": 53077, - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "clique": { - "period": 15, - "epoch": 30000 - }, - "zktrie": false - }, - "nonce": "0x0", - "timestamp": "0x61bc34a0", - "extraData": "0x00000000000000000000000000000000000000000000000000000000000000004cb1ab63af5d8931ce09673ebd8ae2ce16fd65710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x47b760", - "difficulty": "0x1", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "4cb1ab63af5d8931ce09673ebd8ae2ce16fd6571": { - "balance": "0x200000000000000000000000000000000000000000000000000000000000000" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFeePerGas": null -} \ No newline at end of file diff --git a/genesis_zktrie.json b/genesis_zktrie.json deleted file mode 100644 index 5db0f740a..000000000 --- a/genesis_zktrie.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "config": { - "chainId": 53077, - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "clique": { - "period": 15, - "epoch": 30000 - }, - "zktrie": true - }, - "nonce": "0x0", - "timestamp": "0x61bc34a0", - "extraData": "0x00000000000000000000000000000000000000000000000000000000000000004cb1ab63af5d8931ce09673ebd8ae2ce16fd65710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x6691b7", - "difficulty": "0x1", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "4cb1ab63af5d8931ce09673ebd8ae2ce16fd6571": { - "balance": "0x56BC75E2D63100000000000000000000000000000000000000000000000000" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFeePerGas": null -} From ddaab71dbb8a4ccb6ba5b5888d18bf28e763a3b5 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Thu, 20 Apr 2023 20:11:49 +0800 Subject: [PATCH 06/12] Bump version v3.1.7 (#299) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 2cd828f96..d8751c1ea 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 3 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 6 // Patch version component of the current release + VersionPatch = 7 // Patch version component of the current release VersionMeta = "alpha" // Version metadata to append to the version string ) From 61d15e9d56d693e9375e217a1a487829d75b87b2 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Mon, 24 Apr 2023 20:49:50 +0800 Subject: [PATCH 07/12] feat: print ScrollConfig when starting node (#291) * feat: print ScrollConfig when starting node * Update version.go --- params/config.go | 13 ++++++++++++- params/version.go | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/params/config.go b/params/config.go index e05f0f12c..958d79789 100644 --- a/params/config.go +++ b/params/config.go @@ -453,6 +453,16 @@ func (s ScrollConfig) ZktrieEnabled() bool { return s.UseZktrie } +func (s ScrollConfig) String() string { + if s.MaxTxPerBlock == nil { + return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: , feeVaultAddress: %v, enableEIP2718:%v, enableEIP1559:%v}", + s.UseZktrie, s.FeeVaultAddress, s.EnableEIP2718, s.EnableEIP1559) + } + + return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, feeVaultAddress: %v, enableEIP2718:%v, enableEIP1559:%v}", + s.UseZktrie, *s.MaxTxPerBlock, s.FeeVaultAddress, s.EnableEIP2718, s.EnableEIP1559) +} + // IsValidTxCount returns whether the given block's transaction count is below the limit. func (s ScrollConfig) IsValidTxCount(count int) bool { return s.MaxTxPerBlock == nil || count <= *s.MaxTxPerBlock @@ -488,7 +498,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Engine: %v, Scroll config: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -505,6 +515,7 @@ func (c *ChainConfig) String() string { c.LondonBlock, c.ArrowGlacierBlock, engine, + c.Scroll, ) } diff --git a/params/version.go b/params/version.go index d8751c1ea..672aacf35 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 3 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 7 // Patch version component of the current release + VersionPatch = 8 // Patch version component of the current release VersionMeta = "alpha" // Version metadata to append to the version string ) From ba4feee9ffcdff45acc29ab31266d484bbe5a31e Mon Sep 17 00:00:00 2001 From: Ho Date: Mon, 24 Apr 2023 21:32:50 +0800 Subject: [PATCH 08/12] feat(zktrie): upgrade zktrie to 0.5.3 (#278) * upgrade zktrie to 0.5.3 * Update version.go --------- Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- params/version.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 46106220a..29f173216 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,7 @@ require ( github.com/prometheus/tsdb v0.7.1 github.com/rjeczalik/notify v0.9.1 github.com/rs/cors v1.7.0 - github.com/scroll-tech/zktrie v0.5.2 + github.com/scroll-tech/zktrie v0.5.3 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 github.com/stretchr/testify v1.8.2 diff --git a/go.sum b/go.sum index a336b44a7..bc40f08d6 100644 --- a/go.sum +++ b/go.sum @@ -375,8 +375,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/scroll-tech/zktrie v0.5.2 h1:U34jPXMLGOlRHfdvYp5VVgOcC0RuPeJmcS3bWotCWiY= -github.com/scroll-tech/zktrie v0.5.2/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk= +github.com/scroll-tech/zktrie v0.5.3 h1:jjzQchGU6XPL5s1C5bwwivSadefSRuYASE9OL7UKAdE= +github.com/scroll-tech/zktrie v0.5.3/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= diff --git a/params/version.go b/params/version.go index 672aacf35..ddde26405 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 3 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 8 // Patch version component of the current release + VersionPatch = 9 // Patch version component of the current release VersionMeta = "alpha" // Version metadata to append to the version string ) From 5017dcb92a371695ae91f2bfa7ee8207adcb04da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Garamv=C3=B6lgyi?= Date: Wed, 3 May 2023 17:45:17 +0200 Subject: [PATCH 09/12] Add block payload size limit (#309) add block payload size limit --- miner/worker.go | 19 +++++++++++++------ params/config.go | 24 +++++++++++++++++------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 581df046b..942deae0f 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -82,12 +82,13 @@ const ( type environment struct { signer types.Signer - state *state.StateDB // apply state changes here - ancestors mapset.Set // ancestor set (used for checking uncle parent validity) - family mapset.Set // family set (used for checking uncle invalidity) - uncles mapset.Set // uncle set - tcount int // tx count in cycle - gasPool *core.GasPool // available gas used to pack transactions + state *state.StateDB // apply state changes here + ancestors mapset.Set // ancestor set (used for checking uncle parent validity) + family mapset.Set // family set (used for checking uncle invalidity) + uncles mapset.Set // uncle set + tcount int // tx count in cycle + blockSize common.StorageSize // approximate size of tx payload in bytes + gasPool *core.GasPool // available gas used to pack transactions header *types.Header txs []*types.Transaction @@ -707,6 +708,7 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error { } // Keep track of transactions which return errors so they can be removed env.tcount = 0 + env.blockSize = 0 // Swap out the old work with the new one, terminating any leftover prefetcher // processes in the mean time and starting a new one. @@ -833,6 +835,10 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin if tx == nil { break } + if !w.chainConfig.Scroll.IsValidBlockSize(w.current.blockSize + tx.Size()) { + log.Trace("Block size limit reached", "have", w.current.blockSize, "want", w.chainConfig.Scroll.MaxTxPayloadBytesPerBlock, "tx", tx.Size()) + break + } // Error may be ignored here. The error has already been checked // during transaction acceptance is the transaction pool. // @@ -870,6 +876,7 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin // Everything ok, collect the logs and shift in the next transaction from the same account coalescedLogs = append(coalescedLogs, logs...) w.current.tcount++ + w.current.blockSize += tx.Size() txs.Shift() case errors.Is(err, core.ErrTxTypeNotSupported): diff --git a/params/config.go b/params/config.go index 958d79789..687d84000 100644 --- a/params/config.go +++ b/params/config.go @@ -255,8 +255,9 @@ var ( } // ScrollAlphaChainConfig contains the chain parameters to run a node on the Scroll Alpha test network. - ScrollFeeVaultAddress = common.HexToAddress("0x5300000000000000000000000000000000000005") - ScrollMaxTxPerBlock = 44 + ScrollFeeVaultAddress = common.HexToAddress("0x5300000000000000000000000000000000000005") + ScrollMaxTxPerBlock = 44 + ScrollMaxTxPayloadBytesPerBlock = 120 * 1024 ScrollAlphaChainConfig = &ChainConfig{ ChainID: big.NewInt(534353), @@ -279,11 +280,12 @@ var ( Epoch: 30000, }, Scroll: ScrollConfig{ - UseZktrie: true, - MaxTxPerBlock: &ScrollMaxTxPerBlock, - FeeVaultAddress: &ScrollFeeVaultAddress, - EnableEIP2718: false, - EnableEIP1559: false, + UseZktrie: true, + MaxTxPerBlock: &ScrollMaxTxPerBlock, + MaxTxPayloadBytesPerBlock: &ScrollMaxTxPayloadBytesPerBlock, + FeeVaultAddress: &ScrollFeeVaultAddress, + EnableEIP2718: false, + EnableEIP1559: false, }, } @@ -431,6 +433,9 @@ type ScrollConfig struct { // Maximum number of transactions per block [optional] MaxTxPerBlock *int `json:"maxTxPerBlock,omitempty"` + // Maximum tx payload size of blocks that we produce [optional] + MaxTxPayloadBytesPerBlock *int `json:"maxTxPayloadBytesPerBlock,omitempty"` + // Transaction fee vault address [optional] FeeVaultAddress *common.Address `json:"feeVaultAddress,omitempty"` @@ -468,6 +473,11 @@ func (s ScrollConfig) IsValidTxCount(count int) bool { return s.MaxTxPerBlock == nil || count <= *s.MaxTxPerBlock } +// IsValidBlockSize returns whether the given block's transaction payload size is below the limit. +func (s ScrollConfig) IsValidBlockSize(size common.StorageSize) bool { + return s.MaxTxPayloadBytesPerBlock == nil || size <= common.StorageSize(*s.MaxTxPayloadBytesPerBlock) +} + // EthashConfig is the consensus engine configs for proof-of-work based sealing. type EthashConfig struct{} From 1263e6349d99a31814dee5fb44bcc06cf25022df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Garamv=C3=B6lgyi?= Date: Wed, 3 May 2023 17:55:34 +0200 Subject: [PATCH 10/12] Bump version (#310) bump version to 3.1.10 --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index ddde26405..6496343e6 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 3 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 9 // Patch version component of the current release + VersionPatch = 10 // Patch version component of the current release VersionMeta = "alpha" // Version metadata to append to the version string ) From 49192260a177f1b63fc5ea3b872fb904f396260c Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Thu, 4 May 2023 21:51:10 +0800 Subject: [PATCH 11/12] build: update github CI trigger conditions (#313) --- .github/workflows/l2geth_ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/l2geth_ci.yml b/.github/workflows/l2geth_ci.yml index 127aa2a7b..3722ac70d 100644 --- a/.github/workflows/l2geth_ci.yml +++ b/.github/workflows/l2geth_ci.yml @@ -1,16 +1,11 @@ on: push: - branches: + branches: # we keep this to avoid triggering `push` & `pull_request` every time we update a PR - main - staging - develop - alpha pull_request: - branches: - - main - - staging - - develop - - alpha name: CI jobs: build: From c913b3e2f16ce35adb4b2f625a7872baf8e6a45c Mon Sep 17 00:00:00 2001 From: Ho Date: Mon, 8 May 2023 15:40:54 +0800 Subject: [PATCH 12/12] fix(zktrie): fix deletion proofs and collect them in commiting phase (#263) * new deletion proof * complete tracer and test * extend proof for parallel tracing * integrating into blocktrace * lint * deduplication of deletion proofs * fix an issue on marking deletion * fixs since last review * Update version.go --------- Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Co-authored-by: Ubuntu --- core/state/state_prove.go | 88 ++++++++++++++++++ core/state/statedb.go | 47 +--------- eth/tracers/api_blocktrace.go | 52 ++++++++++- params/version.go | 2 +- trie/zk_trie.go | 52 ++++------- trie/zk_trie_proof_test.go | 60 +++++++++++-- trie/zktrie_deletionproof.go | 163 ++++++++++++++++++++++++++++++++++ 7 files changed, 371 insertions(+), 93 deletions(-) create mode 100644 core/state/state_prove.go create mode 100644 trie/zktrie_deletionproof.go diff --git a/core/state/state_prove.go b/core/state/state_prove.go new file mode 100644 index 000000000..95c54988d --- /dev/null +++ b/core/state/state_prove.go @@ -0,0 +1,88 @@ +package state + +import ( + "fmt" + + zkt "github.com/scroll-tech/zktrie/types" + + zktrie "github.com/scroll-tech/go-ethereum/trie" + + "github.com/scroll-tech/go-ethereum/common" + "github.com/scroll-tech/go-ethereum/crypto" + "github.com/scroll-tech/go-ethereum/ethdb" +) + +type TrieProve interface { + Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error +} + +type ZktrieProofTracer struct { + *zktrie.ProofTracer +} + +// MarkDeletion overwrite the underlayer method with secure key +func (t ZktrieProofTracer) MarkDeletion(key common.Hash) { + key_s, _ := zkt.ToSecureKeyBytes(key.Bytes()) + t.ProofTracer.MarkDeletion(key_s.Bytes()) +} + +// Merge overwrite underlayer method with proper argument +func (t ZktrieProofTracer) Merge(another ZktrieProofTracer) { + t.ProofTracer.Merge(another.ProofTracer) +} + +func (t ZktrieProofTracer) Available() bool { + return t.ProofTracer != nil +} + +// NewProofTracer is not in Db interface and used explictily for reading proof in storage trie (not updated by the dirty value) +func (s *StateDB) NewProofTracer(trieS Trie) ZktrieProofTracer { + if s.IsZktrie() { + zkTrie := trieS.(*zktrie.ZkTrie) + if zkTrie == nil { + panic("unexpected trie type for zktrie") + } + return ZktrieProofTracer{zkTrie.NewProofTracer()} + } + return ZktrieProofTracer{} +} + +// GetStorageTrieForProof is not in Db interface and used explictily for reading proof in storage trie (not updated by the dirty value) +func (s *StateDB) GetStorageTrieForProof(addr common.Address) (Trie, error) { + + // try the trie in stateObject first, else we would create one + stateObject := s.getStateObject(addr) + if stateObject == nil { + // still return a empty trie + addrHash := crypto.Keccak256Hash(addr[:]) + dummy_trie, _ := s.db.OpenStorageTrie(addrHash, common.Hash{}) + return dummy_trie, nil + } + + trie := stateObject.trie + var err error + if trie == nil { + // use a new, temporary trie + trie, err = s.db.OpenStorageTrie(stateObject.addrHash, stateObject.data.Root) + if err != nil { + return nil, fmt.Errorf("can't create storage trie on root %s: %v ", stateObject.data.Root, err) + } + } + + return trie, nil +} + +// GetSecureTrieProof handle any interface with Prove (should be a Trie in most case) and +// deliver the proof in bytes +func (s *StateDB) GetSecureTrieProof(trieProve TrieProve, key common.Hash) ([][]byte, error) { + + var proof proofList + var err error + if s.IsZktrie() { + key_s, _ := zkt.ToSecureKeyBytes(key.Bytes()) + err = trieProve.Prove(key_s.Bytes(), 0, &proof) + } else { + err = trieProve.Prove(crypto.Keccak256(key.Bytes()), 0, &proof) + } + return proof, err +} diff --git a/core/state/statedb.go b/core/state/statedb.go index 60189beb5..2bc0f7fff 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -350,56 +350,13 @@ func (s *StateDB) GetRootHash() common.Hash { return s.trie.Hash() } -// StorageTrieProof is not in Db interface and used explictily for reading proof in storage trie (not the dirty value) -// For zktrie it also provide required data for predict the deletion, else it just fallback to GetStorageProof -func (s *StateDB) GetStorageTrieProof(a common.Address, key common.Hash) ([][]byte, []byte, error) { - - // try the trie in stateObject first, else we would create one - stateObject := s.getStateObject(a) - if stateObject == nil { - return nil, nil, errors.New("storage trie for requested address does not exist") - } - - trieS := stateObject.trie - var err error - if trieS == nil { - // use a new, temporary trie - trieS, err = s.db.OpenStorageTrie(stateObject.addrHash, stateObject.data.Root) - if err != nil { - return nil, nil, fmt.Errorf("can't create storage trie on root %s: %v ", stateObject.data.Root, err) - } - } - - var proof proofList - var sibling []byte - if s.IsZktrie() { - zkTrie := trieS.(*trie.ZkTrie) - if zkTrie == nil { - panic("unexpected trie type for zktrie") - } - key_s, _ := zkt.ToSecureKeyBytes(key.Bytes()) - sibling, err = zkTrie.ProveWithDeletion(key_s.Bytes(), 0, &proof) - } else { - err = trieS.Prove(crypto.Keccak256(key.Bytes()), 0, &proof) - } - return proof, sibling, err -} - // GetStorageProof returns the Merkle proof for given storage slot. func (s *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) { - var proof proofList trie := s.StorageTrie(a) if trie == nil { - return proof, errors.New("storage trie for requested address does not exist") + return nil, errors.New("storage trie for requested address does not exist") } - var err error - if s.IsZktrie() { - key_s, _ := zkt.ToSecureKeyBytes(key.Bytes()) - err = trie.Prove(key_s.Bytes(), 0, &proof) - } else { - err = trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof) - } - return proof, err + return s.GetSecureTrieProof(trie, key) } // GetCommittedState retrieves a value from the given account's committed storage trie. diff --git a/eth/tracers/api_blocktrace.go b/eth/tracers/api_blocktrace.go index 165b358aa..851bf9549 100644 --- a/eth/tracers/api_blocktrace.go +++ b/eth/tracers/api_blocktrace.go @@ -1,6 +1,7 @@ package tracers import ( + "bytes" "context" "errors" "fmt" @@ -42,6 +43,8 @@ type traceEnv struct { // this lock is used to protect StorageTrace's read and write mutual exclusion. sMu sync.Mutex *types.StorageTrace + // zktrie tracer is used for zktrie storage to build additional deletion proof + zkTrieTracer map[string]state.ZktrieProofTracer executionResults []*types.ExecutionResult } @@ -119,6 +122,7 @@ func (api *API) createTraceEnv(ctx context.Context, config *TraceConfig, block * Proofs: make(map[string][]hexutil.Bytes), StorageProofs: make(map[string]map[string][]hexutil.Bytes), }, + zkTrieTracer: make(map[string]state.ZktrieProofTracer), executionResults: make([]*types.ExecutionResult, block.Transactions().Len()), } @@ -189,6 +193,18 @@ func (api *API) getBlockTrace(block *types.Block, env *traceEnv) (*types.BlockTr close(jobs) pend.Wait() + // after all tx has been traced, collect "deletion proof" for zktrie + for _, tracer := range env.zkTrieTracer { + delProofs, err := tracer.GetDeletionProofs() + if err != nil { + log.Error("deletion proof failure", "error", err) + } else { + for _, proof := range delProofs { + env.DeletionProofs = append(env.DeletionProofs, proof) + } + } + } + // If execution failed in between, abort select { case err := <-errCh: @@ -299,22 +315,47 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc proofStorages := tracer.UpdatedStorages() for addr, keys := range proofStorages { - for key := range keys { + env.sMu.Lock() + trie, err := state.GetStorageTrieForProof(addr) + if err != nil { + // but we still continue to next address + log.Error("Storage trie not available", "error", err, "address", addr) + env.sMu.Unlock() + continue + } + zktrieTracer := state.NewProofTracer(trie) + env.sMu.Unlock() + + for key, values := range keys { addrStr := addr.String() keyStr := key.String() + isDelete := bytes.Equal(values.Bytes(), common.Hash{}.Bytes()) env.sMu.Lock() m, existed := env.StorageProofs[addrStr] if !existed { m = make(map[string][]hexutil.Bytes) env.StorageProofs[addrStr] = m + if zktrieTracer.Available() { + env.zkTrieTracer[addrStr] = zktrieTracer + } } else if _, existed := m[keyStr]; existed { + // still need to touch tracer for deletion + if isDelete && zktrieTracer.Available() { + env.zkTrieTracer[addrStr].MarkDeletion(key) + } env.sMu.Unlock() continue } env.sMu.Unlock() - proof, sibling, err := state.GetStorageTrieProof(addr, key) + var proof [][]byte + var err error + if zktrieTracer.Available() { + proof, err = state.GetSecureTrieProof(zktrieTracer, key) + } else { + proof, err = state.GetSecureTrieProof(trie, key) + } if err != nil { log.Error("Storage proof not available", "error", err, "address", addrStr, "key", keyStr) // but we still mark the proofs map with nil array @@ -325,8 +366,11 @@ func (api *API) getTxResult(env *traceEnv, state *state.StateDB, index int, bloc } env.sMu.Lock() m[keyStr] = wrappedProof - if sibling != nil { - env.DeletionProofs = append(env.DeletionProofs, sibling) + if zktrieTracer.Available() { + if isDelete { + zktrieTracer.MarkDeletion(key) + } + env.zkTrieTracer[addrStr].Merge(zktrieTracer) } env.sMu.Unlock() } diff --git a/params/version.go b/params/version.go index 6496343e6..a22915db1 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 3 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 10 // Patch version component of the current release + VersionPatch = 11 // Patch version component of the current release VersionMeta = "alpha" // Version metadata to append to the version string ) diff --git a/trie/zk_trie.go b/trie/zk_trie.go index 449b2aa89..627d3ee58 100644 --- a/trie/zk_trie.go +++ b/trie/zk_trie.go @@ -174,49 +174,29 @@ func (t *ZkTrie) NodeIterator(start []byte) NodeIterator { // nodes of the longest existing prefix of the key (at least the root node), ending // with the node that proves the absence of the key. func (t *ZkTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error { - // omit sibling, which is not required for proving only - _, err := t.ProveWithDeletion(key, fromLevel, proofDb) - return err -} - -// ProveWithDeletion is the implement of Prove, it also return possible sibling node -// (if there is, i.e. the node of key exist and is not the only node in trie) -// so witness generator can predict the final state root after deletion of this key -// the returned sibling node has no key along with it for witness generator must decode -// the node for its purpose -func (t *ZkTrie) ProveWithDeletion(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) (sibling []byte, err error) { - err = t.ZkTrie.ProveWithDeletion(key, fromLevel, - func(n *zktrie.Node) error { - nodeHash, err := n.NodeHash() - if err != nil { - return err - } + err := t.ZkTrie.Prove(key, fromLevel, func(n *zktrie.Node) error { + nodeHash, err := n.NodeHash() + if err != nil { + return err + } - if n.Type == zktrie.NodeTypeLeaf { - preImage := t.GetKey(n.NodeKey.Bytes()) - if len(preImage) > 0 { - n.KeyPreimage = &zkt.Byte32{} - copy(n.KeyPreimage[:], preImage) - //return fmt.Errorf("key preimage not found for [%x] ref %x", n.NodeKey.Bytes(), k.Bytes()) - } - } - return proofDb.Put(nodeHash[:], n.Value()) - }, - func(_ *zktrie.Node, n *zktrie.Node) { - // the sibling for each leaf should be unique except for EmptyNode - if n != nil && n.Type != zktrie.NodeTypeEmpty { - sibling = n.Value() + if n.Type == zktrie.NodeTypeLeaf { + preImage := t.GetKey(n.NodeKey.Bytes()) + if len(preImage) > 0 { + n.KeyPreimage = &zkt.Byte32{} + copy(n.KeyPreimage[:], preImage) + //return fmt.Errorf("key preimage not found for [%x] ref %x", n.NodeKey.Bytes(), k.Bytes()) } - }, - ) + } + return proofDb.Put(nodeHash[:], n.Value()) + }) if err != nil { - return + return err } // we put this special kv pair in db so we can distinguish the type and // make suitable Proof - err = proofDb.Put(magicHash, zktrie.ProofMagicBytes()) - return + return proofDb.Put(magicHash, zktrie.ProofMagicBytes()) } // VerifyProof checks merkle proofs. The given proof must contain the value for diff --git a/trie/zk_trie_proof_test.go b/trie/zk_trie_proof_test.go index c3652b7ee..0109e9be8 100644 --- a/trie/zk_trie_proof_test.go +++ b/trie/zk_trie_proof_test.go @@ -196,7 +196,7 @@ func randomZktrie(t *testing.T, n int) (*ZkTrie, map[string]*kv) { return tr, vals } -// Tests that new "proof with deletion" feature +// Tests that new "proof trace" feature func TestProofWithDeletion(t *testing.T) { tr, _ := NewZkTrie(common.Hash{}, NewZktrieDatabase((memorydb.New()))) mt := &zkTrieImplTestWrapper{tr.Tree()} @@ -217,20 +217,66 @@ func TestProofWithDeletion(t *testing.T) { s_key1, err := zkt.ToSecureKeyBytes(key1) assert.NoError(t, err) - sibling1, err := tr.ProveWithDeletion(s_key1.Bytes(), 0, proof) + proofTracer := tr.NewProofTracer() + + err = proofTracer.Prove(s_key1.Bytes(), 0, proof) assert.NoError(t, err) nd, err := tr.TryGet(key2) assert.NoError(t, err) - l := len(sibling1) + + s_key2, err := zkt.ToSecureKeyBytes(bytes.Repeat([]byte("x"), 32)) + assert.NoError(t, err) + + err = proofTracer.Prove(s_key2.Bytes(), 0, proof) + assert.NoError(t, err) + // assert.Equal(t, len(sibling1), len(delTracer.GetProofs())) + + siblings, err := proofTracer.GetDeletionProofs() + assert.NoError(t, err) + assert.Equal(t, 0, len(siblings)) + + proofTracer.MarkDeletion(s_key1.Bytes()) + siblings, err = proofTracer.GetDeletionProofs() + assert.NoError(t, err) + assert.Equal(t, 1, len(siblings)) + l := len(siblings[0]) // a hacking to grep the value part directly from the encoded leaf node, // notice the sibling of key `k*32`` is just the leaf of key `m*32` - assert.Equal(t, sibling1[l-33:l-1], nd) + assert.Equal(t, siblings[0][l-33:l-1], nd) - s_key2, err := zkt.ToSecureKeyBytes(bytes.Repeat([]byte("x"), 32)) + // no effect + proofTracer.MarkDeletion(s_key2.Bytes()) + siblings, err = proofTracer.GetDeletionProofs() + assert.NoError(t, err) + assert.Equal(t, 1, len(siblings)) + + key3 := bytes.Repeat([]byte("x"), 32) + err = mt.UpdateWord( + zkt.NewByte32FromBytesPaddingZero(key3), + zkt.NewByte32FromBytesPaddingZero(bytes.Repeat([]byte("z"), 32)), + ) + assert.NoError(t, err) + + proofTracer = tr.NewProofTracer() + err = proofTracer.Prove(s_key1.Bytes(), 0, proof) + assert.NoError(t, err) + err = proofTracer.Prove(s_key2.Bytes(), 0, proof) + assert.NoError(t, err) + + proofTracer.MarkDeletion(s_key1.Bytes()) + siblings, err = proofTracer.GetDeletionProofs() assert.NoError(t, err) + assert.Equal(t, 1, len(siblings)) - sibling2, err := tr.ProveWithDeletion(s_key2.Bytes(), 0, proof) + proofTracer.MarkDeletion(s_key2.Bytes()) + siblings, err = proofTracer.GetDeletionProofs() assert.NoError(t, err) - assert.Nil(t, sibling2) + assert.Equal(t, 2, len(siblings)) + // one of the siblings is just leaf for key2, while + // another one must be a middle node + match1 := bytes.Equal(siblings[0][l-33:l-1], nd) + match2 := bytes.Equal(siblings[1][l-33:l-1], nd) + assert.True(t, match1 || match2) + assert.False(t, match1 && match2) } diff --git a/trie/zktrie_deletionproof.go b/trie/zktrie_deletionproof.go new file mode 100644 index 000000000..ebb8419e7 --- /dev/null +++ b/trie/zktrie_deletionproof.go @@ -0,0 +1,163 @@ +package trie + +import ( + "bytes" + + zktrie "github.com/scroll-tech/zktrie/trie" + zkt "github.com/scroll-tech/zktrie/types" + + "github.com/scroll-tech/go-ethereum/ethdb" +) + +// Pick Node from its hash directly from database, notice it has different +// interface with the function of same name in `trie` +func (t *ZkTrie) TryGetNode(nodeHash *zkt.Hash) (*zktrie.Node, error) { + if bytes.Equal(nodeHash[:], zkt.HashZero[:]) { + return zktrie.NewEmptyNode(), nil + } + nBytes, err := t.db.Get(nodeHash[:]) + if err == zktrie.ErrKeyNotFound { + return nil, zktrie.ErrKeyNotFound + } else if err != nil { + return nil, err + } + return zktrie.NewNodeFromBytes(nBytes) +} + +type ProofTracer struct { + *ZkTrie + deletionTracer map[zkt.Hash]struct{} + rawPaths map[string][]*zktrie.Node +} + +// NewProofTracer create a proof tracer object +func (t *ZkTrie) NewProofTracer() *ProofTracer { + return &ProofTracer{ + ZkTrie: t, + // always consider 0 is "deleted" + deletionTracer: map[zkt.Hash]struct{}{zkt.HashZero: {}}, + rawPaths: make(map[string][]*zktrie.Node), + } +} + +// Merge merge the input tracer into current and return current tracer +func (t *ProofTracer) Merge(another *ProofTracer) *ProofTracer { + + // sanity checking + if !bytes.Equal(t.Hash().Bytes(), another.Hash().Bytes()) { + panic("can not merge two proof tracer base on different trie") + } + + for k := range another.deletionTracer { + t.deletionTracer[k] = struct{}{} + } + + for k, v := range another.rawPaths { + t.rawPaths[k] = v + } + + return t +} + +// GetDeletionProofs generate current deletionTracer and collect deletion proofs +// which is possible to be used from all rawPaths, which enabling witness generator +// to predict the final state root after executing any deletion +// along any of the rawpath, no matter of the deletion occurs in any position of the mpt ops +// Note the collected sibling node has no key along with it since witness generator would +// always decode the node for its purpose +func (t *ProofTracer) GetDeletionProofs() ([][]byte, error) { + + retMap := map[zkt.Hash][]byte{} + + // check each path: reversively, skip the final leaf node + for _, path := range t.rawPaths { + + checkPath := path[:len(path)-1] + for i := len(checkPath); i > 0; i-- { + n := checkPath[i-1] + _, deletedL := t.deletionTracer[*n.ChildL] + _, deletedR := t.deletionTracer[*n.ChildR] + if deletedL && deletedR { + nodeHash, _ := n.NodeHash() + t.deletionTracer[*nodeHash] = struct{}{} + } else { + var siblingHash *zkt.Hash + if deletedL { + siblingHash = n.ChildR + } else if deletedR { + siblingHash = n.ChildL + } + if siblingHash != nil { + sibling, err := t.TryGetNode(siblingHash) + if err != nil { + return nil, err + } + if sibling.Type != zktrie.NodeTypeEmpty { + retMap[*siblingHash] = sibling.Value() + } + } + break + } + } + } + + var ret [][]byte + for _, bt := range retMap { + ret = append(ret, bt) + } + + return ret, nil + +} + +// MarkDeletion mark a key has been involved into deletion +func (t *ProofTracer) MarkDeletion(key []byte) { + if path, existed := t.rawPaths[string(key)]; existed { + // sanity check + leafNode := path[len(path)-1] + if leafNode.Type != zktrie.NodeTypeLeaf { + panic("all path recorded in proofTrace should be ended with leafNode") + } + + nodeHash, _ := leafNode.NodeHash() + t.deletionTracer[*nodeHash] = struct{}{} + } +} + +// Prove act the same as zktrie.Prove, while also collect the raw path +// for collecting deletion proofs in a post-work +func (t *ProofTracer) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error { + var mptPath []*zktrie.Node + err := t.ZkTrie.ProveWithDeletion(key, fromLevel, + func(n *zktrie.Node) error { + nodeHash, err := n.NodeHash() + if err != nil { + return err + } + + if n.Type == zktrie.NodeTypeLeaf { + preImage := t.GetKey(n.NodeKey.Bytes()) + if len(preImage) > 0 { + n.KeyPreimage = &zkt.Byte32{} + copy(n.KeyPreimage[:], preImage) + } + } else if n.Type == zktrie.NodeTypeParent { + mptPath = append(mptPath, n) + } + + return proofDb.Put(nodeHash[:], n.Value()) + }, + func(n *zktrie.Node, _ *zktrie.Node) { + // only "hit" path (i.e. the leaf node corresponding the input key can be found) + // would be add into tracer + mptPath = append(mptPath, n) + t.rawPaths[string(key)] = mptPath + }, + ) + if err != nil { + return err + } + // we put this special kv pair in db so we can distinguish the type and + // make suitable Proof + return proofDb.Put(magicHash, zktrie.ProofMagicBytes()) +}