mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-13 15:33:47 +00:00
Merge branch 'gethmaster' into gethintegration
Signed-off-by: Chen Kai <281165273grape@gmail.com>
This commit is contained in:
commit
d2edccaa5b
31 changed files with 742 additions and 297 deletions
|
|
@ -5,56 +5,56 @@
|
||||||
# https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/
|
# https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/
|
||||||
ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz
|
ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz
|
||||||
|
|
||||||
# version:golang 1.23.4
|
# version:golang 1.23.5
|
||||||
# https://go.dev/dl/
|
# https://go.dev/dl/
|
||||||
ad345ac421e90814293a9699cca19dd5238251c3f687980bbcae28495b263531 go1.23.4.src.tar.gz
|
a6f3f4bbd3e6bdd626f79b668f212fbb5649daf75084fb79b678a0ae4d97423b go1.23.5.src.tar.gz
|
||||||
459a09504f7ebf2cbcee6ac282c8f34f97651217b1feae64557dcdd392b9bb62 go1.23.4.aix-ppc64.tar.gz
|
8d8bc7d1b362dd91426da9352741db298ff73e3e0a3ccbe6f607f80ba17647a4 go1.23.5.aix-ppc64.tar.gz
|
||||||
0f4e569b2d38cb75cb2efcaf56beb42778ab5e46d89318fef39060fe36d7b9b7 go1.23.4.darwin-amd64.pkg
|
d8b310b0b6bd6a630307579165cfac8a37571483c7d6804a10dd73bbefb0827f go1.23.5.darwin-amd64.tar.gz
|
||||||
6700067389a53a1607d30aa8d6e01d198230397029faa0b109e89bc871ab5a0e go1.23.4.darwin-amd64.tar.gz
|
d2b06bf0b8299e0187dfe2d8ad39bd3dd96a6d93fe4d1cfd42c7872452f4a0a2 go1.23.5.darwin-amd64.pkg
|
||||||
19c054eaf40c5fac65b027f7443c01382e493d3c8c42cf8b2504832ebddce037 go1.23.4.darwin-arm64.pkg
|
047bfce4fbd0da6426bd30cd19716b35a466b1c15a45525ce65b9824acb33285 go1.23.5.darwin-arm64.tar.gz
|
||||||
87d2bb0ad4fe24d2a0685a55df321e0efe4296419a9b3de03369dbe60b8acd3a go1.23.4.darwin-arm64.tar.gz
|
f819ed94939e08a5016b9a607ec84ebbde6cb3fe59750c59d97aa300c3fd02df go1.23.5.darwin-arm64.pkg
|
||||||
5e73dc89b44626677ec9d9aa4257d6d2ef1245502bc36a99385284910d0ade0a go1.23.4.dragonfly-amd64.tar.gz
|
2dec52821e1f04a538d00b2cafe70fa506f2eea94a551bfe3ce1238f1bd4966f go1.23.5.dragonfly-amd64.tar.gz
|
||||||
8df26b1e71234756c1f0e82cfffba3f427c5a91a251844ada2c7694a6986c546 go1.23.4.freebsd-386.tar.gz
|
7204e7bc62913b12f18c61afe0bc1a92fd192c0e45a54125978592296cb84e49 go1.23.5.freebsd-386.tar.gz
|
||||||
7de078d94d2af50ee9506ef7df85e4d12d4018b23e0b2cbcbc61d686f549b41a go1.23.4.freebsd-amd64.tar.gz
|
90a119995ebc3e36082874df5fa8fe6da194946679d01ae8bef33c87aab99391 go1.23.5.freebsd-amd64.tar.gz
|
||||||
3f23e0a01cfe24e4160124cd7ab02bdd188264652074abdbce401c93f41e58a4 go1.23.4.freebsd-arm.tar.gz
|
255d26d873e41ff2fc278013bb2e5f25cf2ebe8d0ec84c07e3bb1436216020d3 go1.23.5.freebsd-arm.tar.gz
|
||||||
986a20e7c94431f03b44b3c415abc698c7b4edc2ae8431f7ecae1c2429d4cfa2 go1.23.4.freebsd-arm64.tar.gz
|
2785d9122654980b59ca38305a11b34f2a1e12d9f7eb41d52efc137c1fc29e61 go1.23.5.freebsd-arm64.tar.gz
|
||||||
25e39f005f977778ce963fc43089510fe7514f3cfc0358eab584de4ce9f181fb go1.23.4.freebsd-riscv64.tar.gz
|
8f66a94018ab666d56868f61c579aa81e549ac9700979ce6004445d315be2d37 go1.23.5.freebsd-riscv64.tar.gz
|
||||||
7e1d52f93da68c3bab39e3d83f89944d7d151208e54fdc30b0eda2a3812661d7 go1.23.4.illumos-amd64.tar.gz
|
4b7a69928385ec512a4e77a547e24118adbb92301d2be36187ff0852ba9e6303 go1.23.5.illumos-amd64.tar.gz
|
||||||
4a4a0e7587ef8c8a326439b957027f2791795e2d29d4ae3885b4091a48f843bc go1.23.4.linux-386.tar.gz
|
6ecf6a41d0925358905fa2641db0e1c9037aa5b5bcd26ca6734caf50d9196417 go1.23.5.linux-386.tar.gz
|
||||||
6924efde5de86fe277676e929dc9917d466efa02fb934197bc2eba35d5680971 go1.23.4.linux-amd64.tar.gz
|
cbcad4a6482107c7c7926df1608106c189417163428200ce357695cc7e01d091 go1.23.5.linux-amd64.tar.gz
|
||||||
16e5017863a7f6071363782b1b8042eb12c6ca4f4cd71528b2123f0a1275b13e go1.23.4.linux-arm64.tar.gz
|
47c84d332123883653b70da2db7dd57d2a865921ba4724efcdf56b5da7021db0 go1.23.5.linux-arm64.tar.gz
|
||||||
1f1dda0dc7ce0b2295f57258ec5ef0803fd31b9ed0aa20e2e9222334e5755de1 go1.23.4.linux-armv6l.tar.gz
|
04e0b5cf5c216f0aa1bf8204d49312ad0845800ab0702dfe4357c0b1241027a3 go1.23.5.linux-armv6l.tar.gz
|
||||||
4f469179a335a1a7bb9f991ad0c567f3d3eeb9b412ecd192206ab5c3e1a52b5a go1.23.4.linux-loong64.tar.gz
|
e1d14ac2207c78d52b76ba086da18a004c70aeb58cba72cd9bef0da7d1602786 go1.23.5.linux-loong64.tar.gz
|
||||||
86b68185bcc43ea07190e95137c3442f062acc7ae10c3f1cf900fbe23e07df24 go1.23.4.linux-mips.tar.gz
|
d9e937f2fac4fc863850fb4cc31ae76d5495029a62858ef09c78604472d354c0 go1.23.5.linux-mips.tar.gz
|
||||||
3a19245eec76533b3d01c90f3a40a38d63684028f0fd54d442dc9a9d03197891 go1.23.4.linux-mips64.tar.gz
|
59710d0782abafd47e40d1cf96aafa596bbdee09ac7c61062404604f49bd523e go1.23.5.linux-mips64.tar.gz
|
||||||
b53a06fc8455f6a875329e8d2e24d39db298122c9cce6e948117022191f6c613 go1.23.4.linux-mips64le.tar.gz
|
bc528cd836b4aa6701a42093ed390ef9929639a0e2818759887dc5539e517cab go1.23.5.linux-mips64le.tar.gz
|
||||||
66120a8105b8ba6559f4e6a13b1e39b433fb8032df9d1744e4486876fa1723ce go1.23.4.linux-mipsle.tar.gz
|
a0404764ea1fd4a175dc5193622b15be6ed1ab59cbfa478f5ae24531bafb6cbd go1.23.5.linux-mipsle.tar.gz
|
||||||
33be2bfb27f2821a65e9f6aba744c85ea7c5e233e16bac27bb3ec253bcd4e970 go1.23.4.linux-ppc64.tar.gz
|
db110284a0c91d4545273f210ca95b9f89f6e3ac90f39eb819033a6b96f25897 go1.23.5.linux-ppc64.tar.gz
|
||||||
65a303ef51e48ff77e004a6a5b4db6ce59495cd59c6af51b54bf4f786c01a1b9 go1.23.4.linux-ppc64le.tar.gz
|
db268bf5710b5b1b82ab38722ba6e4427d9e4942aed78c7d09195a9dff329613 go1.23.5.linux-ppc64le.tar.gz
|
||||||
7c40e9e0d722cef14ede765159ba297f4c6e3093bb106f10fbccf8564780049a go1.23.4.linux-riscv64.tar.gz
|
d9da15778442464f32acfa777ac731fd4d47362b233b83a0932380cb6d2d5dc8 go1.23.5.linux-riscv64.tar.gz
|
||||||
74aab82bf4eca7c26c830a5b0e2a31d193a4d5ba47045526b92473cc7188d7d7 go1.23.4.linux-s390x.tar.gz
|
14924b917d35311eb130e263f34931043d4f9dc65f20684301bf8f60a72edcdf go1.23.5.linux-s390x.tar.gz
|
||||||
dba009d8bf9928cb5a1e31fcbe0eb41335cce4fe63755d95cef6b5987df4ed5a go1.23.4.netbsd-386.tar.gz
|
7b8074102e7f039bd6473c44f58cb323c98dcda48df98ad1f78aaa2664769c8f go1.23.5.netbsd-386.tar.gz
|
||||||
54b081cc36355aa5ecb6db9544cf7e77366a7b08ce96cb98a45d043e393660c7 go1.23.4.netbsd-amd64.tar.gz
|
1a466b9c8900e66664b15c07548ecb156e8274cf1028ac5da84134728e6dbbed go1.23.5.netbsd-amd64.tar.gz
|
||||||
f05fec348c7c9f07e1ad4e436db4122e98de99ebcfbf6ac6176869785f334a02 go1.23.4.netbsd-arm.tar.gz
|
901c9e72038926e37a4dbde8f03d1d81fcb9992850901a3da1da5a25ef93e65b go1.23.5.netbsd-arm.tar.gz
|
||||||
317878da2bface5a57a8eaf5c1fe2b40b1c82d8172a10453ad3eea36f6946bdb go1.23.4.netbsd-arm64.tar.gz
|
221f69a7c3a920e3666633ee0b4e5c810176982e74339ba4693226996dc636e4 go1.23.5.netbsd-arm64.tar.gz
|
||||||
0d84350dfd72c505c6ad474e51676b04e95ffb748c614bd5bf8510026873059b go1.23.4.openbsd-386.tar.gz
|
42e46cbf73febb8e6ddf848765ce1c39573736383b132402cdc487eb6be3ad06 go1.23.5.openbsd-386.tar.gz
|
||||||
cc62f5a14ea3d573d8edbce1833f70a8f99ca048a9db0fcc9e738fd48e950505 go1.23.4.openbsd-amd64.tar.gz
|
f49e81fce17aab21800fab7c4b10c97ab02f8a9c807fdf8641ccf2f87d69289f go1.23.5.openbsd-amd64.tar.gz
|
||||||
326aba6cf5bb9348fa3e41217abd2c84eac92608684e2fe8c5474fdab23a0db9 go1.23.4.openbsd-arm.tar.gz
|
d8bd7269d4670a46e702b64822254a654824347c35923ef1c444d2e8687381ea go1.23.5.openbsd-arm.tar.gz
|
||||||
51ea2a2588bf3da8e1476f3e2bd4d6724d74126e99f9c6ea9af4ebe389e64de6 go1.23.4.openbsd-arm64.tar.gz
|
9cb259adff431d4d28b18e3348e26fe07ea10380675051dcfd740934b5e8b9f2 go1.23.5.openbsd-arm64.tar.gz
|
||||||
44c5c82ab23e40225b2ba1e7d19150a5973ea58e93b4931e426e6e6f0d108872 go1.23.4.openbsd-ppc64.tar.gz
|
72a03223c98fcecfb06e57c3edd584f99fb7f6574a42f59348473f354be1f379 go1.23.5.openbsd-ppc64.tar.gz
|
||||||
5fa31fc13d1e3c123a5e96ba38683fa2c947baed23ac9c7c341afcfe007c8993 go1.23.4.openbsd-riscv64.tar.gz
|
c06432b859afb36657207382b7bac03f961b8fafc18176b501d239575a9ace64 go1.23.5.openbsd-riscv64.tar.gz
|
||||||
e5952fc93eeaa0094ef09a0e72a9f06f0621ce841a39f9637fb5b9062e77d67a go1.23.4.plan9-386.tar.gz
|
b1f9b12b269ab5cd4aa7ae3dd3075c2407c1ea8bb1211e6835261f98931201cc go1.23.5.plan9-386.tar.gz
|
||||||
fb2a9ee3ae5a77e734862e257a9395b43e707ac45e060dfa84c5a40688e73170 go1.23.4.plan9-amd64.tar.gz
|
45b4026a103e2f6cd436e2b7ad24b24a40dd22c9903519b98b45c535574fa01a go1.23.5.plan9-amd64.tar.gz
|
||||||
e1b95563b19fdebd6ea0d20c07641e69580976fa754e586c831ad7a3ae987140 go1.23.4.plan9-arm.tar.gz
|
6e28e26f8c1e8620006490260aa5743198843aa0003c400cb65cbf5e743b21c7 go1.23.5.plan9-arm.tar.gz
|
||||||
088c282509fc9e1a8f29fc0dd16fe486854d05b8ceba08d077d17d11d6979a41 go1.23.4.solaris-amd64.tar.gz
|
0496c9969f208bd597f3e63fb27068ce1c7ed776618da1007fcc1c8be83ca413 go1.23.5.solaris-amd64.tar.gz
|
||||||
e5865c1bfc3fee5d003819b2e2c800f598fe9994931bac63f573e8d05a10d91f go1.23.4.windows-386.msi
|
8441605a005ea74c28d8c02ca5f2708c17b4df7e91796148b9f8760caafb05c1 go1.23.5.windows-386.zip
|
||||||
e544e0e356147ba998e267002bd0f2c4bf3370d495467a55baf2c63595a2026d go1.23.4.windows-386.zip
|
39962346d8d0cb0cc8716489ee33b08d7a220c24a9e45423487876dd4acbdac6 go1.23.5.windows-386.msi
|
||||||
5f8cc5991eb8f4f96b6c611d839453cd11c9a2c3f23672a4188342c97ee159fa go1.23.4.windows-amd64.msi
|
96d74945d7daeeb98a7978d0cf099321d7eb821b45f5c510373d545162d39c20 go1.23.5.windows-amd64.zip
|
||||||
16c59ac9196b63afb872ce9b47f945b9821a3e1542ec125f16f6085a1c0f3c39 go1.23.4.windows-amd64.zip
|
03e11a988a18ad7e3f9038cef836330af72ba0a454a502cda7b7faee07a0dd8a go1.23.5.windows-amd64.msi
|
||||||
fc77c0531406d092c5356167e45c05a22d16bea84e3fa555e0f03af085c11763 go1.23.4.windows-arm.msi
|
0005b31dcf9732c280a5cceb6aa1c5ab8284bc2541d0256c221256080acf2a09 go1.23.5.windows-arm.zip
|
||||||
1012cfd8ca7241c2beecb5c345dd61f01897c6f6baca80ea1bfed357035c868a go1.23.4.windows-arm.zip
|
a8442de35cbac230db8c4b20e363055671f2295dc4d6b2b2dfec66b89a3c4bce go1.23.5.windows-arm.msi
|
||||||
8347c1aa4e1e67954d12830f88dbe44bd7ac0ec134bb472783dbfb5a3a8865d0 go1.23.4.windows-arm64.msi
|
4f20c2d8a5a387c227e3ef48c5506b22906139d8afd8d66a78ef3de8dda1d1c3 go1.23.5.windows-arm64.zip
|
||||||
db69cae5006753c785345c3215ad941f8b6224e2f81fec471c42d6857bee0e6f go1.23.4.windows-arm64.zip
|
6f54fb46b669345c734936c521f7e0f55555e63ed6e11efbbaaed06f9514773c go1.23.5.windows-arm64.msi
|
||||||
|
|
||||||
# version:golangci 1.63.4
|
# version:golangci 1.63.4
|
||||||
# https://github.com/golangci/golangci-lint/releases/
|
# https://github.com/golangci/golangci-lint/releases/
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@
|
||||||
package t8ntool
|
package t8ntool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -35,7 +33,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -130,9 +127,7 @@ type rejectedTx struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply applies a set of transactions to a pre-state
|
// Apply applies a set of transactions to a pre-state
|
||||||
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txIt txIterator, miningReward int64) (*state.StateDB, *ExecutionResult, []byte, error) {
|
||||||
txIt txIterator, miningReward int64,
|
|
||||||
getTracerFn func(txIndex int, txHash common.Hash, chainConfig *params.ChainConfig) (*tracers.Tracer, io.WriteCloser, error)) (*state.StateDB, *ExecutionResult, []byte, error) {
|
|
||||||
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
||||||
// required blockhashes
|
// required blockhashes
|
||||||
var hashError error
|
var hashError error
|
||||||
|
|
@ -241,23 +236,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tracer, traceOutput, err := getTracerFn(txIndex, tx.Hash(), chainConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
// TODO (rjl493456442) it's a bit weird to reset the tracer in the
|
|
||||||
// middle of block execution, please improve it somehow.
|
|
||||||
if tracer != nil {
|
|
||||||
evm.SetTracer(tracer.Hooks)
|
|
||||||
}
|
|
||||||
statedb.SetTxContext(tx.Hash(), txIndex)
|
statedb.SetTxContext(tx.Hash(), txIndex)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
snapshot = statedb.Snapshot()
|
snapshot = statedb.Snapshot()
|
||||||
prevGas = gaspool.Gas()
|
prevGas = gaspool.Gas()
|
||||||
)
|
)
|
||||||
if tracer != nil && tracer.OnTxStart != nil {
|
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil {
|
||||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
}
|
}
|
||||||
// (ret []byte, usedGas uint64, failed bool, err error)
|
// (ret []byte, usedGas uint64, failed bool, err error)
|
||||||
msgResult, err := core.ApplyMessage(evm, msg, gaspool)
|
msgResult, err := core.ApplyMessage(evm, msg, gaspool)
|
||||||
|
|
@ -266,13 +251,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err)
|
log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err)
|
||||||
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
||||||
gaspool.SetGas(prevGas)
|
gaspool.SetGas(prevGas)
|
||||||
if tracer != nil {
|
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil {
|
||||||
if tracer.OnTxEnd != nil {
|
evm.Config.Tracer.OnTxEnd(nil, err)
|
||||||
tracer.OnTxEnd(nil, err)
|
|
||||||
}
|
|
||||||
if err := writeTraceResult(tracer, traceOutput); err != nil {
|
|
||||||
log.Warn("Error writing tracer output", "err", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -316,13 +296,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
//receipt.BlockNumber
|
//receipt.BlockNumber
|
||||||
receipt.TransactionIndex = uint(txIndex)
|
receipt.TransactionIndex = uint(txIndex)
|
||||||
receipts = append(receipts, receipt)
|
receipts = append(receipts, receipt)
|
||||||
if tracer != nil {
|
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil {
|
||||||
if tracer.Hooks.OnTxEnd != nil {
|
evm.Config.Tracer.OnTxEnd(receipt, nil)
|
||||||
tracer.Hooks.OnTxEnd(receipt, nil)
|
|
||||||
}
|
|
||||||
if err = writeTraceResult(tracer, traceOutput); err != nil {
|
|
||||||
log.Warn("Error writing tracer output", "err", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -468,16 +443,3 @@ func calcDifficulty(config *params.ChainConfig, number, currentTime, parentTime
|
||||||
}
|
}
|
||||||
return ethash.CalcDifficulty(config, currentTime, parent)
|
return ethash.CalcDifficulty(config, currentTime, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTraceResult(tracer *tracers.Tracer, f io.WriteCloser) error {
|
|
||||||
defer f.Close()
|
|
||||||
result, err := tracer.GetResult()
|
|
||||||
if err != nil || result == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = json.NewEncoder(f).Encode(result)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
152
cmd/evm/internal/t8ntool/file_tracer.go
Normal file
152
cmd/evm/internal/t8ntool/file_tracer.go
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
// Copyright 2024 The go-ethereum Authors
|
||||||
|
// This file is part of go-ethereum.
|
||||||
|
//
|
||||||
|
// go-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// go-ethereum is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package t8ntool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fileWritingTracer wraps either a tracer or a logger. On tx start,
|
||||||
|
// it instantiates a tracer/logger, creates a new file to direct output to,
|
||||||
|
// and on tx end it closes the file.
|
||||||
|
type fileWritingTracer struct {
|
||||||
|
txIndex int // transaction counter
|
||||||
|
inner *tracing.Hooks // inner hooks
|
||||||
|
destination io.WriteCloser // the currently open file (if any)
|
||||||
|
baseDir string // baseDir to write output-files to
|
||||||
|
suffix string // suffix is the suffix to use when creating files
|
||||||
|
|
||||||
|
// for custom tracing
|
||||||
|
getResult func() (json.RawMessage, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *fileWritingTracer) Write(p []byte) (n int, err error) {
|
||||||
|
if l.destination != nil {
|
||||||
|
return l.destination.Write(p)
|
||||||
|
}
|
||||||
|
log.Warn("Tracer wrote to non-existing output")
|
||||||
|
// It is tempting to return an error here, however, the json encoder
|
||||||
|
// will no retry writing to an io.Writer once it has returned an error once.
|
||||||
|
// Therefore, we must squash the error.
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newFileWriter creates a set of hooks which wraps inner hooks (typically a logger),
|
||||||
|
// and writes the output to a file, one file per transaction.
|
||||||
|
func newFileWriter(baseDir string, innerFn func(out io.Writer) *tracing.Hooks) *tracing.Hooks {
|
||||||
|
t := &fileWritingTracer{
|
||||||
|
baseDir: baseDir,
|
||||||
|
suffix: "jsonl",
|
||||||
|
}
|
||||||
|
t.inner = innerFn(t) // instantiate the inner tracer
|
||||||
|
return t.hooks()
|
||||||
|
}
|
||||||
|
|
||||||
|
// newResultWriter creates a set of hooks wraps and invokes an underlying tracer,
|
||||||
|
// and writes the result (getResult-output) to file, one per transaction.
|
||||||
|
func newResultWriter(baseDir string, tracer *tracers.Tracer) *tracing.Hooks {
|
||||||
|
t := &fileWritingTracer{
|
||||||
|
baseDir: baseDir,
|
||||||
|
getResult: tracer.GetResult,
|
||||||
|
inner: tracer.Hooks,
|
||||||
|
suffix: "json",
|
||||||
|
}
|
||||||
|
return t.hooks()
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnTxStart creates a new output-file specific for this transaction, and invokes
|
||||||
|
// the inner OnTxStart handler.
|
||||||
|
func (l *fileWritingTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) {
|
||||||
|
// Open a new file, or print a warning log if it's failed
|
||||||
|
fname := filepath.Join(l.baseDir, fmt.Sprintf("trace-%d-%v.%v", l.txIndex, tx.Hash().String(), l.suffix))
|
||||||
|
traceFile, err := os.Create(fname)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Failed creating trace-file", "err", err)
|
||||||
|
} else {
|
||||||
|
log.Info("Created tracing-file", "path", fname)
|
||||||
|
l.destination = traceFile
|
||||||
|
}
|
||||||
|
if l.inner != nil && l.inner.OnTxStart != nil {
|
||||||
|
l.inner.OnTxStart(env, tx, from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnTxEnd writes result (if getResult exist), closes any currently open output-file,
|
||||||
|
// and invokes the inner OnTxEnd handler.
|
||||||
|
func (l *fileWritingTracer) OnTxEnd(receipt *types.Receipt, err error) {
|
||||||
|
if l.inner != nil && l.inner.OnTxEnd != nil {
|
||||||
|
l.inner.OnTxEnd(receipt, err)
|
||||||
|
}
|
||||||
|
if l.getResult != nil && l.destination != nil {
|
||||||
|
if result, err := l.getResult(); result != nil {
|
||||||
|
json.NewEncoder(l.destination).Encode(result)
|
||||||
|
} else {
|
||||||
|
log.Warn("Error obtaining tracer result", "err", err)
|
||||||
|
}
|
||||||
|
l.destination.Close()
|
||||||
|
l.destination = nil
|
||||||
|
}
|
||||||
|
l.txIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *fileWritingTracer) hooks() *tracing.Hooks {
|
||||||
|
return &tracing.Hooks{
|
||||||
|
OnTxStart: l.OnTxStart,
|
||||||
|
OnTxEnd: l.OnTxEnd,
|
||||||
|
OnEnter: func(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
||||||
|
if l.inner != nil && l.inner.OnEnter != nil {
|
||||||
|
l.inner.OnEnter(depth, typ, from, to, input, gas, value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OnExit: func(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
|
||||||
|
if l.inner != nil && l.inner.OnExit != nil {
|
||||||
|
l.inner.OnExit(depth, output, gasUsed, err, reverted)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OnOpcode: func(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
|
||||||
|
if l.inner != nil && l.inner.OnOpcode != nil {
|
||||||
|
l.inner.OnOpcode(pc, op, gas, cost, scope, rData, depth, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OnFault: func(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error) {
|
||||||
|
if l.inner != nil && l.inner.OnFault != nil {
|
||||||
|
l.inner.OnFault(pc, op, gas, cost, scope, depth, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OnSystemCallStart: func() {
|
||||||
|
if l.inner != nil && l.inner.OnSystemCallStart != nil {
|
||||||
|
l.inner.OnSystemCallStart()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OnSystemCallEnd: func() {
|
||||||
|
if l.inner != nil && l.inner.OnSystemCallEnd != nil {
|
||||||
|
l.inner.OnSystemCallEnd()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -64,12 +64,10 @@ func (r *result) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Transaction(ctx *cli.Context) error {
|
func Transaction(ctx *cli.Context) error {
|
||||||
var (
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
// We need to load the transactions. May be either in stdin input or in files.
|
// We need to load the transactions. May be either in stdin input or in files.
|
||||||
// Check if anything needs to be read from stdin
|
// Check if anything needs to be read from stdin
|
||||||
var (
|
var (
|
||||||
|
err error
|
||||||
txStr = ctx.String(InputTxsFlag.Name)
|
txStr = ctx.String(InputTxsFlag.Name)
|
||||||
inputData = &input{}
|
inputData = &input{}
|
||||||
chainConfig *params.ChainConfig
|
chainConfig *params.ChainConfig
|
||||||
|
|
@ -82,6 +80,7 @@ func Transaction(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
// Set the chain id
|
// Set the chain id
|
||||||
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
||||||
|
|
||||||
var body hexutil.Bytes
|
var body hexutil.Bytes
|
||||||
if txStr == stdinSelector {
|
if txStr == stdinSelector {
|
||||||
decoder := json.NewDecoder(os.Stdin)
|
decoder := json.NewDecoder(os.Stdin)
|
||||||
|
|
@ -107,6 +106,7 @@ func Transaction(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(chainConfig, new(big.Int), 0)
|
signer := types.MakeSigner(chainConfig, new(big.Int), 0)
|
||||||
|
|
||||||
// We now have the transactions in 'body', which is supposed to be an
|
// We now have the transactions in 'body', which is supposed to be an
|
||||||
// rlp list of transactions
|
// rlp list of transactions
|
||||||
it, err := rlp.NewListIterator([]byte(body))
|
it, err := rlp.NewListIterator([]byte(body))
|
||||||
|
|
|
||||||
|
|
@ -82,58 +82,10 @@ type input struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Transition(ctx *cli.Context) error {
|
func Transition(ctx *cli.Context) error {
|
||||||
var getTracer = func(txIndex int, txHash common.Hash, chainConfig *params.ChainConfig) (*tracers.Tracer, io.WriteCloser, error) {
|
|
||||||
return nil, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
baseDir, err := createBasedir(ctx)
|
baseDir, err := createBasedir(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Bool(TraceFlag.Name) { // JSON opcode tracing
|
|
||||||
// Configure the EVM logger
|
|
||||||
logConfig := &logger.Config{
|
|
||||||
DisableStack: ctx.Bool(TraceDisableStackFlag.Name),
|
|
||||||
EnableMemory: ctx.Bool(TraceEnableMemoryFlag.Name),
|
|
||||||
EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name),
|
|
||||||
}
|
|
||||||
getTracer = func(txIndex int, txHash common.Hash, _ *params.ChainConfig) (*tracers.Tracer, io.WriteCloser, error) {
|
|
||||||
traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String())))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
|
||||||
}
|
|
||||||
var l *tracing.Hooks
|
|
||||||
if ctx.Bool(TraceEnableCallFramesFlag.Name) {
|
|
||||||
l = logger.NewJSONLoggerWithCallFrames(logConfig, traceFile)
|
|
||||||
} else {
|
|
||||||
l = logger.NewJSONLogger(logConfig, traceFile)
|
|
||||||
}
|
|
||||||
tracer := &tracers.Tracer{
|
|
||||||
Hooks: l,
|
|
||||||
// jsonLogger streams out result to file.
|
|
||||||
GetResult: func() (json.RawMessage, error) { return nil, nil },
|
|
||||||
Stop: func(err error) {},
|
|
||||||
}
|
|
||||||
return tracer, traceFile, nil
|
|
||||||
}
|
|
||||||
} else if ctx.IsSet(TraceTracerFlag.Name) {
|
|
||||||
var config json.RawMessage
|
|
||||||
if ctx.IsSet(TraceTracerConfigFlag.Name) {
|
|
||||||
config = []byte(ctx.String(TraceTracerConfigFlag.Name))
|
|
||||||
}
|
|
||||||
getTracer = func(txIndex int, txHash common.Hash, chainConfig *params.ChainConfig) (*tracers.Tracer, io.WriteCloser, error) {
|
|
||||||
traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String())))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
|
|
||||||
}
|
|
||||||
tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config, chainConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err))
|
|
||||||
}
|
|
||||||
return tracer, traceFile, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// We need to load three things: alloc, env and transactions. May be either in
|
// We need to load three things: alloc, env and transactions. May be either in
|
||||||
// stdin input or in files.
|
// stdin input or in files.
|
||||||
// Check if anything needs to be read from stdin
|
// Check if anything needs to be read from stdin
|
||||||
|
|
@ -179,6 +131,7 @@ func Transition(ctx *cli.Context) error {
|
||||||
chainConfig = cConf
|
chainConfig = cConf
|
||||||
vmConfig.ExtraEips = extraEips
|
vmConfig.ExtraEips = extraEips
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the chain id
|
// Set the chain id
|
||||||
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
||||||
|
|
||||||
|
|
@ -197,8 +150,34 @@ func Transition(ctx *cli.Context) error {
|
||||||
if err := applyCancunChecks(&prestate.Env, chainConfig); err != nil {
|
if err := applyCancunChecks(&prestate.Env, chainConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Configure tracer
|
||||||
|
if ctx.IsSet(TraceTracerFlag.Name) { // Custom tracing
|
||||||
|
config := json.RawMessage(ctx.String(TraceTracerConfigFlag.Name))
|
||||||
|
tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name),
|
||||||
|
nil, config, chainConfig)
|
||||||
|
if err != nil {
|
||||||
|
return NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %v", err))
|
||||||
|
}
|
||||||
|
vmConfig.Tracer = newResultWriter(baseDir, tracer)
|
||||||
|
} else if ctx.Bool(TraceFlag.Name) { // JSON opcode tracing
|
||||||
|
logConfig := &logger.Config{
|
||||||
|
DisableStack: ctx.Bool(TraceDisableStackFlag.Name),
|
||||||
|
EnableMemory: ctx.Bool(TraceEnableMemoryFlag.Name),
|
||||||
|
EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name),
|
||||||
|
}
|
||||||
|
if ctx.Bool(TraceEnableCallFramesFlag.Name) {
|
||||||
|
vmConfig.Tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks {
|
||||||
|
return logger.NewJSONLoggerWithCallFrames(logConfig, out)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
vmConfig.Tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks {
|
||||||
|
return logger.NewJSONLogger(logConfig, out)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
// Run the test and aggregate the result
|
// Run the test and aggregate the result
|
||||||
s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name), getTracer)
|
s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,8 @@ var (
|
||||||
}
|
}
|
||||||
TraceFormatFlag = &cli.StringFlag{
|
TraceFormatFlag = &cli.StringFlag{
|
||||||
Name: "trace.format",
|
Name: "trace.format",
|
||||||
Usage: "Trace output format to use (struct|json)",
|
Usage: "Trace output format to use (json|struct|md)",
|
||||||
Value: "struct",
|
Value: "json",
|
||||||
Category: traceCategory,
|
Category: traceCategory,
|
||||||
}
|
}
|
||||||
TraceDisableMemoryFlag = &cli.BoolFlag{
|
TraceDisableMemoryFlag = &cli.BoolFlag{
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ var stateTestCommand = &cli.Command{
|
||||||
Usage: "Executes the given state tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution).",
|
Usage: "Executes the given state tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution).",
|
||||||
ArgsUsage: "<file>",
|
ArgsUsage: "<file>",
|
||||||
Flags: slices.Concat([]cli.Flag{
|
Flags: slices.Concat([]cli.Flag{
|
||||||
|
BenchFlag,
|
||||||
DumpFlag,
|
DumpFlag,
|
||||||
HumanReadableFlag,
|
HumanReadableFlag,
|
||||||
RunFlag,
|
RunFlag,
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
|
@ -606,18 +607,18 @@ func TestEvmRun(t *testing.T) {
|
||||||
wantStdout: "./testdata/evmrun/1.out.1.txt",
|
wantStdout: "./testdata/evmrun/1.out.1.txt",
|
||||||
wantStderr: "./testdata/evmrun/1.out.2.txt",
|
wantStderr: "./testdata/evmrun/1.out.2.txt",
|
||||||
},
|
},
|
||||||
{ // default tracing (struct)
|
{ // Struct tracing
|
||||||
input: []string{"run", "--trace", "0x6040"},
|
input: []string{"run", "--trace", "--trace.format=struct", "0x6040"},
|
||||||
wantStdout: "./testdata/evmrun/2.out.1.txt",
|
wantStdout: "./testdata/evmrun/2.out.1.txt",
|
||||||
wantStderr: "./testdata/evmrun/2.out.2.txt",
|
wantStderr: "./testdata/evmrun/2.out.2.txt",
|
||||||
},
|
},
|
||||||
{ // default tracing (struct), plus alloc-dump
|
{ // struct-tracing, plus alloc-dump
|
||||||
input: []string{"run", "--trace", "--dump", "0x6040"},
|
input: []string{"run", "--trace", "--trace.format=struct", "--dump", "0x6040"},
|
||||||
wantStdout: "./testdata/evmrun/3.out.1.txt",
|
wantStdout: "./testdata/evmrun/3.out.1.txt",
|
||||||
//wantStderr: "./testdata/evmrun/3.out.2.txt",
|
//wantStderr: "./testdata/evmrun/3.out.2.txt",
|
||||||
},
|
},
|
||||||
{ // json-tracing, plus alloc-dump
|
{ // json-tracing (default), plus alloc-dump
|
||||||
input: []string{"run", "--trace", "--trace.format=json", "--dump", "0x6040"},
|
input: []string{"run", "--trace", "--dump", "0x6040"},
|
||||||
wantStdout: "./testdata/evmrun/4.out.1.txt",
|
wantStdout: "./testdata/evmrun/4.out.1.txt",
|
||||||
//wantStderr: "./testdata/evmrun/4.out.2.txt",
|
//wantStderr: "./testdata/evmrun/4.out.2.txt",
|
||||||
},
|
},
|
||||||
|
|
@ -670,6 +671,61 @@ func TestEvmRun(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEvmRunRegEx(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
tt := cmdtest.NewTestCmd(t, nil)
|
||||||
|
for i, tc := range []struct {
|
||||||
|
input []string
|
||||||
|
wantStdout string
|
||||||
|
wantStderr string
|
||||||
|
}{
|
||||||
|
{ // json tracing
|
||||||
|
input: []string{"run", "--bench", "6040"},
|
||||||
|
wantStdout: "./testdata/evmrun/9.out.1.txt",
|
||||||
|
wantStderr: "./testdata/evmrun/9.out.2.txt",
|
||||||
|
},
|
||||||
|
{ // statetest subcommand
|
||||||
|
input: []string{"statetest", "--bench", "./testdata/statetest.json"},
|
||||||
|
wantStdout: "./testdata/evmrun/10.out.1.txt",
|
||||||
|
wantStderr: "./testdata/evmrun/10.out.2.txt",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
tt.Logf("args: go run ./cmd/evm %v\n", strings.Join(tc.input, " "))
|
||||||
|
tt.Run("evm-test", tc.input...)
|
||||||
|
|
||||||
|
haveStdOut := tt.Output()
|
||||||
|
tt.WaitExit()
|
||||||
|
haveStdErr := tt.StderrText()
|
||||||
|
|
||||||
|
if have, wantFile := haveStdOut, tc.wantStdout; wantFile != "" {
|
||||||
|
want, err := os.ReadFile(wantFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("test %d: could not read expected output: %v", i, err)
|
||||||
|
}
|
||||||
|
re, err := regexp.Compile(string(want))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("test %d: could not compile regular expression: %v", i, err)
|
||||||
|
}
|
||||||
|
if !re.Match(have) {
|
||||||
|
t.Fatalf("test %d, output wrong, have \n%v\nwant\n%v\n", i, string(have), re)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if have, wantFile := haveStdErr, tc.wantStderr; wantFile != "" {
|
||||||
|
want, err := os.ReadFile(wantFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("test %d: could not read expected output: %v", i, err)
|
||||||
|
}
|
||||||
|
re, err := regexp.Compile(string(want))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("test %d: could not compile regular expression: %v", i, err)
|
||||||
|
}
|
||||||
|
if !re.MatchString(have) {
|
||||||
|
t.Fatalf("test %d, output wrong, have \n%v\nwant\n%v\n", i, have, re)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cmpJson compares the JSON in two byte slices.
|
// cmpJson compares the JSON in two byte slices.
|
||||||
func cmpJson(a, b []byte) (bool, error) {
|
func cmpJson(a, b []byte) (bool, error) {
|
||||||
var j, j2 interface{}
|
var j, j2 interface{}
|
||||||
|
|
@ -698,7 +754,10 @@ func TestEVMTracing(t *testing.T) {
|
||||||
"--input.env=./testdata/31/env.json", "--state.fork=Cancun",
|
"--input.env=./testdata/31/env.json", "--state.fork=Cancun",
|
||||||
"--trace",
|
"--trace",
|
||||||
},
|
},
|
||||||
expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl"},
|
//expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl"},
|
||||||
|
expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl",
|
||||||
|
"trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl",
|
||||||
|
"trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.jsonl"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
base: "./testdata/31",
|
base: "./testdata/31",
|
||||||
|
|
@ -706,14 +765,17 @@ func TestEVMTracing(t *testing.T) {
|
||||||
"--input.alloc=./testdata/31/alloc.json", "--input.txs=./testdata/31/txs.json",
|
"--input.alloc=./testdata/31/alloc.json", "--input.txs=./testdata/31/txs.json",
|
||||||
"--input.env=./testdata/31/env.json", "--state.fork=Cancun",
|
"--input.env=./testdata/31/env.json", "--state.fork=Cancun",
|
||||||
"--trace.tracer", `
|
"--trace.tracer", `
|
||||||
{
|
{ count: 0,
|
||||||
result: function(){
|
result: function(){
|
||||||
return "hello world"
|
this.count = this.count + 1;
|
||||||
|
return "hello world " + this.count
|
||||||
},
|
},
|
||||||
fault: function(){}
|
fault: function(){}
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json"},
|
expectedTraces: []string{"trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.json",
|
||||||
|
"trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.json",
|
||||||
|
"trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.json"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
base: "./testdata/32",
|
base: "./testdata/32",
|
||||||
|
|
|
||||||
10
cmd/evm/testdata/31/README.md
vendored
10
cmd/evm/testdata/31/README.md
vendored
|
|
@ -1 +1,11 @@
|
||||||
This test does some EVM execution, and can be used to test the tracers and trace-outputs.
|
This test does some EVM execution, and can be used to test the tracers and trace-outputs.
|
||||||
|
This test should yield three output-traces, in separate files
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```
|
||||||
|
[user@work evm]$ go run . t8n --input.alloc ./testdata/31/alloc.json --input.txs ./testdata/31/txs.json --input.env ./testdata/31/env.json --state.fork Cancun --output.basedir /tmp --trace
|
||||||
|
INFO [12-06|09:53:32.123] Created tracing-file path=/tmp/trace-0-0x88f5fbd1524731a81e49f637aa847543268a5aaf2a6b32a69d2c6d978c45dcfb.jsonl
|
||||||
|
INFO [12-06|09:53:32.124] Created tracing-file path=/tmp/trace-1-0x03a7b0a91e61a170d64ea94b8263641ef5a8bbdb10ac69f466083a6789c77fb8.jsonl
|
||||||
|
INFO [12-06|09:53:32.125] Created tracing-file path=/tmp/trace-2-0xd96e0ce6418ee3360e11d3c7b6886f5a9a08f7ef183da72c23bb3b2374530128.jsonl
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
"hello world"
|
"hello world 1"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"hello world 2"
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{"pc":0,"op":96,"gas":"0x13498","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":2,"op":96,"gas":"0x13495","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":4,"op":96,"gas":"0x13492","gasCost":"0x3","memSize":0,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":6,"op":96,"gas":"0x1348f","gasCost":"0x3","memSize":0,"stack":["0x40","0x40","0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":8,"op":0,"gas":"0x1348c","gasCost":"0x0","memSize":0,"stack":["0x40","0x40","0x40","0x40"],"depth":1,"refund":0,"opName":"STOP"}
|
||||||
|
{"output":"","gasUsed":"0xc"}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"hello world 3"
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{"pc":0,"op":96,"gas":"0x13498","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":2,"op":96,"gas":"0x13495","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":4,"op":96,"gas":"0x13492","gasCost":"0x3","memSize":0,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":6,"op":96,"gas":"0x1348f","gasCost":"0x3","memSize":0,"stack":["0x40","0x40","0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
|
||||||
|
{"pc":8,"op":0,"gas":"0x1348c","gasCost":"0x0","memSize":0,"stack":["0x40","0x40","0x40","0x40"],"depth":1,"refund":0,"opName":"STOP"}
|
||||||
|
{"output":"","gasUsed":"0xc"}
|
||||||
24
cmd/evm/testdata/31/txs.json
vendored
24
cmd/evm/testdata/31/txs.json
vendored
|
|
@ -10,5 +10,29 @@
|
||||||
"r" : "0x0",
|
"r" : "0x0",
|
||||||
"s" : "0x0",
|
"s" : "0x0",
|
||||||
"secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
"secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gas": "0x186a0",
|
||||||
|
"gasPrice": "0x600",
|
||||||
|
"input": "0x",
|
||||||
|
"nonce": "0x1",
|
||||||
|
"to": "0x1111111111111111111111111111111111111111",
|
||||||
|
"value": "0x1",
|
||||||
|
"v" : "0x0",
|
||||||
|
"r" : "0x0",
|
||||||
|
"s" : "0x0",
|
||||||
|
"secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gas": "0x186a0",
|
||||||
|
"gasPrice": "0x600",
|
||||||
|
"input": "0x",
|
||||||
|
"nonce": "0x2",
|
||||||
|
"to": "0x1111111111111111111111111111111111111111",
|
||||||
|
"value": "0x1",
|
||||||
|
"v" : "0x0",
|
||||||
|
"r" : "0x0",
|
||||||
|
"s" : "0x0",
|
||||||
|
"secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
15
cmd/evm/testdata/evmrun/10.out.1.txt
vendored
Normal file
15
cmd/evm/testdata/evmrun/10.out.1.txt
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
\[
|
||||||
|
\{
|
||||||
|
"name": "00000006-naivefuzz-0",
|
||||||
|
"pass": false,
|
||||||
|
"stateRoot": "0xad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458",
|
||||||
|
"fork": "London",
|
||||||
|
"error": "post state root mismatch: got ad1024c87b5548e77c937aa50f72b6cb620d278f4dd79bae7f78f71ff75af458, want 0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"benchStats": \{
|
||||||
|
"time": \d+,
|
||||||
|
"allocs": \d+,
|
||||||
|
"bytesAllocated": \d+,
|
||||||
|
"gasUsed": \d+
|
||||||
|
\}
|
||||||
|
\}
|
||||||
|
\]
|
||||||
0
cmd/evm/testdata/evmrun/10.out.2.txt
vendored
Normal file
0
cmd/evm/testdata/evmrun/10.out.2.txt
vendored
Normal file
0
cmd/evm/testdata/evmrun/9.out.1.txt
vendored
Normal file
0
cmd/evm/testdata/evmrun/9.out.1.txt
vendored
Normal file
4
cmd/evm/testdata/evmrun/9.out.2.txt
vendored
Normal file
4
cmd/evm/testdata/evmrun/9.out.2.txt
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
EVM gas used: \d+
|
||||||
|
execution time: \d+\.\d+.s
|
||||||
|
allocations: \d+
|
||||||
|
allocated bytes: \d+
|
||||||
|
|
@ -224,7 +224,10 @@ func (p *TxPool) loop(head *types.Header, chain BlockChain) {
|
||||||
for _, subpool := range p.subpools {
|
for _, subpool := range p.subpools {
|
||||||
subpool.Reset(oldHead, newHead)
|
subpool.Reset(oldHead, newHead)
|
||||||
}
|
}
|
||||||
resetDone <- newHead
|
select {
|
||||||
|
case resetDone <- newHead:
|
||||||
|
case <-p.term:
|
||||||
|
}
|
||||||
}(oldHead, newHead)
|
}(oldHead, newHead)
|
||||||
|
|
||||||
// If the reset operation was explicitly requested, consider it
|
// If the reset operation was explicitly requested, consider it
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big
|
||||||
}
|
}
|
||||||
// Check that chain ID of tx matches the signer. We also accept ID zero here,
|
// Check that chain ID of tx matches the signer. We also accept ID zero here,
|
||||||
// because it indicates that the chain ID was not specified in the tx.
|
// because it indicates that the chain ID was not specified in the tx.
|
||||||
if txdata.ChainID != nil && txdata.ChainID.CmpBig(s.chainId) != 0 {
|
if txdata.ChainID.Sign() != 0 && txdata.ChainID.CmpBig(s.chainId) != 0 {
|
||||||
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
|
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
|
||||||
}
|
}
|
||||||
R, S, _ = decodeSignature(sig)
|
R, S, _ = decodeSignature(sig)
|
||||||
|
|
@ -287,7 +287,7 @@ func (s cancunSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big
|
||||||
}
|
}
|
||||||
// Check that chain ID of tx matches the signer. We also accept ID zero here,
|
// Check that chain ID of tx matches the signer. We also accept ID zero here,
|
||||||
// because it indicates that the chain ID was not specified in the tx.
|
// because it indicates that the chain ID was not specified in the tx.
|
||||||
if txdata.ChainID.Sign() != 0 && txdata.ChainID.ToBig().Cmp(s.chainId) != 0 {
|
if txdata.ChainID.Sign() != 0 && txdata.ChainID.CmpBig(s.chainId) != 0 {
|
||||||
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
|
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
|
||||||
}
|
}
|
||||||
R, S, _ = decodeSignature(sig)
|
R, S, _ = decodeSignature(sig)
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ func (tx *SetCodeTx) copy() TxData {
|
||||||
AccessList: make(AccessList, len(tx.AccessList)),
|
AccessList: make(AccessList, len(tx.AccessList)),
|
||||||
AuthList: make([]SetCodeAuthorization, len(tx.AuthList)),
|
AuthList: make([]SetCodeAuthorization, len(tx.AuthList)),
|
||||||
Value: new(uint256.Int),
|
Value: new(uint256.Int),
|
||||||
ChainID: tx.ChainID,
|
ChainID: new(uint256.Int),
|
||||||
GasTipCap: new(uint256.Int),
|
GasTipCap: new(uint256.Int),
|
||||||
GasFeeCap: new(uint256.Int),
|
GasFeeCap: new(uint256.Int),
|
||||||
V: new(uint256.Int),
|
V: new(uint256.Int),
|
||||||
|
|
@ -160,6 +160,9 @@ func (tx *SetCodeTx) copy() TxData {
|
||||||
if tx.Value != nil {
|
if tx.Value != nil {
|
||||||
cpy.Value.Set(tx.Value)
|
cpy.Value.Set(tx.Value)
|
||||||
}
|
}
|
||||||
|
if tx.ChainID != nil {
|
||||||
|
cpy.ChainID.Set(tx.ChainID)
|
||||||
|
}
|
||||||
if tx.GasTipCap != nil {
|
if tx.GasTipCap != nil {
|
||||||
cpy.GasTipCap.Set(tx.GasTipCap)
|
cpy.GasTipCap.Set(tx.GasTipCap)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,11 +133,6 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
|
||||||
return evm
|
return evm
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTracer sets the tracer for following state transition.
|
|
||||||
func (evm *EVM) SetTracer(tracer *tracing.Hooks) {
|
|
||||||
evm.Config.Tracer = tracer
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPrecompiles sets the precompiled contracts for the EVM.
|
// SetPrecompiles sets the precompiled contracts for the EVM.
|
||||||
// This method is only used through RPC calls.
|
// This method is only used through RPC calls.
|
||||||
// It is not thread-safe.
|
// It is not thread-safe.
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,11 @@ func (api *FilterAPI) timeoutLoop(timeout time.Duration) {
|
||||||
ticker := time.NewTicker(timeout)
|
ticker := time.NewTicker(timeout)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
for {
|
for {
|
||||||
<-ticker.C
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
case <-api.events.chainSub.Err():
|
||||||
|
return
|
||||||
|
}
|
||||||
api.filtersMu.Lock()
|
api.filtersMu.Lock()
|
||||||
for id, f := range api.filters {
|
for id, f := range api.filters {
|
||||||
select {
|
select {
|
||||||
|
|
|
||||||
16
go.mod
16
go.mod
|
|
@ -1,8 +1,6 @@
|
||||||
module github.com/ethereum/go-ethereum
|
module github.com/ethereum/go-ethereum
|
||||||
|
|
||||||
go 1.22
|
go 1.22.0
|
||||||
|
|
||||||
toolchain go1.22.0
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
|
||||||
|
|
@ -27,7 +25,7 @@ require (
|
||||||
github.com/ethereum/go-verkle v0.2.2
|
github.com/ethereum/go-verkle v0.2.2
|
||||||
github.com/fatih/color v1.16.0
|
github.com/fatih/color v1.16.0
|
||||||
github.com/ferranbt/fastssz v0.1.2
|
github.com/ferranbt/fastssz v0.1.2
|
||||||
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e
|
github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4
|
||||||
github.com/fsnotify/fsnotify v1.6.0
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
|
||||||
github.com/gofrs/flock v0.8.1
|
github.com/gofrs/flock v0.8.1
|
||||||
|
|
@ -65,13 +63,13 @@ require (
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
||||||
github.com/urfave/cli/v2 v2.25.7
|
github.com/urfave/cli/v2 v2.25.7
|
||||||
go.uber.org/automaxprocs v1.5.2
|
go.uber.org/automaxprocs v1.5.2
|
||||||
golang.org/x/crypto v0.31.0
|
golang.org/x/crypto v0.32.0
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||||
golang.org/x/sync v0.10.0
|
golang.org/x/sync v0.10.0
|
||||||
golang.org/x/sys v0.28.0
|
golang.org/x/sys v0.29.0
|
||||||
golang.org/x/text v0.21.0
|
golang.org/x/text v0.21.0
|
||||||
golang.org/x/time v0.5.0
|
golang.org/x/time v0.5.0
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
|
golang.org/x/tools v0.29.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
|
@ -144,8 +142,8 @@ require (
|
||||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
golang.org/x/mod v0.17.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
golang.org/x/net v0.25.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
rsc.io/tmplfunc v0.0.3 // indirect
|
rsc.io/tmplfunc v0.0.3 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
24
go.sum
24
go.sum
|
|
@ -172,8 +172,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||||
github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk=
|
github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk=
|
||||||
github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs=
|
github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs=
|
||||||
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY=
|
github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4 h1:HhaRPDFEB1BrvBF+UCUnhyY9y5dtuBxy0myn+7sFjAw=
|
||||||
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY=
|
github.com/fjl/gencodec v0.0.0-20250117152317-bc3e1c7619d4/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
|
|
@ -543,8 +543,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
|
@ -579,8 +579,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
|
@ -619,8 +619,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
|
@ -705,8 +705,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
|
@ -776,8 +776,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
||||||
144
p2p/config.go
Normal file
144
p2p/config.go
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
// Copyright 2025 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
package p2p
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/mclock"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate go run github.com/fjl/gencodec -type Config -field-override configMarshaling -formats toml -out config_toml.go
|
||||||
|
|
||||||
|
// Config holds Server options.
|
||||||
|
type Config struct {
|
||||||
|
// This field must be set to a valid secp256k1 private key.
|
||||||
|
PrivateKey *ecdsa.PrivateKey `toml:"-"`
|
||||||
|
|
||||||
|
// MaxPeers is the maximum number of peers that can be
|
||||||
|
// connected. It must be greater than zero.
|
||||||
|
MaxPeers int
|
||||||
|
|
||||||
|
// MaxPendingPeers is the maximum number of peers that can be pending in the
|
||||||
|
// handshake phase, counted separately for inbound and outbound connections.
|
||||||
|
// Zero defaults to preset values.
|
||||||
|
MaxPendingPeers int `toml:",omitempty"`
|
||||||
|
|
||||||
|
// DialRatio controls the ratio of inbound to dialed connections.
|
||||||
|
// Example: a DialRatio of 2 allows 1/2 of connections to be dialed.
|
||||||
|
// Setting DialRatio to zero defaults it to 3.
|
||||||
|
DialRatio int `toml:",omitempty"`
|
||||||
|
|
||||||
|
// NoDiscovery can be used to disable the peer discovery mechanism.
|
||||||
|
// Disabling is useful for protocol debugging (manual topology).
|
||||||
|
NoDiscovery bool
|
||||||
|
|
||||||
|
// DiscoveryV4 specifies whether V4 discovery should be started.
|
||||||
|
DiscoveryV4 bool `toml:",omitempty"`
|
||||||
|
|
||||||
|
// DiscoveryV5 specifies whether the new topic-discovery based V5 discovery
|
||||||
|
// protocol should be started or not.
|
||||||
|
DiscoveryV5 bool `toml:",omitempty"`
|
||||||
|
|
||||||
|
// Name sets the node name of this server.
|
||||||
|
Name string `toml:"-"`
|
||||||
|
|
||||||
|
// BootstrapNodes are used to establish connectivity
|
||||||
|
// with the rest of the network.
|
||||||
|
BootstrapNodes []*enode.Node
|
||||||
|
|
||||||
|
// BootstrapNodesV5 are used to establish connectivity
|
||||||
|
// with the rest of the network using the V5 discovery
|
||||||
|
// protocol.
|
||||||
|
BootstrapNodesV5 []*enode.Node `toml:",omitempty"`
|
||||||
|
|
||||||
|
// Static nodes are used as pre-configured connections which are always
|
||||||
|
// maintained and re-connected on disconnects.
|
||||||
|
StaticNodes []*enode.Node
|
||||||
|
|
||||||
|
// Trusted nodes are used as pre-configured connections which are always
|
||||||
|
// allowed to connect, even above the peer limit.
|
||||||
|
TrustedNodes []*enode.Node
|
||||||
|
|
||||||
|
// Connectivity can be restricted to certain IP networks.
|
||||||
|
// If this option is set to a non-nil value, only hosts which match one of the
|
||||||
|
// IP networks contained in the list are considered.
|
||||||
|
NetRestrict *netutil.Netlist `toml:",omitempty"`
|
||||||
|
|
||||||
|
// NodeDatabase is the path to the database containing the previously seen
|
||||||
|
// live nodes in the network.
|
||||||
|
NodeDatabase string `toml:",omitempty"`
|
||||||
|
|
||||||
|
// Protocols should contain the protocols supported
|
||||||
|
// by the server. Matching protocols are launched for
|
||||||
|
// each peer.
|
||||||
|
Protocols []Protocol `toml:"-" json:"-"`
|
||||||
|
|
||||||
|
// If ListenAddr is set to a non-nil address, the server
|
||||||
|
// will listen for incoming connections.
|
||||||
|
//
|
||||||
|
// If the port is zero, the operating system will pick a port. The
|
||||||
|
// ListenAddr field will be updated with the actual address when
|
||||||
|
// the server is started.
|
||||||
|
ListenAddr string
|
||||||
|
|
||||||
|
// If DiscAddr is set to a non-nil value, the server will use ListenAddr
|
||||||
|
// for TCP and DiscAddr for the UDP discovery protocol.
|
||||||
|
DiscAddr string
|
||||||
|
|
||||||
|
// If set to a non-nil value, the given NAT port mapper
|
||||||
|
// is used to make the listening port available to the
|
||||||
|
// Internet.
|
||||||
|
NAT nat.Interface `toml:",omitempty"`
|
||||||
|
|
||||||
|
// If Dialer is set to a non-nil value, the given Dialer
|
||||||
|
// is used to dial outbound peer connections.
|
||||||
|
Dialer NodeDialer `toml:"-"`
|
||||||
|
|
||||||
|
// If NoDial is true, the server will not dial any peers.
|
||||||
|
NoDial bool `toml:",omitempty"`
|
||||||
|
|
||||||
|
// If EnableMsgEvents is set then the server will emit PeerEvents
|
||||||
|
// whenever a message is sent to or received from a peer
|
||||||
|
EnableMsgEvents bool
|
||||||
|
|
||||||
|
// Logger is a custom logger to use with the p2p.Server.
|
||||||
|
Logger log.Logger `toml:"-"`
|
||||||
|
|
||||||
|
clock mclock.Clock
|
||||||
|
}
|
||||||
|
|
||||||
|
type configMarshaling struct {
|
||||||
|
NAT configNAT
|
||||||
|
}
|
||||||
|
|
||||||
|
type configNAT struct {
|
||||||
|
nat.Interface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *configNAT) UnmarshalText(input []byte) error {
|
||||||
|
n, err := nat.Parse(string(input))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid NAT specification: %v", err)
|
||||||
|
}
|
||||||
|
w.Interface = n
|
||||||
|
return nil
|
||||||
|
}
|
||||||
165
p2p/config_toml.go
Normal file
165
p2p/config_toml.go
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||||
|
|
||||||
|
package p2p
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = (*configMarshaling)(nil)
|
||||||
|
|
||||||
|
// MarshalTOML marshals as TOML.
|
||||||
|
func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
|
type Config struct {
|
||||||
|
PrivateKey *ecdsa.PrivateKey `toml:"-"`
|
||||||
|
MaxPeers int
|
||||||
|
MaxPendingPeers int `toml:",omitempty"`
|
||||||
|
DialRatio int `toml:",omitempty"`
|
||||||
|
NoDiscovery bool
|
||||||
|
DiscoveryV4 bool `toml:",omitempty"`
|
||||||
|
DiscoveryV5 bool `toml:",omitempty"`
|
||||||
|
Name string `toml:"-"`
|
||||||
|
BootstrapNodes []*enode.Node
|
||||||
|
BootstrapNodesV5 []*enode.Node `toml:",omitempty"`
|
||||||
|
StaticNodes []*enode.Node
|
||||||
|
TrustedNodes []*enode.Node
|
||||||
|
NetRestrict *netutil.Netlist `toml:",omitempty"`
|
||||||
|
NodeDatabase string `toml:",omitempty"`
|
||||||
|
Protocols []Protocol `toml:"-" json:"-"`
|
||||||
|
ListenAddr string
|
||||||
|
DiscAddr string
|
||||||
|
NAT nat.Interface `toml:",omitempty"`
|
||||||
|
Dialer NodeDialer `toml:"-"`
|
||||||
|
NoDial bool `toml:",omitempty"`
|
||||||
|
EnableMsgEvents bool
|
||||||
|
Logger log.Logger `toml:"-"`
|
||||||
|
}
|
||||||
|
var enc Config
|
||||||
|
enc.PrivateKey = c.PrivateKey
|
||||||
|
enc.MaxPeers = c.MaxPeers
|
||||||
|
enc.MaxPendingPeers = c.MaxPendingPeers
|
||||||
|
enc.DialRatio = c.DialRatio
|
||||||
|
enc.NoDiscovery = c.NoDiscovery
|
||||||
|
enc.DiscoveryV4 = c.DiscoveryV4
|
||||||
|
enc.DiscoveryV5 = c.DiscoveryV5
|
||||||
|
enc.Name = c.Name
|
||||||
|
enc.BootstrapNodes = c.BootstrapNodes
|
||||||
|
enc.BootstrapNodesV5 = c.BootstrapNodesV5
|
||||||
|
enc.StaticNodes = c.StaticNodes
|
||||||
|
enc.TrustedNodes = c.TrustedNodes
|
||||||
|
enc.NetRestrict = c.NetRestrict
|
||||||
|
enc.NodeDatabase = c.NodeDatabase
|
||||||
|
enc.Protocols = c.Protocols
|
||||||
|
enc.ListenAddr = c.ListenAddr
|
||||||
|
enc.DiscAddr = c.DiscAddr
|
||||||
|
enc.NAT = c.NAT
|
||||||
|
enc.Dialer = c.Dialer
|
||||||
|
enc.NoDial = c.NoDial
|
||||||
|
enc.EnableMsgEvents = c.EnableMsgEvents
|
||||||
|
enc.Logger = c.Logger
|
||||||
|
return &enc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalTOML unmarshals from TOML.
|
||||||
|
func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
|
type Config struct {
|
||||||
|
PrivateKey *ecdsa.PrivateKey `toml:"-"`
|
||||||
|
MaxPeers *int
|
||||||
|
MaxPendingPeers *int `toml:",omitempty"`
|
||||||
|
DialRatio *int `toml:",omitempty"`
|
||||||
|
NoDiscovery *bool
|
||||||
|
DiscoveryV4 *bool `toml:",omitempty"`
|
||||||
|
DiscoveryV5 *bool `toml:",omitempty"`
|
||||||
|
Name *string `toml:"-"`
|
||||||
|
BootstrapNodes []*enode.Node
|
||||||
|
BootstrapNodesV5 []*enode.Node `toml:",omitempty"`
|
||||||
|
StaticNodes []*enode.Node
|
||||||
|
TrustedNodes []*enode.Node
|
||||||
|
NetRestrict *netutil.Netlist `toml:",omitempty"`
|
||||||
|
NodeDatabase *string `toml:",omitempty"`
|
||||||
|
Protocols []Protocol `toml:"-" json:"-"`
|
||||||
|
ListenAddr *string
|
||||||
|
DiscAddr *string
|
||||||
|
NAT *configNAT `toml:",omitempty"`
|
||||||
|
Dialer NodeDialer `toml:"-"`
|
||||||
|
NoDial *bool `toml:",omitempty"`
|
||||||
|
EnableMsgEvents *bool
|
||||||
|
Logger log.Logger `toml:"-"`
|
||||||
|
}
|
||||||
|
var dec Config
|
||||||
|
if err := unmarshal(&dec); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if dec.PrivateKey != nil {
|
||||||
|
c.PrivateKey = dec.PrivateKey
|
||||||
|
}
|
||||||
|
if dec.MaxPeers != nil {
|
||||||
|
c.MaxPeers = *dec.MaxPeers
|
||||||
|
}
|
||||||
|
if dec.MaxPendingPeers != nil {
|
||||||
|
c.MaxPendingPeers = *dec.MaxPendingPeers
|
||||||
|
}
|
||||||
|
if dec.DialRatio != nil {
|
||||||
|
c.DialRatio = *dec.DialRatio
|
||||||
|
}
|
||||||
|
if dec.NoDiscovery != nil {
|
||||||
|
c.NoDiscovery = *dec.NoDiscovery
|
||||||
|
}
|
||||||
|
if dec.DiscoveryV4 != nil {
|
||||||
|
c.DiscoveryV4 = *dec.DiscoveryV4
|
||||||
|
}
|
||||||
|
if dec.DiscoveryV5 != nil {
|
||||||
|
c.DiscoveryV5 = *dec.DiscoveryV5
|
||||||
|
}
|
||||||
|
if dec.Name != nil {
|
||||||
|
c.Name = *dec.Name
|
||||||
|
}
|
||||||
|
if dec.BootstrapNodes != nil {
|
||||||
|
c.BootstrapNodes = dec.BootstrapNodes
|
||||||
|
}
|
||||||
|
if dec.BootstrapNodesV5 != nil {
|
||||||
|
c.BootstrapNodesV5 = dec.BootstrapNodesV5
|
||||||
|
}
|
||||||
|
if dec.StaticNodes != nil {
|
||||||
|
c.StaticNodes = dec.StaticNodes
|
||||||
|
}
|
||||||
|
if dec.TrustedNodes != nil {
|
||||||
|
c.TrustedNodes = dec.TrustedNodes
|
||||||
|
}
|
||||||
|
if dec.NetRestrict != nil {
|
||||||
|
c.NetRestrict = dec.NetRestrict
|
||||||
|
}
|
||||||
|
if dec.NodeDatabase != nil {
|
||||||
|
c.NodeDatabase = *dec.NodeDatabase
|
||||||
|
}
|
||||||
|
if dec.Protocols != nil {
|
||||||
|
c.Protocols = dec.Protocols
|
||||||
|
}
|
||||||
|
if dec.ListenAddr != nil {
|
||||||
|
c.ListenAddr = *dec.ListenAddr
|
||||||
|
}
|
||||||
|
if dec.DiscAddr != nil {
|
||||||
|
c.DiscAddr = *dec.DiscAddr
|
||||||
|
}
|
||||||
|
if dec.NAT != nil {
|
||||||
|
c.NAT = dec.NAT
|
||||||
|
}
|
||||||
|
if dec.Dialer != nil {
|
||||||
|
c.Dialer = dec.Dialer
|
||||||
|
}
|
||||||
|
if dec.NoDial != nil {
|
||||||
|
c.NoDial = *dec.NoDial
|
||||||
|
}
|
||||||
|
if dec.EnableMsgEvents != nil {
|
||||||
|
c.EnableMsgEvents = *dec.EnableMsgEvents
|
||||||
|
}
|
||||||
|
if dec.Logger != nil {
|
||||||
|
c.Logger = dec.Logger
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -141,8 +141,9 @@ func Map(m Interface, c <-chan struct{}, protocol string, extport, intport int,
|
||||||
// Mapping operations will not return an error but won't actually do anything.
|
// Mapping operations will not return an error but won't actually do anything.
|
||||||
type ExtIP net.IP
|
type ExtIP net.IP
|
||||||
|
|
||||||
func (n ExtIP) ExternalIP() (net.IP, error) { return net.IP(n), nil }
|
func (n ExtIP) ExternalIP() (net.IP, error) { return net.IP(n), nil }
|
||||||
func (n ExtIP) String() string { return fmt.Sprintf("ExtIP(%v)", net.IP(n)) }
|
func (n ExtIP) String() string { return fmt.Sprintf("ExtIP(%v)", net.IP(n)) }
|
||||||
|
func (n ExtIP) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("extip:%v", net.IP(n))), nil }
|
||||||
|
|
||||||
// These do nothing.
|
// These do nothing.
|
||||||
|
|
||||||
|
|
@ -156,7 +157,7 @@ func (ExtIP) DeleteMapping(string, int, int) error { return nil }
|
||||||
func Any() Interface {
|
func Any() Interface {
|
||||||
// TODO: attempt to discover whether the local machine has an
|
// TODO: attempt to discover whether the local machine has an
|
||||||
// Internet-class address. Return ExtIP in this case.
|
// Internet-class address. Return ExtIP in this case.
|
||||||
return startautodisc("UPnP or NAT-PMP", func() Interface {
|
return startautodisc("any", func() Interface {
|
||||||
found := make(chan Interface, 2)
|
found := make(chan Interface, 2)
|
||||||
go func() { found <- discoverUPnP() }()
|
go func() { found <- discoverUPnP() }()
|
||||||
go func() { found <- discoverPMP() }()
|
go func() { found <- discoverPMP() }()
|
||||||
|
|
@ -172,7 +173,7 @@ func Any() Interface {
|
||||||
// UPnP returns a port mapper that uses UPnP. It will attempt to
|
// UPnP returns a port mapper that uses UPnP. It will attempt to
|
||||||
// discover the address of your router using UDP broadcasts.
|
// discover the address of your router using UDP broadcasts.
|
||||||
func UPnP() Interface {
|
func UPnP() Interface {
|
||||||
return startautodisc("UPnP", discoverUPnP)
|
return startautodisc("upnp", discoverUPnP)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PMP returns a port mapper that uses NAT-PMP. The provided gateway
|
// PMP returns a port mapper that uses NAT-PMP. The provided gateway
|
||||||
|
|
@ -182,7 +183,7 @@ func PMP(gateway net.IP) Interface {
|
||||||
if gateway != nil {
|
if gateway != nil {
|
||||||
return &pmp{gw: gateway, c: natpmp.NewClient(gateway)}
|
return &pmp{gw: gateway, c: natpmp.NewClient(gateway)}
|
||||||
}
|
}
|
||||||
return startautodisc("NAT-PMP", discoverPMP)
|
return startautodisc("natpmp", discoverPMP)
|
||||||
}
|
}
|
||||||
|
|
||||||
// autodisc represents a port mapping mechanism that is still being
|
// autodisc represents a port mapping mechanism that is still being
|
||||||
|
|
@ -236,6 +237,10 @@ func (n *autodisc) String() string {
|
||||||
return n.found.String()
|
return n.found.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *autodisc) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(n.what), nil
|
||||||
|
}
|
||||||
|
|
||||||
// wait blocks until auto-discovery has been performed.
|
// wait blocks until auto-discovery has been performed.
|
||||||
func (n *autodisc) wait() error {
|
func (n *autodisc) wait() error {
|
||||||
n.once.Do(func() {
|
n.once.Do(func() {
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,10 @@ func (n *pmp) DeleteMapping(protocol string, extport, intport int) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *pmp) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(fmt.Sprintf("natpmp:%v", n.gw)), nil
|
||||||
|
}
|
||||||
|
|
||||||
func discoverPMP() Interface {
|
func discoverPMP() Interface {
|
||||||
// run external address lookups on all potential gateways
|
// run external address lookups on all potential gateways
|
||||||
gws := potentialGateways()
|
gws := potentialGateways()
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -72,104 +71,6 @@ var (
|
||||||
errProtoHandshakeError = errors.New("rlpx proto error")
|
errProtoHandshakeError = errors.New("rlpx proto error")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config holds Server options.
|
|
||||||
type Config struct {
|
|
||||||
// This field must be set to a valid secp256k1 private key.
|
|
||||||
PrivateKey *ecdsa.PrivateKey `toml:"-"`
|
|
||||||
|
|
||||||
// MaxPeers is the maximum number of peers that can be
|
|
||||||
// connected. It must be greater than zero.
|
|
||||||
MaxPeers int
|
|
||||||
|
|
||||||
// MaxPendingPeers is the maximum number of peers that can be pending in the
|
|
||||||
// handshake phase, counted separately for inbound and outbound connections.
|
|
||||||
// Zero defaults to preset values.
|
|
||||||
MaxPendingPeers int `toml:",omitempty"`
|
|
||||||
|
|
||||||
// DialRatio controls the ratio of inbound to dialed connections.
|
|
||||||
// Example: a DialRatio of 2 allows 1/2 of connections to be dialed.
|
|
||||||
// Setting DialRatio to zero defaults it to 3.
|
|
||||||
DialRatio int `toml:",omitempty"`
|
|
||||||
|
|
||||||
// NoDiscovery can be used to disable the peer discovery mechanism.
|
|
||||||
// Disabling is useful for protocol debugging (manual topology).
|
|
||||||
NoDiscovery bool
|
|
||||||
|
|
||||||
// DiscoveryV4 specifies whether V4 discovery should be started.
|
|
||||||
DiscoveryV4 bool `toml:",omitempty"`
|
|
||||||
|
|
||||||
// DiscoveryV5 specifies whether the new topic-discovery based V5 discovery
|
|
||||||
// protocol should be started or not.
|
|
||||||
DiscoveryV5 bool `toml:",omitempty"`
|
|
||||||
|
|
||||||
// Name sets the node name of this server.
|
|
||||||
Name string `toml:"-"`
|
|
||||||
|
|
||||||
// BootstrapNodes are used to establish connectivity
|
|
||||||
// with the rest of the network.
|
|
||||||
BootstrapNodes []*enode.Node
|
|
||||||
|
|
||||||
// BootstrapNodesV5 are used to establish connectivity
|
|
||||||
// with the rest of the network using the V5 discovery
|
|
||||||
// protocol.
|
|
||||||
BootstrapNodesV5 []*enode.Node `toml:",omitempty"`
|
|
||||||
|
|
||||||
// Static nodes are used as pre-configured connections which are always
|
|
||||||
// maintained and re-connected on disconnects.
|
|
||||||
StaticNodes []*enode.Node
|
|
||||||
|
|
||||||
// Trusted nodes are used as pre-configured connections which are always
|
|
||||||
// allowed to connect, even above the peer limit.
|
|
||||||
TrustedNodes []*enode.Node
|
|
||||||
|
|
||||||
// Connectivity can be restricted to certain IP networks.
|
|
||||||
// If this option is set to a non-nil value, only hosts which match one of the
|
|
||||||
// IP networks contained in the list are considered.
|
|
||||||
NetRestrict *netutil.Netlist `toml:",omitempty"`
|
|
||||||
|
|
||||||
// NodeDatabase is the path to the database containing the previously seen
|
|
||||||
// live nodes in the network.
|
|
||||||
NodeDatabase string `toml:",omitempty"`
|
|
||||||
|
|
||||||
// Protocols should contain the protocols supported
|
|
||||||
// by the server. Matching protocols are launched for
|
|
||||||
// each peer.
|
|
||||||
Protocols []Protocol `toml:"-" json:"-"`
|
|
||||||
|
|
||||||
// If ListenAddr is set to a non-nil address, the server
|
|
||||||
// will listen for incoming connections.
|
|
||||||
//
|
|
||||||
// If the port is zero, the operating system will pick a port. The
|
|
||||||
// ListenAddr field will be updated with the actual address when
|
|
||||||
// the server is started.
|
|
||||||
ListenAddr string
|
|
||||||
|
|
||||||
// If DiscAddr is set to a non-nil value, the server will use ListenAddr
|
|
||||||
// for TCP and DiscAddr for the UDP discovery protocol.
|
|
||||||
DiscAddr string
|
|
||||||
|
|
||||||
// If set to a non-nil value, the given NAT port mapper
|
|
||||||
// is used to make the listening port available to the
|
|
||||||
// Internet.
|
|
||||||
NAT nat.Interface `toml:",omitempty"`
|
|
||||||
|
|
||||||
// If Dialer is set to a non-nil value, the given Dialer
|
|
||||||
// is used to dial outbound peer connections.
|
|
||||||
Dialer NodeDialer `toml:"-"`
|
|
||||||
|
|
||||||
// If NoDial is true, the server will not dial any peers.
|
|
||||||
NoDial bool `toml:",omitempty"`
|
|
||||||
|
|
||||||
// If EnableMsgEvents is set then the server will emit PeerEvents
|
|
||||||
// whenever a message is sent to or received from a peer
|
|
||||||
EnableMsgEvents bool
|
|
||||||
|
|
||||||
// Logger is a custom logger to use with the p2p.Server.
|
|
||||||
Logger log.Logger `toml:",omitempty"`
|
|
||||||
|
|
||||||
clock mclock.Clock
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server manages all peer connections.
|
// Server manages all peer connections.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// Config fields may not be modified while the server is running.
|
// Config fields may not be modified while the server is running.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue