From b2bf6ce8847bdb11f695eefee87f7a5bbc73080f Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Fri, 11 Apr 2025 23:13:47 +0800 Subject: [PATCH] rename geth to aiigo --- .github/CONTRIBUTING.md | 4 +- .github/ISSUE_TEMPLATE/bug.md | 2 +- .gitignore | 14 +- .travis.yml | 16 +- Dockerfile | 10 +- Dockerfile.alltools | 4 +- Makefile | 10 +- README.md | 82 +- SECURITY.md | 4 +- accounts/abi/abigen/bind.go | 2 +- accounts/manager.go | 2 +- accounts/scwallet/README.md | 8 +- appveyor.yml | 4 +- beacon/engine/errors.go | 2 +- build/bot/macos-build.sh | 4 +- build/bot/ppa-build.sh | 2 +- build/ci-notes.md | 2 +- build/ci.go | 70 +- build/deb/ethereum/completions/bash/geth | 4 +- build/deb/ethereum/completions/zsh/_geth | 4 +- build/deb/ethereum/deb.control | 4 +- build/deb/ethereum/deb.install | 6 +- build/nsis.geth.nsi | 10 +- build/nsis.install.nsh | 28 +- build/nsis.uninstall.nsh | 8 +- circle.yml | 8 +- cmd/aiigo/accountcmd.go | 367 +++++++ cmd/aiigo/accountcmd_test.go | 207 ++++ cmd/aiigo/attach_test.go | 83 ++ cmd/aiigo/chaincmd.go | 660 +++++++++++++ cmd/aiigo/config.go | 408 ++++++++ cmd/aiigo/consolecmd.go | 160 +++ cmd/aiigo/consolecmd_test.go | 160 +++ cmd/aiigo/dbcmd.go | 909 ++++++++++++++++++ cmd/aiigo/exportcmd_test.go | 45 + cmd/aiigo/genesis_test.go | 198 ++++ cmd/aiigo/logging_test.go | 237 +++++ cmd/aiigo/logtestcmd_active.go | 171 ++++ cmd/aiigo/logtestcmd_inactive.go | 23 + cmd/aiigo/main.go | 428 +++++++++ cmd/aiigo/misccmd.go | 104 ++ cmd/aiigo/run_test.go | 120 +++ cmd/aiigo/snapshot.go | 694 +++++++++++++ cmd/aiigo/testdata/blockchain.blocks | Bin 0 -> 23287 bytes cmd/aiigo/testdata/clique.json | 25 + cmd/aiigo/testdata/empty.js | 1 + cmd/aiigo/testdata/guswallet.json | 6 + cmd/aiigo/testdata/key.prv | 1 + cmd/aiigo/testdata/logging/logtest-json.txt | 52 + cmd/aiigo/testdata/logging/logtest-logfmt.txt | 52 + .../testdata/logging/logtest-terminal.txt | 53 + cmd/aiigo/testdata/password.txt | 1 + cmd/aiigo/testdata/passwords.txt | 3 + cmd/aiigo/testdata/vcheck/data.json | 61 ++ .../vcheck/minisig-sigs-new/data.json.minisig | 4 + .../vulnerabilities.json.minisig.1 | 4 + .../vulnerabilities.json.minisig.2 | 4 + .../vulnerabilities.json.minisig.3 | 4 + cmd/aiigo/testdata/vcheck/minisign.pub | 2 + cmd/aiigo/testdata/vcheck/minisign.sec | 2 + .../vcheck/signify-sigs/data.json.sig | 2 + cmd/aiigo/testdata/vcheck/signifykey.pub | 2 + cmd/aiigo/testdata/vcheck/signifykey.sec | 2 + .../sigs/vulnerabilities.json.minisig.1 | 4 + .../sigs/vulnerabilities.json.minisig.2 | 4 + .../sigs/vulnerabilities.json.minisig.3 | 4 + .../testdata/vcheck/vulnerabilities.json | 202 ++++ cmd/aiigo/testdata/wrong-passwords.txt | 3 + cmd/aiigo/verkle.go | 214 +++++ cmd/aiigo/version_check.go | 170 ++++ cmd/aiigo/version_check_test.go | 185 ++++ cmd/clef/README.md | 18 +- cmd/clef/rules.md | 2 +- cmd/clef/tests/testsigner.js | 4 +- cmd/clef/tutorial.md | 14 +- cmd/devp2p/README.md | 8 +- cmd/devp2p/internal/ethtest/suite_test.go | 24 +- cmd/evm/README.md | 2 +- cmd/evm/internal/t8ntool/execution.go | 2 +- cmd/evm/testdata/12/readme.md | 2 +- cmd/evm/transition-test.sh | 2 +- cmd/geth/accountcmd.go | 14 +- cmd/geth/accountcmd_test.go | 68 +- cmd/geth/attach_test.go | 8 +- cmd/geth/chaincmd.go | 2 +- cmd/geth/config.go | 22 +- cmd/geth/consolecmd.go | 22 +- cmd/geth/consolecmd_test.go | 58 +- cmd/geth/exportcmd_test.go | 8 +- cmd/geth/genesis_test.go | 22 +- cmd/geth/logging_test.go | 2 +- cmd/geth/main.go | 26 +- cmd/geth/misccmd.go | 12 +- cmd/geth/run_test.go | 22 +- cmd/geth/snapshot.go | 16 +- cmd/geth/testdata/vcheck/data.json | 28 +- cmd/geth/testdata/vcheck/vulnerabilities.json | 64 +- cmd/geth/verkle.go | 4 +- cmd/geth/version_check.go | 6 +- cmd/geth/version_check_test.go | 14 +- cmd/utils/cmd.go | 8 +- cmd/utils/flags.go | 10 +- console/console.go | 6 +- core/blockchain.go | 2 +- core/blockchain_snapshot_test.go | 18 +- core/filtermaps/filtermaps.go | 2 +- core/genesis.go | 2 +- core/headerchain.go | 2 +- core/state/snapshot/journal.go | 6 +- core/tracing/CHANGELOG.md | 2 +- core/tracing/hooks.go | 4 +- core/types/receipt.go | 2 +- core/vm/runtime/env.go | 2 +- crypto/kzg4844/kzg4844_ckzg_cgo.go | 2 +- crypto/kzg4844/kzg4844_ckzg_nocgo.go | 2 +- .../2021-08-22-split-postmortem.md | 12 +- eth/backend.go | 8 +- eth/catalyst/api.go | 10 +- eth/catalyst/tester.go | 2 +- eth/downloader/downloader.go | 2 +- eth/downloader/skeleton.go | 6 +- eth/ethconfig/config.go | 4 +- eth/protocols/snap/sync.go | 2 +- eth/tracers/internal/tracetest/README.md | 2 +- eth/tracers/native/call_flat.go | 4 +- ethclient/ethclient.go | 2 +- ethclient/gethclient/gethclient.go | 8 +- ethclient/gethclient/gethclient_test.go | 4 +- ethclient/simulated/options.go | 2 +- ethdb/remotedb/remotedb.go | 4 +- interfaces.go | 2 +- internal/build/gotool.go | 2 +- internal/cmdtest/test_cmd.go | 4 +- internal/debug/flags.go | 4 +- internal/flags/helpers.go | 4 +- internal/jsre/completion.go | 2 +- internal/jsre/deps/web3.js | 8 +- internal/version/version.go | 8 +- internal/web3ext/web3ext.go | 2 +- log/logger.go | 2 +- metrics/config.go | 6 +- miner/miner.go | 2 +- node/config.go | 26 +- node/config_test.go | 14 +- node/node.go | 2 +- node/node_auth_test.go | 2 +- p2p/peer.go | 2 +- params/config.go | 2 +- signer/core/apitypes/types_test.go | 2 +- signer/core/signed_data.go | 2 +- signer/fourbyte/4byte.json | 14 +- tests/fuzzers/bls12381/bls12381_fuzz.go | 12 +- tests/fuzzers/secp256k1/secp_test.go | 2 +- tests/solidity/truffle-config.js | 2 +- tests/transaction_test.go | 2 +- trie/iterator.go | 2 +- triedb/pathdb/journal.go | 2 +- 157 files changed, 6584 insertions(+), 543 deletions(-) create mode 100644 cmd/aiigo/accountcmd.go create mode 100644 cmd/aiigo/accountcmd_test.go create mode 100644 cmd/aiigo/attach_test.go create mode 100644 cmd/aiigo/chaincmd.go create mode 100644 cmd/aiigo/config.go create mode 100644 cmd/aiigo/consolecmd.go create mode 100644 cmd/aiigo/consolecmd_test.go create mode 100644 cmd/aiigo/dbcmd.go create mode 100644 cmd/aiigo/exportcmd_test.go create mode 100644 cmd/aiigo/genesis_test.go create mode 100644 cmd/aiigo/logging_test.go create mode 100644 cmd/aiigo/logtestcmd_active.go create mode 100644 cmd/aiigo/logtestcmd_inactive.go create mode 100644 cmd/aiigo/main.go create mode 100644 cmd/aiigo/misccmd.go create mode 100644 cmd/aiigo/run_test.go create mode 100644 cmd/aiigo/snapshot.go create mode 100644 cmd/aiigo/testdata/blockchain.blocks create mode 100644 cmd/aiigo/testdata/clique.json create mode 100644 cmd/aiigo/testdata/empty.js create mode 100644 cmd/aiigo/testdata/guswallet.json create mode 100644 cmd/aiigo/testdata/key.prv create mode 100644 cmd/aiigo/testdata/logging/logtest-json.txt create mode 100644 cmd/aiigo/testdata/logging/logtest-logfmt.txt create mode 100644 cmd/aiigo/testdata/logging/logtest-terminal.txt create mode 100644 cmd/aiigo/testdata/password.txt create mode 100644 cmd/aiigo/testdata/passwords.txt create mode 100644 cmd/aiigo/testdata/vcheck/data.json create mode 100644 cmd/aiigo/testdata/vcheck/minisig-sigs-new/data.json.minisig create mode 100644 cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1 create mode 100644 cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2 create mode 100644 cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3 create mode 100644 cmd/aiigo/testdata/vcheck/minisign.pub create mode 100644 cmd/aiigo/testdata/vcheck/minisign.sec create mode 100644 cmd/aiigo/testdata/vcheck/signify-sigs/data.json.sig create mode 100644 cmd/aiigo/testdata/vcheck/signifykey.pub create mode 100644 cmd/aiigo/testdata/vcheck/signifykey.sec create mode 100644 cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.1 create mode 100644 cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.2 create mode 100644 cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.3 create mode 100644 cmd/aiigo/testdata/vcheck/vulnerabilities.json create mode 100644 cmd/aiigo/testdata/wrong-passwords.txt create mode 100644 cmd/aiigo/verkle.go create mode 100644 cmd/aiigo/version_check.go create mode 100644 cmd/aiigo/version_check_test.go diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 969b7f8f9f..376ff6202f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -30,11 +30,11 @@ Please make sure your contributions adhere to our coding guidelines: Before you submit a feature request, please check and make sure that it isn't possible through some other means. The JavaScript-enabled console is a powerful feature in the right hands. Please check our -[Geth documentation page](https://geth.ethereum.org/docs/) for more info +[Aiigo documentation page](https://aiigo.ethereum.org/docs/) for more info and help. ## Configuration, dependencies, and tests -Please see the [Developers' Guide](https://geth.ethereum.org/docs/developers/geth-developer/dev-guide) +Please see the [Developers' Guide](https://aiigo.ethereum.org/docs/developers/aiigo-developer/dev-guide) for more details on configuring your environment, managing project dependencies and testing procedures. diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 45bfd986ac..1701eca4e2 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -8,7 +8,7 @@ assignees: '' #### System information -Geth version: `geth version` +Aiigo version: `aiigo version` CL client & version: e.g. lighthouse/nimbus/prysm@v1.0.0 OS & Version: Windows/Linux/OSX Commit hash : (if `develop`) diff --git a/.gitignore b/.gitignore index 269455db7a..9cb556b972 100644 --- a/.gitignore +++ b/.gitignore @@ -21,14 +21,14 @@ /build/_workspace/ /build/cache/ /build/bin/ -/geth*.zip +/aiigo*.zip # used by the build/ci.go archive + upload tool -/geth*.tar.gz -/geth*.tar.gz.sig -/geth*.tar.gz.asc -/geth*.zip.sig -/geth*.zip.asc +/aiigo*.tar.gz +/aiigo*.tar.gz.sig +/aiigo*.tar.gz.asc +/aiigo*.zip.sig +/aiigo*.zip.asc # travis @@ -53,6 +53,6 @@ cmd/devp2p/devp2p cmd/era/era cmd/ethkey/ethkey cmd/evm/evm -cmd/geth/geth +cmd/aiigo/aiigo cmd/rlpdump/rlpdump cmd/workload/workload \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 43f8ced19c..9c2758cd6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,26 +35,26 @@ jobs: script: # build amd64 - go run build/ci.go install -dlgo - - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload aiigostore/builds # build 386 - sudo -E apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib - git status --porcelain - go run build/ci.go install -dlgo -arch 386 - - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload aiigostore/builds # Switch over GCC to cross compilation (breaks 386, hence why do it here only) - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross - sudo ln -s /usr/include/asm-generic /usr/include/asm - GOARM=5 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload aiigostore/builds - GOARM=6 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabi-gcc - - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload aiigostore/builds - GOARM=7 go run build/ci.go install -dlgo -arch arm -cc arm-linux-gnueabihf-gcc - - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload aiigostore/builds - go run build/ci.go install -dlgo -arch arm64 -cc aarch64-linux-gnu-gcc - - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds + - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload aiigostore/builds # These builders run the tests - stage: build @@ -88,7 +88,7 @@ jobs: - sudo -E apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot script: - echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts - - go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder " + - go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user aiigo-ci -signer "Go Ethereum Linux Builder " # This builder does the Azure archive purges to avoid accumulating junk - stage: build @@ -101,7 +101,7 @@ jobs: git: submodules: false # avoid cloning ethereum/tests script: - - go run build/ci.go purge -store gethstore/builds -days 14 + - go run build/ci.go purge -store aiigostore/builds -days 14 # This builder executes race tests - stage: build diff --git a/Dockerfile b/Dockerfile index 9b70e9e8a0..dda5af8121 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG COMMIT="" ARG VERSION="" ARG BUILDNUM="" -# Build Geth in a stock Go builder container +# Build Aiigo in a stock Go builder container FROM golang:1.24-alpine AS builder RUN apk add --no-cache gcc musl-dev linux-headers git @@ -14,16 +14,16 @@ COPY go.sum /go-ethereum/ RUN cd /go-ethereum && go mod download ADD . /go-ethereum -RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/geth +RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/aiigo -# Pull Geth into a second stage deploy alpine container +# Pull Aiigo 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/ +COPY --from=builder /go-ethereum/build/bin/aiigo /usr/local/bin/ EXPOSE 8545 8546 30303 30303/udp -ENTRYPOINT ["geth"] +ENTRYPOINT ["aiigo"] # Add some metadata labels to help programmatic image consumption ARG COMMIT="" diff --git a/Dockerfile.alltools b/Dockerfile.alltools index ac9303c678..0c6d027e94 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -3,7 +3,7 @@ ARG COMMIT="" ARG VERSION="" ARG BUILDNUM="" -# Build Geth in a stock Go builder container +# Build Aiigo in a stock Go builder container FROM golang:1.24-alpine AS builder RUN apk add --no-cache gcc musl-dev linux-headers git @@ -19,7 +19,7 @@ ADD . /go-ethereum # makes it so that under certain circumstances, the docker layer can be cached, # and the builder can jump to the next (build all) command, with the go cache fully loaded. # -RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/geth +RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/aiigo RUN cd /go-ethereum && go run build/ci.go install -static diff --git a/Makefile b/Makefile index f4932165a4..1a4908ea0f 100644 --- a/Makefile +++ b/Makefile @@ -2,17 +2,17 @@ # with Go source code. If you know what GOPATH is then you probably # don't need to bother with make. -.PHONY: geth all test lint fmt clean devtools help +.PHONY: aiigo all test lint fmt clean devtools help GOBIN = ./build/bin GO ?= latest GORUN = go run -#? geth: Build geth. -geth: - $(GORUN) build/ci.go install ./cmd/geth +#? aiigo: Build aiigo. +aiigo: + $(GORUN) build/ci.go install ./cmd/aiigo @echo "Done building." - @echo "Run \"$(GOBIN)/geth\" to launch geth." + @echo "Run \"$(GOBIN)/aiigo\" to launch aiigo." #? all: Build all packages and executables. all: diff --git a/README.md b/README.md index 9ccfe933aa..cde1e0ff30 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,17 @@ https://pkg.go.dev/badge/github.com/ethereum/go-ethereum [![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) Automated builds are available for stable releases and the unstable master branch. Binary -archives are published at https://geth.ethereum.org/downloads/. +archives are published at https://aiigo.ethereum.org/downloads/. ## Building the source -For prerequisites and detailed build instructions please read the [Installation Instructions](https://geth.ethereum.org/docs/getting-started/installing-geth). +For prerequisites and detailed build instructions please read the [Installation Instructions](https://aiigo.ethereum.org/docs/getting-started/installing-aiigo). -Building `geth` requires both a Go (version 1.23 or later) and a C compiler. You can install +Building `aiigo` requires both a Go (version 1.23 or later) and a C compiler. You can install them using your favourite package manager. Once the dependencies are installed, run ```shell -make geth +make aiigo ``` or, to build the full suite of utilities: @@ -36,19 +36,19 @@ directory. | Command | Description | | :--------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default), archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI page](https://geth.ethereum.org/docs/fundamentals/command-line-options) for command line options. | -| `clef` | Stand-alone signing tool, which can be used as a backend signer for `geth`. | +| **`aiigo`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default), archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `aiigo --help` and the [CLI page](https://aiigo.ethereum.org/docs/fundamentals/command-line-options) for command line options. | +| `clef` | Stand-alone signing tool, which can be used as a backend signer for `aiigo`. | | `devp2p` | Utilities to interact with nodes on the networking layer, without running a full blockchain. | -| `abigen` | Source code generator to convert Ethereum contract definitions into easy-to-use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://docs.soliditylang.org/en/develop/abi-spec.html) with expanded functionality if the contract bytecode is also available. However, it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings) page for details. | +| `abigen` | Source code generator to convert Ethereum contract definitions into easy-to-use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://docs.soliditylang.org/en/develop/abi-spec.html) with expanded functionality if the contract bytecode is also available. However, it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://aiigo.ethereum.org/docs/developers/dapp-developer/native-bindings) page for details. | | `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow isolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug run`). | | `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user-friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). | -## Running `geth` +## Running `aiigo` Going through all the possible command line flags is out of scope here (please consult our -[CLI Wiki page](https://geth.ethereum.org/docs/fundamentals/command-line-options)), +[CLI Wiki page](https://aiigo.ethereum.org/docs/fundamentals/command-line-options)), but we've enumerated a few common parameter combos to get you up to speed quickly -on how you can run your own `geth` instance. +on how you can run your own `aiigo` instance. ### Hardware Requirements @@ -74,19 +74,19 @@ particular use case, the user doesn't care about years-old historical data, so w sync quickly to the current state of the network. To do so: ```shell -$ geth console +$ aiigo console ``` This command will: - * Start `geth` in snap sync mode (default, can be changed with the `--syncmode` flag), + * Start `aiigo` in snap sync mode (default, can be changed with the `--syncmode` flag), causing it to download more data in exchange for avoiding processing the entire history of the Ethereum network, which is very CPU intensive. - * Start the built-in interactive [JavaScript console](https://geth.ethereum.org/docs/interacting-with-geth/javascript-console), + * Start the built-in interactive [JavaScript console](https://aiigo.ethereum.org/docs/interacting-with-aiigo/javascript-console), (via the trailing `console` subcommand) through which you can interact using [`web3` methods](https://github.com/ChainSafe/web3.js/blob/0.20.7/DOCUMENTATION.md) - (note: the `web3` version bundled within `geth` is very old, and not up to date with official docs), - as well as `geth`'s own [management APIs](https://geth.ethereum.org/docs/interacting-with-geth/rpc). + (note: the `web3` version bundled within `aiigo` is very old, and not up to date with official docs), + as well as `aiigo`'s own [management APIs](https://aiigo.ethereum.org/docs/interacting-with-aiigo/rpc). This tool is optional and if you leave it out you can always attach it to an already running - `geth` instance with `geth attach`. + `aiigo` instance with `aiigo attach`. ### A Full node on the Holesky test network @@ -97,45 +97,45 @@ network, you want to join the **test** network with your node, which is fully eq the main network, but with play-Ether only. ```shell -$ geth --holesky console +$ aiigo --holesky console ``` The `console` subcommand has the same meaning as above and is equally useful on the testnet too. -Specifying the `--holesky` flag, however, will reconfigure your `geth` instance a bit: +Specifying the `--holesky` flag, however, will reconfigure your `aiigo` instance a bit: * Instead of connecting to the main Ethereum network, the client will connect to the Holesky test network, which uses different P2P bootnodes, different network IDs and genesis states. - * Instead of using the default data directory (`~/.ethereum` on Linux for example), `geth` + * Instead of using the default data directory (`~/.ethereum` on Linux for example), `aiigo` will nest itself one level deeper into a `holesky` subfolder (`~/.ethereum/holesky` on Linux). Note, on OSX and Linux this also means that attaching to a running testnet node - requires the use of a custom endpoint since `geth attach` will try to attach to a + requires the use of a custom endpoint since `aiigo attach` will try to attach to a production node endpoint by default, e.g., - `geth attach /holesky/geth.ipc`. Windows users are not affected by + `aiigo attach /holesky/aiigo.ipc`. Windows users are not affected by this. *Note: Although some internal protective measures prevent transactions from crossing over between the main network and test network, you should always use separate accounts for play and real money. Unless you manually move -accounts, `geth` will by default correctly separate the two networks and will not make any +accounts, `aiigo` will by default correctly separate the two networks and will not make any accounts available between them.* ### Configuration -As an alternative to passing the numerous flags to the `geth` binary, you can also pass a +As an alternative to passing the numerous flags to the `aiigo` binary, you can also pass a configuration file via: ```shell -$ geth --config /path/to/your_config.toml +$ aiigo --config /path/to/your_config.toml ``` To get an idea of how the file should look like you can use the `dumpconfig` subcommand to export your existing configuration: ```shell -$ geth --your-favourite-flags dumpconfig +$ aiigo --your-favourite-flags dumpconfig ``` #### Docker quick start @@ -149,25 +149,25 @@ docker run -d --name ethereum-node -v /Users/alice/ethereum:/root \ ethereum/client-go ``` -This will start `geth` in snap-sync mode with a DB memory allowance of 1GB, as the +This will start `aiigo` in snap-sync mode with a DB memory allowance of 1GB, as the above command does. It will also create a persistent volume in your home directory for saving your blockchain as well as map the default ports. There is also an `alpine` tag available for a slim version of the image. Do not forget `--http.addr 0.0.0.0`, if you want to access RPC from other containers -and/or hosts. By default, `geth` binds to the local interface and RPC endpoints are not +and/or hosts. By default, `aiigo` binds to the local interface and RPC endpoints are not accessible from the outside. -### Programmatically interfacing `geth` nodes +### Programmatically interfacing `aiigo` nodes -As a developer, sooner rather than later you'll want to start interacting with `geth` and the +As a developer, sooner rather than later you'll want to start interacting with `aiigo` and the Ethereum network via your own programs and not manually through the console. To aid -this, `geth` has built-in support for a JSON-RPC based APIs ([standard APIs](https://ethereum.github.io/execution-apis/api-documentation/) -and [`geth` specific APIs](https://geth.ethereum.org/docs/interacting-with-geth/rpc)). +this, `aiigo` has built-in support for a JSON-RPC based APIs ([standard APIs](https://ethereum.github.io/execution-apis/api-documentation/) +and [`aiigo` specific APIs](https://aiigo.ethereum.org/docs/interacting-with-aiigo/rpc)). These can be exposed via HTTP, WebSockets and IPC (UNIX sockets on UNIX based platforms, and named pipes on Windows). -The IPC interface is enabled by default and exposes all the APIs supported by `geth`, +The IPC interface is enabled by default and exposes all the APIs supported by `aiigo`, whereas the HTTP and WS interfaces need to manually be enabled and only expose a subset of APIs due to security reasons. These can be turned on/off and configured as you'd expect. @@ -188,7 +188,7 @@ HTTP based JSON-RPC API options: * `--ipcpath` Filename for IPC socket/pipe within the datadir (explicit paths escape it) You'll need to use your own programming environments' capabilities (libraries, tools, etc) to -connect via HTTP, WS or IPC to a `geth` node configured with the above flags and you'll +connect via HTTP, WS or IPC to a `aiigo` node configured with the above flags and you'll need to speak [JSON-RPC](https://www.jsonrpc.org/specification) on all transports. You can reuse the same connection for multiple requests! @@ -204,13 +204,13 @@ Maintaining your own private network is more involved as a lot of configurations granted in the official networks need to be manually set up. Unfortunately since [the Merge](https://ethereum.org/en/roadmap/merge/) it is no longer possible -to easily set up a network of geth nodes without also setting up a corresponding beacon chain. +to easily set up a network of aiigo nodes without also setting up a corresponding beacon chain. There are three different solutions depending on your use case: - * If you are looking for a simple way to test smart contracts from go in your CI, you can use the [Simulated Backend](https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings#blockchain-simulator). - * If you want a convenient single node environment for testing, you can use our [Dev Mode](https://geth.ethereum.org/docs/developers/dapp-developer/dev-mode). - * If you are looking for a multiple node test network, you can set one up quite easily with [Kurtosis](https://geth.ethereum.org/docs/fundamentals/kurtosis). + * If you are looking for a simple way to test smart contracts from go in your CI, you can use the [Simulated Backend](https://aiigo.ethereum.org/docs/developers/dapp-developer/native-bindings#blockchain-simulator). + * If you want a convenient single node environment for testing, you can use our [Dev Mode](https://aiigo.ethereum.org/docs/developers/dapp-developer/dev-mode). + * If you are looking for a multiple node test network, you can set one up quite easily with [Kurtosis](https://aiigo.ethereum.org/docs/fundamentals/kurtosis). ## Contribution @@ -234,15 +234,15 @@ Please make sure your contributions adhere to our coding guidelines: * Commit messages should be prefixed with the package(s) they modify. * E.g. "eth, rpc: make trace configs optional" -Please see the [Developers' Guide](https://geth.ethereum.org/docs/developers/geth-developer/dev-guide) +Please see the [Developers' Guide](https://aiigo.ethereum.org/docs/developers/aiigo-developer/dev-guide) for more details on configuring your environment, managing project dependencies, and testing procedures. -### Contributing to geth.ethereum.org +### Contributing to aiigo.ethereum.org -For contributions to the [go-ethereum website](https://geth.ethereum.org), please checkout and raise pull requests against the `website` branch. +For contributions to the [go-ethereum website](https://aiigo.ethereum.org), please checkout and raise pull requests against the `website` branch. For more detailed instructions please see the `website` branch [README](https://github.com/ethereum/go-ethereum/tree/website#readme) or the -[contributing](https://geth.ethereum.org/docs/developers/geth-developer/contributing) page of the website. +[contributing](https://aiigo.ethereum.org/docs/developers/aiigo-developer/contributing) page of the website. ## License diff --git a/SECURITY.md b/SECURITY.md index 0b497b44ae..b0eac22838 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -10,7 +10,7 @@ Audit reports are published in the `docs` folder: https://github.com/ethereum/go | Scope | Date | Report Link | | ------- | ------- | ----------- | -| `geth` | 20170425 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2017-04-25_Geth-audit_Truesec.pdf) | +| `aiigo` | 20170425 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2017-04-25_Aiigo-audit_Truesec.pdf) | | `clef` | 20180914 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2018-09-14_Clef-audit_NCC.pdf) | | `Discv5` | 20191015 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2019-10-15_Discv5_audit_LeastAuthority.pdf) | | `Discv5` | 20200124 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2020-01-24_DiscV5_audit_Cure53.pdf) | @@ -21,7 +21,7 @@ Audit reports are published in the `docs` folder: https://github.com/ethereum/go To find out how to disclose a vulnerability in Ethereum visit [https://bounty.ethereum.org](https://bounty.ethereum.org) or email bounty@ethereum.org. Please read the [disclosure page](https://github.com/ethereum/go-ethereum/security/advisories?state=published) for more information about publicly disclosed security vulnerabilities. -Use the built-in `geth version-check` feature to check whether the software is affected by any known vulnerability. This command will fetch the latest [`vulnerabilities.json`](https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json) file which contains known security vulnerabilities concerning `geth`, and cross-check the data against its own version number. +Use the built-in `aiigo version-check` feature to check whether the software is affected by any known vulnerability. This command will fetch the latest [`vulnerabilities.json`](https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities.json) file which contains known security vulnerabilities concerning `aiigo`, and cross-check the data against its own version number. The following key may be used to communicate sensitive information to developers. diff --git a/accounts/abi/abigen/bind.go b/accounts/abi/abigen/bind.go index 56e5e214de..104e16083f 100644 --- a/accounts/abi/abigen/bind.go +++ b/accounts/abi/abigen/bind.go @@ -17,7 +17,7 @@ // Package abigen generates Ethereum contract Go bindings. // // Detailed usage document and tutorial available on the go-ethereum Wiki page: -// https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings +// https://aiigo.ethereum.org/docs/developers/dapp-developer/native-bindings package abigen import ( diff --git a/accounts/manager.go b/accounts/manager.go index ac21ecd985..eb329db598 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -102,7 +102,7 @@ func (am *Manager) Close() error { } // AddBackend starts the tracking of an additional backend for wallet updates. -// cmd/geth assumes once this func returns the backends have been already integrated. +// cmd/aiigo assumes once this func returns the backends have been already integrated. func (am *Manager) AddBackend(backend Backend) { done := make(chan struct{}) am.newBackends <- newBackendEvent{backend, done} diff --git a/accounts/scwallet/README.md b/accounts/scwallet/README.md index 28079c4743..c688623230 100644 --- a/accounts/scwallet/README.md +++ b/accounts/scwallet/README.md @@ -22,13 +22,13 @@ At the end of this process, you will be provided with a PIN, a PUK and a pairing password. Write them down, you'll need them shortly. - Start `geth` with the `console` command. You will notice the following warning: + Start `aiigo` with the `console` command. You will notice the following warning: ``` WARN [04-09|16:58:38.898] Failed to open wallet url=keycard://044def09 err="smartcard: pairing password needed" ``` - Write down the URL (`keycard://044def09` in this example). Then ask `geth` to open the wallet: + Write down the URL (`keycard://044def09` in this example). Then ask `aiigo` to open the wallet: ``` > personal.openWallet("keycard://044def09", "pairing password") @@ -82,7 +82,7 @@ ## Usage - 1. Start `geth` with the `console` command + 1. Start `aiigo` with the `console` command 2. Check the card's URL by checking `personal.listWallets`: ``` @@ -102,5 +102,5 @@ personal.openWallet("keycard://a4d73015") ## Known issues - * Starting geth with a valid card seems to make firefox crash. + * Starting aiigo with a valid card seems to make firefox crash. * PCSC version 4.4 should work, but is currently untested diff --git a/appveyor.yml b/appveyor.yml index ae1c74c18e..19a1c88491 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -53,7 +53,7 @@ for: - go run build/ci.go install -dlgo -arch %GETH_ARCH% -cc %GETH_CC% after_build: # Upload builds. Note that ci.go makes this a no-op PR builds. - - go run build/ci.go archive -arch %GETH_ARCH% -type zip -signer WINDOWS_SIGNING_KEY -upload gethstore/builds - - go run build/ci.go nsis -arch %GETH_ARCH% -signer WINDOWS_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go archive -arch %GETH_ARCH% -type zip -signer WINDOWS_SIGNING_KEY -upload aiigostore/builds + - go run build/ci.go nsis -arch %GETH_ARCH% -signer WINDOWS_SIGNING_KEY -upload aiigostore/builds test_script: - go run build/ci.go test -dlgo -arch %GETH_ARCH% -cc %GETH_CC% -short diff --git a/beacon/engine/errors.go b/beacon/engine/errors.go index 62773a0ea9..63501e5e8d 100644 --- a/beacon/engine/errors.go +++ b/beacon/engine/errors.go @@ -22,7 +22,7 @@ import ( ) // EngineAPIError is a standardized error message between consensus and execution -// clients, also containing any custom error message Geth might include. +// clients, also containing any custom error message Aiigo might include. type EngineAPIError struct { code int msg string diff --git a/build/bot/macos-build.sh b/build/bot/macos-build.sh index f1620bca86..6cf6345c1c 100644 --- a/build/bot/macos-build.sh +++ b/build/bot/macos-build.sh @@ -8,7 +8,7 @@ xcodebuild -version # -- Build for macOS and upload to Azure go run build/ci.go install -dlgo -go run build/ci.go archive -type tar # -signer OSX_SIGNING_KEY -upload gethstore/builds +go run build/ci.go archive -type tar # -signer OSX_SIGNING_KEY -upload aiigostore/builds # # -- CocoaPods # gem uninstall cocoapods -a -x @@ -19,4 +19,4 @@ go run build/ci.go archive -type tar # -signer OSX_SIGNING_KEY -upload gethstore # pod setup --verbose # # -- Build for iOS and upload to Azure -# go run build/ci.go xcode -signer IOS_SIGNING_KEY -upload gethstore/builds +# go run build/ci.go xcode -signer IOS_SIGNING_KEY -upload aiigostore/builds diff --git a/build/bot/ppa-build.sh b/build/bot/ppa-build.sh index ca04262a20..fc30135205 100644 --- a/build/bot/ppa-build.sh +++ b/build/bot/ppa-build.sh @@ -14,4 +14,4 @@ mkdir -p ~/.ssh echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts # Build the source package and upload. -go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder " +go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user aiigo-ci -signer "Go Ethereum Linux Builder " diff --git a/build/ci-notes.md b/build/ci-notes.md index edd9adc1c2..f8c226d6e8 100644 --- a/build/ci-notes.md +++ b/build/ci-notes.md @@ -47,4 +47,4 @@ Then go into the source package directory for your running distribution and buil Built packages are placed in the dist/ directory. $ cd .. - $ dpkg-deb -c geth-unstable_1.9.6+bionic_amd64.deb + $ dpkg-deb -c aiigo-unstable_1.9.6+bionic_amd64.deb diff --git a/build/ci.go b/build/ci.go index b2ff829d3f..47c87534dc 100644 --- a/build/ci.go +++ b/build/ci.go @@ -63,18 +63,18 @@ import ( ) var ( - // Files that end up in the geth*.zip archive. - gethArchiveFiles = []string{ + // Files that end up in the aiigo*.zip archive. + aiigoArchiveFiles = []string{ "COPYING", - executablePath("geth"), + executablePath("aiigo"), } - // Files that end up in the geth-alltools*.zip archive. + // Files that end up in the aiigo-alltools*.zip archive. allToolsArchiveFiles = []string{ "COPYING", executablePath("abigen"), executablePath("evm"), - executablePath("geth"), + executablePath("aiigo"), executablePath("rlpdump"), executablePath("clef"), } @@ -90,7 +90,7 @@ var ( Description: "Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode.", }, { - BinaryName: "geth", + BinaryName: "aiigo", Description: "Ethereum CLI client.", }, { @@ -567,7 +567,7 @@ func doArchive(cmdline []string) { atype = flag.String("type", "zip", "Type of archive to write (zip|tar)") signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`) signify = flag.String("signify", "", `Environment variable holding the signify key (e.g. LINUX_SIGNIFY_KEY)`) - upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "aiigostore/builds")`) ext string ) flag.CommandLine.Parse(cmdline) @@ -582,18 +582,18 @@ func doArchive(cmdline []string) { var ( env = build.Env() - basegeth = archiveBasename(*arch, version.Archive(env.Commit)) - geth = "geth-" + basegeth + ext - alltools = "geth-alltools-" + basegeth + ext + baseaiigo = archiveBasename(*arch, version.Archive(env.Commit)) + aiigo = "aiigo-" + baseaiigo + ext + alltools = "aiigo-alltools-" + baseaiigo + ext ) maybeSkipArchive(env) - if err := build.WriteArchive(geth, gethArchiveFiles); err != nil { + if err := build.WriteArchive(aiigo, aiigoArchiveFiles); err != nil { log.Fatal(err) } if err := build.WriteArchive(alltools, allToolsArchiveFiles); err != nil { log.Fatal(err) } - for _, archive := range []string{geth, alltools} { + for _, archive := range []string{aiigo, alltools} { if err := archiveUpload(archive, *upload, *signer, *signify); err != nil { log.Fatal(err) } @@ -624,7 +624,7 @@ func archiveUpload(archive string, blobstore string, signer string, signifyVar s } if signifyVar != "" { key := os.Getenv(signifyVar) - untrustedComment := "verify with geth-release.pub" + untrustedComment := "verify with aiigo-release.pub" trustedComment := fmt.Sprintf("%s (%s)", archive, time.Now().UTC().Format(time.RFC1123)) if err := signify.SignFile(archive, archive+".sig", key, untrustedComment, trustedComment); err != nil { return err @@ -689,14 +689,14 @@ func doDockerBuildx(cmdline []string) { build.MustRun(auther) } // Retrieve the version infos to build and push to the following paths: - // - ethereum/client-go:latest - Pushes to the master branch, Geth only - // - ethereum/client-go:stable - Version tag publish on GitHub, Geth only - // - ethereum/client-go:alltools-latest - Pushes to the master branch, Geth & tools - // - ethereum/client-go:alltools-stable - Version tag publish on GitHub, Geth & tools - // - ethereum/client-go:release-. - Version tag publish on GitHub, Geth only - // - ethereum/client-go:alltools-release-. - Version tag publish on GitHub, Geth & tools - // - ethereum/client-go:v.. - Version tag publish on GitHub, Geth only - // - ethereum/client-go:alltools-v.. - Version tag publish on GitHub, Geth & tools + // - ethereum/client-go:latest - Pushes to the master branch, Aiigo only + // - ethereum/client-go:stable - Version tag publish on GitHub, Aiigo only + // - ethereum/client-go:alltools-latest - Pushes to the master branch, Aiigo & tools + // - ethereum/client-go:alltools-stable - Version tag publish on GitHub, Aiigo & tools + // - ethereum/client-go:release-. - Version tag publish on GitHub, Aiigo only + // - ethereum/client-go:alltools-release-. - Version tag publish on GitHub, Aiigo & tools + // - ethereum/client-go:v.. - Version tag publish on GitHub, Aiigo only + // - ethereum/client-go:alltools-v.. - Version tag publish on GitHub, Aiigo & tools var tags []string switch { @@ -719,12 +719,12 @@ func doDockerBuildx(cmdline []string) { {file: "Dockerfile.alltools", base: fmt.Sprintf("%s:alltools-", *hubImage)}, } { for _, tag := range tags { // latest, stable etc - gethImage := fmt.Sprintf("%s%s", spec.base, tag) + aiigoImage := fmt.Sprintf("%s%s", spec.base, tag) cmd := exec.Command("docker", "buildx", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+version.WithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, - "--tag", gethImage, + "--tag", aiigoImage, "--platform", *platform, "--file", spec.file, ) @@ -743,7 +743,7 @@ func doDebianSource(cmdline []string) { cachedir = flag.String("cachedir", "./build/cache", `Filesystem path to cache the downloaded Go bundles at`) signer = flag.String("signer", "", `Signing key name, also used as package author`) upload = flag.String("upload", "", `Where to upload the source package (usually "ethereum/ethereum")`) - sshUser = flag.String("sftp-user", "", `Username for SFTP upload (usually "geth-ci")`) + sshUser = flag.String("sftp-user", "", `Username for SFTP upload (usually "aiigo-ci")`) workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) now = time.Now() ) @@ -904,7 +904,7 @@ func makeWorkdir(wdflag string) string { if wdflag != "" { err = os.MkdirAll(wdflag, 0744) } else { - wdflag, err = os.MkdirTemp("", "geth-build-") + wdflag, err = os.MkdirTemp("", "aiigo-build-") } if err != nil { log.Fatal(err) @@ -1058,7 +1058,7 @@ func doWindowsInstaller(cmdline []string) { arch = flag.String("arch", runtime.GOARCH, "Architecture for cross build packaging") signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. WINDOWS_SIGNING_KEY)`) signify = flag.String("signify key", "", `Environment variable holding the signify signing key (e.g. WINDOWS_SIGNIFY_KEY)`) - upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "aiigostore/builds")`) workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) ) flag.CommandLine.Parse(cmdline) @@ -1070,28 +1070,28 @@ func doWindowsInstaller(cmdline []string) { var ( devTools []string allTools []string - gethTool string + aiigoTool string ) for _, file := range allToolsArchiveFiles { if file == "COPYING" { // license, copied later continue } allTools = append(allTools, filepath.Base(file)) - if filepath.Base(file) == "geth.exe" { - gethTool = file + if filepath.Base(file) == "aiigo.exe" { + aiigoTool = file } else { devTools = append(devTools, file) } } // Render NSIS scripts: Installer NSIS contains two installer sections, - // first section contains the geth binary, second section holds the dev tools. + // first section contains the aiigo binary, second section holds the dev tools. templateData := map[string]interface{}{ "License": "COPYING", - "Geth": gethTool, + "Aiigo": aiigoTool, "DevTools": devTools, } - build.Render("build/nsis.geth.nsi", filepath.Join(*workdir, "geth.nsi"), 0644, nil) + build.Render("build/nsis.aiigo.nsi", filepath.Join(*workdir, "aiigo.nsi"), 0644, nil) build.Render("build/nsis.install.nsh", filepath.Join(*workdir, "install.nsh"), 0644, templateData) build.Render("build/nsis.uninstall.nsh", filepath.Join(*workdir, "uninstall.nsh"), 0644, allTools) build.Render("build/nsis.pathupdate.nsh", filepath.Join(*workdir, "PathUpdate.nsh"), 0644, nil) @@ -1109,7 +1109,7 @@ func doWindowsInstaller(cmdline []string) { if env.Commit != "" { ver[2] += "-" + env.Commit[:8] } - installer, err := filepath.Abs("geth-" + archiveBasename(*arch, version.Archive(env.Commit)) + ".exe") + installer, err := filepath.Abs("aiigo-" + archiveBasename(*arch, version.Archive(env.Commit)) + ".exe") if err != nil { log.Fatalf("Failed to convert installer file path: %v", err) } @@ -1119,7 +1119,7 @@ func doWindowsInstaller(cmdline []string) { "/DMINORVERSION="+ver[1], "/DBUILDVERSION="+ver[2], "/DARCH="+*arch, - filepath.Join(*workdir, "geth.nsi"), + filepath.Join(*workdir, "aiigo.nsi"), ) // Sign and publish installer. if err := archiveUpload(installer, *upload, *signer, *signify); err != nil { @@ -1131,7 +1131,7 @@ func doWindowsInstaller(cmdline []string) { func doPurge(cmdline []string) { var ( - store = flag.String("store", "", `Destination from where to purge archives (usually "gethstore/builds")`) + store = flag.String("store", "", `Destination from where to purge archives (usually "aiigostore/builds")`) limit = flag.Int("days", 30, `Age threshold above which to delete unstable archives`) ) flag.CommandLine.Parse(cmdline) diff --git a/build/deb/ethereum/completions/bash/geth b/build/deb/ethereum/completions/bash/geth index a78952793e..fb9b5354b1 100755 --- a/build/deb/ethereum/completions/bash/geth +++ b/build/deb/ethereum/completions/bash/geth @@ -1,4 +1,4 @@ -_geth_bash_autocomplete() { +_aiigo_bash_autocomplete() { if [[ "${COMP_WORDS[0]}" != "source" ]]; then local cur opts base COMPREPLY=() @@ -13,4 +13,4 @@ _geth_bash_autocomplete() { fi } -complete -o bashdefault -o default -o nospace -F _geth_bash_autocomplete geth +complete -o bashdefault -o default -o nospace -F _aiigo_bash_autocomplete aiigo diff --git a/build/deb/ethereum/completions/zsh/_geth b/build/deb/ethereum/completions/zsh/_geth index 119794c532..020882e31d 100644 --- a/build/deb/ethereum/completions/zsh/_geth +++ b/build/deb/ethereum/completions/zsh/_geth @@ -1,4 +1,4 @@ -_geth_zsh_autocomplete() { +_aiigo_zsh_autocomplete() { local -a opts local cur cur=${words[-1]} @@ -15,4 +15,4 @@ _geth_zsh_autocomplete() { fi } -compdef _geth_zsh_autocomplete geth +compdef _aiigo_zsh_autocomplete aiigo diff --git a/build/deb/ethereum/deb.control b/build/deb/ethereum/deb.control index 333e954c17..d86fe3339e 100644 --- a/build/deb/ethereum/deb.control +++ b/build/deb/ethereum/deb.control @@ -11,8 +11,8 @@ Vcs-Browser: https://github.com/ethereum/go-ethereum Package: {{.Name}} Architecture: any Depends: ${misc:Depends}, {{.ExeList}} -Description: Meta-package to install geth and other tools - Meta-package to install geth and other tools +Description: Meta-package to install aiigo and other tools + Meta-package to install aiigo and other tools {{range .Executables}} Package: {{$.ExeName .}} diff --git a/build/deb/ethereum/deb.install b/build/deb/ethereum/deb.install index 5a624594b0..e374eeeb0d 100644 --- a/build/deb/ethereum/deb.install +++ b/build/deb/ethereum/deb.install @@ -1,5 +1,5 @@ build/bin/{{.BinaryName}} usr/bin -{{- if eq .BinaryName "geth" }} -build/deb/ethereum/completions/bash/geth etc/bash_completion.d -build/deb/ethereum/completions/zsh/_geth usr/share/zsh/vendor-completions +{{- if eq .BinaryName "aiigo" }} +build/deb/ethereum/completions/bash/aiigo etc/bash_completion.d +build/deb/ethereum/completions/zsh/_aiigo usr/share/zsh/vendor-completions {{end -}} diff --git a/build/nsis.geth.nsi b/build/nsis.geth.nsi index 03710dd95d..c51a42a6ad 100644 --- a/build/nsis.geth.nsi +++ b/build/nsis.geth.nsi @@ -6,11 +6,11 @@ # - BUILDVERSION, build id version # # The created installer executes the following steps: -# 1. install geth for all users +# 1. install aiigo for all users # 2. install optional development tools such as abigen # 3. create an uninstaller -# 4. configures the Windows firewall for geth -# 5. create geth, attach and uninstall start menu entries +# 4. configures the Windows firewall for aiigo +# 5. create aiigo, attach and uninstall start menu entries # 6. configures the registry that allows Windows to manage the package through its platform tools # 7. adds the environment system wide variable ETHEREUM_SOCKET # 8. adds the install directory to %PATH% @@ -30,7 +30,7 @@ CRCCheck on !define GROUPNAME "Ethereum" -!define APPNAME "Geth" +!define APPNAME "Aiigo" !define DESCRIPTION "Official Go implementation of the Ethereum protocol" !addplugindir .\ @@ -55,7 +55,7 @@ ${EndIf} !macroend function .onInit - # make vars are global for all users since geth is installed global + # make vars are global for all users since aiigo is installed global setShellVarContext all !insertmacro VerifyUserIsAdmin diff --git a/build/nsis.install.nsh b/build/nsis.install.nsh index 9b73148a44..fd73729737 100644 --- a/build/nsis.install.nsh +++ b/build/nsis.install.nsh @@ -1,4 +1,4 @@ -Name "geth ${MAJORVERSION}.${MINORVERSION}.${BUILDVERSION}" # VERSION variables set through command line arguments +Name "aiigo ${MAJORVERSION}.${MINORVERSION}.${BUILDVERSION}" # VERSION variables set through command line arguments InstallDir "$InstDir" OutFile "${OUTPUTFILE}" # set through command line arguments @@ -12,30 +12,30 @@ PageEx license LicenseData {{.License}} PageExEnd -# Install geth binary -Section "Geth" GETH_IDX +# Install aiigo binary +Section "Aiigo" GETH_IDX SetOutPath $INSTDIR - file {{.Geth}} + file {{.Aiigo}} # Create start menu launcher createDirectory "$SMPROGRAMS\${APPNAME}" - createShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\geth.exe" - createShortCut "$SMPROGRAMS\${APPNAME}\Attach.lnk" "$INSTDIR\geth.exe" "attach" + createShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\aiigo.exe" + createShortCut "$SMPROGRAMS\${APPNAME}\Attach.lnk" "$INSTDIR\aiigo.exe" "attach" createShortCut "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" # Firewall - remove rules (if exists) - SimpleFC::AdvRemoveRule "Geth incoming peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Geth outgoing peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Geth UDP discovery (UDP:30303)" + SimpleFC::AdvRemoveRule "Aiigo incoming peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Aiigo outgoing peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Aiigo UDP discovery (UDP:30303)" # Firewall - add rules - SimpleFC::AdvAddRule "Geth incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" 30303 "" "" "" - SimpleFC::AdvAddRule "Geth outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" - SimpleFC::AdvAddRule "Geth UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" + SimpleFC::AdvAddRule "Aiigo incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\aiigo.exe" "" "" "Ethereum" 30303 "" "" "" + SimpleFC::AdvAddRule "Aiigo outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\aiigo.exe" "" "" "Ethereum" "" 30303 "" "" + SimpleFC::AdvAddRule "Aiigo UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\aiigo.exe" "" "" "Ethereum" "" 30303 "" "" # Set default IPC endpoint (https://github.com/ethereum/EIPs/issues/147) - ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\geth.ipc" - ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "A" "HKLM" "\\.\pipe\geth.ipc" + ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\aiigo.ipc" + ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "A" "HKLM" "\\.\pipe\aiigo.ipc" # Add instdir to PATH Push "$INSTDIR" diff --git a/build/nsis.uninstall.nsh b/build/nsis.uninstall.nsh index 6358faa74e..c5aacd8290 100644 --- a/build/nsis.uninstall.nsh +++ b/build/nsis.uninstall.nsh @@ -17,12 +17,12 @@ Section "Uninstall" rmDir "$SMPROGRAMS\${APPNAME}" # Firewall - remove rules if exists - SimpleFC::AdvRemoveRule "Geth incoming peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Geth outgoing peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Geth UDP discovery (UDP:30303)" + SimpleFC::AdvRemoveRule "Aiigo incoming peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Aiigo outgoing peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Aiigo UDP discovery (UDP:30303)" # Remove IPC endpoint (https://github.com/ethereum/EIPs/issues/147) - ${un.EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\geth.ipc" + ${un.EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\aiigo.ipc" # Remove install directory from PATH Push "$INSTDIR" diff --git a/circle.yml b/circle.yml index 39ff5d83c6..f489fb304b 100644 --- a/circle.yml +++ b/circle.yml @@ -23,10 +23,10 @@ dependencies: test: override: - # Build Geth and move into a known folder - - make geth - - cp ./build/bin/geth $HOME/geth + # Build Aiigo and move into a known folder + - make aiigo + - cp ./build/bin/aiigo $HOME/aiigo # Run hive and move all generated logs into the public artifacts folder - - (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=go-ethereum:local --override=$HOME/geth --test=. --sim=.) + - (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=go-ethereum:local --override=$HOME/aiigo --test=. --sim=.) - cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/logs/* $CIRCLE_ARTIFACTS diff --git a/cmd/aiigo/accountcmd.go b/cmd/aiigo/accountcmd.go new file mode 100644 index 0000000000..05c754b9a4 --- /dev/null +++ b/cmd/aiigo/accountcmd.go @@ -0,0 +1,367 @@ +// Copyright 2016 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 . + +package main + +import ( + "errors" + "fmt" + "os" + "strings" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/urfave/cli/v2" +) + +var ( + walletCommand = &cli.Command{ + Name: "wallet", + Usage: "Manage Ethereum presale wallets", + ArgsUsage: "", + Description: ` + aiigo wallet import /path/to/my/presale.wallet + +will prompt for your password and imports your ether presale account. +It can be used non-interactively with the --password option taking a +passwordfile as argument containing the wallet password in plaintext.`, + Subcommands: []*cli.Command{ + { + + Name: "import", + Usage: "Import Ethereum presale wallet", + ArgsUsage: "", + Action: importWallet, + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, + Description: ` + aiigo wallet [options] /path/to/my/presale.wallet + +will prompt for your password and imports your ether presale account. +It can be used non-interactively with the --password option taking a +passwordfile as argument containing the wallet password in plaintext.`, + }, + }, + } + + accountCommand = &cli.Command{ + Name: "account", + Usage: "Manage accounts", + Description: ` + +Manage accounts, list all existing accounts, import a private key into a new +account, create a new account or update an existing account. + +It supports interactive mode, when you are prompted for password as well as +non-interactive mode where passwords are supplied via a given password file. +Non-interactive mode is only meant for scripted use on test networks or known +safe environments. + +Make sure you remember the password you gave when creating a new account (with +either new or import). Without it you are not able to unlock your account. + +Note that exporting your key in unencrypted format is NOT supported. + +Keys are stored under /keystore. +It is safe to transfer the entire directory or the individual keys therein +between ethereum nodes by simply copying. + +Make sure you backup your keys regularly.`, + Subcommands: []*cli.Command{ + { + Name: "list", + Usage: "Print summary of existing accounts", + Action: accountList, + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + }, + Description: ` +Print a short summary of all accounts`, + }, + { + Name: "new", + Usage: "Create a new account", + Action: accountCreate, + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, + Description: ` + aiigo account new + +Creates a new account and prints the address. + +The account is saved in encrypted format, you are prompted for a password. + +You must remember this password to unlock your account in the future. + +For non-interactive use the password can be specified with the --password flag: + +Note, this is meant to be used for testing only, it is a bad idea to save your +password to file or expose in any other way. +`, + }, + { + Name: "update", + Usage: "Update an existing account", + Action: accountUpdate, + ArgsUsage: "
", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.LightKDFFlag, + }, + Description: ` + aiigo account update
+ +Update an existing account. + +The account is saved in the newest version in encrypted format, you are prompted +for a password to unlock the account and another to save the updated file. + +This same command can therefore be used to migrate an account of a deprecated +format to the newest format or change the password for an account. + +For non-interactive use the password can be specified with the --password flag: + + aiigo account update [options]
+ +Since only one password can be given, only format update can be performed, +changing your password is only possible interactively. +`, + }, + { + Name: "import", + Usage: "Import a private key into a new account", + Action: accountImport, + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, + ArgsUsage: "", + Description: ` + aiigo account import + +Imports an unencrypted private key from and creates a new account. +Prints the address. + +The keyfile is assumed to contain an unencrypted private key in hexadecimal format. + +The account is saved in encrypted format, you are prompted for a password. + +You must remember this password to unlock your account in the future. + +For non-interactive use the password can be specified with the -password flag: + + aiigo account import [options] + +Note: +As you can directly copy your encrypted accounts to another ethereum instance, +this import mechanism is not needed when you transfer an account between +nodes. +`, + }, + }, + } +) + +// makeAccountManager creates an account manager with backends +func makeAccountManager(ctx *cli.Context) *accounts.Manager { + cfg := loadBaseConfig(ctx) + am := accounts.NewManager(nil) + keydir, isEphemeral, err := cfg.Node.GetKeyStoreDir() + if err != nil { + utils.Fatalf("Failed to get the keystore directory: %v", err) + } + if isEphemeral { + utils.Fatalf("Can't use ephemeral directory as keystore path") + } + + if err := setAccountManagerBackends(&cfg.Node, am, keydir); err != nil { + utils.Fatalf("Failed to set account manager backends: %v", err) + } + return am +} + +func accountList(ctx *cli.Context) error { + am := makeAccountManager(ctx) + var index int + for _, wallet := range am.Wallets() { + for _, account := range wallet.Accounts() { + fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, &account.URL) + index++ + } + } + + return nil +} + +// readPasswordFromFile reads the first line of the given file, trims line endings, +// and returns the password and whether the reading was successful. +func readPasswordFromFile(path string) (string, bool) { + if path == "" { + return "", false + } + text, err := os.ReadFile(path) + if err != nil { + utils.Fatalf("Failed to read password file: %v", err) + } + lines := strings.Split(string(text), "\n") + if len(lines) == 0 { + return "", false + } + // Sanitise DOS line endings. + return strings.TrimRight(lines[0], "\r"), true +} + +// accountCreate creates a new account into the keystore defined by the CLI flags. +func accountCreate(ctx *cli.Context) error { + cfg := loadBaseConfig(ctx) + keydir, isEphemeral, err := cfg.Node.GetKeyStoreDir() + if err != nil { + utils.Fatalf("Failed to get the keystore directory: %v", err) + } + if isEphemeral { + utils.Fatalf("Can't use ephemeral directory as keystore path") + } + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + if cfg.Node.UseLightweightKDF { + scryptN = keystore.LightScryptN + scryptP = keystore.LightScryptP + } + + password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name)) + if !ok { + password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true) + } + account, err := keystore.StoreKey(keydir, password, scryptN, scryptP) + + if err != nil { + utils.Fatalf("Failed to create account: %v", err) + } + fmt.Printf("\nYour new key was generated\n\n") + fmt.Printf("Public address of the key: %s\n", account.Address.Hex()) + fmt.Printf("Path of the secret key file: %s\n\n", account.URL.Path) + fmt.Printf("- You can share your public address with anyone. Others need it to interact with you.\n") + fmt.Printf("- You must NEVER share the secret key with anyone! The key controls access to your funds!\n") + fmt.Printf("- You must BACKUP your key file! Without the key, it's impossible to access account funds!\n") + fmt.Printf("- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!\n\n") + return nil +} + +// accountUpdate transitions an account from a previous format to the current +// one, also providing the possibility to change the pass-phrase. +func accountUpdate(ctx *cli.Context) error { + if ctx.Args().Len() == 0 { + utils.Fatalf("No accounts specified to update") + } + am := makeAccountManager(ctx) + backends := am.Backends(keystore.KeyStoreType) + if len(backends) == 0 { + utils.Fatalf("Keystore is not available") + } + ks := backends[0].(*keystore.KeyStore) + + for _, addr := range ctx.Args().Slice() { + if !common.IsHexAddress(addr) { + return errors.New("address must be specified in hexadecimal form") + } + account := accounts.Account{Address: common.HexToAddress(addr)} + newPassword := utils.GetPassPhrase("Please give a NEW password. Do not forget this password.", true) + updateFn := func(attempt int) error { + prompt := fmt.Sprintf("Please provide the OLD password for account %s | Attempt %d/%d", addr, attempt+1, 3) + password := utils.GetPassPhrase(prompt, false) + return ks.Update(account, password, newPassword) + } + // let user attempt unlock thrice. + err := updateFn(0) + for attempts := 1; attempts < 3 && errors.Is(err, keystore.ErrDecrypt); attempts++ { + err = updateFn(attempts) + } + if err != nil { + return fmt.Errorf("could not update account: %w", err) + } + } + return nil +} + +func importWallet(ctx *cli.Context) error { + if ctx.Args().Len() != 1 { + utils.Fatalf("keyfile must be given as the only argument") + } + keyfile := ctx.Args().First() + keyJSON, err := os.ReadFile(keyfile) + if err != nil { + utils.Fatalf("Could not read wallet file: %v", err) + } + + am := makeAccountManager(ctx) + backends := am.Backends(keystore.KeyStoreType) + if len(backends) == 0 { + utils.Fatalf("Keystore is not available") + } + password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name)) + if !ok { + password = utils.GetPassPhrase("", false) + } + ks := backends[0].(*keystore.KeyStore) + acct, err := ks.ImportPreSaleKey(keyJSON, password) + if err != nil { + utils.Fatalf("%v", err) + } + fmt.Printf("Address: {%x}\n", acct.Address) + return nil +} + +func accountImport(ctx *cli.Context) error { + if ctx.Args().Len() != 1 { + utils.Fatalf("keyfile must be given as the only argument") + } + keyfile := ctx.Args().First() + key, err := crypto.LoadECDSA(keyfile) + if err != nil { + utils.Fatalf("Failed to load the private key: %v", err) + } + am := makeAccountManager(ctx) + backends := am.Backends(keystore.KeyStoreType) + if len(backends) == 0 { + utils.Fatalf("Keystore is not available") + } + ks := backends[0].(*keystore.KeyStore) + password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name)) + if !ok { + password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true) + } + acct, err := ks.ImportECDSA(key, password) + if err != nil { + utils.Fatalf("Could not create the account: %v", err) + } + fmt.Printf("Address: {%x}\n", acct.Address) + return nil +} diff --git a/cmd/aiigo/accountcmd_test.go b/cmd/aiigo/accountcmd_test.go new file mode 100644 index 0000000000..2f467a3b77 --- /dev/null +++ b/cmd/aiigo/accountcmd_test.go @@ -0,0 +1,207 @@ +// Copyright 2016 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 . + +package main + +import ( + "os" + "path/filepath" + "runtime" + "testing" + + "github.com/cespare/cp" +) + +// These tests are 'smoke tests' for the account related +// subcommands and flags. +// +// For most tests, the test files from package accounts +// are copied into a temporary keystore directory. + +func tmpDatadirWithKeystore(t *testing.T) string { + datadir := t.TempDir() + keystore := filepath.Join(datadir, "keystore") + source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore") + if err := cp.CopyAll(keystore, source); err != nil { + t.Fatal(err) + } + return datadir +} + +func TestAccountListEmpty(t *testing.T) { + t.Parallel() + aiigo := runaiigo(t, "account", "list") + aiigo.ExpectExit() +} + +func TestAccountList(t *testing.T) { + t.Parallel() + datadir := tmpDatadirWithKeystore(t) + var want = ` +Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 +Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa +Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz +` + if runtime.GOOS == "windows" { + want = ` +Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 +Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa +Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz +` + } + { + aiigo := runaiigo(t, "account", "list", "--datadir", datadir) + aiigo.Expect(want) + aiigo.ExpectExit() + } + { + aiigo := runaiigo(t, "--datadir", datadir, "account", "list") + aiigo.Expect(want) + aiigo.ExpectExit() + } +} + +func TestAccountNew(t *testing.T) { + t.Parallel() + aiigo := runaiigo(t, "account", "new", "--lightkdf") + defer aiigo.ExpectExit() + aiigo.Expect(` +Your new account is locked with a password. Please give a password. Do not forget this password. +!! Unsupported terminal, password will be echoed. +Password: {{.InputLine "foobar"}} +Repeat password: {{.InputLine "foobar"}} + +Your new key was generated +`) + aiigo.ExpectRegexp(` +Public address of the key: 0x[0-9a-fA-F]{40} +Path of the secret key file: .*UTC--.+--[0-9a-f]{40} + +- You can share your public address with anyone. Others need it to interact with you. +- You must NEVER share the secret key with anyone! The key controls access to your funds! +- You must BACKUP your key file! Without the key, it's impossible to access account funds! +- You must REMEMBER your password! Without the password, it's impossible to decrypt the key! +`) +} + +func TestAccountImport(t *testing.T) { + t.Parallel() + tests := []struct{ name, key, output string }{ + { + name: "correct account", + key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + output: "Address: {fcad0b19bb29d4674531d6f115237e16afce377c}\n", + }, + { + name: "invalid character", + key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef1", + output: "Fatal: Failed to load the private key: invalid character '1' at end of key file\n", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + importAccountWithExpect(t, test.key, test.output) + }) + } +} + +func TestAccountHelp(t *testing.T) { + t.Parallel() + aiigo := runaiigo(t, "account", "-h") + aiigo.WaitExit() + if have, want := aiigo.ExitStatus(), 0; have != want { + t.Errorf("exit error, have %d want %d", have, want) + } + + aiigo = runaiigo(t, "account", "import", "-h") + aiigo.WaitExit() + if have, want := aiigo.ExitStatus(), 0; have != want { + t.Errorf("exit error, have %d want %d", have, want) + } +} + +func importAccountWithExpect(t *testing.T, key string, expected string) { + dir := t.TempDir() + keyfile := filepath.Join(dir, "key.prv") + if err := os.WriteFile(keyfile, []byte(key), 0600); err != nil { + t.Error(err) + } + passwordFile := filepath.Join(dir, "password.txt") + if err := os.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil { + t.Error(err) + } + aiigo := runaiigo(t, "--lightkdf", "account", "import", "-password", passwordFile, keyfile) + defer aiigo.ExpectExit() + aiigo.Expect(expected) +} + +func TestAccountNewBadRepeat(t *testing.T) { + t.Parallel() + aiigo := runaiigo(t, "account", "new", "--lightkdf") + defer aiigo.ExpectExit() + aiigo.Expect(` +Your new account is locked with a password. Please give a password. Do not forget this password. +!! Unsupported terminal, password will be echoed. +Password: {{.InputLine "something"}} +Repeat password: {{.InputLine "something else"}} +Fatal: Passwords do not match +`) +} + +func TestAccountUpdate(t *testing.T) { + t.Parallel() + datadir := tmpDatadirWithKeystore(t) + aiigo := runaiigo(t, "account", "update", + "--datadir", datadir, "--lightkdf", + "f466859ead1932d743d622cb74fc058882e8648a") + defer aiigo.ExpectExit() + aiigo.Expect(` +Please give a NEW password. Do not forget this password. +!! Unsupported terminal, password will be echoed. +Password: {{.InputLine "foobar2"}} +Repeat password: {{.InputLine "foobar2"}} +Please provide the OLD password for account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 +Password: {{.InputLine "foobar"}} +`) +} + +func TestWalletImport(t *testing.T) { + t.Parallel() + aiigo := runaiigo(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") + defer aiigo.ExpectExit() + aiigo.Expect(` +!! Unsupported terminal, password will be echoed. +Password: {{.InputLine "foo"}} +Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f} +`) + + files, err := os.ReadDir(filepath.Join(aiigo.Datadir, "keystore")) + if len(files) != 1 { + t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err) + } +} + +func TestWalletImportBadPassword(t *testing.T) { + t.Parallel() + aiigo := runaiigo(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") + defer aiigo.ExpectExit() + aiigo.Expect(` +!! Unsupported terminal, password will be echoed. +Password: {{.InputLine "wrong"}} +Fatal: could not decrypt key with given password +`) +} diff --git a/cmd/aiigo/attach_test.go b/cmd/aiigo/attach_test.go new file mode 100644 index 0000000000..65273ee253 --- /dev/null +++ b/cmd/aiigo/attach_test.go @@ -0,0 +1,83 @@ +// Copyright 2022 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 . + +package main + +import ( + "fmt" + "net" + "net/http" + "sync/atomic" + "testing" +) + +type testHandler struct { + body func(http.ResponseWriter, *http.Request) +} + +func (t *testHandler) ServeHTTP(out http.ResponseWriter, in *http.Request) { + t.body(out, in) +} + +// TestAttachWithHeaders tests that 'aiigo attach' with custom headers works, i.e +// that custom headers are forwarded to the target. +func TestAttachWithHeaders(t *testing.T) { + t.Parallel() + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal(err) + } + port := ln.Addr().(*net.TCPAddr).Port + testReceiveHeaders(t, ln, "attach", "-H", "first: one", "-H", "second: two", fmt.Sprintf("http://localhost:%d", port)) + // This way to do it fails due to flag ordering: + // + // testReceiveHeaders(t, ln, "-H", "first: one", "-H", "second: two", "attach", fmt.Sprintf("http://localhost:%d", port)) + // This is fixed in a follow-up PR. +} + +// TestRemoteDbWithHeaders tests that 'aiigo db --remotedb' with custom headers works, i.e +// that custom headers are forwarded to the target. +func TestRemoteDbWithHeaders(t *testing.T) { + t.Parallel() + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatal(err) + } + port := ln.Addr().(*net.TCPAddr).Port + testReceiveHeaders(t, ln, "db", "metadata", "--remotedb", fmt.Sprintf("http://localhost:%d", port), "-H", "first: one", "-H", "second: two") +} + +func testReceiveHeaders(t *testing.T, ln net.Listener, aiigoArgs ...string) { + var ok atomic.Uint32 + server := &http.Server{ + Addr: "localhost:0", + Handler: &testHandler{func(w http.ResponseWriter, r *http.Request) { + // We expect two headers + if have, want := r.Header.Get("first"), "one"; have != want { + t.Fatalf("missing header, have %v want %v", have, want) + } + if have, want := r.Header.Get("second"), "two"; have != want { + t.Fatalf("missing header, have %v want %v", have, want) + } + ok.Store(1) + }}} + go server.Serve(ln) + defer server.Close() + runaiigo(t, aiigoArgs...).WaitExit() + if ok.Load() != 1 { + t.Fatal("Test fail, expected invocation to succeed") + } +} diff --git a/cmd/aiigo/chaincmd.go b/cmd/aiigo/chaincmd.go new file mode 100644 index 0000000000..16fa69e0af --- /dev/null +++ b/cmd/aiigo/chaincmd.go @@ -0,0 +1,660 @@ +// Copyright 2015 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 . + +package main + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "runtime" + "slices" + "strconv" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/internal/era" + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/urfave/cli/v2" +) + +var ( + initCommand = &cli.Command{ + Action: initGenesis, + Name: "init", + Usage: "Bootstrap and initialize a new genesis block", + ArgsUsage: "", + Flags: slices.Concat([]cli.Flag{ + utils.CachePreimagesFlag, + utils.OverridePrague, + utils.OverrideVerkle, + }, utils.DatabaseFlags), + Description: ` +The init command initializes a new genesis block and definition for the network. +This is a destructive action and changes the network in which you will be +participating. + +It expects the genesis file as argument.`, + } + dumpGenesisCommand = &cli.Command{ + Action: dumpGenesis, + Name: "dumpgenesis", + Usage: "Dumps genesis block JSON configuration to stdout", + ArgsUsage: "", + Flags: slices.Concat([]cli.Flag{utils.DataDirFlag}, utils.NetworkFlags), + Description: ` +The dumpgenesis command prints the genesis configuration of the network preset +if one is set. Otherwise it prints the genesis from the datadir.`, + } + importCommand = &cli.Command{ + Action: importChain, + Name: "import", + Usage: "Import a blockchain file", + ArgsUsage: " ( ... ) ", + Flags: slices.Concat([]cli.Flag{ + utils.CacheFlag, + utils.GCModeFlag, + utils.SnapshotFlag, + utils.CacheDatabaseFlag, + utils.CacheGCFlag, + utils.NoCompactionFlag, + utils.MetricsEnabledFlag, + utils.MetricsEnabledExpensiveFlag, + utils.MetricsHTTPFlag, + utils.MetricsPortFlag, + utils.MetricsEnableInfluxDBFlag, + utils.MetricsEnableInfluxDBV2Flag, + utils.MetricsInfluxDBEndpointFlag, + utils.MetricsInfluxDBDatabaseFlag, + utils.MetricsInfluxDBUsernameFlag, + utils.MetricsInfluxDBPasswordFlag, + utils.MetricsInfluxDBTagsFlag, + utils.MetricsInfluxDBTokenFlag, + utils.MetricsInfluxDBBucketFlag, + utils.MetricsInfluxDBOrganizationFlag, + utils.TxLookupLimitFlag, + utils.VMTraceFlag, + utils.VMTraceJsonConfigFlag, + utils.TransactionHistoryFlag, + utils.LogHistoryFlag, + utils.LogNoHistoryFlag, + utils.LogExportCheckpointsFlag, + utils.StateHistoryFlag, + }, utils.DatabaseFlags, debug.Flags), + Before: func(ctx *cli.Context) error { + flags.MigrateGlobalFlags(ctx) + return debug.Setup(ctx) + }, + Description: ` +The import command allows the import of blocks from an RLP-encoded format. This format can be a single file +containing multiple RLP-encoded blocks, or multiple files can be given. + +If only one file is used, an import error will result in the entire import process failing. If +multiple files are processed, the import process will continue even if an individual RLP file fails +to import successfully.`, + } + exportCommand = &cli.Command{ + Action: exportChain, + Name: "export", + Usage: "Export blockchain into file", + ArgsUsage: " [ ]", + Flags: slices.Concat([]cli.Flag{utils.CacheFlag}, utils.DatabaseFlags), + Description: ` +Requires a first argument of the file to write to. +Optional second and third arguments control the first and +last block to write. In this mode, the file will be appended +if already existing. If the file ends with .gz, the output will +be gzipped.`, + } + importHistoryCommand = &cli.Command{ + Action: importHistory, + Name: "import-history", + Usage: "Import an Era archive", + ArgsUsage: "", + Flags: slices.Concat([]cli.Flag{utils.TxLookupLimitFlag, utils.TransactionHistoryFlag}, utils.DatabaseFlags, utils.NetworkFlags), + Description: ` +The import-history command will import blocks and their corresponding receipts +from Era archives. +`, + } + exportHistoryCommand = &cli.Command{ + Action: exportHistory, + Name: "export-history", + Usage: "Export blockchain history to Era archives", + ArgsUsage: " ", + Flags: utils.DatabaseFlags, + Description: ` +The export-history command will export blocks and their corresponding receipts +into Era archives. Eras are typically packaged in steps of 8192 blocks. +`, + } + importPreimagesCommand = &cli.Command{ + Action: importPreimages, + Name: "import-preimages", + Usage: "Import the preimage database from an RLP stream", + ArgsUsage: "", + Flags: slices.Concat([]cli.Flag{utils.CacheFlag}, utils.DatabaseFlags), + Description: ` +The import-preimages command imports hash preimages from an RLP encoded stream. +It's deprecated, please use "aiigo db import" instead. +`, + } + + dumpCommand = &cli.Command{ + Action: dump, + Name: "dump", + Usage: "Dump a specific block from storage", + ArgsUsage: "[? | ]", + Flags: slices.Concat([]cli.Flag{ + utils.CacheFlag, + utils.IterativeOutputFlag, + utils.ExcludeCodeFlag, + utils.ExcludeStorageFlag, + utils.IncludeIncompletesFlag, + utils.StartKeyFlag, + utils.DumpLimitFlag, + }, utils.DatabaseFlags), + Description: ` +This command dumps out the state for a given block (or latest, if none provided). +`, + } + + pruneCommand = &cli.Command{ + Action: pruneHistory, + Name: "prune-history", + Usage: "Prune blockchain history (block bodies and receipts) up to the merge block", + ArgsUsage: "", + Flags: utils.DatabaseFlags, + Description: ` +The prune-history command removes historical block bodies and receipts from the +blockchain database up to the merge block, while preserving block headers. This +helps reduce storage requirements for nodes that don't need full historical data.`, + } +) + +// initGenesis will initialise the given JSON format genesis file and writes it as +// the zero'd block (i.e. genesis) or will fail hard if it can't succeed. +func initGenesis(ctx *cli.Context) error { + if ctx.Args().Len() != 1 { + utils.Fatalf("need genesis.json file as the only argument") + } + genesisPath := ctx.Args().First() + if len(genesisPath) == 0 { + utils.Fatalf("invalid path to genesis file") + } + file, err := os.Open(genesisPath) + if err != nil { + utils.Fatalf("Failed to read genesis file: %v", err) + } + defer file.Close() + + genesis := new(core.Genesis) + if err := json.NewDecoder(file).Decode(genesis); err != nil { + utils.Fatalf("invalid genesis file: %v", err) + } + // Open and initialise both full and light databases + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + var overrides core.ChainOverrides + if ctx.IsSet(utils.OverridePrague.Name) { + v := ctx.Uint64(utils.OverridePrague.Name) + overrides.OverridePrague = &v + } + if ctx.IsSet(utils.OverrideVerkle.Name) { + v := ctx.Uint64(utils.OverrideVerkle.Name) + overrides.OverrideVerkle = &v + } + + chaindb, err := stack.OpenDatabaseWithFreezer("chaindata", 0, 0, ctx.String(utils.AncientFlag.Name), "", false) + if err != nil { + utils.Fatalf("Failed to open database: %v", err) + } + defer chaindb.Close() + + triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) + defer triedb.Close() + + _, hash, _, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + if err != nil { + utils.Fatalf("Failed to write genesis block: %v", err) + } + log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash) + + return nil +} + +func dumpGenesis(ctx *cli.Context) error { + // check if there is a testnet preset enabled + var genesis *core.Genesis + if utils.IsNetworkPreset(ctx) { + genesis = utils.MakeGenesis(ctx) + } else if ctx.IsSet(utils.DeveloperFlag.Name) && !ctx.IsSet(utils.DataDirFlag.Name) { + genesis = core.DeveloperGenesisBlock(11_500_000, nil) + } + + if genesis != nil { + if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil { + utils.Fatalf("could not encode genesis: %s", err) + } + return nil + } + + // dump whatever already exists in the datadir + stack, _ := makeConfigNode(ctx) + + db, err := stack.OpenDatabase("chaindata", 0, 0, "", true) + if err != nil { + return err + } + defer db.Close() + + genesis, err = core.ReadGenesis(db) + if err != nil { + utils.Fatalf("failed to read genesis: %s", err) + } + + if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil { + utils.Fatalf("could not encode stored genesis: %s", err) + } + + return nil +} + +func importChain(ctx *cli.Context) error { + if ctx.Args().Len() < 1 { + utils.Fatalf("This command requires an argument.") + } + stack, cfg := makeConfigNode(ctx) + defer stack.Close() + + // Start metrics export if enabled + utils.SetupMetrics(&cfg.Metrics) + + chain, db := utils.MakeChain(ctx, stack, false) + defer db.Close() + + // Start periodically gathering memory profiles + var peakMemAlloc, peakMemSys atomic.Uint64 + go func() { + stats := new(runtime.MemStats) + for { + runtime.ReadMemStats(stats) + if peakMemAlloc.Load() < stats.Alloc { + peakMemAlloc.Store(stats.Alloc) + } + if peakMemSys.Load() < stats.Sys { + peakMemSys.Store(stats.Sys) + } + time.Sleep(5 * time.Second) + } + }() + // Import the chain + start := time.Now() + + var importErr error + + if ctx.Args().Len() == 1 { + if err := utils.ImportChain(chain, ctx.Args().First()); err != nil { + importErr = err + log.Error("Import error", "err", err) + } + } else { + for _, arg := range ctx.Args().Slice() { + if err := utils.ImportChain(chain, arg); err != nil { + importErr = err + log.Error("Import error", "file", arg, "err", err) + if err == utils.ErrImportInterrupted { + break + } + } + } + } + chain.Stop() + fmt.Printf("Import done in %v.\n\n", time.Since(start)) + + // Output pre-compaction stats mostly to see the import trashing + showDBStats(db) + + // Print the memory statistics used by the importing + mem := new(runtime.MemStats) + runtime.ReadMemStats(mem) + + fmt.Printf("Object memory: %.3f MB current, %.3f MB peak\n", float64(mem.Alloc)/1024/1024, float64(peakMemAlloc.Load())/1024/1024) + fmt.Printf("System memory: %.3f MB current, %.3f MB peak\n", float64(mem.Sys)/1024/1024, float64(peakMemSys.Load())/1024/1024) + fmt.Printf("Allocations: %.3f million\n", float64(mem.Mallocs)/1000000) + fmt.Printf("GC pause: %v\n\n", time.Duration(mem.PauseTotalNs)) + + if ctx.Bool(utils.NoCompactionFlag.Name) { + return nil + } + + // Compact the entire database to more accurately measure disk io and print the stats + start = time.Now() + fmt.Println("Compacting entire database...") + if err := db.Compact(nil, nil); err != nil { + utils.Fatalf("Compaction failed: %v", err) + } + fmt.Printf("Compaction done in %v.\n\n", time.Since(start)) + + showDBStats(db) + return importErr +} + +func exportChain(ctx *cli.Context) error { + if ctx.Args().Len() < 1 { + utils.Fatalf("This command requires an argument.") + } + + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chain, db := utils.MakeChain(ctx, stack, true) + defer db.Close() + start := time.Now() + + var err error + fp := ctx.Args().First() + if ctx.Args().Len() < 3 { + err = utils.ExportChain(chain, fp) + } else { + // This can be improved to allow for numbers larger than 9223372036854775807 + first, ferr := strconv.ParseInt(ctx.Args().Get(1), 10, 64) + last, lerr := strconv.ParseInt(ctx.Args().Get(2), 10, 64) + if ferr != nil || lerr != nil { + utils.Fatalf("Export error in parsing parameters: block number not an integer\n") + } + if first < 0 || last < 0 { + utils.Fatalf("Export error: block number must be greater than 0\n") + } + if head := chain.CurrentSnapBlock(); uint64(last) > head.Number.Uint64() { + utils.Fatalf("Export error: block number %d larger than head block %d\n", uint64(last), head.Number.Uint64()) + } + err = utils.ExportAppendChain(chain, fp, uint64(first), uint64(last)) + } + if err != nil { + utils.Fatalf("Export error: %v\n", err) + } + fmt.Printf("Export done in %v\n", time.Since(start)) + return nil +} + +func importHistory(ctx *cli.Context) error { + if ctx.Args().Len() != 1 { + utils.Fatalf("usage: %s", ctx.Command.ArgsUsage) + } + + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chain, db := utils.MakeChain(ctx, stack, false) + defer db.Close() + + var ( + start = time.Now() + dir = ctx.Args().Get(0) + network string + ) + + // Determine network. + if utils.IsNetworkPreset(ctx) { + switch { + case ctx.Bool(utils.MainnetFlag.Name): + network = "mainnet" + case ctx.Bool(utils.SepoliaFlag.Name): + network = "sepolia" + case ctx.Bool(utils.HoleskyFlag.Name): + network = "holesky" + case ctx.Bool(utils.HoodiFlag.Name): + network = "hoodi" + } + } else { + // No network flag set, try to determine network based on files + // present in directory. + var networks []string + for _, n := range params.NetworkNames { + entries, err := era.ReadDir(dir, n) + if err != nil { + return fmt.Errorf("error reading %s: %w", dir, err) + } + if len(entries) > 0 { + networks = append(networks, n) + } + } + if len(networks) == 0 { + return fmt.Errorf("no era1 files found in %s", dir) + } + if len(networks) > 1 { + return errors.New("multiple networks found, use a network flag to specify desired network") + } + network = networks[0] + } + + if err := utils.ImportHistory(chain, db, dir, network); err != nil { + return err + } + fmt.Printf("Import done in %v\n", time.Since(start)) + return nil +} + +// exportHistory exports chain history in Era archives at a specified +// directory. +func exportHistory(ctx *cli.Context) error { + if ctx.Args().Len() != 3 { + utils.Fatalf("usage: %s", ctx.Command.ArgsUsage) + } + + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chain, _ := utils.MakeChain(ctx, stack, true) + start := time.Now() + + var ( + dir = ctx.Args().Get(0) + first, ferr = strconv.ParseInt(ctx.Args().Get(1), 10, 64) + last, lerr = strconv.ParseInt(ctx.Args().Get(2), 10, 64) + ) + if ferr != nil || lerr != nil { + utils.Fatalf("Export error in parsing parameters: block number not an integer\n") + } + if first < 0 || last < 0 { + utils.Fatalf("Export error: block number must be greater than 0\n") + } + if head := chain.CurrentSnapBlock(); uint64(last) > head.Number.Uint64() { + utils.Fatalf("Export error: block number %d larger than head block %d\n", uint64(last), head.Number.Uint64()) + } + err := utils.ExportHistory(chain, dir, uint64(first), uint64(last), uint64(era.MaxEra1Size)) + if err != nil { + utils.Fatalf("Export error: %v\n", err) + } + fmt.Printf("Export done in %v\n", time.Since(start)) + return nil +} + +// importPreimages imports preimage data from the specified file. +// it is deprecated, and the export function has been removed, but +// the import function is kept around for the time being so that +// older file formats can still be imported. +func importPreimages(ctx *cli.Context) error { + if ctx.Args().Len() < 1 { + utils.Fatalf("This command requires an argument.") + } + + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, false) + defer db.Close() + start := time.Now() + + if err := utils.ImportPreimages(db, ctx.Args().First()); err != nil { + utils.Fatalf("Import error: %v\n", err) + } + fmt.Printf("Import done in %v\n", time.Since(start)) + return nil +} + +func parseDumpConfig(ctx *cli.Context, db ethdb.Database) (*state.DumpConfig, common.Hash, error) { + var header *types.Header + if ctx.NArg() > 1 { + return nil, common.Hash{}, fmt.Errorf("expected 1 argument (number or hash), got %d", ctx.NArg()) + } + if ctx.NArg() == 1 { + arg := ctx.Args().First() + if hashish(arg) { + hash := common.HexToHash(arg) + if number := rawdb.ReadHeaderNumber(db, hash); number != nil { + header = rawdb.ReadHeader(db, hash, *number) + } else { + return nil, common.Hash{}, fmt.Errorf("block %x not found", hash) + } + } else { + number, err := strconv.ParseUint(arg, 10, 64) + if err != nil { + return nil, common.Hash{}, err + } + if hash := rawdb.ReadCanonicalHash(db, number); hash != (common.Hash{}) { + header = rawdb.ReadHeader(db, hash, number) + } else { + return nil, common.Hash{}, fmt.Errorf("header for block %d not found", number) + } + } + } else { + // Use latest + header = rawdb.ReadHeadHeader(db) + } + if header == nil { + return nil, common.Hash{}, errors.New("no head block found") + } + startArg := common.FromHex(ctx.String(utils.StartKeyFlag.Name)) + var start common.Hash + switch len(startArg) { + case 0: // common.Hash + case 32: + start = common.BytesToHash(startArg) + case 20: + start = crypto.Keccak256Hash(startArg) + log.Info("Converting start-address to hash", "address", common.BytesToAddress(startArg), "hash", start.Hex()) + default: + return nil, common.Hash{}, fmt.Errorf("invalid start argument: %x. 20 or 32 hex-encoded bytes required", startArg) + } + conf := &state.DumpConfig{ + SkipCode: ctx.Bool(utils.ExcludeCodeFlag.Name), + SkipStorage: ctx.Bool(utils.ExcludeStorageFlag.Name), + OnlyWithAddresses: !ctx.Bool(utils.IncludeIncompletesFlag.Name), + Start: start.Bytes(), + Max: ctx.Uint64(utils.DumpLimitFlag.Name), + } + log.Info("State dump configured", "block", header.Number, "hash", header.Hash().Hex(), + "skipcode", conf.SkipCode, "skipstorage", conf.SkipStorage, + "start", hexutil.Encode(conf.Start), "limit", conf.Max) + return conf, header.Root, nil +} + +func dump(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + conf, root, err := parseDumpConfig(ctx, db) + if err != nil { + return err + } + triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup + defer triedb.Close() + + state, err := state.New(root, state.NewDatabase(triedb, nil)) + if err != nil { + return err + } + if ctx.Bool(utils.IterativeOutputFlag.Name) { + state.IterativeDump(conf, json.NewEncoder(os.Stdout)) + } else { + fmt.Println(string(state.Dump(conf))) + } + return nil +} + +// hashish returns true for strings that look like hashes. +func hashish(x string) bool { + _, err := strconv.Atoi(x) + return err != nil +} + +func pruneHistory(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + // Open the chain database + chain, chaindb := utils.MakeChain(ctx, stack, false) + defer chaindb.Close() + defer chain.Stop() + + // Determine the prune point. This will be the first PoS block. + prunePoint, ok := ethconfig.HistoryPrunePoints[chain.Genesis().Hash()] + if !ok || prunePoint == nil { + return errors.New("prune point not found") + } + var ( + mergeBlock = prunePoint.BlockNumber + mergeBlockHash = prunePoint.BlockHash.Hex() + ) + + // Check we're far enough past merge to ensure all data is in freezer + currentHeader := chain.CurrentHeader() + if currentHeader == nil { + return errors.New("current header not found") + } + if currentHeader.Number.Uint64() < mergeBlock+params.FullImmutabilityThreshold { + return fmt.Errorf("chain not far enough past merge block, need %d more blocks", + mergeBlock+params.FullImmutabilityThreshold-currentHeader.Number.Uint64()) + } + + // Double-check the prune block in db has the expected hash. + hash := rawdb.ReadCanonicalHash(chaindb, mergeBlock) + if hash != common.HexToHash(mergeBlockHash) { + return fmt.Errorf("merge block hash mismatch: got %s, want %s", hash.Hex(), mergeBlockHash) + } + + log.Info("Starting history pruning", "head", currentHeader.Number, "tail", mergeBlock, "tailHash", mergeBlockHash) + start := time.Now() + rawdb.PruneTransactionIndex(chaindb, mergeBlock) + if _, err := chaindb.TruncateTail(mergeBlock); err != nil { + return fmt.Errorf("failed to truncate ancient data: %v", err) + } + log.Info("History pruning completed", "tail", mergeBlock, "elapsed", common.PrettyDuration(time.Since(start))) + + // TODO(s1na): what if there is a crash between the two prune operations? + + return nil +} diff --git a/cmd/aiigo/config.go b/cmd/aiigo/config.go new file mode 100644 index 0000000000..f086d15bc6 --- /dev/null +++ b/cmd/aiigo/config.go @@ -0,0 +1,408 @@ +// Copyright 2017 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 . + +package main + +import ( + "bufio" + "errors" + "fmt" + "os" + "reflect" + "runtime" + "slices" + "strings" + "unicode" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/external" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/accounts/scwallet" + "github.com/ethereum/go-ethereum/accounts/usbwallet" + "github.com/ethereum/go-ethereum/beacon/blsync" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/eth/catalyst" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/internal/version" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" + "github.com/naoina/toml" + "github.com/urfave/cli/v2" +) + +var ( + dumpConfigCommand = &cli.Command{ + Action: dumpConfig, + Name: "dumpconfig", + Usage: "Export configuration values in a TOML format", + ArgsUsage: "", + Flags: slices.Concat(nodeFlags, rpcFlags), + Description: `Export configuration values in TOML format (to stdout by default).`, + } + + configFileFlag = &cli.StringFlag{ + Name: "config", + Usage: "TOML configuration file", + Category: flags.EthCategory, + } +) + +// These settings ensure that TOML keys use the same names as Go struct fields. +var tomlSettings = toml.Config{ + NormFieldName: func(rt reflect.Type, key string) string { + return key + }, + FieldToKey: func(rt reflect.Type, field string) string { + return field + }, + MissingField: func(rt reflect.Type, field string) error { + id := fmt.Sprintf("%s.%s", rt.String(), field) + if deprecatedConfigFields[id] { + log.Warn(fmt.Sprintf("Config field '%s' is deprecated and won't have any effect.", id)) + return nil + } + var link string + if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" { + link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name()) + } + return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link) + }, +} + +var deprecatedConfigFields = map[string]bool{ + "ethconfig.Config.EVMInterpreter": true, + "ethconfig.Config.EWASMInterpreter": true, + "ethconfig.Config.TrieCleanCacheJournal": true, + "ethconfig.Config.TrieCleanCacheRejournal": true, + "ethconfig.Config.LightServ": true, + "ethconfig.Config.LightIngress": true, + "ethconfig.Config.LightEgress": true, + "ethconfig.Config.LightPeers": true, + "ethconfig.Config.LightNoPrune": true, + "ethconfig.Config.LightNoSyncServe": true, +} + +type ethstatsConfig struct { + URL string `toml:",omitempty"` +} + +type aiigoConfig struct { + Eth ethconfig.Config + Node node.Config + Ethstats ethstatsConfig + Metrics metrics.Config +} + +func loadConfig(file string, cfg *aiigoConfig) error { + f, err := os.Open(file) + if err != nil { + return err + } + defer f.Close() + + err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg) + // Add file name to errors that have a line number. + if _, ok := err.(*toml.LineError); ok { + err = errors.New(file + ", " + err.Error()) + } + return err +} + +func defaultNodeConfig() node.Config { + git, _ := version.VCS() + cfg := node.DefaultConfig + cfg.Name = clientIdentifier + cfg.Version = version.WithCommit(git.Commit, git.Date) + cfg.HTTPModules = append(cfg.HTTPModules, "eth") + cfg.WSModules = append(cfg.WSModules, "eth") + cfg.IPCPath = clientIdentifier + ".ipc" + return cfg +} + +// loadBaseConfig loads the aiigoConfig based on the given command line +// parameters and config file. +func loadBaseConfig(ctx *cli.Context) aiigoConfig { + // Load defaults. + cfg := aiigoConfig{ + Eth: ethconfig.Defaults, + Node: defaultNodeConfig(), + Metrics: metrics.DefaultConfig, + } + + // Load config file. + if file := ctx.String(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + + // Apply flags. + utils.SetNodeConfig(ctx, &cfg.Node) + return cfg +} + +// makeConfigNode loads aiigo configuration and creates a blank node instance. +func makeConfigNode(ctx *cli.Context) (*node.Node, aiigoConfig) { + cfg := loadBaseConfig(ctx) + stack, err := node.New(&cfg.Node) + if err != nil { + utils.Fatalf("Failed to create the protocol stack: %v", err) + } + // Node doesn't by default populate account manager backends + if err := setAccountManagerBackends(stack.Config(), stack.AccountManager(), stack.KeyStoreDir()); err != nil { + utils.Fatalf("Failed to set account manager backends: %v", err) + } + + utils.SetEthConfig(ctx, stack, &cfg.Eth) + if ctx.IsSet(utils.EthStatsURLFlag.Name) { + cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name) + } + applyMetricConfig(ctx, &cfg) + + return stack, cfg +} + +// makeFullNode loads aiigo configuration and creates the Ethereum backend. +func makeFullNode(ctx *cli.Context) *node.Node { + stack, cfg := makeConfigNode(ctx) + if ctx.IsSet(utils.OverridePrague.Name) { + v := ctx.Uint64(utils.OverridePrague.Name) + cfg.Eth.OverridePrague = &v + } + if ctx.IsSet(utils.OverrideVerkle.Name) { + v := ctx.Uint64(utils.OverrideVerkle.Name) + cfg.Eth.OverrideVerkle = &v + } + + // Start metrics export if enabled + utils.SetupMetrics(&cfg.Metrics) + + backend, eth := utils.RegisterEthService(stack, &cfg.Eth) + + // Create gauge with aiigo system and build information + if eth != nil { // The 'eth' backend may be nil in light mode + var protos []string + for _, p := range eth.Protocols() { + protos = append(protos, fmt.Sprintf("%v/%d", p.Name, p.Version)) + } + metrics.NewRegisteredGaugeInfo("aiigo/info", nil).Update(metrics.GaugeInfoValue{ + "arch": runtime.GOARCH, + "os": runtime.GOOS, + "version": cfg.Node.Version, + "protocols": strings.Join(protos, ","), + }) + } + + // Configure log filter RPC API. + filterSystem := utils.RegisterFilterAPI(stack, backend, &cfg.Eth) + + // Configure GraphQL if requested. + if ctx.IsSet(utils.GraphQLEnabledFlag.Name) { + utils.RegisterGraphQLService(stack, backend, filterSystem, &cfg.Node) + } + // Add the Ethereum Stats daemon if requested. + if cfg.Ethstats.URL != "" { + utils.RegisterEthStatsService(stack, backend, cfg.Ethstats.URL) + } + // Configure full-sync tester service if requested + if ctx.IsSet(utils.SyncTargetFlag.Name) { + hex := hexutil.MustDecode(ctx.String(utils.SyncTargetFlag.Name)) + if len(hex) != common.HashLength { + utils.Fatalf("invalid sync target length: have %d, want %d", len(hex), common.HashLength) + } + utils.RegisterFullSyncTester(stack, eth, common.BytesToHash(hex)) + } + + if ctx.IsSet(utils.DeveloperFlag.Name) { + // Start dev mode. + simBeacon, err := catalyst.NewSimulatedBeacon(ctx.Uint64(utils.DeveloperPeriodFlag.Name), cfg.Eth.Miner.PendingFeeRecipient, eth) + if err != nil { + utils.Fatalf("failed to register dev mode catalyst service: %v", err) + } + catalyst.RegisterSimulatedBeaconAPIs(stack, simBeacon) + stack.RegisterLifecycle(simBeacon) + } else if ctx.IsSet(utils.BeaconApiFlag.Name) { + // Start blsync mode. + srv := rpc.NewServer() + srv.RegisterName("engine", catalyst.NewConsensusAPI(eth)) + blsyncer := blsync.NewClient(utils.MakeBeaconLightConfig(ctx)) + blsyncer.SetEngineRPC(rpc.DialInProc(srv)) + stack.RegisterLifecycle(blsyncer) + } else { + // Launch the engine API for interacting with external consensus client. + err := catalyst.Register(stack, eth) + if err != nil { + utils.Fatalf("failed to register catalyst service: %v", err) + } + } + return stack +} + +// dumpConfig is the dumpconfig command. +func dumpConfig(ctx *cli.Context) error { + _, cfg := makeConfigNode(ctx) + comment := "" + + if cfg.Eth.Genesis != nil { + cfg.Eth.Genesis = nil + comment += "# Note: this config doesn't contain the genesis block.\n\n" + } + + out, err := tomlSettings.Marshal(&cfg) + if err != nil { + return err + } + + dump := os.Stdout + if ctx.NArg() > 0 { + dump, err = os.OpenFile(ctx.Args().Get(0), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + defer dump.Close() + } + dump.WriteString(comment) + dump.Write(out) + + return nil +} + +func applyMetricConfig(ctx *cli.Context, cfg *aiigoConfig) { + if ctx.IsSet(utils.MetricsEnabledFlag.Name) { + cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name) + } + if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) { + log.Warn("Expensive metrics are collected by default, please remove this flag", "flag", utils.MetricsEnabledExpensiveFlag.Name) + } + if ctx.IsSet(utils.MetricsHTTPFlag.Name) { + cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name) + } + if ctx.IsSet(utils.MetricsPortFlag.Name) { + cfg.Metrics.Port = ctx.Int(utils.MetricsPortFlag.Name) + } + if ctx.IsSet(utils.MetricsEnableInfluxDBFlag.Name) { + cfg.Metrics.EnableInfluxDB = ctx.Bool(utils.MetricsEnableInfluxDBFlag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBEndpointFlag.Name) { + cfg.Metrics.InfluxDBEndpoint = ctx.String(utils.MetricsInfluxDBEndpointFlag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBDatabaseFlag.Name) { + cfg.Metrics.InfluxDBDatabase = ctx.String(utils.MetricsInfluxDBDatabaseFlag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBUsernameFlag.Name) { + cfg.Metrics.InfluxDBUsername = ctx.String(utils.MetricsInfluxDBUsernameFlag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBPasswordFlag.Name) { + cfg.Metrics.InfluxDBPassword = ctx.String(utils.MetricsInfluxDBPasswordFlag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBTagsFlag.Name) { + cfg.Metrics.InfluxDBTags = ctx.String(utils.MetricsInfluxDBTagsFlag.Name) + } + if ctx.IsSet(utils.MetricsEnableInfluxDBV2Flag.Name) { + cfg.Metrics.EnableInfluxDBV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBTokenFlag.Name) { + cfg.Metrics.InfluxDBToken = ctx.String(utils.MetricsInfluxDBTokenFlag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name) { + cfg.Metrics.InfluxDBBucket = ctx.String(utils.MetricsInfluxDBBucketFlag.Name) + } + if ctx.IsSet(utils.MetricsInfluxDBOrganizationFlag.Name) { + cfg.Metrics.InfluxDBOrganization = ctx.String(utils.MetricsInfluxDBOrganizationFlag.Name) + } + // Sanity-check the commandline flags. It is fine if some unused fields is part + // of the toml-config, but we expect the commandline to only contain relevant + // arguments, otherwise it indicates an error. + var ( + enableExport = ctx.Bool(utils.MetricsEnableInfluxDBFlag.Name) + enableExportV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name) + ) + if enableExport || enableExportV2 { + v1FlagIsSet := ctx.IsSet(utils.MetricsInfluxDBUsernameFlag.Name) || + ctx.IsSet(utils.MetricsInfluxDBPasswordFlag.Name) + + v2FlagIsSet := ctx.IsSet(utils.MetricsInfluxDBTokenFlag.Name) || + ctx.IsSet(utils.MetricsInfluxDBOrganizationFlag.Name) || + ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name) + + if enableExport && v2FlagIsSet { + utils.Fatalf("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2") + } else if enableExportV2 && v1FlagIsSet { + utils.Fatalf("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1") + } + } +} + +func setAccountManagerBackends(conf *node.Config, am *accounts.Manager, keydir string) error { + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + if conf.UseLightweightKDF { + scryptN = keystore.LightScryptN + scryptP = keystore.LightScryptP + } + + // Assemble the supported backends + if len(conf.ExternalSigner) > 0 { + log.Info("Using external signer", "url", conf.ExternalSigner) + if extBackend, err := external.NewExternalBackend(conf.ExternalSigner); err == nil { + am.AddBackend(extBackend) + return nil + } else { + return fmt.Errorf("error connecting to external signer: %v", err) + } + } + + // For now, we're using EITHER external signer OR local signers. + // If/when we implement some form of lockfile for USB and keystore wallets, + // we can have both, but it's very confusing for the user to see the same + // accounts in both externally and locally, plus very racey. + am.AddBackend(keystore.NewKeyStore(keydir, scryptN, scryptP)) + if conf.USB { + // Start a USB hub for Ledger hardware wallets + if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { + log.Warn(fmt.Sprintf("Failed to start Ledger hub, disabling: %v", err)) + } else { + am.AddBackend(ledgerhub) + } + // Start a USB hub for Trezor hardware wallets (HID version) + if trezorhub, err := usbwallet.NewTrezorHubWithHID(); err != nil { + log.Warn(fmt.Sprintf("Failed to start HID Trezor hub, disabling: %v", err)) + } else { + am.AddBackend(trezorhub) + } + // Start a USB hub for Trezor hardware wallets (WebUSB version) + if trezorhub, err := usbwallet.NewTrezorHubWithWebUSB(); err != nil { + log.Warn(fmt.Sprintf("Failed to start WebUSB Trezor hub, disabling: %v", err)) + } else { + am.AddBackend(trezorhub) + } + } + if len(conf.SmartCardDaemonPath) > 0 { + // Start a smart card hub + if schub, err := scwallet.NewHub(conf.SmartCardDaemonPath, scwallet.Scheme, keydir); err != nil { + log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err)) + } else { + am.AddBackend(schub) + } + } + + return nil +} diff --git a/cmd/aiigo/consolecmd.go b/cmd/aiigo/consolecmd.go new file mode 100644 index 0000000000..4afa8a7669 --- /dev/null +++ b/cmd/aiigo/consolecmd.go @@ -0,0 +1,160 @@ +// Copyright 2016 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 . + +package main + +import ( + "fmt" + "slices" + "strings" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/console" + "github.com/urfave/cli/v2" +) + +var ( + consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} + + consoleCommand = &cli.Command{ + Action: localConsole, + Name: "console", + Usage: "Start an interactive JavaScript environment", + Flags: slices.Concat(nodeFlags, rpcFlags, consoleFlags), + Description: ` +The aiigo console is an interactive shell for the JavaScript runtime environment +which exposes a node admin interface as well as the Ðapp JavaScript API. +See https://aiigo.ethereum.org/docs/interacting-with-aiigo/javascript-console.`, + } + + attachCommand = &cli.Command{ + Action: remoteConsole, + Name: "attach", + Usage: "Start an interactive JavaScript environment (connect to node)", + ArgsUsage: "[endpoint]", + Flags: slices.Concat([]cli.Flag{utils.DataDirFlag, utils.HttpHeaderFlag}, consoleFlags), + Description: ` +The aiigo console is an interactive shell for the JavaScript runtime environment +which exposes a node admin interface as well as the Ðapp JavaScript API. +See https://aiigo.ethereum.org/docs/interacting-with-aiigo/javascript-console. +This command allows to open a console on a running aiigo node.`, + } + + javascriptCommand = &cli.Command{ + Action: ephemeralConsole, + Name: "js", + Usage: "(DEPRECATED) Execute the specified JavaScript files", + ArgsUsage: " [jsfile...]", + Flags: slices.Concat(nodeFlags, consoleFlags), + Description: ` +The JavaScript VM exposes a node admin interface as well as the Ðapp +JavaScript API. See https://aiigo.ethereum.org/docs/interacting-with-aiigo/javascript-console`, + } +) + +// localConsole starts a new aiigo node, attaching a JavaScript console to it at the +// same time. +func localConsole(ctx *cli.Context) error { + // Create and start the node based on the CLI flags + prepare(ctx) + stack := makeFullNode(ctx) + startNode(ctx, stack, true) + defer stack.Close() + + // Attach to the newly started node and create the JavaScript console. + client := stack.Attach() + config := console.Config{ + DataDir: utils.MakeDataDir(ctx), + DocRoot: ctx.String(utils.JSpathFlag.Name), + Client: client, + Preload: utils.MakeConsolePreloads(ctx), + } + console, err := console.New(config) + if err != nil { + return fmt.Errorf("failed to start the JavaScript console: %v", err) + } + defer console.Stop(false) + + // If only a short execution was requested, evaluate and return. + if script := ctx.String(utils.ExecFlag.Name); script != "" { + console.Evaluate(script) + return nil + } + + // Track node shutdown and stop the console when it goes down. + // This happens when SIGTERM is sent to the process. + go func() { + stack.Wait() + console.StopInteractive() + }() + + // Print the welcome screen and enter interactive mode. + console.Welcome() + console.Interactive() + return nil +} + +// remoteConsole will connect to a remote aiigo instance, attaching a JavaScript +// console to it. +func remoteConsole(ctx *cli.Context) error { + if ctx.Args().Len() > 1 { + utils.Fatalf("invalid command-line: too many arguments") + } + endpoint := ctx.Args().First() + if endpoint == "" { + cfg := defaultNodeConfig() + utils.SetDataDir(ctx, &cfg) + endpoint = cfg.IPCEndpoint() + } + client, err := utils.DialRPCWithHeaders(endpoint, ctx.StringSlice(utils.HttpHeaderFlag.Name)) + if err != nil { + utils.Fatalf("Unable to attach to remote aiigo: %v", err) + } + config := console.Config{ + DataDir: utils.MakeDataDir(ctx), + DocRoot: ctx.String(utils.JSpathFlag.Name), + Client: client, + Preload: utils.MakeConsolePreloads(ctx), + } + console, err := console.New(config) + if err != nil { + utils.Fatalf("Failed to start the JavaScript console: %v", err) + } + defer console.Stop(false) + + if script := ctx.String(utils.ExecFlag.Name); script != "" { + console.Evaluate(script) + return nil + } + + // Otherwise print the welcome screen and enter interactive mode + console.Welcome() + console.Interactive() + return nil +} + +// ephemeralConsole starts a new aiigo node, attaches an ephemeral JavaScript +// console to it, executes each of the files specified as arguments and tears +// everything down. +func ephemeralConsole(ctx *cli.Context) error { + var b strings.Builder + for _, file := range ctx.Args().Slice() { + b.WriteString(fmt.Sprintf("loadScript('%s');", file)) + } + utils.Fatalf(`The "js" command is deprecated. Please use the following instead: +aiigo --exec "%s" console`, b.String()) + return nil +} diff --git a/cmd/aiigo/consolecmd_test.go b/cmd/aiigo/consolecmd_test.go new file mode 100644 index 0000000000..b26ecf5d89 --- /dev/null +++ b/cmd/aiigo/consolecmd_test.go @@ -0,0 +1,160 @@ +// Copyright 2016 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 . + +package main + +import ( + "crypto/rand" + "math/big" + "path/filepath" + "runtime" + "strconv" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/internal/version" +) + +const ( + ipcAPIs = "admin:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0" + httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" +) + +// spawns aiigo with the given command line args, using a set of flags to minimise +// memory and disk IO. If the args don't set --datadir, the +// child g gets a temporary data directory. +func runMinimalaiigo(t *testing.T, args ...string) *testaiigo { + // --holesky to make the 'writing genesis to disk' faster (no accounts) + // --networkid=1337 to avoid cache bump + // --syncmode=full to avoid allocating fast sync bloom + allArgs := []string{"--holesky", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0", + "--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64", + "--datadir.minfreedisk", "0"} + return runaiigo(t, append(allArgs, args...)...) +} + +// Tests that a node embedded within a console can be started up properly and +// then terminated by closing the input stream. +func TestConsoleWelcome(t *testing.T) { + t.Parallel() + coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" + + // Start a aiigo console, make sure it's cleaned up and terminate the console + aiigo := runMinimalaiigo(t, "--miner.etherbase", coinbase, "console") + + // Gather all the infos the welcome message needs to contain + aiigo.SetTemplateFunc("goos", func() string { return runtime.GOOS }) + aiigo.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) + aiigo.SetTemplateFunc("gover", runtime.Version) + aiigo.SetTemplateFunc("aiigover", func() string { return version.WithCommit("", "") }) + aiigo.SetTemplateFunc("niltime", func() string { + return time.Unix(1695902100, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)") + }) + aiigo.SetTemplateFunc("apis", func() string { return ipcAPIs }) + + // Verify the actual welcome message to the required template + aiigo.Expect(` +Welcome to the aiigo JavaScript console! + +instance: aiigo/v{{aiigover}}/{{goos}}-{{goarch}}/{{gover}} +at block: 0 ({{niltime}}) + datadir: {{.Datadir}} + modules: {{apis}} + +To exit, press ctrl-d or type exit +> {{.InputLine "exit"}} +`) + aiigo.ExpectExit() +} + +// Tests that a console can be attached to a running node via various means. +func TestAttachWelcome(t *testing.T) { + var ( + ipc string + httpPort string + wsPort string + ) + // Configure the instance for IPC attachment + if runtime.GOOS == "windows" { + ipc = `\\.\pipe\aiigo` + strconv.Itoa(trulyRandInt(100000, 999999)) + } else { + ipc = filepath.Join(t.TempDir(), "aiigo.ipc") + } + // And HTTP + WS attachment + p := trulyRandInt(1024, 65533) // Yeah, sometimes this will fail, sorry :P + httpPort = strconv.Itoa(p) + wsPort = strconv.Itoa(p + 1) + aiigo := runMinimalaiigo(t, "--miner.etherbase", "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182", + "--ipcpath", ipc, + "--http", "--http.port", httpPort, + "--ws", "--ws.port", wsPort) + t.Run("ipc", func(t *testing.T) { + waitForEndpoint(t, ipc, 4*time.Second) + testAttachWelcome(t, aiigo, "ipc:"+ipc, ipcAPIs) + }) + t.Run("http", func(t *testing.T) { + endpoint := "http://127.0.0.1:" + httpPort + waitForEndpoint(t, endpoint, 4*time.Second) + testAttachWelcome(t, aiigo, endpoint, httpAPIs) + }) + t.Run("ws", func(t *testing.T) { + endpoint := "ws://127.0.0.1:" + wsPort + waitForEndpoint(t, endpoint, 4*time.Second) + testAttachWelcome(t, aiigo, endpoint, httpAPIs) + }) + aiigo.Kill() +} + +func testAttachWelcome(t *testing.T, aiigo *testaiigo, endpoint, apis string) { + // Attach to a running aiigo node and terminate immediately + attach := runaiigo(t, "attach", endpoint) + defer attach.ExpectExit() + attach.CloseStdin() + + // Gather all the infos the welcome message needs to contain + attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) + attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) + attach.SetTemplateFunc("gover", runtime.Version) + attach.SetTemplateFunc("aiigover", func() string { return version.WithCommit("", "") }) + attach.SetTemplateFunc("niltime", func() string { + return time.Unix(1695902100, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)") + }) + attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) + attach.SetTemplateFunc("datadir", func() string { return aiigo.Datadir }) + attach.SetTemplateFunc("apis", func() string { return apis }) + + // Verify the actual welcome message to the required template + attach.Expect(` +Welcome to the aiigo JavaScript console! + +instance: aiigo/v{{aiigover}}/{{goos}}-{{goarch}}/{{gover}} +at block: 0 ({{niltime}}){{if ipc}} + datadir: {{datadir}}{{end}} + modules: {{apis}} + +To exit, press ctrl-d or type exit +> {{.InputLine "exit" }} +`) + attach.ExpectExit() +} + +// trulyRandInt generates a crypto random integer used by the console tests to +// not clash network ports with other tests running concurrently. +func trulyRandInt(lo, hi int) int { + num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo))) + return int(num.Int64()) + lo +} diff --git a/cmd/aiigo/dbcmd.go b/cmd/aiigo/dbcmd.go new file mode 100644 index 0000000000..44a52521f0 --- /dev/null +++ b/cmd/aiigo/dbcmd.go @@ -0,0 +1,909 @@ +// Copyright 2021 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 . + +package main + +import ( + "bytes" + "fmt" + "os" + "os/signal" + "path/filepath" + "slices" + "strconv" + "strings" + "syscall" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/console/prompt" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/triedb" + "github.com/olekukonko/tablewriter" + "github.com/urfave/cli/v2" +) + +var ( + removeStateDataFlag = &cli.BoolFlag{ + Name: "remove.state", + Usage: "If set, selects the state data for removal", + } + removeChainDataFlag = &cli.BoolFlag{ + Name: "remove.chain", + Usage: "If set, selects the state data for removal", + } + + removedbCommand = &cli.Command{ + Action: removeDB, + Name: "removedb", + Usage: "Remove blockchain and state databases", + ArgsUsage: "", + Flags: slices.Concat(utils.DatabaseFlags, + []cli.Flag{removeStateDataFlag, removeChainDataFlag}), + Description: ` +Remove blockchain and state databases`, + } + dbCommand = &cli.Command{ + Name: "db", + Usage: "Low level database operations", + ArgsUsage: "", + Subcommands: []*cli.Command{ + dbInspectCmd, + dbStatCmd, + dbCompactCmd, + dbGetCmd, + dbDeleteCmd, + dbPutCmd, + dbGetSlotsCmd, + dbDumpFreezerIndex, + dbImportCmd, + dbExportCmd, + dbMetadataCmd, + dbCheckStateContentCmd, + dbInspectHistoryCmd, + }, + } + dbInspectCmd = &cli.Command{ + Action: inspect, + Name: "inspect", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Usage: "Inspect the storage size for each type of data in the database", + Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`, + } + dbCheckStateContentCmd = &cli.Command{ + Action: checkStateContent, + Name: "check-state-content", + ArgsUsage: "", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Usage: "Verify that state data is cryptographically correct", + Description: `This command iterates the entire database for 32-byte keys, looking for rlp-encoded trie nodes. +For each trie node encountered, it checks that the key corresponds to the keccak256(value). If this is not true, this indicates +a data corruption.`, + } + dbStatCmd = &cli.Command{ + Action: dbStats, + Name: "stats", + Usage: "Print leveldb statistics", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + } + dbCompactCmd = &cli.Command{ + Action: dbCompact, + Name: "compact", + Usage: "Compact leveldb database. WARNING: May take a very long time", + Flags: slices.Concat([]cli.Flag{ + utils.CacheFlag, + utils.CacheDatabaseFlag, + }, utils.NetworkFlags, utils.DatabaseFlags), + Description: `This command performs a database compaction. +WARNING: This operation may take a very long time to finish, and may cause database +corruption if it is aborted during execution'!`, + } + dbGetCmd = &cli.Command{ + Action: dbGet, + Name: "get", + Usage: "Show the value of a database key", + ArgsUsage: "", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: "This command looks up the specified database key from the database.", + } + dbDeleteCmd = &cli.Command{ + Action: dbDelete, + Name: "delete", + Usage: "Delete a database key (WARNING: may corrupt your database)", + ArgsUsage: "", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: `This command deletes the specified database key from the database. +WARNING: This is a low-level operation which may cause database corruption!`, + } + dbPutCmd = &cli.Command{ + Action: dbPut, + Name: "put", + Usage: "Set the value of a database key (WARNING: may corrupt your database)", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: `This command sets a given database key to the given value. +WARNING: This is a low-level operation which may cause database corruption!`, + } + dbGetSlotsCmd = &cli.Command{ + Action: dbDumpTrie, + Name: "dumptrie", + Usage: "Show the storage key/values of a given storage trie", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: "This command looks up the specified database key from the database.", + } + dbDumpFreezerIndex = &cli.Command{ + Action: freezerInspect, + Name: "freezer-index", + Usage: "Dump out the index of a specific freezer table", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: "This command displays information about the freezer index.", + } + dbImportCmd = &cli.Command{ + Action: importLDBdata, + Name: "import", + Usage: "Imports leveldb-data from an exported RLP dump.", + ArgsUsage: " has .gz suffix, gzip compression will be used.", + ArgsUsage: " ", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: "Exports the specified chain data to an RLP encoded stream, optionally gzip-compressed.", + } + dbMetadataCmd = &cli.Command{ + Action: showMetaData, + Name: "metadata", + Usage: "Shows metadata about the chain status.", + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: "Shows metadata about the chain status.", + } + dbInspectHistoryCmd = &cli.Command{ + Action: inspectHistory, + Name: "inspect-history", + Usage: "Inspect the state history within block range", + ArgsUsage: "
[OPTIONAL ]", + Flags: slices.Concat([]cli.Flag{ + &cli.Uint64Flag{ + Name: "start", + Usage: "block number of the range start, zero means earliest history", + }, + &cli.Uint64Flag{ + Name: "end", + Usage: "block number of the range end(included), zero means latest history", + }, + &cli.BoolFlag{ + Name: "raw", + Usage: "display the decoded raw state value (otherwise shows rlp-encoded value)", + }, + }, utils.NetworkFlags, utils.DatabaseFlags), + Description: "This command queries the history of the account or storage slot within the specified block range", + } +) + +func removeDB(ctx *cli.Context) error { + stack, config := makeConfigNode(ctx) + + // Resolve folder paths. + var ( + rootDir = stack.ResolvePath("chaindata") + ancientDir = config.Eth.DatabaseFreezer + ) + switch { + case ancientDir == "": + ancientDir = filepath.Join(stack.ResolvePath("chaindata"), "ancient") + case !filepath.IsAbs(ancientDir): + ancientDir = config.Node.ResolvePath(ancientDir) + } + // Delete state data + statePaths := []string{ + rootDir, + filepath.Join(ancientDir, rawdb.MerkleStateFreezerName), + filepath.Join(ancientDir, rawdb.VerkleStateFreezerName), + } + confirmAndRemoveDB(statePaths, "state data", ctx, removeStateDataFlag.Name) + + // Delete ancient chain + chainPaths := []string{filepath.Join( + ancientDir, + rawdb.ChainFreezerName, + )} + confirmAndRemoveDB(chainPaths, "ancient chain", ctx, removeChainDataFlag.Name) + return nil +} + +// removeFolder deletes all files (not folders) inside the directory 'dir' (but +// not files in subfolders). +func removeFolder(dir string) { + filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + // If we're at the top level folder, recurse into + if path == dir { + return nil + } + // Delete all the files, but not subfolders + if !info.IsDir() { + os.Remove(path) + return nil + } + return filepath.SkipDir + }) +} + +// confirmAndRemoveDB prompts the user for a last confirmation and removes the +// list of folders if accepted. +func confirmAndRemoveDB(paths []string, kind string, ctx *cli.Context, removeFlagName string) { + var ( + confirm bool + err error + ) + msg := fmt.Sprintf("Location(s) of '%s': \n", kind) + for _, path := range paths { + msg += fmt.Sprintf("\t- %s\n", path) + } + fmt.Println(msg) + if ctx.IsSet(removeFlagName) { + confirm = ctx.Bool(removeFlagName) + if confirm { + fmt.Printf("Remove '%s'? [y/n] y\n", kind) + } else { + fmt.Printf("Remove '%s'? [y/n] n\n", kind) + } + } else { + confirm, err = prompt.Stdin.PromptConfirm(fmt.Sprintf("Remove '%s'?", kind)) + } + switch { + case err != nil: + utils.Fatalf("%v", err) + case !confirm: + log.Info("Database deletion skipped", "kind", kind, "paths", paths) + default: + var ( + deleted []string + start = time.Now() + ) + for _, path := range paths { + if common.FileExist(path) { + removeFolder(path) + deleted = append(deleted, path) + } else { + log.Info("Folder is not existent", "path", path) + } + } + log.Info("Database successfully deleted", "kind", kind, "paths", deleted, "elapsed", common.PrettyDuration(time.Since(start))) + } +} + +func inspect(ctx *cli.Context) error { + var ( + prefix []byte + start []byte + ) + if ctx.NArg() > 2 { + return fmt.Errorf("max 2 arguments: %v", ctx.Command.ArgsUsage) + } + if ctx.NArg() >= 1 { + if d, err := hexutil.Decode(ctx.Args().Get(0)); err != nil { + return fmt.Errorf("failed to hex-decode 'prefix': %v", err) + } else { + prefix = d + } + } + if ctx.NArg() >= 2 { + if d, err := hexutil.Decode(ctx.Args().Get(1)); err != nil { + return fmt.Errorf("failed to hex-decode 'start': %v", err) + } else { + start = d + } + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + return rawdb.InspectDatabase(db, prefix, start) +} + +func checkStateContent(ctx *cli.Context) error { + var ( + prefix []byte + start []byte + ) + if ctx.NArg() > 1 { + return fmt.Errorf("max 1 argument: %v", ctx.Command.ArgsUsage) + } + if ctx.NArg() > 0 { + if d, err := hexutil.Decode(ctx.Args().First()); err != nil { + return fmt.Errorf("failed to hex-decode 'start': %v", err) + } else { + start = d + } + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + var ( + it = rawdb.NewKeyLengthIterator(db.NewIterator(prefix, start), 32) + hasher = crypto.NewKeccakState() + got = make([]byte, 32) + errs int + count int + startTime = time.Now() + lastLog = time.Now() + ) + for it.Next() { + count++ + k := it.Key() + v := it.Value() + hasher.Reset() + hasher.Write(v) + hasher.Read(got) + if !bytes.Equal(k, got) { + errs++ + fmt.Printf("Error at %#x\n", k) + fmt.Printf(" Hash: %#x\n", got) + fmt.Printf(" Data: %#x\n", v) + } + if time.Since(lastLog) > 8*time.Second { + log.Info("Iterating the database", "at", fmt.Sprintf("%#x", k), "elapsed", common.PrettyDuration(time.Since(startTime))) + lastLog = time.Now() + } + } + if err := it.Error(); err != nil { + return err + } + log.Info("Iterated the state content", "errors", errs, "items", count) + return nil +} + +func showDBStats(db ethdb.KeyValueStater) { + stats, err := db.Stat() + if err != nil { + log.Warn("Failed to read database stats", "error", err) + return + } + fmt.Println(stats) +} + +func dbStats(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + showDBStats(db) + return nil +} + +func dbCompact(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, false) + defer db.Close() + + log.Info("Stats before compaction") + showDBStats(db) + + log.Info("Triggering compaction") + if err := db.Compact(nil, nil); err != nil { + log.Info("Compact err", "error", err) + return err + } + log.Info("Stats after compaction") + showDBStats(db) + return nil +} + +// dbGet shows the value of a given database key +func dbGet(ctx *cli.Context) error { + if ctx.NArg() != 1 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + key, err := common.ParseHexOrString(ctx.Args().Get(0)) + if err != nil { + log.Info("Could not decode the key", "error", err) + return err + } + + data, err := db.Get(key) + if err != nil { + log.Info("Get operation failed", "key", fmt.Sprintf("%#x", key), "error", err) + return err + } + fmt.Printf("key %#x: %#x\n", key, data) + return nil +} + +// dbDelete deletes a key from the database +func dbDelete(ctx *cli.Context) error { + if ctx.NArg() != 1 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, false) + defer db.Close() + + key, err := common.ParseHexOrString(ctx.Args().Get(0)) + if err != nil { + log.Info("Could not decode the key", "error", err) + return err + } + data, err := db.Get(key) + if err == nil { + fmt.Printf("Previous value: %#x\n", data) + } + if err = db.Delete(key); err != nil { + log.Info("Delete operation returned an error", "key", fmt.Sprintf("%#x", key), "error", err) + return err + } + return nil +} + +// dbPut overwrite a value in the database +func dbPut(ctx *cli.Context) error { + if ctx.NArg() != 2 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, false) + defer db.Close() + + var ( + key []byte + value []byte + data []byte + err error + ) + key, err = common.ParseHexOrString(ctx.Args().Get(0)) + if err != nil { + log.Info("Could not decode the key", "error", err) + return err + } + value, err = hexutil.Decode(ctx.Args().Get(1)) + if err != nil { + log.Info("Could not decode the value", "error", err) + return err + } + data, err = db.Get(key) + if err == nil { + fmt.Printf("Previous value: %#x\n", data) + } + return db.Put(key, value) +} + +// dbDumpTrie shows the key-value slots of a given storage trie +func dbDumpTrie(ctx *cli.Context) error { + if ctx.NArg() < 3 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + triedb := utils.MakeTrieDatabase(ctx, db, false, true, false) + defer triedb.Close() + + var ( + state []byte + storage []byte + account []byte + start []byte + max = int64(-1) + err error + ) + if state, err = hexutil.Decode(ctx.Args().Get(0)); err != nil { + log.Info("Could not decode the state root", "error", err) + return err + } + if account, err = hexutil.Decode(ctx.Args().Get(1)); err != nil { + log.Info("Could not decode the account hash", "error", err) + return err + } + if storage, err = hexutil.Decode(ctx.Args().Get(2)); err != nil { + log.Info("Could not decode the storage trie root", "error", err) + return err + } + if ctx.NArg() > 3 { + if start, err = hexutil.Decode(ctx.Args().Get(3)); err != nil { + log.Info("Could not decode the seek position", "error", err) + return err + } + } + if ctx.NArg() > 4 { + if max, err = strconv.ParseInt(ctx.Args().Get(4), 10, 64); err != nil { + log.Info("Could not decode the max count", "error", err) + return err + } + } + id := trie.StorageTrieID(common.BytesToHash(state), common.BytesToHash(account), common.BytesToHash(storage)) + theTrie, err := trie.New(id, triedb) + if err != nil { + return err + } + trieIt, err := theTrie.NodeIterator(start) + if err != nil { + return err + } + var count int64 + it := trie.NewIterator(trieIt) + for it.Next() { + if max > 0 && count == max { + fmt.Printf("Exiting after %d values\n", count) + break + } + fmt.Printf(" %d. key %#x: %#x\n", count, it.Key, it.Value) + count++ + } + return it.Err +} + +func freezerInspect(ctx *cli.Context) error { + if ctx.NArg() < 4 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + var ( + freezer = ctx.Args().Get(0) + table = ctx.Args().Get(1) + ) + start, err := strconv.ParseInt(ctx.Args().Get(2), 10, 64) + if err != nil { + log.Info("Could not read start-param", "err", err) + return err + } + end, err := strconv.ParseInt(ctx.Args().Get(3), 10, 64) + if err != nil { + log.Info("Could not read count param", "err", err) + return err + } + stack, _ := makeConfigNode(ctx) + ancient := stack.ResolveAncient("chaindata", ctx.String(utils.AncientFlag.Name)) + stack.Close() + return rawdb.InspectFreezerTable(ancient, freezer, table, start, end) +} + +func importLDBdata(ctx *cli.Context) error { + start := 0 + switch ctx.NArg() { + case 1: + break + case 2: + s, err := strconv.Atoi(ctx.Args().Get(1)) + if err != nil { + return fmt.Errorf("second arg must be an integer: %v", err) + } + start = s + default: + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + var ( + fName = ctx.Args().Get(0) + stack, _ = makeConfigNode(ctx) + interrupt = make(chan os.Signal, 1) + stop = make(chan struct{}) + ) + defer stack.Close() + signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(interrupt) + defer close(interrupt) + go func() { + if _, ok := <-interrupt; ok { + log.Info("Interrupted during ldb import, stopping at next batch") + } + close(stop) + }() + db := utils.MakeChainDatabase(ctx, stack, false) + defer db.Close() + return utils.ImportLDBData(db, fName, int64(start), stop) +} + +type preimageIterator struct { + iter ethdb.Iterator +} + +func (iter *preimageIterator) Next() (byte, []byte, []byte, bool) { + for iter.iter.Next() { + key := iter.iter.Key() + if bytes.HasPrefix(key, rawdb.PreimagePrefix) && len(key) == (len(rawdb.PreimagePrefix)+common.HashLength) { + return utils.OpBatchAdd, key, iter.iter.Value(), true + } + } + return 0, nil, nil, false +} + +func (iter *preimageIterator) Release() { + iter.iter.Release() +} + +type snapshotIterator struct { + init bool + account ethdb.Iterator + storage ethdb.Iterator +} + +func (iter *snapshotIterator) Next() (byte, []byte, []byte, bool) { + if !iter.init { + iter.init = true + return utils.OpBatchDel, rawdb.SnapshotRootKey, nil, true + } + for iter.account.Next() { + key := iter.account.Key() + if bytes.HasPrefix(key, rawdb.SnapshotAccountPrefix) && len(key) == (len(rawdb.SnapshotAccountPrefix)+common.HashLength) { + return utils.OpBatchAdd, key, iter.account.Value(), true + } + } + for iter.storage.Next() { + key := iter.storage.Key() + if bytes.HasPrefix(key, rawdb.SnapshotStoragePrefix) && len(key) == (len(rawdb.SnapshotStoragePrefix)+2*common.HashLength) { + return utils.OpBatchAdd, key, iter.storage.Value(), true + } + } + return 0, nil, nil, false +} + +func (iter *snapshotIterator) Release() { + iter.account.Release() + iter.storage.Release() +} + +// chainExporters defines the export scheme for all exportable chain data. +var chainExporters = map[string]func(db ethdb.Database) utils.ChainDataIterator{ + "preimage": func(db ethdb.Database) utils.ChainDataIterator { + iter := db.NewIterator(rawdb.PreimagePrefix, nil) + return &preimageIterator{iter: iter} + }, + "snapshot": func(db ethdb.Database) utils.ChainDataIterator { + account := db.NewIterator(rawdb.SnapshotAccountPrefix, nil) + storage := db.NewIterator(rawdb.SnapshotStoragePrefix, nil) + return &snapshotIterator{account: account, storage: storage} + }, +} + +func exportChaindata(ctx *cli.Context) error { + if ctx.NArg() < 2 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + // Parse the required chain data type, make sure it's supported. + kind := ctx.Args().Get(0) + kind = strings.ToLower(strings.Trim(kind, " ")) + exporter, ok := chainExporters[kind] + if !ok { + var kinds []string + for kind := range chainExporters { + kinds = append(kinds, kind) + } + return fmt.Errorf("invalid data type %s, supported types: %s", kind, strings.Join(kinds, ", ")) + } + var ( + stack, _ = makeConfigNode(ctx) + interrupt = make(chan os.Signal, 1) + stop = make(chan struct{}) + ) + defer stack.Close() + signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(interrupt) + defer close(interrupt) + go func() { + if _, ok := <-interrupt; ok { + log.Info("Interrupted during db export, stopping at next batch") + } + close(stop) + }() + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + return utils.ExportChaindata(ctx.Args().Get(1), kind, exporter(db), stop) +} + +func showMetaData(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + ancients, err := db.Ancients() + if err != nil { + fmt.Fprintf(os.Stderr, "Error accessing ancients: %v", err) + } + data := rawdb.ReadChainMetadata(db) + data = append(data, []string{"frozen", fmt.Sprintf("%d items", ancients)}) + data = append(data, []string{"snapshotGenerator", snapshot.ParseGeneratorStatus(rawdb.ReadSnapshotGenerator(db))}) + if b := rawdb.ReadHeadBlock(db); b != nil { + data = append(data, []string{"headBlock.Hash", fmt.Sprintf("%v", b.Hash())}) + data = append(data, []string{"headBlock.Root", fmt.Sprintf("%v", b.Root())}) + data = append(data, []string{"headBlock.Number", fmt.Sprintf("%d (%#x)", b.Number(), b.Number())}) + } + if h := rawdb.ReadHeadHeader(db); h != nil { + data = append(data, []string{"headHeader.Hash", fmt.Sprintf("%v", h.Hash())}) + data = append(data, []string{"headHeader.Root", fmt.Sprintf("%v", h.Root)}) + data = append(data, []string{"headHeader.Number", fmt.Sprintf("%d (%#x)", h.Number, h.Number)}) + } + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"Field", "Value"}) + table.AppendBulk(data) + table.Render() + return nil +} + +func inspectAccount(db *triedb.Database, start uint64, end uint64, address common.Address, raw bool) error { + stats, err := db.AccountHistory(address, start, end) + if err != nil { + return err + } + fmt.Printf("Account history:\n\taddress: %s\n\tblockrange: [#%d-#%d]\n", address.Hex(), stats.Start, stats.End) + + from := stats.Start + for i := 0; i < len(stats.Blocks); i++ { + var content string + if len(stats.Origins[i]) == 0 { + content = "" + } else { + if !raw { + content = fmt.Sprintf("%#x", stats.Origins[i]) + } else { + account := new(types.SlimAccount) + if err := rlp.DecodeBytes(stats.Origins[i], account); err != nil { + panic(err) + } + code := "" + if len(account.CodeHash) > 0 { + code = fmt.Sprintf("%#x", account.CodeHash) + } + root := "" + if len(account.Root) > 0 { + root = fmt.Sprintf("%#x", account.Root) + } + content = fmt.Sprintf("nonce: %d, balance: %d, codeHash: %s, root: %s", account.Nonce, account.Balance, code, root) + } + } + fmt.Printf("#%d - #%d: %s\n", from, stats.Blocks[i], content) + from = stats.Blocks[i] + } + return nil +} + +func inspectStorage(db *triedb.Database, start uint64, end uint64, address common.Address, slot common.Hash, raw bool) error { + // The hash of storage slot key is utilized in the history + // rather than the raw slot key, make the conversion. + stats, err := db.StorageHistory(address, slot, start, end) + if err != nil { + return err + } + fmt.Printf("Storage history:\n\taddress: %s\n\tslot: %s\n\tblockrange: [#%d-#%d]\n", address.Hex(), slot.Hex(), stats.Start, stats.End) + + from := stats.Start + for i := 0; i < len(stats.Blocks); i++ { + var content string + if len(stats.Origins[i]) == 0 { + content = "" + } else { + if !raw { + content = fmt.Sprintf("%#x", stats.Origins[i]) + } else { + _, data, _, err := rlp.Split(stats.Origins[i]) + if err != nil { + fmt.Printf("Failed to decode storage slot, %v", err) + return err + } + content = fmt.Sprintf("%#x", data) + } + } + fmt.Printf("#%d - #%d: %s\n", from, stats.Blocks[i], content) + from = stats.Blocks[i] + } + return nil +} + +func inspectHistory(ctx *cli.Context) error { + if ctx.NArg() == 0 || ctx.NArg() > 2 { + return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage) + } + var ( + address common.Address + slot common.Hash + ) + if err := address.UnmarshalText([]byte(ctx.Args().Get(0))); err != nil { + return err + } + if ctx.NArg() > 1 { + if err := slot.UnmarshalText([]byte(ctx.Args().Get(1))); err != nil { + return err + } + } + // Load the databases. + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + triedb := utils.MakeTrieDatabase(ctx, db, false, false, false) + defer triedb.Close() + + var ( + err error + start uint64 // the id of first history object to query + end uint64 // the id (included) of last history object to query + ) + // State histories are identified by state ID rather than block number. + // To address this, load the corresponding block header and perform the + // conversion by this function. + blockToID := func(blockNumber uint64) (uint64, error) { + header := rawdb.ReadHeader(db, rawdb.ReadCanonicalHash(db, blockNumber), blockNumber) + if header == nil { + return 0, fmt.Errorf("block #%d is not existent", blockNumber) + } + id := rawdb.ReadStateID(db, header.Root) + if id == nil { + first, last, err := triedb.HistoryRange() + if err == nil { + return 0, fmt.Errorf("history of block #%d is not existent, available history range: [#%d-#%d]", blockNumber, first, last) + } + return 0, fmt.Errorf("history of block #%d is not existent", blockNumber) + } + return *id, nil + } + // Parse the starting block number for inspection. + startNumber := ctx.Uint64("start") + if startNumber != 0 { + start, err = blockToID(startNumber) + if err != nil { + return err + } + } + // Parse the ending block number for inspection. + endBlock := ctx.Uint64("end") + if endBlock != 0 { + end, err = blockToID(endBlock) + if err != nil { + return err + } + } + // Inspect the state history. + if slot == (common.Hash{}) { + return inspectAccount(triedb, start, end, address, ctx.Bool("raw")) + } + return inspectStorage(triedb, start, end, address, slot, ctx.Bool("raw")) +} diff --git a/cmd/aiigo/exportcmd_test.go b/cmd/aiigo/exportcmd_test.go new file mode 100644 index 0000000000..7ba93b6036 --- /dev/null +++ b/cmd/aiigo/exportcmd_test.go @@ -0,0 +1,45 @@ +// Copyright 2022 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 . + +package main + +import ( + "bytes" + "fmt" + "os" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// TestExport does a basic test of "aiigo export", exporting the test-genesis. +func TestExport(t *testing.T) { + t.Parallel() + outfile := fmt.Sprintf("%v/testExport.out", t.TempDir()) + aiigo := runaiigo(t, "--datadir", initaiigo(t), "export", outfile) + aiigo.WaitExit() + if have, want := aiigo.ExitStatus(), 0; have != want { + t.Errorf("exit error, have %d want %d", have, want) + } + have, err := os.ReadFile(outfile) + if err != nil { + t.Fatal(err) + } + want := common.FromHex("0xf9026bf90266a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a08758259b018f7bce3d2be2ddb62f325eaeea0a0c188cf96623eab468a4413e03a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180837a12008080b875000000000000000000000000000000000000000000000000000000000000000002f0d131f1f97aef08aec6e3291b957d9efe71050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0") + if !bytes.Equal(have, want) { + t.Fatalf("wrong content exported") + } +} diff --git a/cmd/aiigo/genesis_test.go b/cmd/aiigo/genesis_test.go new file mode 100644 index 0000000000..a71c9dfb59 --- /dev/null +++ b/cmd/aiigo/genesis_test.go @@ -0,0 +1,198 @@ +// Copyright 2016 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 . + +package main + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + "testing" +) + +var customGenesisTests = []struct { + genesis string + query string + result string +}{ + // Genesis file with a mostly-empty chain configuration (ensure missing fields work) + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000001338", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config": { + "terminalTotalDifficulty": 0 + } + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000001338", + }, + // Genesis file with specific chain configurations + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000001339", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : { + "homesteadBlock" : 42, + "daoForkBlock" : 141, + "daoForkSupport" : true, + "terminalTotalDifficulty": 0 + } + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000001339", + }, +} + +// Tests that initializing aiigo with a custom genesis block and chain definitions +// work properly. +func TestCustomGenesis(t *testing.T) { + t.Parallel() + for i, tt := range customGenesisTests { + // Create a temporary data directory to use and inspect later + datadir := t.TempDir() + + // Initialize the data directory with the custom genesis block + json := filepath.Join(datadir, "genesis.json") + if err := os.WriteFile(json, []byte(tt.genesis), 0600); err != nil { + t.Fatalf("test %d: failed to write genesis file: %v", i, err) + } + runaiigo(t, "--datadir", datadir, "init", json).WaitExit() + + // Query the custom genesis block + aiigo := runaiigo(t, "--networkid", "1337", "--syncmode=full", "--cache", "16", + "--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0", + "--nodiscover", "--nat", "none", "--ipcdisable", + "--exec", tt.query, "console") + aiigo.ExpectRegexp(tt.result) + aiigo.ExpectExit() + } +} + +// TestCustomBackend that the backend selection and detection (leveldb vs pebble) works properly. +func TestCustomBackend(t *testing.T) { + t.Parallel() + // Test pebble, but only on 64-bit platforms + if strconv.IntSize != 64 { + t.Skip("Custom backends are only available on 64-bit platform") + } + genesis := `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000001338", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config": { + "terminalTotalDifficulty": 0 + } + }` + type backendTest struct { + initArgs []string + initExpect string + execArgs []string + execExpect string + } + testfunc := func(t *testing.T, tt backendTest) error { + // Create a temporary data directory to use and inspect later + datadir := t.TempDir() + + // Initialize the data directory with the custom genesis block + json := filepath.Join(datadir, "genesis.json") + if err := os.WriteFile(json, []byte(genesis), 0600); err != nil { + return fmt.Errorf("failed to write genesis file: %v", err) + } + { // Init + args := append(tt.initArgs, "--datadir", datadir, "init", json) + aiigo := runaiigo(t, args...) + aiigo.ExpectRegexp(tt.initExpect) + aiigo.ExpectExit() + } + { // Exec + query + args := append(tt.execArgs, "--networkid", "1337", "--syncmode=full", "--cache", "16", + "--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0", + "--nodiscover", "--nat", "none", "--ipcdisable", + "--exec", "eth.getBlock(0).nonce", "console") + aiigo := runaiigo(t, args...) + aiigo.ExpectRegexp(tt.execExpect) + aiigo.ExpectExit() + } + return nil + } + for i, tt := range []backendTest{ + { // When not specified, it should default to pebble + execArgs: []string{"--db.engine", "pebble"}, + execExpect: "0x0000000000001338", + }, + { // Explicit leveldb + initArgs: []string{"--db.engine", "leveldb"}, + execArgs: []string{"--db.engine", "leveldb"}, + execExpect: "0x0000000000001338", + }, + { // Explicit leveldb first, then autodiscover + initArgs: []string{"--db.engine", "leveldb"}, + execExpect: "0x0000000000001338", + }, + { // Explicit pebble + initArgs: []string{"--db.engine", "pebble"}, + execArgs: []string{"--db.engine", "pebble"}, + execExpect: "0x0000000000001338", + }, + { // Explicit pebble, then auto-discover + initArgs: []string{"--db.engine", "pebble"}, + execExpect: "0x0000000000001338", + }, + { // Can't start pebble on top of leveldb + initArgs: []string{"--db.engine", "leveldb"}, + execArgs: []string{"--db.engine", "pebble"}, + execExpect: `Fatal: Failed to register the Ethereum service: db.engine choice was pebble but found pre-existing leveldb database in specified data directory`, + }, + { // Can't start leveldb on top of pebble + initArgs: []string{"--db.engine", "pebble"}, + execArgs: []string{"--db.engine", "leveldb"}, + execExpect: `Fatal: Failed to register the Ethereum service: db.engine choice was leveldb but found pre-existing pebble database in specified data directory`, + }, + { // Reject invalid backend choice + initArgs: []string{"--db.engine", "mssql"}, + initExpect: `Fatal: Invalid choice for db.engine 'mssql', allowed 'leveldb' or 'pebble'`, + // Since the init fails, this will return the (default) mainnet genesis + // block nonce + execExpect: `0x0000000000000042`, + }, + } { + if err := testfunc(t, tt); err != nil { + t.Fatalf("test %d-leveldb: %v", i, err) + } + } +} diff --git a/cmd/aiigo/logging_test.go b/cmd/aiigo/logging_test.go new file mode 100644 index 0000000000..986460f7b3 --- /dev/null +++ b/cmd/aiigo/logging_test.go @@ -0,0 +1,237 @@ +// Copyright 2023 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 . + +//go:build integrationtests + +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "math/rand" + "os" + "os/exec" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/internal/reexec" +) + +func runSelf(args ...string) ([]byte, error) { + cmd := &exec.Cmd{ + Path: reexec.Self(), + Args: append([]string{"aiigo-test"}, args...), + } + return cmd.CombinedOutput() +} + +func split(input io.Reader) []string { + var output []string + scanner := bufio.NewScanner(input) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + output = append(output, strings.TrimSpace(scanner.Text())) + } + return output +} + +func censor(input string, start, end int) string { + if len(input) < end { + return input + } + return input[:start] + strings.Repeat("X", end-start) + input[end:] +} + +func TestLogging(t *testing.T) { + t.Parallel() + testConsoleLogging(t, "terminal", 6, 24) + testConsoleLogging(t, "logfmt", 2, 26) +} + +func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) { + haveB, err := runSelf("--log.format", format, "logtest") + if err != nil { + t.Fatal(err) + } + readFile, err := os.Open(fmt.Sprintf("testdata/logging/logtest-%v.txt", format)) + if err != nil { + t.Fatal(err) + } + defer readFile.Close() + wantLines := split(readFile) + haveLines := split(bytes.NewBuffer(haveB)) + for i, want := range wantLines { + if i > len(haveLines)-1 { + t.Fatalf("format %v, line %d missing, want:%v", format, i, want) + } + have := haveLines[i] + for strings.Contains(have, "Unknown config environment variable") { + // This can happen on CI runs. Drop it. + haveLines = append(haveLines[:i], haveLines[i+1:]...) + have = haveLines[i] + } + + // Black out the timestamp + have = censor(have, tStart, tEnd) + want = censor(want, tStart, tEnd) + if have != want { + t.Logf(nicediff([]byte(have), []byte(want))) + t.Fatalf("format %v, line %d\nhave %v\nwant %v", format, i, have, want) + } + } + if len(haveLines) != len(wantLines) { + t.Errorf("format %v, want %d lines, have %d", format, len(haveLines), len(wantLines)) + } +} + +func TestJsonLogging(t *testing.T) { + t.Parallel() + haveB, err := runSelf("--log.format", "json", "logtest") + if err != nil { + t.Fatal(err) + } + readFile, err := os.Open("testdata/logging/logtest-json.txt") + if err != nil { + t.Fatal(err) + } + defer readFile.Close() + wantLines := split(readFile) + haveLines := split(bytes.NewBuffer(haveB)) + for i, wantLine := range wantLines { + if i > len(haveLines)-1 { + t.Fatalf("format %v, line %d missing, want:%v", "json", i, wantLine) + } + haveLine := haveLines[i] + for strings.Contains(haveLine, "Unknown config environment variable") { + // This can happen on CI runs. Drop it. + haveLines = append(haveLines[:i], haveLines[i+1:]...) + haveLine = haveLines[i] + } + var have, want []byte + { + var h map[string]any + if err := json.Unmarshal([]byte(haveLine), &h); err != nil { + t.Fatal(err) + } + h["t"] = "xxx" + have, _ = json.Marshal(h) + } + { + var w map[string]any + if err := json.Unmarshal([]byte(wantLine), &w); err != nil { + t.Fatal(err) + } + w["t"] = "xxx" + want, _ = json.Marshal(w) + } + if !bytes.Equal(have, want) { + // show an intelligent diff + t.Logf(nicediff(have, want)) + t.Errorf("file content wrong") + } + } +} + +func TestVmodule(t *testing.T) { + t.Parallel() + checkOutput := func(level int, want, wantNot string) { + t.Helper() + output, err := runSelf("--log.format", "terminal", "--verbosity=0", "--log.vmodule", fmt.Sprintf("logtestcmd_active.go=%d", level), "logtest") + if err != nil { + t.Fatal(err) + } + if len(want) > 0 && !strings.Contains(string(output), want) { // trace should be present at 5 + t.Errorf("failed to find expected string ('%s') in output", want) + } + if len(wantNot) > 0 && strings.Contains(string(output), wantNot) { // trace should be present at 5 + t.Errorf("string ('%s') should not be present in output", wantNot) + } + } + checkOutput(5, "log at level trace", "") // trace should be present at 5 + checkOutput(4, "log at level debug", "log at level trace") // debug should be present at 4, but trace should be missing + checkOutput(3, "log at level info", "log at level debug") // info should be present at 3, but debug should be missing + checkOutput(2, "log at level warn", "log at level info") // warn should be present at 2, but info should be missing + checkOutput(1, "log at level error", "log at level warn") // error should be present at 1, but warn should be missing +} + +func nicediff(have, want []byte) string { + var i = 0 + for ; i < len(have) && i < len(want); i++ { + if want[i] != have[i] { + break + } + } + var end = i + 40 + var start = i - 50 + if start < 0 { + start = 0 + } + var h, w string + if end < len(have) { + h = string(have[start:end]) + } else { + h = string(have[start:]) + } + if end < len(want) { + w = string(want[start:end]) + } else { + w = string(want[start:]) + } + return fmt.Sprintf("have vs want:\n%q\n%q\n", h, w) +} + +func TestFileOut(t *testing.T) { + t.Parallel() + var ( + have, want []byte + err error + path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63()) + ) + if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "logtest"); err != nil { + t.Fatal(err) + } + if have, err = os.ReadFile(path); err != nil { + t.Fatal(err) + } + if !bytes.Equal(have, want) { + // show an intelligent diff + t.Logf(nicediff(have, want)) + t.Errorf("file content wrong") + } +} + +func TestRotatingFileOut(t *testing.T) { + t.Parallel() + var ( + have, want []byte + err error + path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63()) + ) + if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "--log.rotate", "logtest"); err != nil { + t.Fatal(err) + } + if have, err = os.ReadFile(path); err != nil { + t.Fatal(err) + } + if !bytes.Equal(have, want) { + // show an intelligent diff + t.Logf(nicediff(have, want)) + t.Errorf("file content wrong") + } +} diff --git a/cmd/aiigo/logtestcmd_active.go b/cmd/aiigo/logtestcmd_active.go new file mode 100644 index 0000000000..f9bbc3d4ec --- /dev/null +++ b/cmd/aiigo/logtestcmd_active.go @@ -0,0 +1,171 @@ +// Copyright 2023 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 . + +//go:build integrationtests + +package main + +import ( + "errors" + "fmt" + "math" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/holiman/uint256" + "github.com/urfave/cli/v2" +) + +var logTestCommand = &cli.Command{ + Action: logTest, + Name: "logtest", + Usage: "Print some log messages", + ArgsUsage: " ", + Description: ` +This command is only meant for testing. +`} + +type customQuotedStringer struct { +} + +func (c customQuotedStringer) String() string { + return "output with 'quotes'" +} + +// logTest is an entry point which spits out some logs. This is used by testing +// to verify expected outputs +func logTest(ctx *cli.Context) error { + { // big.Int + ba, _ := new(big.Int).SetString("111222333444555678999", 10) // "111,222,333,444,555,678,999" + bb, _ := new(big.Int).SetString("-111222333444555678999", 10) // "-111,222,333,444,555,678,999" + bc, _ := new(big.Int).SetString("11122233344455567899900", 10) // "11,122,233,344,455,567,899,900" + bd, _ := new(big.Int).SetString("-11122233344455567899900", 10) // "-11,122,233,344,455,567,899,900" + log.Info("big.Int", "111,222,333,444,555,678,999", ba) + log.Info("-big.Int", "-111,222,333,444,555,678,999", bb) + log.Info("big.Int", "11,122,233,344,455,567,899,900", bc) + log.Info("-big.Int", "-11,122,233,344,455,567,899,900", bd) + } + { //uint256 + ua, _ := uint256.FromDecimal("111222333444555678999") + ub, _ := uint256.FromDecimal("11122233344455567899900") + log.Info("uint256", "111,222,333,444,555,678,999", ua) + log.Info("uint256", "11,122,233,344,455,567,899,900", ub) + } + { // int64 + log.Info("int64", "1,000,000", int64(1000000)) + log.Info("int64", "-1,000,000", int64(-1000000)) + log.Info("int64", "9,223,372,036,854,775,807", int64(math.MaxInt64)) + log.Info("int64", "-9,223,372,036,854,775,808", int64(math.MinInt64)) + } + { // uint64 + log.Info("uint64", "1,000,000", uint64(1000000)) + log.Info("uint64", "18,446,744,073,709,551,615", uint64(math.MaxUint64)) + } + { // Special characters + log.Info("Special chars in value", "key", "special \r\n\t chars") + log.Info("Special chars in key", "special \n\t chars", "value") + + log.Info("nospace", "nospace", "nospace") + log.Info("with space", "with nospace", "with nospace") + + log.Info("Bash escapes in value", "key", "\u001b[1G\u001b[K\u001b[1A") + log.Info("Bash escapes in key", "\u001b[1G\u001b[K\u001b[1A", "value") + + log.Info("Bash escapes in message \u001b[1G\u001b[K\u001b[1A end", "key", "value") + + colored := fmt.Sprintf("\u001B[%dmColored\u001B[0m[", 35) + log.Info(colored, colored, colored) + err := errors.New("this is an 'error'") + log.Info("an error message with quotes", "error", err) + } + { // Custom Stringer() - type + log.Info("Custom Stringer value", "2562047h47m16.854s", common.PrettyDuration(time.Duration(9223372036854775807))) + var c customQuotedStringer + log.Info("a custom stringer that emits quoted text", "output", c) + } + { // Multi-line message + log.Info("A message with wonky \U0001F4A9 characters") + log.Info("A multiline message \nINFO [10-18|14:11:31.106] with wonky characters \U0001F4A9") + log.Info("A multiline message \nLALA [ZZZZZZZZZZZZZZZZZZ] Actually part of message above") + } + { // Miscellaneous json-quirks + // This will check if the json output uses strings or json-booleans to represent bool values + log.Info("boolean", "true", true, "false", false) + // Handling of duplicate keys. + // This is actually ill-handled by the current handler: the format.go + // uses a global 'fieldPadding' map and mixes up the two keys. If 'alpha' + // is shorter than beta, it sometimes causes erroneous padding -- and what's more + // it causes _different_ padding in multi-handler context, e.g. both file- + // and console output, making the two mismatch. + log.Info("repeated-key 1", "foo", "alpha", "foo", "beta") + log.Info("repeated-key 2", "xx", "short", "xx", "longer") + } + { // loglevels + log.Debug("log at level debug") + log.Trace("log at level trace") + log.Info("log at level info") + log.Warn("log at level warn") + log.Error("log at level error") + } + { + // The current log formatter has a global map of paddings, storing the + // longest seen padding per key in a map. This results in a statefulness + // which has some odd side-effects. Demonstrated here: + log.Info("test", "bar", "short", "a", "aligned left") + log.Info("test", "bar", "a long message", "a", 1) + log.Info("test", "bar", "short", "a", "aligned right") + } + { + // This sequence of logs should be output with alignment, so each field becoems a column. + log.Info("The following logs should align so that the key-fields make 5 columns") + log.Info("Inserted known block", "number", 1_012, "hash", common.HexToHash("0x1234"), "txs", 200, "gas", 1_123_123, "other", "first") + log.Info("Inserted new block", "number", 1, "hash", common.HexToHash("0x1235"), "txs", 2, "gas", 1_123, "other", "second") + log.Info("Inserted known block", "number", 99, "hash", common.HexToHash("0x12322"), "txs", 10, "gas", 1, "other", "third") + log.Warn("Inserted known block", "number", 1_012, "hash", common.HexToHash("0x1234"), "txs", 200, "gas", 99, "other", "fourth") + } + { // Various types of nil + type customStruct struct { + A string + B *uint64 + } + log.Info("(*big.Int)(nil)", "", (*big.Int)(nil)) + log.Info("(*uint256.Int)(nil)", "", (*uint256.Int)(nil)) + log.Info("(fmt.Stringer)(nil)", "res", (fmt.Stringer)(nil)) + log.Info("nil-concrete-stringer", "res", (*time.Time)(nil)) + + log.Info("error(nil) ", "res", error(nil)) + log.Info("nil-concrete-error", "res", (*customError)(nil)) + + log.Info("nil-custom-struct", "res", (*customStruct)(nil)) + log.Info("raw nil", "res", nil) + log.Info("(*uint64)(nil)", "res", (*uint64)(nil)) + } + { // Logging with 'reserved' keys + log.Info("Using keys 't', 'lvl', 'time', 'level' and 'msg'", "t", "t", "time", "time", "lvl", "lvl", "level", "level", "msg", "msg") + } + { // Logging with wrong attr-value pairs + log.Info("Odd pair (1 attr)", "key") + log.Info("Odd pair (3 attr)", "key", "value", "key2") + } + return nil +} + +// customError is a type which implements error +type customError struct{} + +func (c *customError) Error() string { return "" } diff --git a/cmd/aiigo/logtestcmd_inactive.go b/cmd/aiigo/logtestcmd_inactive.go new file mode 100644 index 0000000000..8dda1c47e4 --- /dev/null +++ b/cmd/aiigo/logtestcmd_inactive.go @@ -0,0 +1,23 @@ +// Copyright 2023 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 . + +//go:build !integrationtests + +package main + +import "github.com/urfave/cli/v2" + +var logTestCommand *cli.Command diff --git a/cmd/aiigo/main.go b/cmd/aiigo/main.go new file mode 100644 index 0000000000..215c1d1a88 --- /dev/null +++ b/cmd/aiigo/main.go @@ -0,0 +1,428 @@ +// Copyright 2014 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 . + +// aiigo is a command-line client for Ethereum. +package main + +import ( + "fmt" + "os" + "slices" + "sort" + "strconv" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/console/prompt" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "go.uber.org/automaxprocs/maxprocs" + + // Force-load the tracer engines to trigger registration + _ "github.com/ethereum/go-ethereum/eth/tracers/js" + _ "github.com/ethereum/go-ethereum/eth/tracers/live" + _ "github.com/ethereum/go-ethereum/eth/tracers/native" + + "github.com/urfave/cli/v2" +) + +const ( + clientIdentifier = "aiigo" // Client identifier to advertise over the network +) + +var ( + // flags that configure the node + nodeFlags = slices.Concat([]cli.Flag{ + utils.IdentityFlag, + utils.UnlockedAccountFlag, + utils.PasswordFileFlag, + utils.BootnodesFlag, + utils.MinFreeDiskSpaceFlag, + utils.KeyStoreDirFlag, + utils.ExternalSignerFlag, + utils.NoUSBFlag, // deprecated + utils.USBFlag, + utils.SmartCardDaemonPathFlag, + utils.OverridePrague, + utils.OverrideVerkle, + utils.EnablePersonal, // deprecated + utils.TxPoolLocalsFlag, + utils.TxPoolNoLocalsFlag, + utils.TxPoolJournalFlag, + utils.TxPoolRejournalFlag, + utils.TxPoolPriceLimitFlag, + utils.TxPoolPriceBumpFlag, + utils.TxPoolAccountSlotsFlag, + utils.TxPoolGlobalSlotsFlag, + utils.TxPoolAccountQueueFlag, + utils.TxPoolGlobalQueueFlag, + utils.TxPoolLifetimeFlag, + utils.BlobPoolDataDirFlag, + utils.BlobPoolDataCapFlag, + utils.BlobPoolPriceBumpFlag, + utils.SyncModeFlag, + utils.SyncTargetFlag, + utils.ExitWhenSyncedFlag, + utils.GCModeFlag, + utils.SnapshotFlag, + utils.TxLookupLimitFlag, // deprecated + utils.TransactionHistoryFlag, + utils.ChainHistoryFlag, + utils.LogHistoryFlag, + utils.LogNoHistoryFlag, + utils.LogExportCheckpointsFlag, + utils.StateHistoryFlag, + utils.LightServeFlag, // deprecated + utils.LightIngressFlag, // deprecated + utils.LightEgressFlag, // deprecated + utils.LightMaxPeersFlag, // deprecated + utils.LightNoPruneFlag, // deprecated + utils.LightKDFFlag, + utils.LightNoSyncServeFlag, // deprecated + utils.EthRequiredBlocksFlag, + utils.LegacyWhitelistFlag, // deprecated + utils.BloomFilterSizeFlag, + utils.CacheFlag, + utils.CacheDatabaseFlag, + utils.CacheTrieFlag, + utils.CacheTrieJournalFlag, // deprecated + utils.CacheTrieRejournalFlag, // deprecated + utils.CacheGCFlag, + utils.CacheSnapshotFlag, + utils.CacheNoPrefetchFlag, + utils.CachePreimagesFlag, + utils.CacheLogSizeFlag, + utils.FDLimitFlag, + utils.CryptoKZGFlag, + utils.ListenPortFlag, + utils.DiscoveryPortFlag, + utils.MaxPeersFlag, + utils.MaxPendingPeersFlag, + utils.MiningEnabledFlag, // deprecated + utils.MinerGasLimitFlag, + utils.MinerGasPriceFlag, + utils.MinerEtherbaseFlag, // deprecated + utils.MinerExtraDataFlag, + utils.MinerRecommitIntervalFlag, + utils.MinerPendingFeeRecipientFlag, + utils.MinerNewPayloadTimeoutFlag, // deprecated + utils.NATFlag, + utils.NoDiscoverFlag, + utils.DiscoveryV4Flag, + utils.DiscoveryV5Flag, + utils.LegacyDiscoveryV5Flag, // deprecated + utils.NetrestrictFlag, + utils.NodeKeyFileFlag, + utils.NodeKeyHexFlag, + utils.DNSDiscoveryFlag, + utils.DeveloperFlag, + utils.DeveloperGasLimitFlag, + utils.DeveloperPeriodFlag, + utils.VMEnableDebugFlag, + utils.VMTraceFlag, + utils.VMTraceJsonConfigFlag, + utils.NetworkIdFlag, + utils.EthStatsURLFlag, + utils.GpoBlocksFlag, + utils.GpoPercentileFlag, + utils.GpoMaxGasPriceFlag, + utils.GpoIgnoreGasPriceFlag, + configFileFlag, + utils.LogDebugFlag, + utils.LogBacktraceAtFlag, + utils.BeaconApiFlag, + utils.BeaconApiHeaderFlag, + utils.BeaconThresholdFlag, + utils.BeaconNoFilterFlag, + utils.BeaconConfigFlag, + utils.BeaconGenesisRootFlag, + utils.BeaconGenesisTimeFlag, + utils.BeaconCheckpointFlag, + }, utils.NetworkFlags, utils.DatabaseFlags) + + rpcFlags = []cli.Flag{ + utils.HTTPEnabledFlag, + utils.HTTPListenAddrFlag, + utils.HTTPPortFlag, + utils.HTTPCORSDomainFlag, + utils.AuthListenFlag, + utils.AuthPortFlag, + utils.AuthVirtualHostsFlag, + utils.JWTSecretFlag, + utils.HTTPVirtualHostsFlag, + utils.GraphQLEnabledFlag, + utils.GraphQLCORSDomainFlag, + utils.GraphQLVirtualHostsFlag, + utils.HTTPApiFlag, + utils.HTTPPathPrefixFlag, + utils.WSEnabledFlag, + utils.WSListenAddrFlag, + utils.WSPortFlag, + utils.WSApiFlag, + utils.WSAllowedOriginsFlag, + utils.WSPathPrefixFlag, + utils.IPCDisabledFlag, + utils.IPCPathFlag, + utils.InsecureUnlockAllowedFlag, + utils.RPCGlobalGasCapFlag, + utils.RPCGlobalEVMTimeoutFlag, + utils.RPCGlobalTxFeeCapFlag, + utils.AllowUnprotectedTxs, + utils.BatchRequestLimit, + utils.BatchResponseMaxSize, + } + + metricsFlags = []cli.Flag{ + utils.MetricsEnabledFlag, + utils.MetricsEnabledExpensiveFlag, + utils.MetricsHTTPFlag, + utils.MetricsPortFlag, + utils.MetricsEnableInfluxDBFlag, + utils.MetricsInfluxDBEndpointFlag, + utils.MetricsInfluxDBDatabaseFlag, + utils.MetricsInfluxDBUsernameFlag, + utils.MetricsInfluxDBPasswordFlag, + utils.MetricsInfluxDBTagsFlag, + utils.MetricsEnableInfluxDBV2Flag, + utils.MetricsInfluxDBTokenFlag, + utils.MetricsInfluxDBBucketFlag, + utils.MetricsInfluxDBOrganizationFlag, + } +) + +var app = flags.NewApp("the go-ethereum command line interface") + +func init() { + // Initialize the CLI app and start aiigo + app.Action = aiigo + app.Commands = []*cli.Command{ + // See chaincmd.go: + initCommand, + importCommand, + exportCommand, + importHistoryCommand, + exportHistoryCommand, + importPreimagesCommand, + removedbCommand, + dumpCommand, + dumpGenesisCommand, + pruneCommand, + // See accountcmd.go: + accountCommand, + walletCommand, + // See consolecmd.go: + consoleCommand, + attachCommand, + javascriptCommand, + // See misccmd.go: + versionCommand, + versionCheckCommand, + licenseCommand, + // See config.go + dumpConfigCommand, + // see dbcmd.go + dbCommand, + // See cmd/utils/flags_legacy.go + utils.ShowDeprecated, + // See snapshot.go + snapshotCommand, + // See verkle.go + verkleCommand, + } + if logTestCommand != nil { + app.Commands = append(app.Commands, logTestCommand) + } + sort.Sort(cli.CommandsByName(app.Commands)) + + app.Flags = slices.Concat( + nodeFlags, + rpcFlags, + consoleFlags, + debug.Flags, + metricsFlags, + ) + flags.AutoEnvVars(app.Flags, "aiigo") + + app.Before = func(ctx *cli.Context) error { + maxprocs.Set() // Automatically set GOMAXPROCS to match Linux container CPU quota. + flags.MigrateGlobalFlags(ctx) + if err := debug.Setup(ctx); err != nil { + return err + } + flags.CheckEnvVars(ctx, app.Flags, "aiigo") + return nil + } + app.After = func(ctx *cli.Context) error { + debug.Exit() + prompt.Stdin.Close() // Resets terminal mode. + return nil + } +} + +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +// prepare manipulates memory cache allowance and setups metric system. +// This function should be called before launching devp2p stack. +func prepare(ctx *cli.Context) { + // If we're running a known preset, log it for convenience. + switch { + case ctx.IsSet(utils.SepoliaFlag.Name): + log.Info("Starting aiigo on Sepolia testnet...") + + case ctx.IsSet(utils.HoleskyFlag.Name): + log.Info("Starting aiigo on Holesky testnet...") + + case ctx.IsSet(utils.HoodiFlag.Name): + log.Info("Starting aiigo on Hoodi testnet...") + + case ctx.IsSet(utils.DeveloperFlag.Name): + log.Info("Starting aiigo in ephemeral dev mode...") + log.Warn(`You are running aiigo in --dev mode. Please note the following: + + 1. This mode is only intended for fast, iterative development without assumptions on + security or persistence. + 2. The database is created in memory unless specified otherwise. Therefore, shutting down + your computer or losing power will wipe your entire block data and chain state for + your dev environment. + 3. A random, pre-allocated developer account will be available and unlocked as + eth.coinbase, which can be used for testing. The random dev account is temporary, + stored on a ramdisk, and will be lost if your machine is restarted. + 4. Mining is enabled by default. However, the client will only seal blocks if transactions + are pending in the mempool. The miner's minimum accepted gas price is 1. + 5. Networking is disabled; there is no listen-address, the maximum number of peers is set + to 0, and discovery is disabled. +`) + + case !ctx.IsSet(utils.NetworkIdFlag.Name): + log.Info("Starting aiigo on Ethereum mainnet...") + } + // If we're a full node on mainnet without --cache specified, bump default cache allowance + if !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) { + // Make sure we're not on any supported preconfigured testnet either + if !ctx.IsSet(utils.HoleskyFlag.Name) && + !ctx.IsSet(utils.SepoliaFlag.Name) && + !ctx.IsSet(utils.HoodiFlag.Name) && + !ctx.IsSet(utils.DeveloperFlag.Name) { + // Nope, we're really on mainnet. Bump that cache up! + log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096) + ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096)) + } + } +} + +// aiigo is the main entry point into the system if no special subcommand is run. +// It creates a default node based on the command line arguments and runs it in +// blocking mode, waiting for it to be shut down. +func aiigo(ctx *cli.Context) error { + if args := ctx.Args().Slice(); len(args) > 0 { + return fmt.Errorf("invalid command: %q", args[0]) + } + + prepare(ctx) + stack := makeFullNode(ctx) + defer stack.Close() + + startNode(ctx, stack, false) + stack.Wait() + return nil +} + +// startNode boots up the system node and all registered protocols, after which +// it starts the RPC/IPC interfaces and the miner. +func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) { + // Start up the node itself + utils.StartNode(ctx, stack, isConsole) + + if ctx.IsSet(utils.UnlockedAccountFlag.Name) { + log.Warn(`The "unlock" flag has been deprecated and has no effect`) + } + + // Register wallet event handlers to open and auto-derive wallets + events := make(chan accounts.WalletEvent, 16) + stack.AccountManager().Subscribe(events) + + // Create a client to interact with local aiigo node. + rpcClient := stack.Attach() + ethClient := ethclient.NewClient(rpcClient) + + go func() { + // Open any wallets already attached + for _, wallet := range stack.AccountManager().Wallets() { + if err := wallet.Open(""); err != nil { + log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) + } + } + // Listen for wallet event till termination + for event := range events { + switch event.Kind { + case accounts.WalletArrived: + if err := event.Wallet.Open(""); err != nil { + log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) + } + case accounts.WalletOpened: + status, _ := event.Wallet.Status() + log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) + + var derivationPaths []accounts.DerivationPath + if event.Wallet.URL().Scheme == "ledger" { + derivationPaths = append(derivationPaths, accounts.LegacyLedgerBaseDerivationPath) + } + derivationPaths = append(derivationPaths, accounts.DefaultBaseDerivationPath) + + event.Wallet.SelfDerive(derivationPaths, ethClient) + + case accounts.WalletDropped: + log.Info("Old wallet dropped", "url", event.Wallet.URL()) + event.Wallet.Close() + } + } + }() + + // Spawn a standalone goroutine for status synchronization monitoring, + // close the node when synchronization is complete if user required. + if ctx.Bool(utils.ExitWhenSyncedFlag.Name) { + go func() { + sub := stack.EventMux().Subscribe(downloader.DoneEvent{}) + defer sub.Unsubscribe() + for { + event := <-sub.Chan() + if event == nil { + continue + } + done, ok := event.Data.(downloader.DoneEvent) + if !ok { + continue + } + if timestamp := time.Unix(int64(done.Latest.Time), 0); time.Since(timestamp) < 10*time.Minute { + log.Info("Synchronisation completed", "latestnum", done.Latest.Number, "latesthash", done.Latest.Hash(), + "age", common.PrettyAge(timestamp)) + stack.Close() + } + } + }() + } +} diff --git a/cmd/aiigo/misccmd.go b/cmd/aiigo/misccmd.go new file mode 100644 index 0000000000..1f825c2364 --- /dev/null +++ b/cmd/aiigo/misccmd.go @@ -0,0 +1,104 @@ +// Copyright 2016 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 . + +package main + +import ( + "fmt" + "os" + "runtime" + "strings" + + "github.com/ethereum/go-ethereum/internal/version" + "github.com/urfave/cli/v2" +) + +var ( + VersionCheckUrlFlag = &cli.StringFlag{ + Name: "check.url", + Usage: "URL to use when checking vulnerabilities", + Value: "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities.json", + } + VersionCheckVersionFlag = &cli.StringFlag{ + Name: "check.version", + Usage: "Version to check", + Value: version.ClientName(clientIdentifier), + } + versionCommand = &cli.Command{ + Action: printVersion, + Name: "version", + Usage: "Print version numbers", + ArgsUsage: " ", + Description: ` +The output of this command is supposed to be machine-readable. +`, + } + versionCheckCommand = &cli.Command{ + Action: versionCheck, + Flags: []cli.Flag{ + VersionCheckUrlFlag, + VersionCheckVersionFlag, + }, + Name: "version-check", + Usage: "Checks (online) for known aiigo security vulnerabilities", + ArgsUsage: "", + Description: ` +The version-check command fetches vulnerability-information from https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities.json, +and displays information about any security vulnerabilities that affect the currently executing version. +`, + } + licenseCommand = &cli.Command{ + Action: license, + Name: "license", + Usage: "Display license information", + ArgsUsage: " ", + } +) + +func printVersion(ctx *cli.Context) error { + git, _ := version.VCS() + + fmt.Println(strings.Title(clientIdentifier)) + fmt.Println("Version:", version.WithMeta) + if git.Commit != "" { + fmt.Println("Git Commit:", git.Commit) + } + if git.Date != "" { + fmt.Println("Git Commit Date:", git.Date) + } + fmt.Println("Architecture:", runtime.GOARCH) + fmt.Println("Go Version:", runtime.Version()) + fmt.Println("Operating System:", runtime.GOOS) + fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) + fmt.Printf("GOROOT=%s\n", runtime.GOROOT()) + return nil +} + +func license(_ *cli.Context) error { + fmt.Println(`aiigo 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. + +aiigo 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 aiigo. If not, see .`) + return nil +} diff --git a/cmd/aiigo/run_test.go b/cmd/aiigo/run_test.go new file mode 100644 index 0000000000..79579ed753 --- /dev/null +++ b/cmd/aiigo/run_test.go @@ -0,0 +1,120 @@ +// Copyright 2016 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 . + +package main + +import ( + "context" + "fmt" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/internal/cmdtest" + "github.com/ethereum/go-ethereum/internal/reexec" + "github.com/ethereum/go-ethereum/rpc" +) + +type testaiigo struct { + *cmdtest.TestCmd + + // template variables for expect + Datadir string + Etherbase string +} + +func init() { + // Run the app if we've been exec'd as "aiigo-test" in runaiigo. + reexec.Register("aiigo-test", func() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + os.Exit(0) + }) +} + +func TestMain(m *testing.M) { + // check if we have been reexec'd + if reexec.Init() { + return + } + os.Exit(m.Run()) +} + +func initaiigo(t *testing.T) string { + args := []string{"--networkid=42", "init", "./testdata/clique.json"} + t.Logf("Initializing aiigo: %v ", args) + g := runaiigo(t, args...) + datadir := g.Datadir + g.WaitExit() + return datadir +} + +// spawns aiigo with the given command line args. If the args don't set --datadir, the +// child g gets a temporary data directory. +func runaiigo(t *testing.T, args ...string) *testaiigo { + tt := &testaiigo{} + tt.TestCmd = cmdtest.NewTestCmd(t, tt) + for i, arg := range args { + switch arg { + case "--datadir": + if i < len(args)-1 { + tt.Datadir = args[i+1] + } + case "--miner.etherbase": + if i < len(args)-1 { + tt.Etherbase = args[i+1] + } + } + } + if tt.Datadir == "" { + // The temporary datadir will be removed automatically if something fails below. + tt.Datadir = t.TempDir() + args = append([]string{"--datadir", tt.Datadir}, args...) + } + + // Boot "aiigo". This actually runs the test binary but the TestMain + // function will prevent any tests from running. + tt.Run("aiigo-test", args...) + + return tt +} + +// waitForEndpoint attempts to connect to an RPC endpoint until it succeeds. +func waitForEndpoint(t *testing.T, endpoint string, timeout time.Duration) { + probe := func() bool { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + c, err := rpc.DialContext(ctx, endpoint) + if c != nil { + _, err = c.SupportedModules() + c.Close() + } + return err == nil + } + + start := time.Now() + for { + if probe() { + return + } + if time.Since(start) > timeout { + t.Fatal("endpoint", endpoint, "did not open within", timeout) + } + time.Sleep(200 * time.Millisecond) + } +} diff --git a/cmd/aiigo/snapshot.go b/cmd/aiigo/snapshot.go new file mode 100644 index 0000000000..8b2c8c81c6 --- /dev/null +++ b/cmd/aiigo/snapshot.go @@ -0,0 +1,694 @@ +// Copyright 2021 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 . + +package main + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "os" + "slices" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/state/pruner" + "github.com/ethereum/go-ethereum/core/state/snapshot" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/urfave/cli/v2" +) + +var ( + snapshotCommand = &cli.Command{ + Name: "snapshot", + Usage: "A set of commands based on the snapshot", + Description: "", + Subcommands: []*cli.Command{ + { + Name: "prune-state", + Usage: "Prune stale ethereum state data based on the snapshot", + ArgsUsage: "", + Action: pruneState, + Flags: slices.Concat([]cli.Flag{ + utils.BloomFilterSizeFlag, + }, utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo snapshot prune-state +will prune historical state data with the help of the state snapshot. +All trie nodes and contract codes that do not belong to the specified +version state will be deleted from the database. After pruning, only +two version states are available: genesis and the specific one. + +The default pruning target is the HEAD-127 state. + +WARNING: it's only supported in hash mode(--state.scheme=hash)". +`, + }, + { + Name: "verify-state", + Usage: "Recalculate state hash based on the snapshot for verification", + ArgsUsage: "", + Action: verifyState, + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo snapshot verify-state +will traverse the whole accounts and storages set based on the specified +snapshot and recalculate the root hash of state for verification. +In other words, this command does the snapshot to trie conversion. +`, + }, + { + Name: "check-dangling-storage", + Usage: "Check that there is no 'dangling' snap storage", + ArgsUsage: "", + Action: checkDanglingStorage, + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo snapshot check-dangling-storage traverses the snap storage +data, and verifies that all snapshot storage data has a corresponding account. +`, + }, + { + Name: "inspect-account", + Usage: "Check all snapshot layers for the specific account", + ArgsUsage: "
", + Action: checkAccount, + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo snapshot inspect-account
checks all snapshot layers and prints out +information about the specified address. +`, + }, + { + Name: "traverse-state", + Usage: "Traverse the state with given root hash and perform quick verification", + ArgsUsage: "", + Action: traverseState, + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo snapshot traverse-state +will traverse the whole state from the given state root and will abort if any +referenced trie node or contract code is missing. This command can be used for +state integrity verification. The default checking target is the HEAD state. + +It's also usable without snapshot enabled. +`, + }, + { + Name: "traverse-rawstate", + Usage: "Traverse the state with given root hash and perform detailed verification", + ArgsUsage: "", + Action: traverseRawState, + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo snapshot traverse-rawstate +will traverse the whole state from the given root and will abort if any referenced +trie node or contract code is missing. This command can be used for state integrity +verification. The default checking target is the HEAD state. It's basically identical +to traverse-state, but the check granularity is smaller. + +It's also usable without snapshot enabled. +`, + }, + { + Name: "dump", + Usage: "Dump a specific block from storage (same as 'aiigo dump' but using snapshots)", + ArgsUsage: "[? | ]", + Action: dumpState, + Flags: slices.Concat([]cli.Flag{ + utils.ExcludeCodeFlag, + utils.ExcludeStorageFlag, + utils.StartKeyFlag, + utils.DumpLimitFlag, + }, utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +This command is semantically equivalent to 'aiigo dump', but uses the snapshots +as the backend data source, making this command a lot faster. + +The argument is interpreted as block number or hash. If none is provided, the latest +block is used. +`, + }, + { + Action: snapshotExportPreimages, + Name: "export-preimages", + Usage: "Export the preimage in snapshot enumeration order", + ArgsUsage: " []", + Flags: utils.DatabaseFlags, + Description: ` +The export-preimages command exports hash preimages to a flat file, in exactly +the expected order for the overlay tree migration. +`, + }, + }, + } +) + +// Deprecation: this command should be deprecated once the hash-based +// scheme is deprecated. +func pruneState(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chaindb := utils.MakeChainDatabase(ctx, stack, false) + defer chaindb.Close() + + if rawdb.ReadStateScheme(chaindb) != rawdb.HashScheme { + log.Crit("Offline pruning is not required for path scheme") + } + prunerconfig := pruner.Config{ + Datadir: stack.ResolvePath(""), + BloomSize: ctx.Uint64(utils.BloomFilterSizeFlag.Name), + } + pruner, err := pruner.NewPruner(chaindb, prunerconfig) + if err != nil { + log.Error("Failed to open snapshot tree", "err", err) + return err + } + if ctx.NArg() > 1 { + log.Error("Too many arguments given") + return errors.New("too many arguments") + } + var targetRoot common.Hash + if ctx.NArg() == 1 { + targetRoot, err = parseRoot(ctx.Args().First()) + if err != nil { + log.Error("Failed to resolve state root", "err", err) + return err + } + } + if err = pruner.Prune(targetRoot); err != nil { + log.Error("Failed to prune state", "err", err) + return err + } + return nil +} + +func verifyState(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chaindb := utils.MakeChainDatabase(ctx, stack, true) + defer chaindb.Close() + + headBlock := rawdb.ReadHeadBlock(chaindb) + if headBlock == nil { + log.Error("Failed to load head block") + return errors.New("no head block") + } + triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + defer triedb.Close() + + snapConfig := snapshot.Config{ + CacheSize: 256, + Recovery: false, + NoBuild: true, + AsyncBuild: false, + } + snaptree, err := snapshot.New(snapConfig, chaindb, triedb, headBlock.Root()) + if err != nil { + log.Error("Failed to open snapshot tree", "err", err) + return err + } + if ctx.NArg() > 1 { + log.Error("Too many arguments given") + return errors.New("too many arguments") + } + var root = headBlock.Root() + if ctx.NArg() == 1 { + root, err = parseRoot(ctx.Args().First()) + if err != nil { + log.Error("Failed to resolve state root", "err", err) + return err + } + } + if err := snaptree.Verify(root); err != nil { + log.Error("Failed to verify state", "root", root, "err", err) + return err + } + log.Info("Verified the state", "root", root) + return snapshot.CheckDanglingStorage(chaindb) +} + +// checkDanglingStorage iterates the snap storage data, and verifies that all +// storage also has corresponding account data. +func checkDanglingStorage(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + return snapshot.CheckDanglingStorage(db) +} + +// traverseState is a helper function used for pruning verification. +// Basically it just iterates the trie, ensure all nodes and associated +// contract codes are present. +func traverseState(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chaindb := utils.MakeChainDatabase(ctx, stack, true) + defer chaindb.Close() + + triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + defer triedb.Close() + + headBlock := rawdb.ReadHeadBlock(chaindb) + if headBlock == nil { + log.Error("Failed to load head block") + return errors.New("no head block") + } + if ctx.NArg() > 1 { + log.Error("Too many arguments given") + return errors.New("too many arguments") + } + var ( + root common.Hash + err error + ) + if ctx.NArg() == 1 { + root, err = parseRoot(ctx.Args().First()) + if err != nil { + log.Error("Failed to resolve state root", "err", err) + return err + } + log.Info("Start traversing the state", "root", root) + } else { + root = headBlock.Root() + log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64()) + } + t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb) + if err != nil { + log.Error("Failed to open trie", "root", root, "err", err) + return err + } + var ( + accounts int + slots int + codes int + lastReport time.Time + start = time.Now() + ) + acctIt, err := t.NodeIterator(nil) + if err != nil { + log.Error("Failed to open iterator", "root", root, "err", err) + return err + } + accIter := trie.NewIterator(acctIt) + for accIter.Next() { + accounts += 1 + var acc types.StateAccount + if err := rlp.DecodeBytes(accIter.Value, &acc); err != nil { + log.Error("Invalid account encountered during traversal", "err", err) + return err + } + if acc.Root != types.EmptyRootHash { + id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root) + storageTrie, err := trie.NewStateTrie(id, triedb) + if err != nil { + log.Error("Failed to open storage trie", "root", acc.Root, "err", err) + return err + } + storageIt, err := storageTrie.NodeIterator(nil) + if err != nil { + log.Error("Failed to open storage iterator", "root", acc.Root, "err", err) + return err + } + storageIter := trie.NewIterator(storageIt) + for storageIter.Next() { + slots += 1 + + if time.Since(lastReport) > time.Second*8 { + log.Info("Traversing state", "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) + lastReport = time.Now() + } + } + if storageIter.Err != nil { + log.Error("Failed to traverse storage trie", "root", acc.Root, "err", storageIter.Err) + return storageIter.Err + } + } + if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) { + if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) { + log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash)) + return errors.New("missing code") + } + codes += 1 + } + if time.Since(lastReport) > time.Second*8 { + log.Info("Traversing state", "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) + lastReport = time.Now() + } + } + if accIter.Err != nil { + log.Error("Failed to traverse state trie", "root", root, "err", accIter.Err) + return accIter.Err + } + log.Info("State is complete", "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) + return nil +} + +// traverseRawState is a helper function used for pruning verification. +// Basically it just iterates the trie, ensure all nodes and associated +// contract codes are present. It's basically identical to traverseState +// but it will check each trie node. +func traverseRawState(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chaindb := utils.MakeChainDatabase(ctx, stack, true) + defer chaindb.Close() + + triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + defer triedb.Close() + + headBlock := rawdb.ReadHeadBlock(chaindb) + if headBlock == nil { + log.Error("Failed to load head block") + return errors.New("no head block") + } + if ctx.NArg() > 1 { + log.Error("Too many arguments given") + return errors.New("too many arguments") + } + var ( + root common.Hash + err error + ) + if ctx.NArg() == 1 { + root, err = parseRoot(ctx.Args().First()) + if err != nil { + log.Error("Failed to resolve state root", "err", err) + return err + } + log.Info("Start traversing the state", "root", root) + } else { + root = headBlock.Root() + log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64()) + } + t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb) + if err != nil { + log.Error("Failed to open trie", "root", root, "err", err) + return err + } + var ( + nodes int + accounts int + slots int + codes int + lastReport time.Time + start = time.Now() + hasher = crypto.NewKeccakState() + got = make([]byte, 32) + ) + accIter, err := t.NodeIterator(nil) + if err != nil { + log.Error("Failed to open iterator", "root", root, "err", err) + return err + } + reader, err := triedb.NodeReader(root) + if err != nil { + log.Error("State is non-existent", "root", root) + return nil + } + for accIter.Next(true) { + nodes += 1 + node := accIter.Hash() + + // Check the present for non-empty hash node(embedded node doesn't + // have their own hash). + if node != (common.Hash{}) { + blob, _ := reader.Node(common.Hash{}, accIter.Path(), node) + if len(blob) == 0 { + log.Error("Missing trie node(account)", "hash", node) + return errors.New("missing account") + } + hasher.Reset() + hasher.Write(blob) + hasher.Read(got) + if !bytes.Equal(got, node.Bytes()) { + log.Error("Invalid trie node(account)", "hash", node.Hex(), "value", blob) + return errors.New("invalid account node") + } + } + // If it's a leaf node, yes we are touching an account, + // dig into the storage trie further. + if accIter.Leaf() { + accounts += 1 + var acc types.StateAccount + if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil { + log.Error("Invalid account encountered during traversal", "err", err) + return errors.New("invalid account") + } + if acc.Root != types.EmptyRootHash { + id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root) + storageTrie, err := trie.NewStateTrie(id, triedb) + if err != nil { + log.Error("Failed to open storage trie", "root", acc.Root, "err", err) + return errors.New("missing storage trie") + } + storageIter, err := storageTrie.NodeIterator(nil) + if err != nil { + log.Error("Failed to open storage iterator", "root", acc.Root, "err", err) + return err + } + for storageIter.Next(true) { + nodes += 1 + node := storageIter.Hash() + + // Check the presence for non-empty hash node(embedded node doesn't + // have their own hash). + if node != (common.Hash{}) { + blob, _ := reader.Node(common.BytesToHash(accIter.LeafKey()), storageIter.Path(), node) + if len(blob) == 0 { + log.Error("Missing trie node(storage)", "hash", node) + return errors.New("missing storage") + } + hasher.Reset() + hasher.Write(blob) + hasher.Read(got) + if !bytes.Equal(got, node.Bytes()) { + log.Error("Invalid trie node(storage)", "hash", node.Hex(), "value", blob) + return errors.New("invalid storage node") + } + } + // Bump the counter if it's leaf node. + if storageIter.Leaf() { + slots += 1 + } + if time.Since(lastReport) > time.Second*8 { + log.Info("Traversing state", "nodes", nodes, "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) + lastReport = time.Now() + } + } + if storageIter.Error() != nil { + log.Error("Failed to traverse storage trie", "root", acc.Root, "err", storageIter.Error()) + return storageIter.Error() + } + } + if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) { + if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) { + log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey())) + return errors.New("missing code") + } + codes += 1 + } + if time.Since(lastReport) > time.Second*8 { + log.Info("Traversing state", "nodes", nodes, "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) + lastReport = time.Now() + } + } + } + if accIter.Error() != nil { + log.Error("Failed to traverse state trie", "root", root, "err", accIter.Error()) + return accIter.Error() + } + log.Info("State is complete", "nodes", nodes, "accounts", accounts, "slots", slots, "codes", codes, "elapsed", common.PrettyDuration(time.Since(start))) + return nil +} + +func parseRoot(input string) (common.Hash, error) { + var h common.Hash + if err := h.UnmarshalText([]byte(input)); err != nil { + return h, err + } + return h, nil +} + +func dumpState(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack, true) + defer db.Close() + + conf, root, err := parseDumpConfig(ctx, db) + if err != nil { + return err + } + triedb := utils.MakeTrieDatabase(ctx, db, false, true, false) + defer triedb.Close() + + snapConfig := snapshot.Config{ + CacheSize: 256, + Recovery: false, + NoBuild: true, + AsyncBuild: false, + } + snaptree, err := snapshot.New(snapConfig, db, triedb, root) + if err != nil { + return err + } + accIt, err := snaptree.AccountIterator(root, common.BytesToHash(conf.Start)) + if err != nil { + return err + } + defer accIt.Release() + + log.Info("Snapshot dumping started", "root", root) + var ( + start = time.Now() + logged = time.Now() + accounts uint64 + ) + enc := json.NewEncoder(os.Stdout) + enc.Encode(struct { + Root common.Hash `json:"root"` + }{root}) + for accIt.Next() { + account, err := types.FullAccount(accIt.Account()) + if err != nil { + return err + } + da := &state.DumpAccount{ + Balance: account.Balance.String(), + Nonce: account.Nonce, + Root: account.Root.Bytes(), + CodeHash: account.CodeHash, + AddressHash: accIt.Hash().Bytes(), + } + if !conf.SkipCode && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) { + da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash)) + } + if !conf.SkipStorage { + da.Storage = make(map[common.Hash]string) + + stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{}) + if err != nil { + return err + } + for stIt.Next() { + da.Storage[stIt.Hash()] = common.Bytes2Hex(stIt.Slot()) + } + } + enc.Encode(da) + accounts++ + if time.Since(logged) > 8*time.Second { + log.Info("Snapshot dumping in progress", "at", accIt.Hash(), "accounts", accounts, + "elapsed", common.PrettyDuration(time.Since(start))) + logged = time.Now() + } + if conf.Max > 0 && accounts >= conf.Max { + break + } + } + log.Info("Snapshot dumping complete", "accounts", accounts, + "elapsed", common.PrettyDuration(time.Since(start))) + return nil +} + +// snapshotExportPreimages dumps the preimage data to a flat file. +func snapshotExportPreimages(ctx *cli.Context) error { + if ctx.NArg() < 1 { + utils.Fatalf("This command requires an argument.") + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chaindb := utils.MakeChainDatabase(ctx, stack, true) + defer chaindb.Close() + + triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + defer triedb.Close() + + var root common.Hash + if ctx.NArg() > 1 { + rootBytes := common.FromHex(ctx.Args().Get(1)) + if len(rootBytes) != common.HashLength { + return fmt.Errorf("invalid hash: %s", ctx.Args().Get(1)) + } + root = common.BytesToHash(rootBytes) + } else { + headBlock := rawdb.ReadHeadBlock(chaindb) + if headBlock == nil { + log.Error("Failed to load head block") + return errors.New("no head block") + } + root = headBlock.Root() + } + snapConfig := snapshot.Config{ + CacheSize: 256, + Recovery: false, + NoBuild: true, + AsyncBuild: false, + } + snaptree, err := snapshot.New(snapConfig, chaindb, triedb, root) + if err != nil { + return err + } + return utils.ExportSnapshotPreimages(chaindb, snaptree, ctx.Args().First(), root) +} + +// checkAccount iterates the snap data layers, and looks up the given account +// across all layers. +func checkAccount(ctx *cli.Context) error { + if ctx.NArg() != 1 { + return errors.New("need arg") + } + var ( + hash common.Hash + addr common.Address + ) + switch arg := ctx.Args().First(); len(arg) { + case 40, 42: + addr = common.HexToAddress(arg) + hash = crypto.Keccak256Hash(addr.Bytes()) + case 64, 66: + hash = common.HexToHash(arg) + default: + return errors.New("malformed address or hash") + } + stack, _ := makeConfigNode(ctx) + defer stack.Close() + chaindb := utils.MakeChainDatabase(ctx, stack, true) + defer chaindb.Close() + start := time.Now() + log.Info("Checking difflayer journal", "address", addr, "hash", hash) + if err := snapshot.CheckJournalAccount(chaindb, hash); err != nil { + return err + } + log.Info("Checked the snapshot journalled storage", "time", common.PrettyDuration(time.Since(start))) + return nil +} diff --git a/cmd/aiigo/testdata/blockchain.blocks b/cmd/aiigo/testdata/blockchain.blocks new file mode 100644 index 0000000000000000000000000000000000000000..d29453d3e53b4382cc3ff4254e1931182a6c630d GIT binary patch literal 23287 zcmeI4cT^O~+wW&!$QcAll2t&EAWQgs;ax6Q`^v;ZRi&O@(%$x)pl)W zv`OEiAgJ8pY1=#M9#UDFxG*QO<#g#?$#=2xaY*FKN_jl> z>qj+EW3KW~CS{EOSfCR64=w-yKRW;o0zm|DE%hS;)!y9olLk0~s;VYU*@*ENu}@zq zzlnL;+5d4-YoCABy-klaokcmMTN}lfvQ4$1nwo7Ki*4vvU~8Gof5XHEZK2S2-{PL_ zoQEc-U}pSaeucZx-qSrs-(zT~pjFLEnGx3SE(u}lyL$0KknvB-6G;aC_5IE2^;B5VX% zgBU^hy^j2gMZpjz#O!UgC*V*HO@s+)ZsiG-yoiz~ou=ea@+wNwo!PyBlKLn~AH^+* zlDAQk?_!8PN+M8Fs7-+fCF4=@x<`)%N>-z!W-Hfglx#&wGu69}C^?RjmZ942D7lD| zE>(;JC*Wuhl)Oikr;3t5?adE^3mhi> z>oG_;dJkyXr}(L&6gZ3wWpv#CoA7hF1~{zYN98?m^ooPZ@qVgm1`bpEQDhSigZ^@U zG;BBq{U7;gR0j>7{9!l?$Bg}v5<0j*)D`^KJwTI#!vcS#)Znn63Y#4i4*!wua$r#Y zVF)=e82m8A!!gQ!q%z?c@;_1~aP*~Ln_dscgdFChy1@tnheB}u)clP0(Woe*0?m`=tW3Un}@24{8Ka_WR>hXuqV;|7g_T_T``33H#|_ z@PdpWQEE}(iKAdBK%$i4=&0Kh_5GTSpg-~;cwk=Fk36&=dEbwlKg>{f*_%QH$;aTC6ts++p+r)BUKwrLo*XVs zjj@dTm(NXt-NEjM`qQAAlCFDjF^5S2OhSGAVnw(S8q+fxmgcA0iO%+EW9#zp#<-ivB{>}gN7n2bb?Z0mnk0%csV{Bd42E0u&&j1+kID275akH;C zo=IMu{^FG3PbbUzwZ|XbWGb3M?q#Bh6#oh%zlbqtoW<4Kn z`SxWIC8MNHA_e97b8ff}*XgX>8gUxeey_B^m6jwLxYF`hT?Q9g9}z&#y~u*xavICg zngn@gF$&E$l+kx^$Ld&|qMhdO$GP&5%cori0C9V{E%Pl?C^P`p$`xlEzeuBG)2A%& z!WDD9UBK()?5jxJKycwi11y{;vNveUFB9OPs_o=|gy1QlEtsYrl$d#Pb1%igf)p^1 z#!_NU^S5Ds!;1Y_Kv;V&KC&W@zKJo!pyRR@$yKvM&IsAo)t?P{lEcpLr5238EbicN zheqFjPJ&g!&lo+PEPYJQCRD@uongz9ZFDoKx6A9P_oVCg^ zHR&nN0Xn@svN*pv135#WA8@9Y3UW4q06g#M&ADhsE$%%V;dMqBmD&z61}y4loz8QX zDiyk6bO#xV&6LhlxyKH2hISNZ;F_8SNU47nJI-8Yqi-XzI&}{7172o`XZYql$?(XC zxUA-Up>~R8-TH9GXvR&-oJ}GwE;-Q|4nrs)0i~FSY%5uadCI<*&*)y$Q zpAM6=z2&GiddyV}zQ^T~$2>xhFZADG>{Sy9=ZIi-tv;tUE%t0SlttKZ9q6~NS%T^5o-E=rM5DUC1@YqD+}u9l7B&bIA6wqcLO zIr}E#9xk_QOVdQTKU`bOiuj|Z-Qsbd$_O~1S95PpoQY9)Gg`#qx%E6{St-|2k*TJ? zrK6E(MF;SQo-{mbhxJu#+QOcCQAtfmis5dGDarbLi`QzP|?gg5r z_aD7evQqCH-xfhTIbSq~q&t;1Z#c2d4RVHY6ldVOW?G;k#v8K(+E_dA{7G^&tf_6t za%3l!rbKl+~UAoX*tt^EA1=aoO#aHw4Ja$^R*lj;(1BukTY{@ z1Cw43rO0wiZt{r0mMCt&b#1oCL&~y^mrZr0uvCsYo)zaT)W{3%RASGke}vwKD_+3I7(d*6d3TRE*KRxmH$2gC<82S;yvErybKC5kF8Ul`Q{BdY zkmF_hgIR?dVkPNsB?#(R7f5pbpw*LU<{PJ+e{%+MhQRvHnJLKG3Ifahk>|)jSd0~ffIp14t=t3AW6gheGJom<1kTcAqI0L_b&;ZYE%!H?c7B>i-pq)2LS5mkD@tz} z3Mf4+4>`M>II-qYcX_X2`07%}-PsHaiqJYe9mlj-qYYQ_?&|`_A>XC`=ZhTwoqc7trFojzyb25}h2%@wms#D-0HSgoA`@2N#} zKeI_-SVX{g;=H^?bnf-w^1^e?KAySE>=HTU*KUcw#^IrA{mmK3Sq=7g&d5N{))4@e zS+8n!YUv#8GAu#q*B&pQ3zwz@azMqG0Pb4kLG53wcg(0eH_f}CL;#ToeZjTRud zesYF#1)Wvuxj}pAwc>XH=V`ISVoD3P(J^b@*x{T4>^0@N7c0&J0_-*0>;Y$j#lI<) zG;sUv>GSah(k$Xwqc{r!pZ;YxNhqab#8lL>9}hTEE@&*Ub8yBMrqWgjNtAZRIyxPb zvxkN04x{JD8PhYtBq|+>0nEuHY zrhb*`if?yrIy;D??>mkHEi{j7%%jXceVW-bUE@){AQ0i2piAH;@U%Ax^6K6u*?%_fF;!f;n#s0=XXp4ato!C4mg!S^4Y7@#zO!hWj-w9DXuj}jsDf$@El8ceQ=brJDY+s_yk%o=wd z1HPOc>RXa_^;fJAXys|{v`g<0bdw}_OXjJo7|7aYlS2;Cjk^}36Hip2weobY?^)>u zC<(MtsfV@tWd(2rJ4Of}lf$70Q#YC4%`1~|x)uzbAB@IY(R=;L$4Yxl^YY_jd_w|2 zP(u_;G)X1nU8u0dEptIiZo4K}kFooT_SE1m)EDy`kj2KBbvb2^Dko35mcYJE9{6Gz zOyPEp!Pj*{K8~Kx{x^pphmyDl99kNI9DYFnqx?5yN$vH^lTN-r{ZSFCuGEfkhvET^ z_T}~m-PbOi1dtg|HcrbBwc3Cj;{00c%lSr;!F%C?!z`k?rxUbC{GWvr`OIo* zRahjE$*}>_ITJe^f_9~aGfAdD3U6CHHnf zFxxthKkepytM=s!oSOnrZ_-zfC~J<%p)z^xBc7yOeq#i@t4D6C-dl*nlFtT8%Z)os z+cZWG0W5BH$mgh>3PXv?<7oe$ju)jRy zP+QyaV_TdGs}Il9yp266AiL?A66Y{R>!1T5g+Eo+4fw9$kkY(vkZo3==OJrf7i#K>7uFj!k6xg}v z+?y_%k>Gd%?c+Vue&q(5Mq)Bq;y?$>8$o>UrFedG2y$41|9w1E13BD90JSE2>N9G!@P`53j}sa zXs_nHUx*`kMwGhH%=^ZD4mwfDG$9^kMwCfG{sb^?7c~4rlbRqTZ8EdTUu58nMs2E{ zQ$fZwiE)y4_1V@Tha8k$iKS@J{2SQMhXiPbI%OW!A}1_f z=P!+=eol}*UleEk&g1$yq4x=?b(&n+uSE_ytbfAJif2gx82}>~g>=W>LA=C;MPQ-f+}<1C8lSB;erUJIr%KE_+QWmHdoWT`)(UpuD6gIa_v| zE${Gt+qK{0A;_U5;dc&mP#o5yApq}{^Sw@5K@0evpRP7ndyGhtk`%Syb&gCmVbkg@ z6)QyMrl#2kF|ZJV91EWLY2p&6yj3u>CtwN5SZhV zEtP=Mh3UqI)kk*j=o@0*-i1mMJ5S$G=Pq_vZa4WdVzokn9=u4$kYK^p+*vF78_#;3 zY~>jF7uNZltS{C-7NX9T`pqH8A%f^Thy5UjFa+>?+lFc>9jZEXDnRev%mNd-2~k4U z7h}j~-z$@dwr>}akOWS#oq*(dkVC?wI0PMz^IxHdW-sP4@QhPfwyWk~rir zrQLv`je8AE(=|EwEZ&bRzOC1blnUG@*xV2>0T$Df#iH_nBbcg?E4$eQ_E6ntgTqo&<7B93d95~q#ItnR-71E&SbNv06ZkxrVHuU z+I;kajCLEv;ej_KrCZ~wz1wLbF?GsYtRclNv1Z9@SOYc%ofl}hmNO&qkIA9;(k?0A z7pb+oNDkgFP80X{F6}cW*lkhf`kHb|C3S=X_Dx1?drzFtM21+Ue zc;Ka0kBb0i;vvOeD;2R1X>&EZ96T5;=iLNI)$l`huFE|G!jd|W8y8*Gt|#$Pf$yn_ zkKiy6^irb*FbSG5)MjMM9SW?FgT;|f(OV*yF!nN*Egs?tN|X8)11xZ(izSR|@q&Sr6IJ~5;)VUK!Tdz7>4!JT(=M6l@f zRB!5|E;LF(u0T5DY&XZj7;&PTUBIh1WACK2ECt>+xr<}biu=6$iqkhK*^|mbWJV{x z(xv{JGmtY$((jysUTXD(D6d-<{KsC>QVk5E_&dX&wx+c(_Lf!1i_$pn!eti*HFc4a zayC8BlxL$s&Pa~p?7Np*No)!0P+qhdjV7jZSE*n~J;ArDCM06l6OeOr@n@>b0U_Zz zyz|Yq#JT1kY{EOO${&gQ-^m1BFQt-kJ^eu~iTsc=iV=aXm6L|nYYQcWvobP*cB55U zrw9X6;!Q^+6-L!FkI5O^8g;XvzD5~=03bC##Mwi=#ebV~;|l?-9w$umme3afcwU)A zuor%Q{Lx1qJ(|^kQLN`}<*nrez(=M>f~KGE0Mz+cOx_1s&n7KAg3ISVG)Ft7?M!X? zr8ma`78( zr;xZOL5ZZ%^&Xp*zI^cAjr1taKz|h)An{?jIE~>5Rxi1$9L-qv>xmmh(r86I-yAKT zm_5m^AP3l7*iIq*l7ejphn45#7m(Oz`1#ENC1yz<{CcVeSLQ>`WH?GPWL}tm3UPBj z>pe`{{MwsUX{uDy&lfXeGqSUB;h3D|Wdt!uV>J8SZ}T$FG#Hrn^XF7~>-}WU_5$IU z+;o2~z$|#JAZ#p*!H7(I=XI+ys|X(bTc$_Dy;V=yLi$YgrvdM(q_NtW&P(}k`iUE9)>&bXW$+cVMkzw1cv=&*H zM;~nad=tjQxhn$T|Fjefw}LMFbn0K&hUQv)(bN|Q#c^w zY?tVM%BP@Y!eZzH9YCk_`catNFoy1)sOH2nS>){;Sj|}(=O7_#eXJUDs!l+|fmdeU zx~CG3rocnU^1N`07=txQtg6}#vWHz3Rg(XkGZbeS5c2Pwf&MD>Liu|%!_kh2pZt`}JWm3!OKTSQW^buFRg>OVskEX~HPQJraT8xyYt3F7 zmoldLkh51+wO!tQlv$Q~PQ#{82(P(J^iskK6dm0zu)E7oi5=HpC4rW#zfY}@FA^K! z+G?USEgo`6^qqCcAHewaHyvqY#tM^rTY}*sXL+B@zI;ZP^pvW)4RhswzUKo>Vt2tsQ!_ z5+j9Tn6vQbrE}nSv4iK$j9fjdTU$&-t=DWs@Xd_GdoM(!U1FR)tLaPFx39fxdCc*Q ztwltbw<-K;*TXR4Q!ddT?%sS^79`^TUgU}1w~a|$Uf_P+U>>9O66;G!b!ihyhPm!B zSHGI%o!9Mq+vKuiO&UPdw2*v7cajXDO#kXF_4Tj*+~pfrt^lk41N9oh*!HtOaVGf> z-*5iUWdBVo82)nRzbW*WGN`>P{>Ju;3GE<-;tX-}fHST0AZIiPAYU+;^CD$=3YUU( zjcxF)Hgmnvq>OuE#a>e78-lOYl#$DRU!T4H*7ySCjN&NH!0iQSfeW$cRJC#`(A78+ zY(iQ~jE7I?M`Bdn74DbaV%K00s{}~#H7C7mJG0=F1HH99x7)a!0jZr=8L#@uXs=`r z2%b9ROjIgOxKuK$Ua!tG(hX7JK1}^0>BJ+ljO=V(q+atp=P@}`siZbChcK^(Z%dq2 zyvz5|aD>Y!N)COSX@O?Q>;j7*!1S;z4iI_h;o*+8HXSKv+_AD{v9d;YwfDw{uh^jy za{wg|gjUyS@d97)iy@ZOxHTT^LM;(2De=$V*)YDhi)cS__DdK1UrR{-^~?-^HT_2x z#D7!@9M5Vf4>;2l0y(2c03(n6-_y9c+~k77I-+?WM;O;(Q}3=x*KwUywj8_BRF0fj zP3E?0ywD7CcJe6Bz)dJ<0I8{R7vqUxr>5=h(KG#LqN+)=lov*?Nzdn)0K3y$UVv)S z%UD^`SEYhy?}mPRFx9{lF)l4x9+Uq$J;l+RDn<8@Ga5n$9U&6|PxyEy4*Rgj1Bw{~ z=AmaZx%G-!cGdNaWXI&JGr>y2wTVw)?(LF&zm6b7G7!cB(px>3V^XH19>cK!7_2zvHIqWC3j2TAAv`moKA=p+?Bw%G4Omo)EZZo?EqSf3IHv4C z6e<9JYpSGQ+tWq$Xm;4L=_O!j_U3}=PKavEYZhTXW4`d`M2+G8={sy(4GtMEt<|;v zPjhx;kAs<#e=WiASJQuFL4c(s!RW|<;!KkI`@D$;a>k4R(C$oeH|U!>-T9zUS(Ik( z6c)8{%>o*Ai}P_=DKjIL6|&x_x+=skEdu0>>L|{@&3b46pr$Pcmnma7@mgAdGG89Lr zXu2{}&LH-FW0-7Umtlh+P%1X^_HT;~yt*8kTq1VGN6E%@x%4SEevA5fUJ{naNSN`>Qqiou#_Yi9T`xZA!xpjXK;`+4g|1$JwlGwv&n278Vi?- zbuyxH_(<*b>ZTB0Qo^Yb^DQZ4&Q4Xi0tS2)CJn@^XXi)NW0le3--k&P?TV_ZgcEQ#Ah zND!vZU>fG&iB7lVy9pt#nh}n%Vh1W@_ab@;;-Y`|D&A!Hy9y6yCfJL8BmnE6JpgjXjQ~!ldN)ao)@M4sd6^U{&rO=bnB-IbNJOng` z$QjL1oPisP(Et%Q@@})T)#&+sy%Zl6Ib`BJ8Ap<{r}Dh3|Ac}$?#u3$tudD#wylqEhW#Ed?&W=WRFrY4_K>rS>wWsTqTNr)oljcKM>gi1tMyU!t_RVj;t zb2(+Y8=kKzp6N{$xLZX|@izPd|q)9m0PZoRp6#aISE{n-qqWgMowWIcolu|8vrR1p4 zDr!`-&&NsdZ#g^U3Gt_{JhcDG{5MI4Uu}|y$shI~>M-x`e*anu0Tz=4qd$i~b0$f5 zz?mK+$e92Fu>SD6sBFt{>22{sf)ztMOCv-!?IN>2@&13YK)Gw~#6MLScc2^t?L6njbTGBg6OzL<} z1`p`w9Fwz$IEkGI>6?8@Ebh-Y_&Xz`qAG}9sc1?yCaasSOu1D9LJX_jas}@t0%6I6 zL8-IZ$sGX%M$8kRIkHSNadYzR02ayDiW1I`?!ZpxihF+Cq*k#fVKM7`d);`Nzud;& zZR-Cu&VC`}7kn6gNr4Fj7)gQ=1bPtv5&ft|67(CwLeL*@X0QZub`iDPOMQd%lOb8{ zl!48ut?HT<@qwF)F?|MbuSB#lV6srS-lD;YH~scNgb0COL-{GDE3yuVdJX? zRyLDdv{drVvi0ZF0Iu~=kOW8GV#!Ou$azGV_Dgh=QYth^KUEptg;NtHR*N=MjMuU| zv&||DWaIi+%v@MkKFuOXH(}gX)!5il%|1u2-T+sIc&JkT={x%WjrAGBAH9DdP#yn0 zFdT{_=FLBfpu~^zhgJkAB*Ey<;Rk1^9293Y4ByAIWRNp41aN)C_0_(HhV~2G@i@ll zh-*t`144O_xj1IRVtTz9{AA=1CO4#*5OD_NjQ%Ljz^z?r06Sd>yZ0s*R*w+rI9niz z1I":""} +{"t":"2023-11-22T15:42:00.408303+08:00","lvl":"info","msg":"(*uint256.Int)(nil)","":""} +{"t":"2023-11-22T15:42:00.408311+08:00","lvl":"info","msg":"(fmt.Stringer)(nil)","res":null} +{"t":"2023-11-22T15:42:00.408318+08:00","lvl":"info","msg":"nil-concrete-stringer","res":""} +{"t":"2023-11-22T15:42:00.408322+08:00","lvl":"info","msg":"error(nil) ","res":null} +{"t":"2023-11-22T15:42:00.408326+08:00","lvl":"info","msg":"nil-concrete-error","res":""} +{"t":"2023-11-22T15:42:00.408334+08:00","lvl":"info","msg":"nil-custom-struct","res":null} +{"t":"2023-11-22T15:42:00.40835+08:00","lvl":"info","msg":"raw nil","res":null} +{"t":"2023-11-22T15:42:00.408354+08:00","lvl":"info","msg":"(*uint64)(nil)","res":null} +{"t":"2023-11-22T15:42:00.408361+08:00","lvl":"info","msg":"Using keys 't', 'lvl', 'time', 'level' and 'msg'","t":"t","time":"time","lvl":"lvl","level":"level","msg":"msg"} +{"t":"2023-11-29T15:13:00.195655931+01:00","lvl":"info","msg":"Odd pair (1 attr)","key":null,"LOG_ERROR":"Normalized odd number of arguments by adding nil"} +{"t":"2023-11-29T15:13:00.195681832+01:00","lvl":"info","msg":"Odd pair (3 attr)","key":"value","key2":null,"LOG_ERROR":"Normalized odd number of arguments by adding nil"} diff --git a/cmd/aiigo/testdata/logging/logtest-logfmt.txt b/cmd/aiigo/testdata/logging/logtest-logfmt.txt new file mode 100644 index 0000000000..5c5316b7d9 --- /dev/null +++ b/cmd/aiigo/testdata/logging/logtest-logfmt.txt @@ -0,0 +1,52 @@ +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=big.Int 111,222,333,444,555,678,999=111222333444555678999 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=-big.Int -111,222,333,444,555,678,999=-111222333444555678999 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=big.Int 11,122,233,344,455,567,899,900=11122233344455567899900 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=-big.Int -11,122,233,344,455,567,899,900=-11122233344455567899900 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=uint256 111,222,333,444,555,678,999=111222333444555678999 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=uint256 11,122,233,344,455,567,899,900=11122233344455567899900 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=int64 1,000,000=1000000 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=int64 -1,000,000=-1000000 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=int64 9,223,372,036,854,775,807=9223372036854775807 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=int64 -9,223,372,036,854,775,808=-9223372036854775808 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=uint64 1,000,000=1000000 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=uint64 18,446,744,073,709,551,615=18446744073709551615 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Special chars in value" key="special \r\n\t chars" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Special chars in key" "special \n\t chars"=value +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=nospace nospace=nospace +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="with space" "with nospace"="with nospace" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Bash escapes in value" key="\x1b[1G\x1b[K\x1b[1A" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Bash escapes in key" "\x1b[1G\x1b[K\x1b[1A"=value +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Bash escapes in message \x1b[1G\x1b[K\x1b[1A end" key=value +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="\x1b[35mColored\x1b[0m[" "\x1b[35mColored\x1b[0m["="\x1b[35mColored\x1b[0m[" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="an error message with quotes" error="this is an 'error'" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Custom Stringer value" 2562047h47m16.854s=2562047h47m16.854s +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="a custom stringer that emits quoted text" output="output with 'quotes'" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="A message with wonky 💩 characters" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="A multiline message \nINFO [10-18|14:11:31.106] with wonky characters 💩" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="A multiline message \nLALA [ZZZZZZZZZZZZZZZZZZ] Actually part of message above" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=boolean true=true false=false +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="repeated-key 1" foo=alpha foo=beta +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="repeated-key 2" xx=short xx=longer +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="log at level info" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=warn msg="log at level warn" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=error msg="log at level error" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=test bar=short a="aligned left" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=test bar="a long message" a=1 +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=test bar=short a="aligned right" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="The following logs should align so that the key-fields make 5 columns" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Inserted known block" number=1012 hash=0x0000000000000000000000000000000000000000000000000000000000001234 txs=200 gas=1123123 other=first +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Inserted new block" number=1 hash=0x0000000000000000000000000000000000000000000000000000000000001235 txs=2 gas=1123 other=second +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Inserted known block" number=99 hash=0x0000000000000000000000000000000000000000000000000000000000012322 txs=10 gas=1 other=third +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=warn msg="Inserted known block" number=1012 hash=0x0000000000000000000000000000000000000000000000000000000000001234 txs=200 gas=99 other=fourth +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=(*big.Int)(nil) = +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=(*uint256.Int)(nil) = +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=(fmt.Stringer)(nil) res= +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=nil-concrete-stringer res= +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="error(nil) " res= +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=nil-concrete-error res="" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=nil-custom-struct res= +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="raw nil" res= +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg=(*uint64)(nil) res= +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Using keys 't', 'lvl', 'time', 'level' and 'msg'" t=t time=time lvl=lvl level=level msg=msg +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Odd pair (1 attr)" key= LOG_ERROR="Normalized odd number of arguments by adding nil" +t=xxxx-xx-xxTxx:xx:xx+xxxx lvl=info msg="Odd pair (3 attr)" key=value key2= LOG_ERROR="Normalized odd number of arguments by adding nil" diff --git a/cmd/aiigo/testdata/logging/logtest-terminal.txt b/cmd/aiigo/testdata/logging/logtest-terminal.txt new file mode 100644 index 0000000000..e3b562117c --- /dev/null +++ b/cmd/aiigo/testdata/logging/logtest-terminal.txt @@ -0,0 +1,53 @@ +INFO [xx-xx|xx:xx:xx.xxx] big.Int 111,222,333,444,555,678,999=111,222,333,444,555,678,999 +INFO [xx-xx|xx:xx:xx.xxx] -big.Int -111,222,333,444,555,678,999=-111,222,333,444,555,678,999 +INFO [xx-xx|xx:xx:xx.xxx] big.Int 11,122,233,344,455,567,899,900=11,122,233,344,455,567,899,900 +INFO [xx-xx|xx:xx:xx.xxx] -big.Int -11,122,233,344,455,567,899,900=-11,122,233,344,455,567,899,900 +INFO [xx-xx|xx:xx:xx.xxx] uint256 111,222,333,444,555,678,999=111,222,333,444,555,678,999 +INFO [xx-xx|xx:xx:xx.xxx] uint256 11,122,233,344,455,567,899,900=11,122,233,344,455,567,899,900 +INFO [xx-xx|xx:xx:xx.xxx] int64 1,000,000=1,000,000 +INFO [xx-xx|xx:xx:xx.xxx] int64 -1,000,000=-1,000,000 +INFO [xx-xx|xx:xx:xx.xxx] int64 9,223,372,036,854,775,807=9,223,372,036,854,775,807 +INFO [xx-xx|xx:xx:xx.xxx] int64 -9,223,372,036,854,775,808=-9,223,372,036,854,775,808 +INFO [xx-xx|xx:xx:xx.xxx] uint64 1,000,000=1,000,000 +INFO [xx-xx|xx:xx:xx.xxx] uint64 18,446,744,073,709,551,615=18,446,744,073,709,551,615 +INFO [xx-xx|xx:xx:xx.xxx] Special chars in value key="special \r\n\t chars" +INFO [xx-xx|xx:xx:xx.xxx] Special chars in key "special \n\t chars"=value +INFO [xx-xx|xx:xx:xx.xxx] nospace nospace=nospace +INFO [xx-xx|xx:xx:xx.xxx] with space "with nospace"="with nospace" +INFO [xx-xx|xx:xx:xx.xxx] Bash escapes in value key="\x1b[1G\x1b[K\x1b[1A" +INFO [xx-xx|xx:xx:xx.xxx] Bash escapes in key "\x1b[1G\x1b[K\x1b[1A"=value +INFO [xx-xx|xx:xx:xx.xxx] "Bash escapes in message \x1b[1G\x1b[K\x1b[1A end" key=value +INFO [xx-xx|xx:xx:xx.xxx] "\x1b[35mColored\x1b[0m[" "\x1b[35mColored\x1b[0m["="\x1b[35mColored\x1b[0m[" +INFO [xx-xx|xx:xx:xx.xxx] an error message with quotes error="this is an 'error'" +INFO [xx-xx|xx:xx:xx.xxx] Custom Stringer value 2562047h47m16.854s=2562047h47m16.854s +INFO [xx-xx|xx:xx:xx.xxx] a custom stringer that emits quoted text output="output with 'quotes'" +INFO [xx-xx|xx:xx:xx.xxx] "A message with wonky 💩 characters" +INFO [xx-xx|xx:xx:xx.xxx] "A multiline message \nINFO [10-18|14:11:31.106] with wonky characters 💩" +INFO [xx-xx|xx:xx:xx.xxx] A multiline message +LALA [ZZZZZZZZZZZZZZZZZZ] Actually part of message above +INFO [xx-xx|xx:xx:xx.xxx] boolean true=true false=false +INFO [xx-xx|xx:xx:xx.xxx] repeated-key 1 foo=alpha foo=beta +INFO [xx-xx|xx:xx:xx.xxx] repeated-key 2 xx=short xx=longer +INFO [xx-xx|xx:xx:xx.xxx] log at level info +WARN [xx-xx|xx:xx:xx.xxx] log at level warn +ERROR[xx-xx|xx:xx:xx.xxx] log at level error +INFO [xx-xx|xx:xx:xx.xxx] test bar=short a="aligned left" +INFO [xx-xx|xx:xx:xx.xxx] test bar="a long message" a=1 +INFO [xx-xx|xx:xx:xx.xxx] test bar=short a="aligned right" +INFO [xx-xx|xx:xx:xx.xxx] The following logs should align so that the key-fields make 5 columns +INFO [xx-xx|xx:xx:xx.xxx] Inserted known block number=1012 hash=000000..001234 txs=200 gas=1,123,123 other=first +INFO [xx-xx|xx:xx:xx.xxx] Inserted new block number=1 hash=000000..001235 txs=2 gas=1123 other=second +INFO [xx-xx|xx:xx:xx.xxx] Inserted known block number=99 hash=000000..012322 txs=10 gas=1 other=third +WARN [xx-xx|xx:xx:xx.xxx] Inserted known block number=1012 hash=000000..001234 txs=200 gas=99 other=fourth +INFO [xx-xx|xx:xx:xx.xxx] (*big.Int)(nil) = +INFO [xx-xx|xx:xx:xx.xxx] (*uint256.Int)(nil) = +INFO [xx-xx|xx:xx:xx.xxx] (fmt.Stringer)(nil) res= +INFO [xx-xx|xx:xx:xx.xxx] nil-concrete-stringer res= +INFO [xx-xx|xx:xx:xx.xxx] error(nil) res= +INFO [xx-xx|xx:xx:xx.xxx] nil-concrete-error res= +INFO [xx-xx|xx:xx:xx.xxx] nil-custom-struct res= +INFO [xx-xx|xx:xx:xx.xxx] raw nil res= +INFO [xx-xx|xx:xx:xx.xxx] (*uint64)(nil) res= +INFO [xx-xx|xx:xx:xx.xxx] Using keys 't', 'lvl', 'time', 'level' and 'msg' t=t time=time lvl=lvl level=level msg=msg +INFO [xx-xx|xx:xx:xx.xxx] Odd pair (1 attr) key= LOG_ERROR="Normalized odd number of arguments by adding nil" +INFO [xx-xx|xx:xx:xx.xxx] Odd pair (3 attr) key=value key2= LOG_ERROR="Normalized odd number of arguments by adding nil" diff --git a/cmd/aiigo/testdata/password.txt b/cmd/aiigo/testdata/password.txt new file mode 100644 index 0000000000..f6ea049518 --- /dev/null +++ b/cmd/aiigo/testdata/password.txt @@ -0,0 +1 @@ +foobar \ No newline at end of file diff --git a/cmd/aiigo/testdata/passwords.txt b/cmd/aiigo/testdata/passwords.txt new file mode 100644 index 0000000000..96f98c7f43 --- /dev/null +++ b/cmd/aiigo/testdata/passwords.txt @@ -0,0 +1,3 @@ +foobar +foobar +foobar diff --git a/cmd/aiigo/testdata/vcheck/data.json b/cmd/aiigo/testdata/vcheck/data.json new file mode 100644 index 0000000000..52afb321d1 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/data.json @@ -0,0 +1,61 @@ +[ + { + "name": "CorruptedDAG", + "uid": "aiigo-2020-01", + "summary": "Mining nodes will generate erroneous PoW on epochs > `385`.", + "description": "A mining flaw could cause miners to erroneously calculate PoW, due to an index overflow, if DAG size is exceeding the maximum 32 bit unsigned value.\n\nThis occurred on the ETC chain on 2020-11-06. This is likely to trigger for ETH mainnet around block `11550000`/epoch `385`, slated to occur early January 2021.\n\nThis issue is relevant only for miners, non-mining nodes are unaffected, since non-mining nodes use a smaller verification cache instead of a full DAG.", + "links": [ + "https://github.com/ethereum/go-ethereum/pull/21793", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", + "https://github.com/ethereum/go-ethereum/commit/567d41d9363706b4b13ce0903804e8acf214af49" + ], + "introduced": "v1.6.0", + "fixed": "v1.9.24", + "published": "2020-11-12", + "severity": "Medium", + "check": "aiigo\\/v1\\.(6|7|8)\\..*|aiigo\\/v1\\.9\\.2(1|2|3)-.*" + }, + { + "name": "GoCrash", + "uid": "aiigo-2020-02", + "summary": "A denial-of-service issue can be used to crash aiigo nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", + "description": "The DoS issue can be used to crash all aiigo nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of aiigo (such as Turboaiigo or ETC’s core-aiigo) which is built with versions of Go which contains the vulnerability.", + "links": [ + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", + "https://groups.google.com/g/golang-announce/c/NpBGTTmKzpM", + "https://github.com/golang/go/issues/42552" + ], + "fixed": "v1.9.24", + "published": "2020-11-12", + "severity": "Critical", + "check": "aiigo.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" + }, + { + "name": "ShallowCopy", + "uid": "aiigo-2020-03", + "summary": "A consensus flaw in aiigo, related to `datacopy` precompile", + "description": "aiigo erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", + "links": [ + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/" + ], + "introduced": "v1.9.7", + "fixed": "v1.9.17", + "published": "2020-11-12", + "severity": "Critical", + "check": "aiigo\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" + }, + { + "name": "aiigoCrash", + "uid": "aiigo-2020-04", + "summary": "A denial-of-service issue can be used to crash aiigo nodes during block processing", + "description": "Full details to be disclosed at a later date", + "links": [ + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/" + ], + "introduced": "v1.9.16", + "fixed": "v1.9.18", + "published": "2020-11-12", + "severity": "Critical", + "check": "aiigo\\/v1\\.9.(16|17).*$" + } +] diff --git a/cmd/aiigo/testdata/vcheck/minisig-sigs-new/data.json.minisig b/cmd/aiigo/testdata/vcheck/minisig-sigs-new/data.json.minisig new file mode 100644 index 0000000000..eaea9f9053 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/minisig-sigs-new/data.json.minisig @@ -0,0 +1,4 @@ +untrusted comment: signature from minisign secret key +RUQkliYstQBOKLK05Sy5f3bVRMBqJT26ABo6Vbp3BNJAVjejoqYCu4GWE/+7qcDfHBqYIniDCbFIUvYEnOHxV6vZ93wO1xJWDQw= +trusted comment: timestamp:1693986492 file:data.json hashed +6Fdw2H+W1ZXK7QXSF77Z5AWC7+AEFAfDmTSxNGylU5HLT1AuSJQmxslj+VjtUBamYCvOuET7plbXza942AlWDw== diff --git a/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1 b/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1 new file mode 100644 index 0000000000..f9066d4fe0 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1 @@ -0,0 +1,4 @@ +untrusted comment: signature from minisign secret key +RWQkliYstQBOKFQFQTjmCd6TPw07VZyWFSB3v4+1BM1kv8eHLE5FDy2OkPEqtdaL53xftlrHoJQie0uCcovdlSV8kpyxiLrxEQ0= +trusted comment: timestamp:1605618622 file:vulnerabilities.json +osAPs4QPdDkmiWQxqeMIzYv/b+ZGxJ+19Sbrk1Cpq4t2gHBT+lqFtwL3OCzKWWyjGRTmHfsVGBYpzEdPRQ0/BQ== diff --git a/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2 b/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2 new file mode 100644 index 0000000000..a89a83d21a --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2 @@ -0,0 +1,4 @@ +untrusted comment: Here's a comment +RWQkliYstQBOKFQFQTjmCd6TPw07VZyWFSB3v4+1BM1kv8eHLE5FDy2OkPEqtdaL53xftlrHoJQie0uCcovdlSV8kpyxiLrxEQ0= +trusted comment: Here's a trusted comment +3CnkIuz9MEDa7uNyGZAbKZhuirwfiqm7E1uQHrd2SiO4Y8+Akw9vs052AyKw0s5nhbYHCZE2IMQdHNjKwxEGAQ== diff --git a/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3 b/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3 new file mode 100644 index 0000000000..6fd33b19a3 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3 @@ -0,0 +1,4 @@ +untrusted comment: One more (untrusted) comment +RWQkliYstQBOKFQFQTjmCd6TPw07VZyWFSB3v4+1BM1kv8eHLE5FDy2OkPEqtdaL53xftlrHoJQie0uCcovdlSV8kpyxiLrxEQ0= +trusted comment: Here's a trusted comment +3CnkIuz9MEDa7uNyGZAbKZhuirwfiqm7E1uQHrd2SiO4Y8+Akw9vs052AyKw0s5nhbYHCZE2IMQdHNjKwxEGAQ== diff --git a/cmd/aiigo/testdata/vcheck/minisign.pub b/cmd/aiigo/testdata/vcheck/minisign.pub new file mode 100644 index 0000000000..183dce5f6b --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/minisign.pub @@ -0,0 +1,2 @@ +untrusted comment: minisign public key 284E00B52C269624 +RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp diff --git a/cmd/aiigo/testdata/vcheck/minisign.sec b/cmd/aiigo/testdata/vcheck/minisign.sec new file mode 100644 index 0000000000..5c50715b20 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/minisign.sec @@ -0,0 +1,2 @@ +untrusted comment: minisign encrypted secret key +RWRTY0Iyz8kmPMKrqk6DCtlO9a33akKiaOQG1aLolqDxs52qvPoAAAACAAAAAAAAAEAAAAAArEiggdvyn6+WzTprirLtgiYQoU+ihz/HyGgjhuF+Pz2ddMduyCO+xjCHeq+vgVVW039fbsI8hW6LRGJZLBKV5/jdxCXAVVQE7qTQ6xpEdO0z8Z731/pV1hlspQXG2PNd16NMtwd9dWw= diff --git a/cmd/aiigo/testdata/vcheck/signify-sigs/data.json.sig b/cmd/aiigo/testdata/vcheck/signify-sigs/data.json.sig new file mode 100644 index 0000000000..3d5fcacf9a --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/signify-sigs/data.json.sig @@ -0,0 +1,2 @@ +untrusted comment: verify with ./signifykey.pub +RWSKLNhZb0KdAbhRUhW2LQZXdnwttu2SYhM9EuC4mMgOJB85h7/YIPupf8/ldTs4N8e9Y/fhgdY40q5LQpt5IFC62fq0v8U1/w8= diff --git a/cmd/aiigo/testdata/vcheck/signifykey.pub b/cmd/aiigo/testdata/vcheck/signifykey.pub new file mode 100644 index 0000000000..328f973ab4 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/signifykey.pub @@ -0,0 +1,2 @@ +untrusted comment: signify public key +RWSKLNhZb0KdATtRT7mZC/bybI3t3+Hv/O2i3ye04Dq9fnT9slpZ1a2/ diff --git a/cmd/aiigo/testdata/vcheck/signifykey.sec b/cmd/aiigo/testdata/vcheck/signifykey.sec new file mode 100644 index 0000000000..3279a2e58b --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/signifykey.sec @@ -0,0 +1,2 @@ +untrusted comment: signify secret key +RWRCSwAAACpLQDLawSQCtI7eAVIvaiHzjTsTyJsfV5aKLNhZb0KdAWeICXJGa93/bHAcsY6jUh9I8RdEcDWEoGxmaXZC+IdVBPxDpkix9fBRGEUdKWHi3dOfqME0YRzErWI5AVg3cRw= diff --git a/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.1 b/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.1 new file mode 100644 index 0000000000..f9066d4fe0 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.1 @@ -0,0 +1,4 @@ +untrusted comment: signature from minisign secret key +RWQkliYstQBOKFQFQTjmCd6TPw07VZyWFSB3v4+1BM1kv8eHLE5FDy2OkPEqtdaL53xftlrHoJQie0uCcovdlSV8kpyxiLrxEQ0= +trusted comment: timestamp:1605618622 file:vulnerabilities.json +osAPs4QPdDkmiWQxqeMIzYv/b+ZGxJ+19Sbrk1Cpq4t2gHBT+lqFtwL3OCzKWWyjGRTmHfsVGBYpzEdPRQ0/BQ== diff --git a/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.2 b/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.2 new file mode 100644 index 0000000000..a89a83d21a --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.2 @@ -0,0 +1,4 @@ +untrusted comment: Here's a comment +RWQkliYstQBOKFQFQTjmCd6TPw07VZyWFSB3v4+1BM1kv8eHLE5FDy2OkPEqtdaL53xftlrHoJQie0uCcovdlSV8kpyxiLrxEQ0= +trusted comment: Here's a trusted comment +3CnkIuz9MEDa7uNyGZAbKZhuirwfiqm7E1uQHrd2SiO4Y8+Akw9vs052AyKw0s5nhbYHCZE2IMQdHNjKwxEGAQ== diff --git a/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.3 b/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.3 new file mode 100644 index 0000000000..6fd33b19a3 --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/sigs/vulnerabilities.json.minisig.3 @@ -0,0 +1,4 @@ +untrusted comment: One more (untrusted) comment +RWQkliYstQBOKFQFQTjmCd6TPw07VZyWFSB3v4+1BM1kv8eHLE5FDy2OkPEqtdaL53xftlrHoJQie0uCcovdlSV8kpyxiLrxEQ0= +trusted comment: Here's a trusted comment +3CnkIuz9MEDa7uNyGZAbKZhuirwfiqm7E1uQHrd2SiO4Y8+Akw9vs052AyKw0s5nhbYHCZE2IMQdHNjKwxEGAQ== diff --git a/cmd/aiigo/testdata/vcheck/vulnerabilities.json b/cmd/aiigo/testdata/vcheck/vulnerabilities.json new file mode 100644 index 0000000000..fc5838dafd --- /dev/null +++ b/cmd/aiigo/testdata/vcheck/vulnerabilities.json @@ -0,0 +1,202 @@ +[ + { + "name": "CorruptedDAG", + "uid": "aiigo-2020-01", + "summary": "Mining nodes will generate erroneous PoW on epochs > `385`.", + "description": "A mining flaw could cause miners to erroneously calculate PoW, due to an index overflow, if DAG size is exceeding the maximum 32 bit unsigned value.\n\nThis occurred on the ETC chain on 2020-11-06. This is likely to trigger for ETH mainnet around block `11550000`/epoch `385`, slated to occur early January 2021.\n\nThis issue is relevant only for miners, non-mining nodes are unaffected, since non-mining nodes use a smaller verification cache instead of a full DAG.", + "links": [ + "https://github.com/ethereum/go-ethereum/pull/21793", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", + "https://github.com/ethereum/go-ethereum/commit/567d41d9363706b4b13ce0903804e8acf214af49", + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-v592-xf75-856p" + ], + "introduced": "v1.6.0", + "fixed": "v1.9.24", + "published": "2020-11-12", + "severity": "Medium", + "CVE": "CVE-2020-26240", + "check": "aiigo\\/v1\\.(6|7|8)\\..*|aiigo\\/v1\\.9\\.\\d-.*|aiigo\\/v1\\.9\\.1.*|aiigo\\/v1\\.9\\.2(0|1|2|3)-.*" + }, + { + "name": "Denial of service due to Go CVE-2020-28362", + "uid": "aiigo-2020-02", + "summary": "A denial-of-service issue can be used to crash aiigo nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", + "description": "The DoS issue can be used to crash all aiigo nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of aiigo (such as Turboaiigo or ETC’s core-aiigo) which is built with versions of Go which contains the vulnerability.", + "links": [ + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", + "https://groups.google.com/g/golang-announce/c/NpBGTTmKzpM", + "https://github.com/golang/go/issues/42552", + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-m6gx-rhvj-fh52" + ], + "introduced": "v0.0.0", + "fixed": "v1.9.24", + "published": "2020-11-12", + "severity": "Critical", + "CVE": "CVE-2020-28362", + "check": "aiigo.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" + }, + { + "name": "ShallowCopy", + "uid": "aiigo-2020-03", + "summary": "A consensus flaw in aiigo, related to `datacopy` precompile", + "description": "aiigo erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", + "links": [ + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-69v6-xc2j-r2jf" + ], + "introduced": "v1.9.7", + "fixed": "v1.9.17", + "published": "2020-11-12", + "severity": "Critical", + "CVE": "CVE-2020-26241", + "check": "aiigo\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" + }, + { + "name": "aiigo DoS via MULMOD", + "uid": "aiigo-2020-04", + "summary": "A denial-of-service issue can be used to crash aiigo nodes during block processing", + "description": "Affected versions suffer from a vulnerability which can be exploited through the `MULMOD` operation, by specifying a modulo of `0`: `mulmod(a,b,0)`, causing a `panic` in the underlying library. \nThe crash was in the `uint256` library, where a buffer [underflowed](https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L442).\n\n\tif `d == 0`, `dLen` remains `0`\n\nand https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L451 will try to access index `[-1]`.\n\nThe `uint256` library was first merged in this [commit](https://github.com/ethereum/go-ethereum/commit/cf6674539c589f80031f3371a71c6a80addbe454), on 2020-06-08. \nExploiting this vulnerabilty would cause all vulnerable nodes to drop off the network. \n\nThe issue was brought to our attention through a [bug report](https://github.com/ethereum/go-ethereum/issues/21367), showing a `panic` occurring on sync from genesis on the Ropsten network.\n \nIt was estimated that the least obvious way to fix this would be to merge the fix into `uint256`, make a new release of that library and then update the aiigo-dependency.\n", + "links": [ + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-jm5c-rv3w-w83m", + "https://github.com/holiman/uint256/releases/tag/v1.1.1", + "https://github.com/holiman/uint256/pull/80", + "https://github.com/ethereum/go-ethereum/pull/21368" + ], + "introduced": "v1.9.16", + "fixed": "v1.9.18", + "published": "2020-11-12", + "severity": "Critical", + "CVE": "CVE-2020-26242", + "check": "aiigo\\/v1\\.9.(16|17).*$" + }, + { + "name": "LES Server DoS via GetProofsV2", + "uid": "aiigo-2020-05", + "summary": "A DoS vulnerability can make a LES server crash.", + "description": "A DoS vulnerability can make a LES server crash via malicious GetProofsV2 request from a connected LES client.\n\nThe vulnerability was patched in #21896.\n\nThis vulnerability only concern users explicitly running aiigo as a light server", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-r33q-22hv-j29q", + "https://github.com/ethereum/go-ethereum/pull/21896" + ], + "introduced": "v1.8.0", + "fixed": "v1.9.25", + "published": "2020-12-10", + "severity": "Medium", + "CVE": "CVE-2020-26264", + "check": "(aiigo\\/v1\\.8\\.*)|(aiigo\\/v1\\.9\\.\\d-.*)|(aiigo\\/v1\\.9\\.1\\d-.*)|(aiigo\\/v1\\.9\\.(20|21|22|23|24)-.*)$" + }, + { + "name": "SELFDESTRUCT-recreate consensus flaw", + "uid": "aiigo-2020-06", + "introduced": "v1.9.4", + "fixed": "v1.9.20", + "summary": "A consensus-vulnerability in aiigo could cause a chain split, where vulnerable versions refuse to accept the canonical chain.", + "description": "A flaw was repoted at 2020-08-11 by John Youngseok Yang (Software Platform Lab), where a particular sequence of transactions could cause a consensus failure.\n\n- Tx 1:\n - `sender` invokes `caller`.\n - `caller` invokes `0xaa`. `0xaa` has 3 wei, does a self-destruct-to-self\n - `caller` does a `1 wei` -call to `0xaa`, who thereby has 1 wei (the code in `0xaa` still executed, since the tx is still ongoing, but doesn't redo the selfdestruct, it takes a different path if callvalue is non-zero)\n\n-Tx 2:\n - `sender` does a 5-wei call to 0xaa. No exec (since no code). \n\nIn aiigo, the result would be that `0xaa` had `6 wei`, whereas OE reported (correctly) `5` wei. Furthermore, in aiigo, if the second tx was not executed, the `0xaa` would be destructed, resulting in `0 wei`. Thus obviously wrong. \n\nIt was determined that the root cause was this [commit](https://github.com/ethereum/go-ethereum/commit/223b950944f494a5b4e0957fd9f92c48b09037ad) from [this PR](https://github.com/ethereum/go-ethereum/pull/19953). The semantics of `createObject` was subtly changd, into returning a non-nil object (with `deleted=true`) where it previously did not if the account had been destructed. This return value caused the new object to inherit the old `balance`.\n", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-xw37-57qp-9mm4" + ], + "published": "2020-12-10", + "severity": "High", + "CVE": "CVE-2020-26265", + "check": "(aiigo\\/v1\\.9\\.(4|5|6|7|8|9)-.*)|(aiigo\\/v1\\.9\\.1\\d-.*)$" + }, + { + "name": "Not ready for London upgrade", + "uid": "aiigo-2021-01", + "summary": "The client is not ready for the 'London' technical upgrade, and will deviate from the canonical chain when the London upgrade occurs (at block '12965000' around August 4, 2021.", + "description": "At (or around) August 4, Ethereum will undergo a technical upgrade called 'London'. Clients not upgraded will fail to progress on the canonical chain.", + "links": [ + "https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/london.md", + "https://notes.ethereum.org/@timbeiko/ropsten-postmortem" + ], + "introduced": "v1.10.1", + "fixed": "v1.10.6", + "published": "2021-07-22", + "severity": "High", + "check": "(aiigo\\/v1\\.10\\.(1|2|3|4|5)-.*)$" + }, + { + "name": "RETURNDATA corruption via datacopy", + "uid": "aiigo-2021-02", + "summary": "A consensus-flaw in the aiigo EVM could cause a node to deviate from the canonical chain.", + "description": "A memory-corruption bug within the EVM can cause a consensus error, where vulnerable nodes obtain a different `stateRoot` when processing a maliciously crafted transaction. This, in turn, would lead to the chain being split: mainnet splitting in two forks.\n\nAll aiigo versions supporting the London hard fork are vulnerable (the bug is older than London), so all users should update.\n\nThis bug was exploited on Mainnet at block 13107518.\n\nCredits for the discovery go to @guidovranken (working for Sentnl during an audit of the Telos EVM) and reported via bounty@ethereum.org.", + "links": [ + "https://github.com/ethereum/go-ethereum/blob/master/docs/postmortems/2021-08-22-split-postmortem.md", + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-9856-9gg9-qcmq", + "https://github.com/ethereum/go-ethereum/releases/tag/v1.10.8" + ], + "introduced": "v1.10.0", + "fixed": "v1.10.8", + "published": "2021-08-24", + "severity": "High", + "CVE": "CVE-2021-39137", + "check": "(aiigo\\/v1\\.10\\.(0|1|2|3|4|5|6|7)-.*)$" + }, + { + "name": "DoS via malicious `snap/1` request", + "uid": "aiigo-2021-03", + "summary": "A vulnerable node is susceptible to crash when processing a maliciously crafted message from a peer, via the snap/1 protocol. The crash can be triggered by sending a malicious snap/1 GetTrieNodes package.", + "description": "The `snap/1` protocol handler contains two vulnerabilities related to the `GetTrieNodes` packet, which can be exploited to crash the node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v)", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v", + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities", + "https://github.com/ethereum/go-ethereum/pull/23657" + ], + "introduced": "v1.10.0", + "fixed": "v1.10.9", + "published": "2021-10-24", + "severity": "Medium", + "CVE": "CVE-2021-41173", + "check": "(aiigo\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8)-.*)$" + }, + { + "name": "DoS via malicious p2p message", + "uid": "aiigo-2022-01", + "summary": "A vulnerable node can crash via p2p messages sent from an attacker node, if running with non-default log options.", + "description": "A vulnerable node, if configured to use high verbosity logging, can be made to crash when handling specially crafted p2p messages sent from an attacker node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5)", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5", + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities", + "https://github.com/ethereum/go-ethereum/pull/24507" + ], + "introduced": "v1.10.0", + "fixed": "v1.10.17", + "published": "2022-05-11", + "severity": "Low", + "CVE": "CVE-2022-29177", + "check": "(aiigo\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$" + }, + { + "name": "DoS via malicious p2p message", + "uid": "aiigo-2023-01", + "summary": "A vulnerable node can be made to consume unbounded amounts of memory when handling specially crafted p2p messages sent from an attacker node.", + "description": "The p2p handler spawned a new goroutine to respond to ping requests. By flooding a node with ping requests, an unbounded number of goroutines can be created, leading to resource exhaustion and potentially crash due to OOM.", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-ppjg-v974-84cm", + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities" + ], + "introduced": "v1.10.0", + "fixed": "v1.12.1", + "published": "2023-09-06", + "severity": "High", + "CVE": "CVE-2023-40591", + "check": "(aiigo\\/v1\\.(10|11)\\..*)|(aiigo\\/v1\\.12\\.0-.*)$" + }, + { + "name": "DoS via malicious p2p message", + "uid": "aiigo-2024-01", + "summary": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node.", + "description": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node. Full details will be available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652)", + "links": [ + "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652", + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities" + ], + "introduced": "v1.10.0", + "fixed": "v1.13.15", + "published": "2024-05-06", + "severity": "High", + "CVE": "CVE-2024-32972", + "check": "(aiigo\\/v1\\.(10|11|12)\\..*)|(aiigo\\/v1\\.13\\.\\d-.*)|(aiigo\\/v1\\.13\\.1(0|1|2|3|4)-.*)$" + } +] diff --git a/cmd/aiigo/testdata/wrong-passwords.txt b/cmd/aiigo/testdata/wrong-passwords.txt new file mode 100644 index 0000000000..7d1e338bbf --- /dev/null +++ b/cmd/aiigo/testdata/wrong-passwords.txt @@ -0,0 +1,3 @@ +wrong +wrong +wrong diff --git a/cmd/aiigo/verkle.go b/cmd/aiigo/verkle.go new file mode 100644 index 0000000000..e4b6ba637e --- /dev/null +++ b/cmd/aiigo/verkle.go @@ -0,0 +1,214 @@ +// Copyright 2022 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 . + +package main + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "os" + "slices" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-verkle" + "github.com/urfave/cli/v2" +) + +var ( + zero [32]byte + + verkleCommand = &cli.Command{ + Name: "verkle", + Usage: "A set of experimental verkle tree management commands", + Description: "", + Subcommands: []*cli.Command{ + { + Name: "verify", + Usage: "verify the conversion of a MPT into a verkle tree", + ArgsUsage: "", + Action: verifyVerkle, + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo verkle verify +This command takes a root commitment and attempts to rebuild the tree. + `, + }, + { + Name: "dump", + Usage: "Dump a verkle tree to a DOT file", + ArgsUsage: " [ ...]", + Action: expandVerkle, + Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), + Description: ` +aiigo verkle dump [ ...] +This command will produce a dot file representing the tree, rooted at . +in which key1, key2, ... are expanded. + `, + }, + }, + } +) + +// recurse into each child to ensure they can be loaded from the db. The tree isn't rebuilt +// (only its nodes are loaded) so there is no need to flush them, the garbage collector should +// take care of that for us. +func checkChildren(root verkle.VerkleNode, resolver verkle.NodeResolverFn) error { + switch node := root.(type) { + case *verkle.InternalNode: + for i, child := range node.Children() { + childC := child.Commit().Bytes() + + childS, err := resolver(childC[:]) + if bytes.Equal(childC[:], zero[:]) { + continue + } + if err != nil { + return fmt.Errorf("could not find child %x in db: %w", childC, err) + } + // depth is set to 0, the tree isn't rebuilt so it's not a problem + childN, err := verkle.ParseNode(childS, 0) + if err != nil { + return fmt.Errorf("decode error child %x in db: %w", child.Commitment().Bytes(), err) + } + if err := checkChildren(childN, resolver); err != nil { + return fmt.Errorf("%x%w", i, err) // write the path to the erroring node + } + } + case *verkle.LeafNode: + // sanity check: ensure at least one value is non-zero + + for i := 0; i < verkle.NodeWidth; i++ { + if len(node.Value(i)) != 0 { + return nil + } + } + return errors.New("both balance and nonce are 0") + case verkle.Empty: + // nothing to do + default: + return fmt.Errorf("unsupported type encountered %v", root) + } + + return nil +} + +func verifyVerkle(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chaindb := utils.MakeChainDatabase(ctx, stack, true) + defer chaindb.Close() + headBlock := rawdb.ReadHeadBlock(chaindb) + if headBlock == nil { + log.Error("Failed to load head block") + return errors.New("no head block") + } + if ctx.NArg() > 1 { + log.Error("Too many arguments given") + return errors.New("too many arguments") + } + var ( + rootC common.Hash + err error + ) + if ctx.NArg() == 1 { + rootC, err = parseRoot(ctx.Args().First()) + if err != nil { + log.Error("Failed to resolve state root", "error", err) + return err + } + log.Info("Rebuilding the tree", "root", rootC) + } else { + rootC = headBlock.Root() + log.Info("Rebuilding the tree", "root", rootC, "number", headBlock.NumberU64()) + } + + serializedRoot, err := chaindb.Get(rootC[:]) + if err != nil { + return err + } + root, err := verkle.ParseNode(serializedRoot, 0) + if err != nil { + return err + } + + if err := checkChildren(root, chaindb.Get); err != nil { + log.Error("Could not rebuild the tree from the database", "err", err) + return err + } + + log.Info("Tree was rebuilt from the database") + return nil +} + +func expandVerkle(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + defer stack.Close() + + chaindb := utils.MakeChainDatabase(ctx, stack, true) + defer chaindb.Close() + var ( + rootC common.Hash + keylist [][]byte + err error + ) + if ctx.NArg() >= 2 { + rootC, err = parseRoot(ctx.Args().First()) + if err != nil { + log.Error("Failed to resolve state root", "error", err) + return err + } + keylist = make([][]byte, 0, ctx.Args().Len()-1) + args := ctx.Args().Slice() + for i := range args[1:] { + key, err := hex.DecodeString(args[i+1]) + log.Info("decoded key", "arg", args[i+1], "key", key) + if err != nil { + return fmt.Errorf("error decoding key #%d: %w", i+1, err) + } + keylist = append(keylist, key) + } + log.Info("Rebuilding the tree", "root", rootC) + } else { + return fmt.Errorf("usage: %s root key1 [key 2...]", ctx.App.Name) + } + + serializedRoot, err := chaindb.Get(rootC[:]) + if err != nil { + return err + } + root, err := verkle.ParseNode(serializedRoot, 0) + if err != nil { + return err + } + + for i, key := range keylist { + log.Info("Reading key", "index", i, "key", keylist[0]) + root.Get(key, chaindb.Get) + } + + if err := os.WriteFile("dump.dot", []byte(verkle.ToDot(root)), 0600); err != nil { + log.Error("Failed to dump file", "err", err) + } else { + log.Info("Tree was dumped to file", "file", "dump.dot") + } + return nil +} diff --git a/cmd/aiigo/version_check.go b/cmd/aiigo/version_check.go new file mode 100644 index 0000000000..baf7b0634a --- /dev/null +++ b/cmd/aiigo/version_check.go @@ -0,0 +1,170 @@ +// Copyright 2020 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 . + +package main + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + "regexp" + "strings" + + "github.com/ethereum/go-ethereum/log" + "github.com/jedisct1/go-minisign" + "github.com/urfave/cli/v2" +) + +var aiigoPubKeys []string = []string{ + //@holiman, minisign public key FB1D084D39BAEC24 + "RWQk7Lo5TQgd+wxBNZM+Zoy+7UhhMHaWKzqoes9tvSbFLJYZhNTbrIjx", + //minisign public key 138B1CA303E51687 + "RWSHFuUDoxyLEzjszuWZI1xStS66QTyXFFZG18uDfO26CuCsbckX1e9J", + //minisign public key FD9813B2D2098484 + "RWSEhAnSshOY/b+GmaiDkObbCWefsAoavjoLcPjBo1xn71yuOH5I+Lts", +} + +type vulnJson struct { + Name string + Uid string + Summary string + Description string + Links []string + Introduced string + Fixed string + Published string + Severity string + Check string + CVE string +} + +func versionCheck(ctx *cli.Context) error { + url := ctx.String(VersionCheckUrlFlag.Name) + version := ctx.String(VersionCheckVersionFlag.Name) + log.Info("Checking vulnerabilities", "version", version, "url", url) + return checkCurrent(url, version) +} + +func checkCurrent(url, current string) error { + var ( + data []byte + sig []byte + err error + ) + if data, err = fetch(url); err != nil { + return fmt.Errorf("could not retrieve data: %w", err) + } + if sig, err = fetch(fmt.Sprintf("%v.minisig", url)); err != nil { + return fmt.Errorf("could not retrieve signature: %w", err) + } + if err = verifySignature(aiigoPubKeys, data, sig); err != nil { + return err + } + var vulns []vulnJson + if err = json.Unmarshal(data, &vulns); err != nil { + return err + } + allOk := true + for _, vuln := range vulns { + r, err := regexp.Compile(vuln.Check) + if err != nil { + return err + } + if r.MatchString(current) { + allOk = false + fmt.Printf("## Vulnerable to %v (%v)\n\n", vuln.Uid, vuln.Name) + fmt.Printf("Severity: %v\n", vuln.Severity) + fmt.Printf("Summary : %v\n", vuln.Summary) + fmt.Printf("Fixed in: %v\n", vuln.Fixed) + if len(vuln.CVE) > 0 { + fmt.Printf("CVE: %v\n", vuln.CVE) + } + if len(vuln.Links) > 0 { + fmt.Printf("References:\n") + for _, ref := range vuln.Links { + fmt.Printf("\t- %v\n", ref) + } + } + fmt.Println() + } + } + if allOk { + fmt.Println("No vulnerabilities found") + } + return nil +} + +// fetch makes an HTTP request to the given url and returns the response body +func fetch(url string) ([]byte, error) { + if filep := strings.TrimPrefix(url, "file://"); filep != url { + return os.ReadFile(filep) + } + res, err := http.Get(url) + if err != nil { + return nil, err + } + defer res.Body.Close() + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + return body, nil +} + +// verifySignature checks that the sigData is a valid signature of the given +// data, for pubkey aiigoPubkey +func verifySignature(pubkeys []string, data, sigdata []byte) error { + sig, err := minisign.DecodeSignature(string(sigdata)) + if err != nil { + return err + } + // find the used key + var key *minisign.PublicKey + for _, pubkey := range pubkeys { + pub, err := minisign.NewPublicKey(pubkey) + if err != nil { + // our pubkeys should be parseable + return err + } + if pub.KeyId != sig.KeyId { + continue + } + key = &pub + break + } + if key == nil { + log.Info("Signing key not trusted", "keyid", keyID(sig.KeyId), "error", err) + return errors.New("signature could not be verified") + } + if ok, err := key.Verify(data, sig); !ok || err != nil { + log.Info("Verification failed error", "keyid", keyID(key.KeyId), "error", err) + return errors.New("signature could not be verified") + } + return nil +} + +// keyID turns a binary minisign key ID into a hex string. +// Note: key IDs are printed in reverse byte order. +func keyID(id [8]byte) string { + var rev [8]byte + for i := range id { + rev[len(rev)-1-i] = id[i] + } + return fmt.Sprintf("%X", rev) +} diff --git a/cmd/aiigo/version_check_test.go b/cmd/aiigo/version_check_test.go new file mode 100644 index 0000000000..12f6141330 --- /dev/null +++ b/cmd/aiigo/version_check_test.go @@ -0,0 +1,185 @@ +// Copyright 2020 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 . + +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" + "testing" + + "github.com/jedisct1/go-minisign" +) + +func TestVerification(t *testing.T) { + t.Parallel() + // Signatures generated with `minisign`. Legacy format, not pre-hashed file. + t.Run("minisig-legacy", func(t *testing.T) { + t.Parallel() + // For this test, the pubkey is in testdata/vcheck/minisign.pub + // (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' ) + pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp" + testVerification(t, pub, "./testdata/vcheck/minisig-sigs/") + }) + t.Run("minisig-new", func(t *testing.T) { + t.Parallel() + // For this test, the pubkey is in testdata/vcheck/minisign.pub + // (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' ) + // `minisign -S -s ./minisign.sec -m data.json -x ./minisig-sigs-new/data.json.minisig` + pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp" + testVerification(t, pub, "./testdata/vcheck/minisig-sigs-new/") + }) + // Signatures generated with `signify-openbsd` + t.Run("signify-openbsd", func(t *testing.T) { + t.Parallel() + t.Skip("This currently fails, minisign expects 4 lines of data, signify provides only 2") + // For this test, the pubkey is in testdata/vcheck/signifykey.pub + // (the privkey is `signifykey.sec`, if we want to expand this test. Password 'test' ) + pub := "RWSKLNhZb0KdATtRT7mZC/bybI3t3+Hv/O2i3ye04Dq9fnT9slpZ1a2/" + testVerification(t, pub, "./testdata/vcheck/signify-sigs/") + }) +} + +func testVerification(t *testing.T, pubkey, sigdir string) { + // Data to verify + data, err := os.ReadFile("./testdata/vcheck/data.json") + if err != nil { + t.Fatal(err) + } + // Signatures, with and without comments, both trusted and untrusted + files, err := os.ReadDir(sigdir) + if err != nil { + t.Fatal(err) + } + if len(files) == 0 { + t.Fatal("Missing tests") + } + for _, f := range files { + sig, err := os.ReadFile(filepath.Join(sigdir, f.Name())) + if err != nil { + t.Fatal(err) + } + err = verifySignature([]string{pubkey}, data, sig) + if err != nil { + t.Fatal(err) + } + } +} + +func versionUint(v string) int { + mustInt := func(s string) int { + a, err := strconv.Atoi(s) + if err != nil { + panic(v) + } + return a + } + components := strings.Split(strings.TrimPrefix(v, "v"), ".") + a := mustInt(components[0]) + b := mustInt(components[1]) + c := mustInt(components[2]) + return a*100*100 + b*100 + c +} + +// TestMatching can be used to check that the regexps are correct +func TestMatching(t *testing.T) { + t.Parallel() + data, _ := os.ReadFile("./testdata/vcheck/vulnerabilities.json") + var vulns []vulnJson + if err := json.Unmarshal(data, &vulns); err != nil { + t.Fatal(err) + } + check := func(version string) { + vFull := fmt.Sprintf("aiigo/%v-unstable-15339cf1-20201204/linux-amd64/go1.15.4", version) + for _, vuln := range vulns { + r, err := regexp.Compile(vuln.Check) + vulnIntro := versionUint(vuln.Introduced) + vulnFixed := versionUint(vuln.Fixed) + current := versionUint(version) + if err != nil { + t.Fatal(err) + } + if vuln.Name == "Denial of service due to Go CVE-2020-28362" { + // this one is not tied to aiigo-versions + continue + } + if vulnIntro <= current && vulnFixed > current { + // Should be vulnerable + if !r.MatchString(vFull) { + t.Errorf("Should be vulnerable, version %v, intro: %v, fixed: %v %v %v", + version, vuln.Introduced, vuln.Fixed, vuln.Name, vuln.Check) + } + } else { + if r.MatchString(vFull) { + t.Errorf("Should not be flagged vulnerable, version %v, intro: %v, fixed: %v %v %d %d %d", + version, vuln.Introduced, vuln.Fixed, vuln.Name, vulnIntro, current, vulnFixed) + } + } + } + } + for major := 1; major < 2; major++ { + for minor := 0; minor < 30; minor++ { + for patch := 0; patch < 30; patch++ { + vShort := fmt.Sprintf("v%d.%d.%d", major, minor, patch) + check(vShort) + } + } + } +} + +func TestaiigoPubKeysParseable(t *testing.T) { + t.Parallel() + for _, pubkey := range aiigoPubKeys { + _, err := minisign.NewPublicKey(pubkey) + if err != nil { + t.Errorf("Should be parseable") + } + } +} + +func TestKeyID(t *testing.T) { + t.Parallel() + type args struct { + id [8]byte + } + tests := []struct { + name string + args args + want string + }{ + {"@holiman key", args{id: extractKeyId(aiigoPubKeys[0])}, "FB1D084D39BAEC24"}, + {"second key", args{id: extractKeyId(aiigoPubKeys[1])}, "138B1CA303E51687"}, + {"third key", args{id: extractKeyId(aiigoPubKeys[2])}, "FD9813B2D2098484"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if got := keyID(tt.args.id); got != tt.want { + t.Errorf("keyID() = %v, want %v", got, tt.want) + } + }) + } +} + +func extractKeyId(pubkey string) [8]byte { + p, _ := minisign.NewPublicKey(pubkey) + return p.KeyId +} diff --git a/cmd/clef/README.md b/cmd/clef/README.md index d23e70a3d4..c3764e862c 100644 --- a/cmd/clef/README.md +++ b/cmd/clef/README.md @@ -1,6 +1,6 @@ # Clef -Clef can be used to sign transactions and data and is meant as a(n eventual) replacement for Geth's account management. This allows DApps to not depend on Geth's account management. When a DApp wants to sign data (or a transaction), it can send the content to Clef, which will then provide the user with context and ask for permission to sign the content. If the user grants the signing request, Clef will send the signature back to the DApp. +Clef can be used to sign transactions and data and is meant as a(n eventual) replacement for Aiigo's account management. This allows DApps to not depend on Aiigo's account management. When a DApp wants to sign data (or a transaction), it can send the content to Clef, which will then provide the user with context and ask for permission to sign the content. If the user grants the signing request, Clef will send the signature back to the DApp. This setup allows a DApp to connect to a remote Ethereum node and send transactions that are locally signed. This can help in situations when a DApp is connected to an untrusted remote Ethereum node, because a local one is not available, not synchronized with the chain, or is a node that has no built-in (or limited) account management. @@ -67,10 +67,10 @@ The security model of Clef is as follows: * Clef also communicates with whatever process that invoked the binary, via stdin/stdout. * This channel is considered 'trusted'. Over this channel, approvals and passwords are communicated. -The general flow for signing a transaction using e.g. Geth is as follows: +The general flow for signing a transaction using e.g. Aiigo is as follows: ![image](sign_flow.png) -In this case, `geth` would be started with `--signer http://localhost:8550` and would relay requests to `eth.sendTransaction`. +In this case, `aiigo` would be started with `--signer http://localhost:8550` and would relay requests to `eth.sendTransaction`. ## TODOs @@ -94,17 +94,17 @@ Some snags and todos * the total amount * the number of unique recipients -* Geth todos +* Aiigo todos - The signer should pass the `Origin` header as call-info to the UI. As of right now, the way that info about the request is put together is a bit of a hack into the HTTP server. This could probably be greatly improved. - - Relay: Geth should be started in `geth --signer localhost:8550`. - - Currently, the Geth APIs use `common.Address` in the arguments to transaction submission (e.g `to` field). This type is 20 `bytes`, and is incapable of carrying checksum information. The signer uses `common.MixedcaseAddress`, which retains the original input. - - The Geth API should switch to use the same type, and relay `to`-account verbatim to the external API. + - Relay: Aiigo should be started in `aiigo --signer localhost:8550`. + - Currently, the Aiigo APIs use `common.Address` in the arguments to transaction submission (e.g `to` field). This type is 20 `bytes`, and is incapable of carrying checksum information. The signer uses `common.MixedcaseAddress`, which retains the original input. + - The Aiigo API should switch to use the same type, and relay `to`-account verbatim to the external API. * [x] Storage * [x] An encrypted key-value storage should be implemented. * See [rules.md](rules.md) for more info about this. * Another potential thing to introduce is pairing. * To prevent spurious requests which users just accept, implement a way to "pair" the caller with the signer (external API). - * Thus Geth/cpp would cryptographically handshake and afterwards the caller would be allowed to make signing requests. + * Thus Aiigo/cpp would cryptographically handshake and afterwards the caller would be allowed to make signing requests. * This feature would make the addition of rules less dangerous. * Wallets / accounts. Add API methods for wallets. @@ -113,7 +113,7 @@ Some snags and todos ### External API -Clef listens to HTTP requests on `http.addr`:`http.port` (or to IPC on `ipcpath`), with the same JSON-RPC standard as Geth. The messages are expected to be [JSON-RPC 2.0 standard](https://www.jsonrpc.org/specification). +Clef listens to HTTP requests on `http.addr`:`http.port` (or to IPC on `ipcpath`), with the same JSON-RPC standard as Aiigo. The messages are expected to be [JSON-RPC 2.0 standard](https://www.jsonrpc.org/specification). Some of these calls can require user interaction. Clients must be aware that responses may be delayed significantly or may never be received if a user decides to ignore the confirmation request. diff --git a/cmd/clef/rules.md b/cmd/clef/rules.md index ef89ec00c8..7e57c12007 100644 --- a/cmd/clef/rules.md +++ b/cmd/clef/rules.md @@ -89,7 +89,7 @@ Some security precautions can be made, such as: ##### Security of implementation The drawback of this very flexible solution is that the `signer` needs to contain a javascript engine. This is pretty simple to implement since it's already -implemented for `geth`. There are no known security vulnerabilities in it, nor have we had any security problems with it so far. +implemented for `aiigo`. There are no known security vulnerabilities in it, nor have we had any security problems with it so far. The javascript engine would be an added attack surface; but if the validation of `rulesets` is made good (with hash-based attestation), the actual javascript cannot be considered an attack surface -- if an attacker can control the ruleset, a much simpler attack would be to implement an "always-approve" rule instead of exploiting the js vm. The only benefit diff --git a/cmd/clef/tests/testsigner.js b/cmd/clef/tests/testsigner.js index 258679de50..7be9b42699 100644 --- a/cmd/clef/tests/testsigner.js +++ b/cmd/clef/tests/testsigner.js @@ -20,9 +20,9 @@ // // build/bin/clef --4bytedb=./cmd/clef/4byte.json --rpc // -// Start geth with +// Start aiigo with // -// build/bin/geth --nodiscover --maxpeers 0 --signer http://localhost:8550 console --preload=cmd/clef/tests/testsigner.js +// build/bin/aiigo --nodiscover --maxpeers 0 --signer http://localhost:8550 console --preload=cmd/clef/tests/testsigner.js // // and in the console simply invoke // diff --git a/cmd/clef/tutorial.md b/cmd/clef/tutorial.md index 3ea662b5d4..88d90681c7 100644 --- a/cmd/clef/tutorial.md +++ b/cmd/clef/tutorial.md @@ -227,7 +227,7 @@ In this example: - Auto-rejected if the message does not contain `bazonk`, - Any other requests will be passed along for manual confirmation. -*Note, to make this example work, please use you own accounts. You can create a new account either via Clef or the traditional account CLI tools. If the latter was chosen, make sure both Clef and Geth use the same keystore by specifying `--keystore path/to/your/keystore` when running Clef.* +*Note, to make this example work, please use you own accounts. You can create a new account either via Clef or the traditional account CLI tools. If the latter was chosen, make sure both Clef and Aiigo use the same keystore by specifying `--keystore path/to/your/keystore` when running Clef.* Attest the new rule file so that Clef will accept loading it: @@ -290,22 +290,22 @@ t=2019-07-01T15:52:23+0300 lvl=info msg=SignData api=signer type=response data For more details on writing automatic rules, please see the [rules spec](https://github.com/ethereum/go-ethereum/blob/master/cmd/clef/rules.md). -## Geth integration +## Aiigo integration Of course, as awesome as Clef is, it's not feasible to interact with it via JSON RPC by hand. Long term, we're hoping to convince the general Ethereum community to support Clef as a general signer (it's only 3-5 methods), thus allowing your favorite DApp, Metamask, MyCrypto, etc to request signatures directly. -Until then however, we're trying to pave the way via Geth. Geth v1.9.0 has built in support via `--signer ` for using a local or remote Clef instance as an account backend! +Until then however, we're trying to pave the way via Aiigo. Aiigo v1.9.0 has built in support via `--signer ` for using a local or remote Clef instance as an account backend! -We can try this by running Clef with our previous rules on Rinkeby (for now it's a good idea to allow auto-listing accounts, since Geth likes to retrieve them once in a while). +We can try this by running Clef with our previous rules on Rinkeby (for now it's a good idea to allow auto-listing accounts, since Aiigo likes to retrieve them once in a while). ```text $ clef --keystore ~/.ethereum/rinkeby/keystore --chainid 4 --rules rules.js ``` -In a different window we can start Geth, list our accounts, even list our wallets to see where the accounts originate from: +In a different window we can start Aiigo, list our accounts, even list our wallets to see where the accounts originate from: ```text -$ geth --rinkeby --signer=~/.clef/clef.ipc console +$ aiigo --rinkeby --signer=~/.clef/clef.ipc console > eth.accounts ["0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3", "0x086278a6c067775f71d6b2bb1856db6e28c30418"] @@ -350,4 +350,4 @@ Approve? [y/N]: :boom: -*Note, if you enable the external signer backend in Geth, all other account management is disabled. This is because long term we want to remove account management from Geth.* +*Note, if you enable the external signer backend in Aiigo, all other account management is disabled. This is because long term we want to remove account management from Aiigo.* diff --git a/cmd/devp2p/README.md b/cmd/devp2p/README.md index ad2985b4b0..434eab5888 100644 --- a/cmd/devp2p/README.md +++ b/cmd/devp2p/README.md @@ -111,11 +111,11 @@ The Eth Protocol test suite is a conformance test suite for the [eth protocol][e To run the eth protocol test suite against your implementation, the node needs to be initialized with our test chain. The chain files are located in `./cmd/devp2p/internal/ethtest/testdata`. -1. initialize the geth node with the `genesis.json` file +1. initialize the aiigo node with the `genesis.json` file 2. import blocks from `chain.rlp` -3. run the client using the resulting database. For geth, use a command like the one below: +3. run the client using the resulting database. For aiigo, use a command like the one below: - geth \ + aiigo \ --datadir \ --nodiscover \ --nat=none \ @@ -136,6 +136,6 @@ Repeat the above process (re-initialising the node) in order to run the Eth Prot [eth]: https://github.com/ethereum/devp2p/blob/master/caps/eth.md -[dns-tutorial]: https://geth.ethereum.org/docs/developers/geth-developer/dns-discovery-setup +[dns-tutorial]: https://aiigo.ethereum.org/docs/developers/aiigo-developer/dns-discovery-setup [discv4]: https://github.com/ethereum/devp2p/tree/master/discv4.md [discv5]: https://github.com/ethereum/devp2p/tree/master/discv5/discv5.md diff --git a/cmd/devp2p/internal/ethtest/suite_test.go b/cmd/devp2p/internal/ethtest/suite_test.go index a6fca0e524..79f5886a8b 100644 --- a/cmd/devp2p/internal/ethtest/suite_test.go +++ b/cmd/devp2p/internal/ethtest/suite_test.go @@ -51,13 +51,13 @@ func TestEthSuite(t *testing.T) { if err != nil { t.Fatalf("could not make jwt secret: %v", err) } - geth, err := runGeth("./testdata", jwtPath) + aiigo, err := runAiigo("./testdata", jwtPath) if err != nil { - t.Fatalf("could not run geth: %v", err) + t.Fatalf("could not run aiigo: %v", err) } - defer geth.Close() + defer aiigo.Close() - suite, err := NewSuite(geth.Server().Self(), "./testdata", geth.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:])) + suite, err := NewSuite(aiigo.Server().Self(), "./testdata", aiigo.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:])) if err != nil { t.Fatalf("could not create new test suite: %v", err) } @@ -79,13 +79,13 @@ func TestSnapSuite(t *testing.T) { if err != nil { t.Fatalf("could not make jwt secret: %v", err) } - geth, err := runGeth("./testdata", jwtPath) + aiigo, err := runAiigo("./testdata", jwtPath) if err != nil { - t.Fatalf("could not run geth: %v", err) + t.Fatalf("could not run aiigo: %v", err) } - defer geth.Close() + defer aiigo.Close() - suite, err := NewSuite(geth.Server().Self(), "./testdata", geth.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:])) + suite, err := NewSuite(aiigo.Server().Self(), "./testdata", aiigo.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:])) if err != nil { t.Fatalf("could not create new test suite: %v", err) } @@ -99,8 +99,8 @@ func TestSnapSuite(t *testing.T) { } } -// runGeth creates and starts a geth node -func runGeth(dir string, jwtPath string) (*node.Node, error) { +// runAiigo creates and starts a aiigo node +func runAiigo(dir string, jwtPath string) (*node.Node, error) { stack, err := node.New(&node.Config{ AuthAddr: "127.0.0.1", AuthPort: 0, @@ -116,7 +116,7 @@ func runGeth(dir string, jwtPath string) (*node.Node, error) { return nil, err } - err = setupGeth(stack, dir) + err = setupAiigo(stack, dir) if err != nil { stack.Close() return nil, err @@ -128,7 +128,7 @@ func runGeth(dir string, jwtPath string) (*node.Node, error) { return stack, nil } -func setupGeth(stack *node.Node, dir string) error { +func setupAiigo(stack *node.Node, dir string) error { chain, err := NewChain(dir) if err != nil { return err diff --git a/cmd/evm/README.md b/cmd/evm/README.md index 17d663a50c..a59c6b82bb 100644 --- a/cmd/evm/README.md +++ b/cmd/evm/README.md @@ -28,7 +28,7 @@ which can The idea is to specify the behaviour of this binary very _strict_, so that other node implementors can build replicas based on their own state-machines, and the -state generators can swap between a \`geth\`-based implementation and a \`parityvm\`-based +state generators can swap between a \`aiigo\`-based implementation and a \`parityvm\`-based implementation. #### Command line params diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 7de1eb6949..46ab20e246 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -202,7 +202,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, vmContext.BlobBaseFee = eip4844.CalcBlobFee(chainConfig, header) } } - // If DAO is supported/enabled, we need to handle it here. In geth 'proper', it's + // If DAO is supported/enabled, we need to handle it here. In aiigo 'proper', it's // done in StateProcessor.Process(block, ...), right before transactions are applied. if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && diff --git a/cmd/evm/testdata/12/readme.md b/cmd/evm/testdata/12/readme.md index e3195be48b..01d1afa946 100644 --- a/cmd/evm/testdata/12/readme.md +++ b/cmd/evm/testdata/12/readme.md @@ -1,7 +1,7 @@ ## Test 1559 balance + gasCap This test contains an EIP-1559 consensus issue which happened on Ropsten, where -`geth` did not properly account for the value transfer while doing the check on `max_fee_per_gas * gas_limit`. +`aiigo` did not properly account for the value transfer while doing the check on `max_fee_per_gas * gas_limit`. Before the issue was fixed, this invocation allowed the transaction to pass into a block: ``` diff --git a/cmd/evm/transition-test.sh b/cmd/evm/transition-test.sh index 2ddda2d473..46b2f8994e 100644 --- a/cmd/evm/transition-test.sh +++ b/cmd/evm/transition-test.sh @@ -55,7 +55,7 @@ which can The idea is to specify the behaviour of this binary very _strict_, so that other node implementors can build replicas based on their own state-machines, and the -state generators can swap between a \`geth\`-based implementation and a \`parityvm\`-based +state generators can swap between a \`aiigo\`-based implementation and a \`parityvm\`-based implementation. #### Command line params diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index b564fa3b57..05c754b9a4 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -36,7 +36,7 @@ var ( Usage: "Manage Ethereum presale wallets", ArgsUsage: "", Description: ` - geth wallet import /path/to/my/presale.wallet + aiigo wallet import /path/to/my/presale.wallet will prompt for your password and imports your ether presale account. It can be used non-interactively with the --password option taking a @@ -55,7 +55,7 @@ passwordfile as argument containing the wallet password in plaintext.`, utils.LightKDFFlag, }, Description: ` - geth wallet [options] /path/to/my/presale.wallet + aiigo wallet [options] /path/to/my/presale.wallet will prompt for your password and imports your ether presale account. It can be used non-interactively with the --password option taking a @@ -110,7 +110,7 @@ Print a short summary of all accounts`, utils.LightKDFFlag, }, Description: ` - geth account new + aiigo account new Creates a new account and prints the address. @@ -135,7 +135,7 @@ password to file or expose in any other way. utils.LightKDFFlag, }, Description: ` - geth account update
+ aiigo account update
Update an existing account. @@ -147,7 +147,7 @@ format to the newest format or change the password for an account. For non-interactive use the password can be specified with the --password flag: - geth account update [options]
+ aiigo account update [options]
Since only one password can be given, only format update can be performed, changing your password is only possible interactively. @@ -165,7 +165,7 @@ changing your password is only possible interactively. }, ArgsUsage: "", Description: ` - geth account import + aiigo account import Imports an unencrypted private key from and creates a new account. Prints the address. @@ -178,7 +178,7 @@ You must remember this password to unlock your account in the future. For non-interactive use the password can be specified with the -password flag: - geth account import [options] + aiigo account import [options] Note: As you can directly copy your encrypted accounts to another ethereum instance, diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index ab093b54ff..e32a10e7e6 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -43,8 +43,8 @@ func tmpDatadirWithKeystore(t *testing.T) string { func TestAccountListEmpty(t *testing.T) { t.Parallel() - geth := runGeth(t, "account", "list") - geth.ExpectExit() + aiigo := runAiigo(t, "account", "list") + aiigo.ExpectExit() } func TestAccountList(t *testing.T) { @@ -63,22 +63,22 @@ Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\k ` } { - geth := runGeth(t, "account", "list", "--datadir", datadir) - geth.Expect(want) - geth.ExpectExit() + aiigo := runAiigo(t, "account", "list", "--datadir", datadir) + aiigo.Expect(want) + aiigo.ExpectExit() } { - geth := runGeth(t, "--datadir", datadir, "account", "list") - geth.Expect(want) - geth.ExpectExit() + aiigo := runAiigo(t, "--datadir", datadir, "account", "list") + aiigo.Expect(want) + aiigo.ExpectExit() } } func TestAccountNew(t *testing.T) { t.Parallel() - geth := runGeth(t, "account", "new", "--lightkdf") - defer geth.ExpectExit() - geth.Expect(` + aiigo := runAiigo(t, "account", "new", "--lightkdf") + defer aiigo.ExpectExit() + aiigo.Expect(` Your new account is locked with a password. Please give a password. Do not forget this password. !! Unsupported terminal, password will be echoed. Password: {{.InputLine "foobar"}} @@ -86,7 +86,7 @@ Repeat password: {{.InputLine "foobar"}} Your new key was generated `) - geth.ExpectRegexp(` + aiigo.ExpectRegexp(` Public address of the key: 0x[0-9a-fA-F]{40} Path of the secret key file: .*UTC--.+--[0-9a-f]{40} @@ -121,15 +121,15 @@ func TestAccountImport(t *testing.T) { func TestAccountHelp(t *testing.T) { t.Parallel() - geth := runGeth(t, "account", "-h") - geth.WaitExit() - if have, want := geth.ExitStatus(), 0; have != want { + aiigo := runAiigo(t, "account", "-h") + aiigo.WaitExit() + if have, want := aiigo.ExitStatus(), 0; have != want { t.Errorf("exit error, have %d want %d", have, want) } - geth = runGeth(t, "account", "import", "-h") - geth.WaitExit() - if have, want := geth.ExitStatus(), 0; have != want { + aiigo = runAiigo(t, "account", "import", "-h") + aiigo.WaitExit() + if have, want := aiigo.ExitStatus(), 0; have != want { t.Errorf("exit error, have %d want %d", have, want) } } @@ -144,16 +144,16 @@ func importAccountWithExpect(t *testing.T, key string, expected string) { if err := os.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil { t.Error(err) } - geth := runGeth(t, "--lightkdf", "account", "import", "-password", passwordFile, keyfile) - defer geth.ExpectExit() - geth.Expect(expected) + aiigo := runAiigo(t, "--lightkdf", "account", "import", "-password", passwordFile, keyfile) + defer aiigo.ExpectExit() + aiigo.Expect(expected) } func TestAccountNewBadRepeat(t *testing.T) { t.Parallel() - geth := runGeth(t, "account", "new", "--lightkdf") - defer geth.ExpectExit() - geth.Expect(` + aiigo := runAiigo(t, "account", "new", "--lightkdf") + defer aiigo.ExpectExit() + aiigo.Expect(` Your new account is locked with a password. Please give a password. Do not forget this password. !! Unsupported terminal, password will be echoed. Password: {{.InputLine "something"}} @@ -165,11 +165,11 @@ Fatal: Passwords do not match func TestAccountUpdate(t *testing.T) { t.Parallel() datadir := tmpDatadirWithKeystore(t) - geth := runGeth(t, "account", "update", + aiigo := runAiigo(t, "account", "update", "--datadir", datadir, "--lightkdf", "f466859ead1932d743d622cb74fc058882e8648a") - defer geth.ExpectExit() - geth.Expect(` + defer aiigo.ExpectExit() + aiigo.Expect(` Please give a NEW password. Do not forget this password. !! Unsupported terminal, password will be echoed. Password: {{.InputLine "foobar2"}} @@ -181,15 +181,15 @@ Password: {{.InputLine "foobar"}} func TestWalletImport(t *testing.T) { t.Parallel() - geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") - defer geth.ExpectExit() - geth.Expect(` + aiigo := runAiigo(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") + defer aiigo.ExpectExit() + aiigo.Expect(` !! Unsupported terminal, password will be echoed. Password: {{.InputLine "foo"}} Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f} `) - files, err := os.ReadDir(filepath.Join(geth.Datadir, "keystore")) + files, err := os.ReadDir(filepath.Join(aiigo.Datadir, "keystore")) if len(files) != 1 { t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err) } @@ -197,9 +197,9 @@ Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f} func TestWalletImportBadPassword(t *testing.T) { t.Parallel() - geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") - defer geth.ExpectExit() - geth.Expect(` + aiigo := runAiigo(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") + defer aiigo.ExpectExit() + aiigo.Expect(` !! Unsupported terminal, password will be echoed. Password: {{.InputLine "wrong"}} Fatal: could not decrypt key with given password diff --git a/cmd/geth/attach_test.go b/cmd/geth/attach_test.go index 1df25359c5..0660ff5da1 100644 --- a/cmd/geth/attach_test.go +++ b/cmd/geth/attach_test.go @@ -32,7 +32,7 @@ func (t *testHandler) ServeHTTP(out http.ResponseWriter, in *http.Request) { t.body(out, in) } -// TestAttachWithHeaders tests that 'geth attach' with custom headers works, i.e +// TestAttachWithHeaders tests that 'aiigo attach' with custom headers works, i.e // that custom headers are forwarded to the target. func TestAttachWithHeaders(t *testing.T) { t.Parallel() @@ -48,7 +48,7 @@ func TestAttachWithHeaders(t *testing.T) { // This is fixed in a follow-up PR. } -// TestRemoteDbWithHeaders tests that 'geth db --remotedb' with custom headers works, i.e +// TestRemoteDbWithHeaders tests that 'aiigo db --remotedb' with custom headers works, i.e // that custom headers are forwarded to the target. func TestRemoteDbWithHeaders(t *testing.T) { t.Parallel() @@ -60,7 +60,7 @@ func TestRemoteDbWithHeaders(t *testing.T) { testReceiveHeaders(t, ln, "db", "metadata", "--remotedb", fmt.Sprintf("http://localhost:%d", port), "-H", "first: one", "-H", "second: two") } -func testReceiveHeaders(t *testing.T, ln net.Listener, gethArgs ...string) { +func testReceiveHeaders(t *testing.T, ln net.Listener, aiigoArgs ...string) { var ok atomic.Uint32 server := &http.Server{ Addr: "localhost:0", @@ -76,7 +76,7 @@ func testReceiveHeaders(t *testing.T, ln net.Listener, gethArgs ...string) { }}} go server.Serve(ln) defer server.Close() - runGeth(t, gethArgs...).WaitExit() + runAiigo(t, aiigoArgs...).WaitExit() if ok.Load() != 1 { t.Fatal("Test fail, expected invocation to succeed") } diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 708dd8fb7a..16fa69e0af 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -163,7 +163,7 @@ into Era archives. Eras are typically packaged in steps of 8192 blocks. Flags: slices.Concat([]cli.Flag{utils.CacheFlag}, utils.DatabaseFlags), Description: ` The import-preimages command imports hash preimages from an RLP encoded stream. -It's deprecated, please use "geth db import" instead. +It's deprecated, please use "aiigo db import" instead. `, } diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 4215403234..f086d15bc6 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -104,14 +104,14 @@ type ethstatsConfig struct { URL string `toml:",omitempty"` } -type gethConfig struct { +type aiigoConfig struct { Eth ethconfig.Config Node node.Config Ethstats ethstatsConfig Metrics metrics.Config } -func loadConfig(file string, cfg *gethConfig) error { +func loadConfig(file string, cfg *aiigoConfig) error { f, err := os.Open(file) if err != nil { return err @@ -137,11 +137,11 @@ func defaultNodeConfig() node.Config { return cfg } -// loadBaseConfig loads the gethConfig based on the given command line +// loadBaseConfig loads the aiigoConfig based on the given command line // parameters and config file. -func loadBaseConfig(ctx *cli.Context) gethConfig { +func loadBaseConfig(ctx *cli.Context) aiigoConfig { // Load defaults. - cfg := gethConfig{ + cfg := aiigoConfig{ Eth: ethconfig.Defaults, Node: defaultNodeConfig(), Metrics: metrics.DefaultConfig, @@ -159,8 +159,8 @@ func loadBaseConfig(ctx *cli.Context) gethConfig { return cfg } -// makeConfigNode loads geth configuration and creates a blank node instance. -func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { +// makeConfigNode loads aiigo configuration and creates a blank node instance. +func makeConfigNode(ctx *cli.Context) (*node.Node, aiigoConfig) { cfg := loadBaseConfig(ctx) stack, err := node.New(&cfg.Node) if err != nil { @@ -180,7 +180,7 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { return stack, cfg } -// makeFullNode loads geth configuration and creates the Ethereum backend. +// makeFullNode loads aiigo configuration and creates the Ethereum backend. func makeFullNode(ctx *cli.Context) *node.Node { stack, cfg := makeConfigNode(ctx) if ctx.IsSet(utils.OverridePrague.Name) { @@ -197,13 +197,13 @@ func makeFullNode(ctx *cli.Context) *node.Node { backend, eth := utils.RegisterEthService(stack, &cfg.Eth) - // Create gauge with geth system and build information + // Create gauge with aiigo system and build information if eth != nil { // The 'eth' backend may be nil in light mode var protos []string for _, p := range eth.Protocols() { protos = append(protos, fmt.Sprintf("%v/%d", p.Name, p.Version)) } - metrics.NewRegisteredGaugeInfo("geth/info", nil).Update(metrics.GaugeInfoValue{ + metrics.NewRegisteredGaugeInfo("aiigo/info", nil).Update(metrics.GaugeInfoValue{ "arch": runtime.GOARCH, "os": runtime.GOOS, "version": cfg.Node.Version, @@ -285,7 +285,7 @@ func dumpConfig(ctx *cli.Context) error { return nil } -func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) { +func applyMetricConfig(ctx *cli.Context, cfg *aiigoConfig) { if ctx.IsSet(utils.MetricsEnabledFlag.Name) { cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name) } diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go index bf38c86349..7144c59527 100644 --- a/cmd/geth/consolecmd.go +++ b/cmd/geth/consolecmd.go @@ -35,9 +35,9 @@ var ( Usage: "Start an interactive JavaScript environment", Flags: slices.Concat(nodeFlags, rpcFlags, consoleFlags), Description: ` -The Geth console is an interactive shell for the JavaScript runtime environment +The Aiigo console is an interactive shell for the JavaScript runtime environment which exposes a node admin interface as well as the Ðapp JavaScript API. -See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console.`, +See https://aiigo.ethereum.org/docs/interacting-with-aiigo/javascript-console.`, } attachCommand = &cli.Command{ @@ -47,10 +47,10 @@ See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console.`, ArgsUsage: "[endpoint]", Flags: slices.Concat([]cli.Flag{utils.DataDirFlag, utils.HttpHeaderFlag}, consoleFlags), Description: ` -The Geth console is an interactive shell for the JavaScript runtime environment +The Aiigo console is an interactive shell for the JavaScript runtime environment which exposes a node admin interface as well as the Ðapp JavaScript API. -See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console. -This command allows to open a console on a running geth node.`, +See https://aiigo.ethereum.org/docs/interacting-with-aiigo/javascript-console. +This command allows to open a console on a running aiigo node.`, } javascriptCommand = &cli.Command{ @@ -61,11 +61,11 @@ This command allows to open a console on a running geth node.`, Flags: slices.Concat(nodeFlags, consoleFlags), Description: ` The JavaScript VM exposes a node admin interface as well as the Ðapp -JavaScript API. See https://geth.ethereum.org/docs/interacting-with-geth/javascript-console`, +JavaScript API. See https://aiigo.ethereum.org/docs/interacting-with-aiigo/javascript-console`, } ) -// localConsole starts a new geth node, attaching a JavaScript console to it at the +// localConsole starts a new aiigo node, attaching a JavaScript console to it at the // same time. func localConsole(ctx *cli.Context) error { // Create and start the node based on the CLI flags @@ -107,7 +107,7 @@ func localConsole(ctx *cli.Context) error { return nil } -// remoteConsole will connect to a remote geth instance, attaching a JavaScript +// remoteConsole will connect to a remote aiigo instance, attaching a JavaScript // console to it. func remoteConsole(ctx *cli.Context) error { if ctx.Args().Len() > 1 { @@ -121,7 +121,7 @@ func remoteConsole(ctx *cli.Context) error { } client, err := utils.DialRPCWithHeaders(endpoint, ctx.StringSlice(utils.HttpHeaderFlag.Name)) if err != nil { - utils.Fatalf("Unable to attach to remote geth: %v", err) + utils.Fatalf("Unable to attach to remote aiigo: %v", err) } config := console.Config{ DataDir: utils.MakeDataDir(ctx), @@ -146,7 +146,7 @@ func remoteConsole(ctx *cli.Context) error { return nil } -// ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript +// ephemeralConsole starts a new aiigo node, attaches an ephemeral JavaScript // console to it, executes each of the files specified as arguments and tears // everything down. func ephemeralConsole(ctx *cli.Context) error { @@ -155,6 +155,6 @@ func ephemeralConsole(ctx *cli.Context) error { b.WriteString(fmt.Sprintf("loadScript('%s');", file)) } utils.Fatalf(`The "js" command is deprecated. Please use the following instead: -geth --exec "%s" console`, b.String()) +aiigo --exec "%s" console`, b.String()) return nil } diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index b8c2c498a6..16eac76352 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -34,17 +34,17 @@ const ( httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" ) -// spawns geth with the given command line args, using a set of flags to minimise +// spawns aiigo with the given command line args, using a set of flags to minimise // memory and disk IO. If the args don't set --datadir, the // child g gets a temporary data directory. -func runMinimalGeth(t *testing.T, args ...string) *testgeth { +func runMinimalAiigo(t *testing.T, args ...string) *testaiigo { // --holesky to make the 'writing genesis to disk' faster (no accounts) // --networkid=1337 to avoid cache bump // --syncmode=full to avoid allocating fast sync bloom allArgs := []string{"--holesky", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0", "--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64", "--datadir.minfreedisk", "0"} - return runGeth(t, append(allArgs, args...)...) + return runAiigo(t, append(allArgs, args...)...) } // Tests that a node embedded within a console can be started up properly and @@ -53,24 +53,24 @@ func TestConsoleWelcome(t *testing.T) { t.Parallel() coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" - // Start a geth console, make sure it's cleaned up and terminate the console - geth := runMinimalGeth(t, "--miner.etherbase", coinbase, "console") + // Start a aiigo console, make sure it's cleaned up and terminate the console + aiigo := runMinimalAiigo(t, "--miner.etherbase", coinbase, "console") // Gather all the infos the welcome message needs to contain - geth.SetTemplateFunc("goos", func() string { return runtime.GOOS }) - geth.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) - geth.SetTemplateFunc("gover", runtime.Version) - geth.SetTemplateFunc("gethver", func() string { return version.WithCommit("", "") }) - geth.SetTemplateFunc("niltime", func() string { + aiigo.SetTemplateFunc("goos", func() string { return runtime.GOOS }) + aiigo.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) + aiigo.SetTemplateFunc("gover", runtime.Version) + aiigo.SetTemplateFunc("aiigover", func() string { return version.WithCommit("", "") }) + aiigo.SetTemplateFunc("niltime", func() string { return time.Unix(1695902100, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)") }) - geth.SetTemplateFunc("apis", func() string { return ipcAPIs }) + aiigo.SetTemplateFunc("apis", func() string { return ipcAPIs }) // Verify the actual welcome message to the required template - geth.Expect(` -Welcome to the Geth JavaScript console! + aiigo.Expect(` +Welcome to the Aiigo JavaScript console! -instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}} +instance: Aiigo/v{{aiigover}}/{{goos}}-{{goarch}}/{{gover}} at block: 0 ({{niltime}}) datadir: {{.Datadir}} modules: {{apis}} @@ -78,7 +78,7 @@ at block: 0 ({{niltime}}) To exit, press ctrl-d or type exit > {{.InputLine "exit"}} `) - geth.ExpectExit() + aiigo.ExpectExit() } // Tests that a console can be attached to a running node via various means. @@ -90,38 +90,38 @@ func TestAttachWelcome(t *testing.T) { ) // Configure the instance for IPC attachment if runtime.GOOS == "windows" { - ipc = `\\.\pipe\geth` + strconv.Itoa(trulyRandInt(100000, 999999)) + ipc = `\\.\pipe\aiigo` + strconv.Itoa(trulyRandInt(100000, 999999)) } else { - ipc = filepath.Join(t.TempDir(), "geth.ipc") + ipc = filepath.Join(t.TempDir(), "aiigo.ipc") } // And HTTP + WS attachment p := trulyRandInt(1024, 65533) // Yeah, sometimes this will fail, sorry :P httpPort = strconv.Itoa(p) wsPort = strconv.Itoa(p + 1) - geth := runMinimalGeth(t, "--miner.etherbase", "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182", + aiigo := runMinimalAiigo(t, "--miner.etherbase", "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182", "--ipcpath", ipc, "--http", "--http.port", httpPort, "--ws", "--ws.port", wsPort) t.Run("ipc", func(t *testing.T) { waitForEndpoint(t, ipc, 4*time.Second) - testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs) + testAttachWelcome(t, aiigo, "ipc:"+ipc, ipcAPIs) }) t.Run("http", func(t *testing.T) { endpoint := "http://127.0.0.1:" + httpPort waitForEndpoint(t, endpoint, 4*time.Second) - testAttachWelcome(t, geth, endpoint, httpAPIs) + testAttachWelcome(t, aiigo, endpoint, httpAPIs) }) t.Run("ws", func(t *testing.T) { endpoint := "ws://127.0.0.1:" + wsPort waitForEndpoint(t, endpoint, 4*time.Second) - testAttachWelcome(t, geth, endpoint, httpAPIs) + testAttachWelcome(t, aiigo, endpoint, httpAPIs) }) - geth.Kill() + aiigo.Kill() } -func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { - // Attach to a running geth node and terminate immediately - attach := runGeth(t, "attach", endpoint) +func testAttachWelcome(t *testing.T, aiigo *testaiigo, endpoint, apis string) { + // Attach to a running aiigo node and terminate immediately + attach := runAiigo(t, "attach", endpoint) defer attach.ExpectExit() attach.CloseStdin() @@ -129,19 +129,19 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) attach.SetTemplateFunc("gover", runtime.Version) - attach.SetTemplateFunc("gethver", func() string { return version.WithCommit("", "") }) + attach.SetTemplateFunc("aiigover", func() string { return version.WithCommit("", "") }) attach.SetTemplateFunc("niltime", func() string { return time.Unix(1695902100, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)") }) attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) - attach.SetTemplateFunc("datadir", func() string { return geth.Datadir }) + attach.SetTemplateFunc("datadir", func() string { return aiigo.Datadir }) attach.SetTemplateFunc("apis", func() string { return apis }) // Verify the actual welcome message to the required template attach.Expect(` -Welcome to the Geth JavaScript console! +Welcome to the Aiigo JavaScript console! -instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}} +instance: Aiigo/v{{aiigover}}/{{goos}}-{{goarch}}/{{gover}} at block: 0 ({{niltime}}){{if ipc}} datadir: {{datadir}}{{end}} modules: {{apis}} diff --git a/cmd/geth/exportcmd_test.go b/cmd/geth/exportcmd_test.go index d08c890734..fd91d31f01 100644 --- a/cmd/geth/exportcmd_test.go +++ b/cmd/geth/exportcmd_test.go @@ -25,13 +25,13 @@ import ( "github.com/ethereum/go-ethereum/common" ) -// TestExport does a basic test of "geth export", exporting the test-genesis. +// TestExport does a basic test of "aiigo export", exporting the test-genesis. func TestExport(t *testing.T) { t.Parallel() outfile := fmt.Sprintf("%v/testExport.out", t.TempDir()) - geth := runGeth(t, "--datadir", initGeth(t), "export", outfile) - geth.WaitExit() - if have, want := geth.ExitStatus(), 0; have != want { + aiigo := runAiigo(t, "--datadir", initAiigo(t), "export", outfile) + aiigo.WaitExit() + if have, want := aiigo.ExitStatus(), 0; have != want { t.Errorf("exit error, have %d want %d", have, want) } have, err := os.ReadFile(outfile) diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go index f5d21cc00b..cefe03043e 100644 --- a/cmd/geth/genesis_test.go +++ b/cmd/geth/genesis_test.go @@ -72,7 +72,7 @@ var customGenesisTests = []struct { }, } -// Tests that initializing Geth with a custom genesis block and chain definitions +// Tests that initializing Aiigo with a custom genesis block and chain definitions // work properly. func TestCustomGenesis(t *testing.T) { t.Parallel() @@ -85,15 +85,15 @@ func TestCustomGenesis(t *testing.T) { if err := os.WriteFile(json, []byte(tt.genesis), 0600); err != nil { t.Fatalf("test %d: failed to write genesis file: %v", i, err) } - runGeth(t, "--datadir", datadir, "init", json).WaitExit() + runAiigo(t, "--datadir", datadir, "init", json).WaitExit() // Query the custom genesis block - geth := runGeth(t, "--networkid", "1337", "--syncmode=full", "--cache", "16", + aiigo := runAiigo(t, "--networkid", "1337", "--syncmode=full", "--cache", "16", "--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--exec", tt.query, "console") - geth.ExpectRegexp(tt.result) - geth.ExpectExit() + aiigo.ExpectRegexp(tt.result) + aiigo.ExpectExit() } } @@ -135,18 +135,18 @@ func TestCustomBackend(t *testing.T) { } { // Init args := append(tt.initArgs, "--datadir", datadir, "init", json) - geth := runGeth(t, args...) - geth.ExpectRegexp(tt.initExpect) - geth.ExpectExit() + aiigo := runAiigo(t, args...) + aiigo.ExpectRegexp(tt.initExpect) + aiigo.ExpectExit() } { // Exec + query args := append(tt.execArgs, "--networkid", "1337", "--syncmode=full", "--cache", "16", "--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--exec", "eth.getBlock(0).nonce", "console") - geth := runGeth(t, args...) - geth.ExpectRegexp(tt.execExpect) - geth.ExpectExit() + aiigo := runAiigo(t, args...) + aiigo.ExpectRegexp(tt.execExpect) + aiigo.ExpectExit() } return nil } diff --git a/cmd/geth/logging_test.go b/cmd/geth/logging_test.go index 37fffecc30..986460f7b3 100644 --- a/cmd/geth/logging_test.go +++ b/cmd/geth/logging_test.go @@ -36,7 +36,7 @@ import ( func runSelf(args ...string) ([]byte, error) { cmd := &exec.Cmd{ Path: reexec.Self(), - Args: append([]string{"geth-test"}, args...), + Args: append([]string{"aiigo-test"}, args...), } return cmd.CombinedOutput() } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index cd74fb7b6a..44fbb78fb5 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . -// geth is a command-line client for Ethereum. +// aiigo is a command-line client for Ethereum. package main import ( @@ -46,7 +46,7 @@ import ( ) const ( - clientIdentifier = "geth" // Client identifier to advertise over the network + clientIdentifier = "aiigo" // Client identifier to advertise over the network ) var ( @@ -212,8 +212,8 @@ var ( var app = flags.NewApp("the go-ethereum command line interface") func init() { - // Initialize the CLI app and start Geth - app.Action = geth + // Initialize the CLI app and start Aiigo + app.Action = aiigo app.Commands = []*cli.Command{ // See chaincmd.go: initCommand, @@ -291,17 +291,17 @@ func prepare(ctx *cli.Context) { // If we're running a known preset, log it for convenience. switch { case ctx.IsSet(utils.SepoliaFlag.Name): - log.Info("Starting Geth on Sepolia testnet...") + log.Info("Starting Aiigo on Sepolia testnet...") case ctx.IsSet(utils.HoleskyFlag.Name): - log.Info("Starting Geth on Holesky testnet...") + log.Info("Starting Aiigo on Holesky testnet...") case ctx.IsSet(utils.HoodiFlag.Name): - log.Info("Starting Geth on Hoodi testnet...") + log.Info("Starting Aiigo on Hoodi testnet...") case ctx.IsSet(utils.DeveloperFlag.Name): - log.Info("Starting Geth in ephemeral dev mode...") - log.Warn(`You are running Geth in --dev mode. Please note the following: + log.Info("Starting Aiigo in ephemeral dev mode...") + log.Warn(`You are running Aiigo in --dev mode. Please note the following: 1. This mode is only intended for fast, iterative development without assumptions on security or persistence. @@ -318,7 +318,7 @@ func prepare(ctx *cli.Context) { `) case !ctx.IsSet(utils.NetworkIdFlag.Name): - log.Info("Starting Geth on Ethereum mainnet...") + log.Info("Starting Aiigo on Ethereum mainnet...") } // If we're a full node on mainnet without --cache specified, bump default cache allowance if !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) { @@ -334,10 +334,10 @@ func prepare(ctx *cli.Context) { } } -// geth is the main entry point into the system if no special subcommand is run. +// aiigo is the main entry point into the system if no special subcommand is run. // It creates a default node based on the command line arguments and runs it in // blocking mode, waiting for it to be shut down. -func geth(ctx *cli.Context) error { +func aiigo(ctx *cli.Context) error { if args := ctx.Args().Slice(); len(args) > 0 { return fmt.Errorf("invalid command: %q", args[0]) } @@ -365,7 +365,7 @@ func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) { events := make(chan accounts.WalletEvent, 16) stack.AccountManager().Subscribe(events) - // Create a client to interact with local geth node. + // Create a client to interact with local aiigo node. rpcClient := stack.Attach() ethClient := ethclient.NewClient(rpcClient) diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go index 2d31f3abe7..637880c3c1 100644 --- a/cmd/geth/misccmd.go +++ b/cmd/geth/misccmd.go @@ -30,7 +30,7 @@ var ( VersionCheckUrlFlag = &cli.StringFlag{ Name: "check.url", Usage: "URL to use when checking vulnerabilities", - Value: "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json", + Value: "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities.json", } VersionCheckVersionFlag = &cli.StringFlag{ Name: "check.version", @@ -53,10 +53,10 @@ The output of this command is supposed to be machine-readable. VersionCheckVersionFlag, }, Name: "version-check", - Usage: "Checks (online) for known Geth security vulnerabilities", + Usage: "Checks (online) for known Aiigo security vulnerabilities", ArgsUsage: "", Description: ` -The version-check command fetches vulnerability-information from https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json, +The version-check command fetches vulnerability-information from https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities.json, and displays information about any security vulnerabilities that affect the currently executing version. `, } @@ -88,17 +88,17 @@ func printVersion(ctx *cli.Context) error { } func license(_ *cli.Context) error { - fmt.Println(`Geth is free software: you can redistribute it and/or modify + fmt.Println(`Aiigo 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. -Geth is distributed in the hope that it will be useful, +Aiigo 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 geth. If not, see .`) +along with aiigo. If not, see .`) return nil } diff --git a/cmd/geth/run_test.go b/cmd/geth/run_test.go index 1d32880325..ca174043ef 100644 --- a/cmd/geth/run_test.go +++ b/cmd/geth/run_test.go @@ -28,7 +28,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) -type testgeth struct { +type testaiigo struct { *cmdtest.TestCmd // template variables for expect @@ -37,8 +37,8 @@ type testgeth struct { } func init() { - // Run the app if we've been exec'd as "geth-test" in runGeth. - reexec.Register("geth-test", func() { + // Run the app if we've been exec'd as "aiigo-test" in runAiigo. + reexec.Register("aiigo-test", func() { if err := app.Run(os.Args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) @@ -55,19 +55,19 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -func initGeth(t *testing.T) string { +func initAiigo(t *testing.T) string { args := []string{"--networkid=42", "init", "./testdata/clique.json"} - t.Logf("Initializing geth: %v ", args) - g := runGeth(t, args...) + t.Logf("Initializing aiigo: %v ", args) + g := runAiigo(t, args...) datadir := g.Datadir g.WaitExit() return datadir } -// spawns geth with the given command line args. If the args don't set --datadir, the +// spawns aiigo with the given command line args. If the args don't set --datadir, the // child g gets a temporary data directory. -func runGeth(t *testing.T, args ...string) *testgeth { - tt := &testgeth{} +func runAiigo(t *testing.T, args ...string) *testaiigo { + tt := &testaiigo{} tt.TestCmd = cmdtest.NewTestCmd(t, tt) for i, arg := range args { switch arg { @@ -87,9 +87,9 @@ func runGeth(t *testing.T, args ...string) *testgeth { args = append([]string{"--datadir", tt.Datadir}, args...) } - // Boot "geth". This actually runs the test binary but the TestMain + // Boot "aiigo". This actually runs the test binary but the TestMain // function will prevent any tests from running. - tt.Run("geth-test", args...) + tt.Run("aiigo-test", args...) return tt } diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go index f0be52a0df..8b2c8c81c6 100644 --- a/cmd/geth/snapshot.go +++ b/cmd/geth/snapshot.go @@ -54,7 +54,7 @@ var ( utils.BloomFilterSizeFlag, }, utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth snapshot prune-state +aiigo snapshot prune-state will prune historical state data with the help of the state snapshot. All trie nodes and contract codes that do not belong to the specified version state will be deleted from the database. After pruning, only @@ -72,7 +72,7 @@ WARNING: it's only supported in hash mode(--state.scheme=hash)". Action: verifyState, Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth snapshot verify-state +aiigo snapshot verify-state will traverse the whole accounts and storages set based on the specified snapshot and recalculate the root hash of state for verification. In other words, this command does the snapshot to trie conversion. @@ -85,7 +85,7 @@ In other words, this command does the snapshot to trie conversion. Action: checkDanglingStorage, Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth snapshot check-dangling-storage traverses the snap storage +aiigo snapshot check-dangling-storage traverses the snap storage data, and verifies that all snapshot storage data has a corresponding account. `, }, @@ -96,7 +96,7 @@ data, and verifies that all snapshot storage data has a corresponding account. Action: checkAccount, Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth snapshot inspect-account
checks all snapshot layers and prints out +aiigo snapshot inspect-account
checks all snapshot layers and prints out information about the specified address. `, }, @@ -107,7 +107,7 @@ information about the specified address. Action: traverseState, Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth snapshot traverse-state +aiigo snapshot traverse-state will traverse the whole state from the given state root and will abort if any referenced trie node or contract code is missing. This command can be used for state integrity verification. The default checking target is the HEAD state. @@ -122,7 +122,7 @@ It's also usable without snapshot enabled. Action: traverseRawState, Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth snapshot traverse-rawstate +aiigo snapshot traverse-rawstate will traverse the whole state from the given root and will abort if any referenced trie node or contract code is missing. This command can be used for state integrity verification. The default checking target is the HEAD state. It's basically identical @@ -133,7 +133,7 @@ It's also usable without snapshot enabled. }, { Name: "dump", - Usage: "Dump a specific block from storage (same as 'geth dump' but using snapshots)", + Usage: "Dump a specific block from storage (same as 'aiigo dump' but using snapshots)", ArgsUsage: "[? | ]", Action: dumpState, Flags: slices.Concat([]cli.Flag{ @@ -143,7 +143,7 @@ It's also usable without snapshot enabled. utils.DumpLimitFlag, }, utils.NetworkFlags, utils.DatabaseFlags), Description: ` -This command is semantically equivalent to 'geth dump', but uses the snapshots +This command is semantically equivalent to 'aiigo dump', but uses the snapshots as the backend data source, making this command a lot faster. The argument is interpreted as block number or hash. If none is provided, the latest diff --git a/cmd/geth/testdata/vcheck/data.json b/cmd/geth/testdata/vcheck/data.json index e7ee2bf7e4..2948b3592d 100644 --- a/cmd/geth/testdata/vcheck/data.json +++ b/cmd/geth/testdata/vcheck/data.json @@ -6,56 +6,56 @@ "description": "A mining flaw could cause miners to erroneously calculate PoW, due to an index overflow, if DAG size is exceeding the maximum 32 bit unsigned value.\n\nThis occurred on the ETC chain on 2020-11-06. This is likely to trigger for ETH mainnet around block `11550000`/epoch `385`, slated to occur early January 2021.\n\nThis issue is relevant only for miners, non-mining nodes are unaffected, since non-mining nodes use a smaller verification cache instead of a full DAG.", "links": [ "https://github.com/ethereum/go-ethereum/pull/21793", - "https://blog.ethereum.org/2020/11/12/geth_security_release/", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", "https://github.com/ethereum/go-ethereum/commit/567d41d9363706b4b13ce0903804e8acf214af49" ], "introduced": "v1.6.0", "fixed": "v1.9.24", "published": "2020-11-12", "severity": "Medium", - "check": "Geth\\/v1\\.(6|7|8)\\..*|Geth\\/v1\\.9\\.2(1|2|3)-.*" + "check": "Aiigo\\/v1\\.(6|7|8)\\..*|Aiigo\\/v1\\.9\\.2(1|2|3)-.*" }, { "name": "GoCrash", "uid": "GETH-2020-02", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", - "description": "The DoS issue can be used to crash all Geth nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of Geth (such as TurboGeth or ETC’s core-geth) which is built with versions of Go which contains the vulnerability.", + "summary": "A denial-of-service issue can be used to crash Aiigo nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", + "description": "The DoS issue can be used to crash all Aiigo nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of Aiigo (such as TurboAiigo or ETC’s core-aiigo) which is built with versions of Go which contains the vulnerability.", "links": [ - "https://blog.ethereum.org/2020/11/12/geth_security_release/", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", "https://groups.google.com/g/golang-announce/c/NpBGTTmKzpM", "https://github.com/golang/go/issues/42552" ], "fixed": "v1.9.24", "published": "2020-11-12", "severity": "Critical", - "check": "Geth.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" + "check": "Aiigo.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" }, { "name": "ShallowCopy", "uid": "GETH-2020-03", - "summary": "A consensus flaw in Geth, related to `datacopy` precompile", - "description": "Geth erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", + "summary": "A consensus flaw in Aiigo, related to `datacopy` precompile", + "description": "Aiigo erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", "links": [ - "https://blog.ethereum.org/2020/11/12/geth_security_release/" + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/" ], "introduced": "v1.9.7", "fixed": "v1.9.17", "published": "2020-11-12", "severity": "Critical", - "check": "Geth\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" + "check": "Aiigo\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" }, { - "name": "GethCrash", + "name": "AiigoCrash", "uid": "GETH-2020-04", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing", + "summary": "A denial-of-service issue can be used to crash Aiigo nodes during block processing", "description": "Full details to be disclosed at a later date", "links": [ - "https://blog.ethereum.org/2020/11/12/geth_security_release/" + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/" ], "introduced": "v1.9.16", "fixed": "v1.9.18", "published": "2020-11-12", "severity": "Critical", - "check": "Geth\\/v1\\.9.(16|17).*$" + "check": "Aiigo\\/v1\\.9.(16|17).*$" } ] diff --git a/cmd/geth/testdata/vcheck/vulnerabilities.json b/cmd/geth/testdata/vcheck/vulnerabilities.json index 31a34de6be..3a30d8acd5 100644 --- a/cmd/geth/testdata/vcheck/vulnerabilities.json +++ b/cmd/geth/testdata/vcheck/vulnerabilities.json @@ -6,7 +6,7 @@ "description": "A mining flaw could cause miners to erroneously calculate PoW, due to an index overflow, if DAG size is exceeding the maximum 32 bit unsigned value.\n\nThis occurred on the ETC chain on 2020-11-06. This is likely to trigger for ETH mainnet around block `11550000`/epoch `385`, slated to occur early January 2021.\n\nThis issue is relevant only for miners, non-mining nodes are unaffected, since non-mining nodes use a smaller verification cache instead of a full DAG.", "links": [ "https://github.com/ethereum/go-ethereum/pull/21793", - "https://blog.ethereum.org/2020/11/12/geth_security_release/", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", "https://github.com/ethereum/go-ethereum/commit/567d41d9363706b4b13ce0903804e8acf214af49", "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-v592-xf75-856p" ], @@ -15,15 +15,15 @@ "published": "2020-11-12", "severity": "Medium", "CVE": "CVE-2020-26240", - "check": "Geth\\/v1\\.(6|7|8)\\..*|Geth\\/v1\\.9\\.\\d-.*|Geth\\/v1\\.9\\.1.*|Geth\\/v1\\.9\\.2(0|1|2|3)-.*" + "check": "Aiigo\\/v1\\.(6|7|8)\\..*|Aiigo\\/v1\\.9\\.\\d-.*|Aiigo\\/v1\\.9\\.1.*|Aiigo\\/v1\\.9\\.2(0|1|2|3)-.*" }, { "name": "Denial of service due to Go CVE-2020-28362", "uid": "GETH-2020-02", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", - "description": "The DoS issue can be used to crash all Geth nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of Geth (such as TurboGeth or ETC’s core-geth) which is built with versions of Go which contains the vulnerability.", + "summary": "A denial-of-service issue can be used to crash Aiigo nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", + "description": "The DoS issue can be used to crash all Aiigo nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of Aiigo (such as TurboAiigo or ETC’s core-aiigo) which is built with versions of Go which contains the vulnerability.", "links": [ - "https://blog.ethereum.org/2020/11/12/geth_security_release/", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", "https://groups.google.com/g/golang-announce/c/NpBGTTmKzpM", "https://github.com/golang/go/issues/42552", "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-m6gx-rhvj-fh52" @@ -33,15 +33,15 @@ "published": "2020-11-12", "severity": "Critical", "CVE": "CVE-2020-28362", - "check": "Geth.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" + "check": "Aiigo.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" }, { "name": "ShallowCopy", "uid": "GETH-2020-03", - "summary": "A consensus flaw in Geth, related to `datacopy` precompile", - "description": "Geth erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", + "summary": "A consensus flaw in Aiigo, related to `datacopy` precompile", + "description": "Aiigo erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", "links": [ - "https://blog.ethereum.org/2020/11/12/geth_security_release/", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-69v6-xc2j-r2jf" ], "introduced": "v1.9.7", @@ -49,15 +49,15 @@ "published": "2020-11-12", "severity": "Critical", "CVE": "CVE-2020-26241", - "check": "Geth\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" + "check": "Aiigo\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" }, { - "name": "Geth DoS via MULMOD", + "name": "Aiigo DoS via MULMOD", "uid": "GETH-2020-04", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing", - "description": "Affected versions suffer from a vulnerability which can be exploited through the `MULMOD` operation, by specifying a modulo of `0`: `mulmod(a,b,0)`, causing a `panic` in the underlying library. \nThe crash was in the `uint256` library, where a buffer [underflowed](https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L442).\n\n\tif `d == 0`, `dLen` remains `0`\n\nand https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L451 will try to access index `[-1]`.\n\nThe `uint256` library was first merged in this [commit](https://github.com/ethereum/go-ethereum/commit/cf6674539c589f80031f3371a71c6a80addbe454), on 2020-06-08. \nExploiting this vulnerabilty would cause all vulnerable nodes to drop off the network. \n\nThe issue was brought to our attention through a [bug report](https://github.com/ethereum/go-ethereum/issues/21367), showing a `panic` occurring on sync from genesis on the Ropsten network.\n \nIt was estimated that the least obvious way to fix this would be to merge the fix into `uint256`, make a new release of that library and then update the geth-dependency.\n", + "summary": "A denial-of-service issue can be used to crash Aiigo nodes during block processing", + "description": "Affected versions suffer from a vulnerability which can be exploited through the `MULMOD` operation, by specifying a modulo of `0`: `mulmod(a,b,0)`, causing a `panic` in the underlying library. \nThe crash was in the `uint256` library, where a buffer [underflowed](https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L442).\n\n\tif `d == 0`, `dLen` remains `0`\n\nand https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L451 will try to access index `[-1]`.\n\nThe `uint256` library was first merged in this [commit](https://github.com/ethereum/go-ethereum/commit/cf6674539c589f80031f3371a71c6a80addbe454), on 2020-06-08. \nExploiting this vulnerabilty would cause all vulnerable nodes to drop off the network. \n\nThe issue was brought to our attention through a [bug report](https://github.com/ethereum/go-ethereum/issues/21367), showing a `panic` occurring on sync from genesis on the Ropsten network.\n \nIt was estimated that the least obvious way to fix this would be to merge the fix into `uint256`, make a new release of that library and then update the aiigo-dependency.\n", "links": [ - "https://blog.ethereum.org/2020/11/12/geth_security_release/", + "https://blog.ethereum.org/2020/11/12/aiigo_security_release/", "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-jm5c-rv3w-w83m", "https://github.com/holiman/uint256/releases/tag/v1.1.1", "https://github.com/holiman/uint256/pull/80", @@ -68,13 +68,13 @@ "published": "2020-11-12", "severity": "Critical", "CVE": "CVE-2020-26242", - "check": "Geth\\/v1\\.9.(16|17).*$" + "check": "Aiigo\\/v1\\.9.(16|17).*$" }, { "name": "LES Server DoS via GetProofsV2", "uid": "GETH-2020-05", "summary": "A DoS vulnerability can make a LES server crash.", - "description": "A DoS vulnerability can make a LES server crash via malicious GetProofsV2 request from a connected LES client.\n\nThe vulnerability was patched in #21896.\n\nThis vulnerability only concern users explicitly running geth as a light server", + "description": "A DoS vulnerability can make a LES server crash via malicious GetProofsV2 request from a connected LES client.\n\nThe vulnerability was patched in #21896.\n\nThis vulnerability only concern users explicitly running aiigo as a light server", "links": [ "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-r33q-22hv-j29q", "https://github.com/ethereum/go-ethereum/pull/21896" @@ -84,22 +84,22 @@ "published": "2020-12-10", "severity": "Medium", "CVE": "CVE-2020-26264", - "check": "(Geth\\/v1\\.8\\.*)|(Geth\\/v1\\.9\\.\\d-.*)|(Geth\\/v1\\.9\\.1\\d-.*)|(Geth\\/v1\\.9\\.(20|21|22|23|24)-.*)$" + "check": "(Aiigo\\/v1\\.8\\.*)|(Aiigo\\/v1\\.9\\.\\d-.*)|(Aiigo\\/v1\\.9\\.1\\d-.*)|(Aiigo\\/v1\\.9\\.(20|21|22|23|24)-.*)$" }, { "name": "SELFDESTRUCT-recreate consensus flaw", "uid": "GETH-2020-06", "introduced": "v1.9.4", "fixed": "v1.9.20", - "summary": "A consensus-vulnerability in Geth could cause a chain split, where vulnerable versions refuse to accept the canonical chain.", - "description": "A flaw was repoted at 2020-08-11 by John Youngseok Yang (Software Platform Lab), where a particular sequence of transactions could cause a consensus failure.\n\n- Tx 1:\n - `sender` invokes `caller`.\n - `caller` invokes `0xaa`. `0xaa` has 3 wei, does a self-destruct-to-self\n - `caller` does a `1 wei` -call to `0xaa`, who thereby has 1 wei (the code in `0xaa` still executed, since the tx is still ongoing, but doesn't redo the selfdestruct, it takes a different path if callvalue is non-zero)\n\n-Tx 2:\n - `sender` does a 5-wei call to 0xaa. No exec (since no code). \n\nIn geth, the result would be that `0xaa` had `6 wei`, whereas OE reported (correctly) `5` wei. Furthermore, in geth, if the second tx was not executed, the `0xaa` would be destructed, resulting in `0 wei`. Thus obviously wrong. \n\nIt was determined that the root cause was this [commit](https://github.com/ethereum/go-ethereum/commit/223b950944f494a5b4e0957fd9f92c48b09037ad) from [this PR](https://github.com/ethereum/go-ethereum/pull/19953). The semantics of `createObject` was subtly changd, into returning a non-nil object (with `deleted=true`) where it previously did not if the account had been destructed. This return value caused the new object to inherit the old `balance`.\n", + "summary": "A consensus-vulnerability in Aiigo could cause a chain split, where vulnerable versions refuse to accept the canonical chain.", + "description": "A flaw was repoted at 2020-08-11 by John Youngseok Yang (Software Platform Lab), where a particular sequence of transactions could cause a consensus failure.\n\n- Tx 1:\n - `sender` invokes `caller`.\n - `caller` invokes `0xaa`. `0xaa` has 3 wei, does a self-destruct-to-self\n - `caller` does a `1 wei` -call to `0xaa`, who thereby has 1 wei (the code in `0xaa` still executed, since the tx is still ongoing, but doesn't redo the selfdestruct, it takes a different path if callvalue is non-zero)\n\n-Tx 2:\n - `sender` does a 5-wei call to 0xaa. No exec (since no code). \n\nIn aiigo, the result would be that `0xaa` had `6 wei`, whereas OE reported (correctly) `5` wei. Furthermore, in aiigo, if the second tx was not executed, the `0xaa` would be destructed, resulting in `0 wei`. Thus obviously wrong. \n\nIt was determined that the root cause was this [commit](https://github.com/ethereum/go-ethereum/commit/223b950944f494a5b4e0957fd9f92c48b09037ad) from [this PR](https://github.com/ethereum/go-ethereum/pull/19953). The semantics of `createObject` was subtly changd, into returning a non-nil object (with `deleted=true`) where it previously did not if the account had been destructed. This return value caused the new object to inherit the old `balance`.\n", "links": [ "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-xw37-57qp-9mm4" ], "published": "2020-12-10", "severity": "High", "CVE": "CVE-2020-26265", - "check": "(Geth\\/v1\\.9\\.(4|5|6|7|8|9)-.*)|(Geth\\/v1\\.9\\.1\\d-.*)$" + "check": "(Aiigo\\/v1\\.9\\.(4|5|6|7|8|9)-.*)|(Aiigo\\/v1\\.9\\.1\\d-.*)$" }, { "name": "Not ready for London upgrade", @@ -114,13 +114,13 @@ "fixed": "v1.10.6", "published": "2021-07-22", "severity": "High", - "check": "(Geth\\/v1\\.10\\.(1|2|3|4|5)-.*)$" + "check": "(Aiigo\\/v1\\.10\\.(1|2|3|4|5)-.*)$" }, { "name": "RETURNDATA corruption via datacopy", "uid": "GETH-2021-02", - "summary": "A consensus-flaw in the Geth EVM could cause a node to deviate from the canonical chain.", - "description": "A memory-corruption bug within the EVM can cause a consensus error, where vulnerable nodes obtain a different `stateRoot` when processing a maliciously crafted transaction. This, in turn, would lead to the chain being split: mainnet splitting in two forks.\n\nAll Geth versions supporting the London hard fork are vulnerable (the bug is older than London), so all users should update.\n\nThis bug was exploited on Mainnet at block 13107518.\n\nCredits for the discovery go to @guidovranken (working for Sentnl during an audit of the Telos EVM) and reported via bounty@ethereum.org.", + "summary": "A consensus-flaw in the Aiigo EVM could cause a node to deviate from the canonical chain.", + "description": "A memory-corruption bug within the EVM can cause a consensus error, where vulnerable nodes obtain a different `stateRoot` when processing a maliciously crafted transaction. This, in turn, would lead to the chain being split: mainnet splitting in two forks.\n\nAll Aiigo versions supporting the London hard fork are vulnerable (the bug is older than London), so all users should update.\n\nThis bug was exploited on Mainnet at block 13107518.\n\nCredits for the discovery go to @guidovranken (working for Sentnl during an audit of the Telos EVM) and reported via bounty@ethereum.org.", "links": [ "https://github.com/ethereum/go-ethereum/blob/master/docs/postmortems/2021-08-22-split-postmortem.md", "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-9856-9gg9-qcmq", @@ -131,7 +131,7 @@ "published": "2021-08-24", "severity": "High", "CVE": "CVE-2021-39137", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7)-.*)$" + "check": "(Aiigo\\/v1\\.10\\.(0|1|2|3|4|5|6|7)-.*)$" }, { "name": "DoS via malicious `snap/1` request", @@ -140,7 +140,7 @@ "description": "The `snap/1` protocol handler contains two vulnerabilities related to the `GetTrieNodes` packet, which can be exploited to crash the node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v)", "links": [ "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities", + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities", "https://github.com/ethereum/go-ethereum/pull/23657" ], "introduced": "v1.10.0", @@ -148,7 +148,7 @@ "published": "2021-10-24", "severity": "Medium", "CVE": "CVE-2021-41173", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8)-.*)$" + "check": "(Aiigo\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8)-.*)$" }, { "name": "DoS via malicious p2p message", @@ -157,7 +157,7 @@ "description": "A vulnerable node, if configured to use high verbosity logging, can be made to crash when handling specially crafted p2p messages sent from an attacker node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5)", "links": [ "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities", + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities", "https://github.com/ethereum/go-ethereum/pull/24507" ], "introduced": "v1.10.0", @@ -165,7 +165,7 @@ "published": "2022-05-11", "severity": "Low", "CVE": "CVE-2022-29177", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$" + "check": "(Aiigo\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$" }, { "name": "DoS via malicious p2p message", @@ -174,14 +174,14 @@ "description": "The p2p handler spawned a new goroutine to respond to ping requests. By flooding a node with ping requests, an unbounded number of goroutines can be created, leading to resource exhaustion and potentially crash due to OOM.", "links": [ "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-ppjg-v974-84cm", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities" ], "introduced": "v1.10.0", "fixed": "v1.12.1", "published": "2023-09-06", "severity": "High", "CVE": "CVE-2023-40591", - "check": "(Geth\\/v1\\.(10|11)\\..*)|(Geth\\/v1\\.12\\.0-.*)$" + "check": "(Aiigo\\/v1\\.(10|11)\\..*)|(Aiigo\\/v1\\.12\\.0-.*)$" }, { "name": "DoS via malicious p2p message", @@ -190,13 +190,13 @@ "description": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node. Full details will be available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652)", "links": [ "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" + "https://aiigo.ethereum.org/docs/vulnerabilities/vulnerabilities" ], "introduced": "v1.10.0", "fixed": "v1.13.15", "published": "2024-05-06", "severity": "High", "CVE": "CVE-2024-32972", - "check": "(Geth\\/v1\\.(10|11|12)\\..*)|(Geth\\/v1\\.13\\.\\d-.*)|(Geth\\/v1\\.13\\.1(0|1|2|3|4)-.*)$" + "check": "(Aiigo\\/v1\\.(10|11|12)\\..*)|(Aiigo\\/v1\\.13\\.\\d-.*)|(Aiigo\\/v1\\.13\\.1(0|1|2|3|4)-.*)$" } ] diff --git a/cmd/geth/verkle.go b/cmd/geth/verkle.go index 6490f832af..e4b6ba637e 100644 --- a/cmd/geth/verkle.go +++ b/cmd/geth/verkle.go @@ -47,7 +47,7 @@ var ( Action: verifyVerkle, Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth verkle verify +aiigo verkle verify This command takes a root commitment and attempts to rebuild the tree. `, }, @@ -58,7 +58,7 @@ This command takes a root commitment and attempts to rebuild the tree. Action: expandVerkle, Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), Description: ` -geth verkle dump [ ...] +aiigo verkle dump [ ...] This command will produce a dot file representing the tree, rooted at . in which key1, key2, ... are expanded. `, diff --git a/cmd/geth/version_check.go b/cmd/geth/version_check.go index 237556788e..db0a5331ac 100644 --- a/cmd/geth/version_check.go +++ b/cmd/geth/version_check.go @@ -31,7 +31,7 @@ import ( "github.com/urfave/cli/v2" ) -var gethPubKeys []string = []string{ +var aiigoPubKeys []string = []string{ //@holiman, minisign public key FB1D084D39BAEC24 "RWQk7Lo5TQgd+wxBNZM+Zoy+7UhhMHaWKzqoes9tvSbFLJYZhNTbrIjx", //minisign public key 138B1CA303E51687 @@ -73,7 +73,7 @@ func checkCurrent(url, current string) error { if sig, err = fetch(fmt.Sprintf("%v.minisig", url)); err != nil { return fmt.Errorf("could not retrieve signature: %w", err) } - if err = verifySignature(gethPubKeys, data, sig); err != nil { + if err = verifySignature(aiigoPubKeys, data, sig); err != nil { return err } var vulns []vulnJson @@ -128,7 +128,7 @@ func fetch(url string) ([]byte, error) { } // verifySignature checks that the sigData is a valid signature of the given -// data, for pubkey GethPubkey +// data, for pubkey AiigoPubkey func verifySignature(pubkeys []string, data, sigdata []byte) error { sig, err := minisign.DecodeSignature(string(sigdata)) if err != nil { diff --git a/cmd/geth/version_check_test.go b/cmd/geth/version_check_test.go index 34171cb035..898f556a05 100644 --- a/cmd/geth/version_check_test.go +++ b/cmd/geth/version_check_test.go @@ -108,7 +108,7 @@ func TestMatching(t *testing.T) { t.Fatal(err) } check := func(version string) { - vFull := fmt.Sprintf("Geth/%v-unstable-15339cf1-20201204/linux-amd64/go1.15.4", version) + vFull := fmt.Sprintf("Aiigo/%v-unstable-15339cf1-20201204/linux-amd64/go1.15.4", version) for _, vuln := range vulns { r, err := regexp.Compile(vuln.Check) vulnIntro := versionUint(vuln.Introduced) @@ -118,7 +118,7 @@ func TestMatching(t *testing.T) { t.Fatal(err) } if vuln.Name == "Denial of service due to Go CVE-2020-28362" { - // this one is not tied to geth-versions + // this one is not tied to aiigo-versions continue } if vulnIntro <= current && vulnFixed > current { @@ -145,9 +145,9 @@ func TestMatching(t *testing.T) { } } -func TestGethPubKeysParseable(t *testing.T) { +func TestAiigoPubKeysParseable(t *testing.T) { t.Parallel() - for _, pubkey := range gethPubKeys { + for _, pubkey := range aiigoPubKeys { _, err := minisign.NewPublicKey(pubkey) if err != nil { t.Errorf("Should be parseable") @@ -165,9 +165,9 @@ func TestKeyID(t *testing.T) { args args want string }{ - {"@holiman key", args{id: extractKeyId(gethPubKeys[0])}, "FB1D084D39BAEC24"}, - {"second key", args{id: extractKeyId(gethPubKeys[1])}, "138B1CA303E51687"}, - {"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"}, + {"@holiman key", args{id: extractKeyId(aiigoPubKeys[0])}, "FB1D084D39BAEC24"}, + {"second key", args{id: extractKeyId(aiigoPubKeys[1])}, "138B1CA303E51687"}, + {"third key", args{id: extractKeyId(aiigoPubKeys[2])}, "FD9813B2D2098484"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index d91d6ca5a8..6c3706d105 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -138,11 +138,11 @@ func monitorFreeDiskSpace(sigc chan os.Signal, path string, freeDiskSpaceCritica break } if freeSpace < freeDiskSpaceCritical { - log.Error("Low disk space. Gracefully shutting down Geth to prevent database corruption.", "available", common.StorageSize(freeSpace), "path", path) + log.Error("Low disk space. Gracefully shutting down Aiigo to prevent database corruption.", "available", common.StorageSize(freeSpace), "path", path) sigc <- syscall.SIGTERM break } else if freeSpace < 2*freeDiskSpaceCritical { - log.Warn("Disk space is running low. Geth will shutdown if disk space runs below critical level.", "available", common.StorageSize(freeSpace), "critical_level", common.StorageSize(freeDiskSpaceCritical), "path", path) + log.Warn("Disk space is running low. Aiigo will shutdown if disk space runs below critical level.", "available", common.StorageSize(freeSpace), "critical_level", common.StorageSize(freeDiskSpaceCritical), "path", path) } time.Sleep(30 * time.Second) } @@ -671,13 +671,13 @@ func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn // should be bumped. // If the importer sees a higher version, it should reject the import. type exportHeader struct { - Magic string // Always set to 'gethdbdump' for disambiguation + Magic string // Always set to 'aiigodbdump' for disambiguation Version uint64 Kind string UnixTime uint64 } -const exportMagic = "gethdbdump" +const exportMagic = "aiigodbdump" const ( OpBatchAdd = 0 OpBatchDel = 1 diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index fb2892d2c1..c97620b422 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -838,7 +838,7 @@ var ( HttpHeaderFlag = &cli.StringSliceFlag{ Name: "header", Aliases: []string{"H"}, - Usage: "Pass custom headers to the RPC server when using --" + RemoteDBFlag.Name + " or the geth attach console. This flag can be given multiple times.", + Usage: "Pass custom headers to the RPC server when using --" + RemoteDBFlag.Name + " or the aiigo attach console. This flag can be given multiple times.", Category: flags.APICategory, } @@ -1263,7 +1263,7 @@ func setLes(ctx *cli.Context, cfg *ethconfig.Config) { } // MakeDatabaseHandles raises out the number of allowed file handles per process -// for Geth and returns half of the allowance to assign to the database. +// for Aiigo and returns half of the allowance to assign to the database. func MakeDatabaseHandles(max int) int { limit, err := fdlimit.Maximum() if err != nil { @@ -2025,11 +2025,11 @@ func SetupMetrics(cfg *metrics.Config) { ) if enableExport { log.Info("Enabling metrics export to InfluxDB") - go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap) + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "aiigo.", tagsMap) } else if enableExportV2 { tagsMap := SplitTagsFlag(cfg.InfluxDBTags) log.Info("Enabling metrics export to InfluxDB (v2)") - go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap) + go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "aiigo.", tagsMap) } // Expvar exporter. @@ -2115,7 +2115,7 @@ func DialRPCWithHeaders(endpoint string, headers []string) (*rpc.Client, error) return nil, errors.New("endpoint must be specified") } if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { - // Backwards compatibility with geth < 1.5 which required + // Backwards compatibility with aiigo < 1.5 which required // these prefixes. endpoint = endpoint[4:] } diff --git a/console/console.go b/console/console.go index b5c77bd78f..578067df3e 100644 --- a/console/console.go +++ b/console/console.go @@ -292,12 +292,12 @@ func (c *Console) AutoCompleteInput(line string, pos int) (string, []string, str return line[:start], c.jsre.CompleteKeywords(line[start:pos]), line[pos:] } -// Welcome show summary of current Geth instance and some metadata about the +// Welcome show summary of current Aiigo instance and some metadata about the // console's available modules. func (c *Console) Welcome() { - message := "Welcome to the Geth JavaScript console!\n\n" + message := "Welcome to the Aiigo JavaScript console!\n\n" - // Print some generic Geth metadata + // Print some generic Aiigo metadata if res, err := c.jsre.Run(` var message = "instance: " + web3.version.node + "\n"; message += "at block: " + eth.blockNumber + " (" + new Date(1000 * eth.getBlock(eth.blockNumber).timestamp) + ")\n"; diff --git a/core/blockchain.go b/core/blockchain.go index d80236c902..5836955c3d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -346,7 +346,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis // Update chain info data metrics chainInfoGauge.Update(metrics.GaugeInfoValue{"chain_id": bc.chainConfig.ChainID.String()}) - // If Geth is initialized with an external ancient store, re-initialize the + // If Aiigo is initialized with an external ancient store, re-initialize the // missing chain indexes and chain flags. This procedure can survive crash // and can be resumed in next restart since chain flags are updated in last step. if bc.empty() { diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 1a6fe38af6..21c53c43af 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -216,7 +216,7 @@ func (basic *snapshotTestBasic) teardown() { } // snapshotTest is a test case type for normal snapshot recovery. -// It can be used for testing that restart Geth normally. +// It can be used for testing that restart Aiigo normally. type snapshotTest struct { snapshotTestBasic } @@ -239,7 +239,7 @@ func (snaptest *snapshotTest) test(t *testing.T) { } // crashSnapshotTest is a test case type for irregular snapshot recovery. -// It can be used for testing that restart Geth after the crash. +// It can be used for testing that restart Aiigo after the crash. type crashSnapshotTest struct { snapshotTestBasic } @@ -420,7 +420,7 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) { newchain.Stop() } -// Tests a Geth restart with valid snapshot. Before the shutdown, all snapshot +// Tests a Aiigo restart with valid snapshot. Before the shutdown, all snapshot // journal will be persisted correctly. In this case no snapshot recovery is // required. func TestRestartWithNewSnapshot(t *testing.T) { @@ -460,7 +460,7 @@ func TestRestartWithNewSnapshot(t *testing.T) { } } -// Tests a Geth was crashed and restarts with a broken snapshot. In this case the +// Tests a Aiigo was crashed and restarts with a broken snapshot. In this case the // chain head should be rewound to the point with available state. And also the // new head should must be lower than disk layer. But there is no committed point // so the chain should be rewound to genesis and the disk layer should be left @@ -502,7 +502,7 @@ func TestNoCommitCrashWithNewSnapshot(t *testing.T) { } } -// Tests a Geth was crashed and restarts with a broken snapshot. In this case the +// Tests a Aiigo was crashed and restarts with a broken snapshot. In this case the // chain head should be rewound to the point with available state. And also the // new head should must be lower than disk layer. But there is only a low committed // point so the chain should be rewound to committed point and the disk layer @@ -544,7 +544,7 @@ func TestLowCommitCrashWithNewSnapshot(t *testing.T) { } } -// Tests a Geth was crashed and restarts with a broken snapshot. In this case +// Tests a Aiigo was crashed and restarts with a broken snapshot. In this case // the chain head should be rewound to the point with available state. And also // the new head should must be lower than disk layer. But there is only a high // committed point so the chain should be rewound to genesis and the disk layer @@ -590,7 +590,7 @@ func TestHighCommitCrashWithNewSnapshot(t *testing.T) { } } -// Tests a Geth was running with snapshot enabled. Then restarts without +// Tests a Aiigo was running with snapshot enabled. Then restarts without // enabling snapshot and after that re-enable the snapshot again. In this // case the snapshot should be rebuilt with latest chain head. func TestGappedNewSnapshot(t *testing.T) { @@ -631,7 +631,7 @@ func TestGappedNewSnapshot(t *testing.T) { } } -// Tests the Geth was running with snapshot enabled and resetHead is applied. +// Tests the Aiigo was running with snapshot enabled and resetHead is applied. // In this case the head is rewound to the target(with state available). After // that the chain is restarted and the original disk layer is kept. func TestSetHeadWithNewSnapshot(t *testing.T) { @@ -672,7 +672,7 @@ func TestSetHeadWithNewSnapshot(t *testing.T) { } } -// Tests the Geth was running with a complete snapshot and then imports a few +// Tests the Aiigo was running with a complete snapshot and then imports a few // more new blocks on top without enabling the snapshot. After the restart, // crash happens. Check everything is ok after the restart. func TestRecoverSnapshotFromWipingCrash(t *testing.T) { diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 18b1c7dc79..66070d77b5 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -66,7 +66,7 @@ const ( // https://eips.ethereum.org/EIPS/eip-7745 type FilterMaps struct { // If disabled is set, log indexing is fully disabled. - // This is configured by the --history.logs.disable Geth flag. + // This is configured by the --history.logs.disable Aiigo flag. // We chose to implement disabling this way because it requires less special // case logic in eth/filters. disabled bool diff --git a/core/genesis.go b/core/genesis.go index 95782a827a..55781462aa 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -641,7 +641,7 @@ func DefaultHoodiGenesisBlock() *Genesis { } } -// DeveloperGenesisBlock returns the 'geth --dev' genesis block. +// DeveloperGenesisBlock returns the 'aiigo --dev' genesis block. func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis { // Override the default period to the user requested one config := *params.AllDevChainProtocolChanges diff --git a/core/headerchain.go b/core/headerchain.go index cb707a152f..44310edd90 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -545,7 +545,7 @@ func (hc *HeaderChain) setHead(headBlock uint64, headTime uint64, updateFn Updat } parentHash = parent.Hash() - // Notably, since geth has the possibility for setting the head to a low + // Notably, since aiigo has the possibility for setting the head to a low // height which is even lower than ancient head. // In order to ensure that the head is always no higher than the data in // the database (ancient store or active store), we need to update head diff --git a/core/state/snapshot/journal.go b/core/state/snapshot/journal.go index e4b396b990..7e4da31118 100644 --- a/core/state/snapshot/journal.go +++ b/core/state/snapshot/journal.go @@ -107,7 +107,7 @@ func loadAndParseJournal(db ethdb.KeyValueStore, base *diskLayer) (snapshot, jou return nil, journalGenerator{}, fmt.Errorf("failed to decode snapshot generator: %v", err) } // Retrieve the diff layer journal. It's possible that the journal is - // not existent, e.g. the disk layer is generating while that the Geth + // not existent, e.g. the disk layer is generating while that the Aiigo // crashes without persisting the diff journal. // So if there is no journal, or the journal is invalid(e.g. the journal // is not matched with disk layer; or the it's the legacy-format journal, @@ -151,7 +151,7 @@ func loadSnapshot(diskdb ethdb.KeyValueStore, triedb *triedb.Database, root comm // snapshot is not matched with current state root, print a warning log // or discard the entire snapshot it's legacy snapshot. // - // Possible scenario: Geth was crashed without persisting journal and then + // Possible scenario: Aiigo was crashed without persisting journal and then // restart, the head is rewound to the point with available state(trie) // which is below the snapshot. In this case the snapshot can be recovered // by re-executing blocks but right now it's unavailable. @@ -340,7 +340,7 @@ func iterateJournal(db ethdb.KeyValueReader, callback journalCallback) error { // pre-funded account deletions may face incompatibilities, leading to automatic // snapshot regeneration. // - // This approach minimizes snapshot regeneration for Geth nodes upgrading from a + // This approach minimizes snapshot regeneration for Aiigo nodes upgrading from a // legacy version that are already synced. The workaround can be safely removed // after the next hard fork. if version == journalV0 { diff --git a/core/tracing/CHANGELOG.md b/core/tracing/CHANGELOG.md index a14e123d99..b2116208a9 100644 --- a/core/tracing/CHANGELOG.md +++ b/core/tracing/CHANGELOG.md @@ -86,7 +86,7 @@ There have been minor backwards-compatible changes to the tracing interface to e ## [v1.14.0] -There has been a major breaking change in the tracing interface for custom native tracers. JS and built-in tracers are not affected by this change and tracing API methods may be used as before. This overhaul has been done as part of the new live tracing feature ([#29189](https://github.com/ethereum/go-ethereum/pull/29189)). To learn more about live tracing please refer to the [docs](https://geth.ethereum.org/docs/developers/evm-tracing/live-tracing). +There has been a major breaking change in the tracing interface for custom native tracers. JS and built-in tracers are not affected by this change and tracing API methods may be used as before. This overhaul has been done as part of the new live tracing feature ([#29189](https://github.com/ethereum/go-ethereum/pull/29189)). To learn more about live tracing please refer to the [docs](https://aiigo.ethereum.org/docs/developers/evm-tracing/live-tracing). **The `EVMLogger` interface which the tracers implemented has been removed.** It has been replaced by a new struct `tracing.Hooks`. `Hooks` keeps pointers to event listening functions. Internally the EVM will use these function pointers to emit events and can skip an event if the tracer has opted not to implement it. In fact this is the main reason for this change of approach. Another benefit is the ease of adding new hooks in future, and dynamically assigning event receivers. diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 0485f7a3eb..9143f6b880 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -18,10 +18,10 @@ // execution. Here we define the low-level [Hooks] object that carries hooks which are // invoked by the go-ethereum core at various points in the state transition. // -// To create a tracer that can be invoked with Geth, you need to register it using +// To create a tracer that can be invoked with Aiigo, you need to register it using // [github.com/ethereum/go-ethereum/eth/tracers.LiveDirectory.Register]. // -// See https://geth.ethereum.org/docs/developers/evm-tracing/live-tracing for a tutorial. +// See https://aiigo.ethereum.org/docs/developers/evm-tracing/live-tracing for a tutorial. package tracing import ( diff --git a/core/types/receipt.go b/core/types/receipt.go index e52a0c6477..7dd18c4451 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -58,7 +58,7 @@ type Receipt struct { Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` - // Implementation fields: These fields are added by geth when processing a transaction. + // Implementation fields: These fields are added by aiigo when processing a transaction. TxHash common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress common.Address `json:"contractAddress"` GasUsed uint64 `json:"gasUsed" gencodec:"required"` diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index e54041f7e2..4208f25129 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -31,7 +31,7 @@ func NewEnv(cfg *Config) *vm.EVM { blockContext := vm.BlockContext{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, - GetHash: cfg.GetHashFn, + Aiigoash: cfg.AiigoashFn, Coinbase: cfg.Coinbase, BlockNumber: cfg.BlockNumber, Time: cfg.Time, diff --git a/crypto/kzg4844/kzg4844_ckzg_cgo.go b/crypto/kzg4844/kzg4844_ckzg_cgo.go index dce592b444..5fed2c25ce 100644 --- a/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_cgo.go @@ -28,7 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ) -// ckzgAvailable signals whether the library was compiled into Geth. +// ckzgAvailable signals whether the library was compiled into Aiigo. const ckzgAvailable = true // ckzgIniter ensures that we initialize the KZG library once before using it. diff --git a/crypto/kzg4844/kzg4844_ckzg_nocgo.go b/crypto/kzg4844/kzg4844_ckzg_nocgo.go index 0662b2632f..ce631baf7b 100644 --- a/crypto/kzg4844/kzg4844_ckzg_nocgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_nocgo.go @@ -20,7 +20,7 @@ package kzg4844 import "sync" -// ckzgAvailable signals whether the library was compiled into Geth. +// ckzgAvailable signals whether the library was compiled into Aiigo. const ckzgAvailable = false // ckzgIniter ensures that we initialize the KZG library once before using it. diff --git a/docs/postmortems/2021-08-22-split-postmortem.md b/docs/postmortems/2021-08-22-split-postmortem.md index 2e5c41c764..c6a95b21aa 100644 --- a/docs/postmortems/2021-08-22-split-postmortem.md +++ b/docs/postmortems/2021-08-22-split-postmortem.md @@ -16,13 +16,13 @@ This is a post-mortem concerning the minority split that occurred on Ethereum ma ### 2021-08-17 RETURNDATA corruption via datacopy -On 2021-08-17, Guido Vranken submitted a report to bounty@ethereum.org. This coincided with a geth-meetup in Berlin, so the geth team could fairly quickly analyse the issue. +On 2021-08-17, Guido Vranken submitted a report to bounty@ethereum.org. This coincided with a aiigo-meetup in Berlin, so the aiigo team could fairly quickly analyse the issue. He submitted a proof of concept which called the `dataCopy` precompile, where the input slice and output slice were overlapping but shifted. Doing a `copy` where the `src` and `dest` overlaps is not a problem in itself, however, the `returnData`slice was _also_ using the same memory as a backing-array. #### Technical details -During CALL-variants, `geth` does not copy the input. This was changed at one point, to avoid a DoS attack reported by Hubert Ritzdorf, to avoid copying data a lot on repeated `CALL`s -- essentially combating a DoS via `malloc`. Further, the datacopy precompile also does not copy the data, but just returns the same slice. This is fine so far. +During CALL-variants, `aiigo` does not copy the input. This was changed at one point, to avoid a DoS attack reported by Hubert Ritzdorf, to avoid copying data a lot on repeated `CALL`s -- essentially combating a DoS via `malloc`. Further, the datacopy precompile also does not copy the data, but just returns the same slice. This is fine so far. After the execution of `dataCopy`, we copy the `ret` into the designated memory area, and this is what causes a problem. Because we're copying a slice of memory over a slice of memory, and this operation modifies (shifts) the data in the source -- the `ret`. So this means we wind up with corrupted returndata. @@ -51,7 +51,7 @@ A memory-corruption bug within the EVM can cause a consensus error, where vulner #### Handling -On the evening of 17th, we discussed options on how to handle it. We made a state test to reproduce the issue, and verified that neither `openethereum`, `nethermind` nor `besu` were affected by the same vulnerability, and started a full-sync with a patched version of `geth`. +On the evening of 17th, we discussed options on how to handle it. We made a state test to reproduce the issue, and verified that neither `openethereum`, `nethermind` nor `besu` were affected by the same vulnerability, and started a full-sync with a patched version of `aiigo`. It was decided that in this specific instance, it would be possible to make a public announcement and a patch release: @@ -87,9 +87,9 @@ The blocks on the 'bad' chain were investigated, and Tim Beiko reached out to th ### Disclosure decision -The geth-team have an official policy regarding [vulnerability disclosure](https://geth.ethereum.org/docs/developers/geth-developer/disclosures). +The aiigo-team have an official policy regarding [vulnerability disclosure](https://aiigo.ethereum.org/docs/developers/aiigo-developer/disclosures). -> The primary goal for the Geth team is the health of the Ethereum network as a whole, and the decision whether or not to publish details about a serious vulnerability boils down to minimizing the risk and/or impact of discovery and exploitation. +> The primary goal for the Aiigo team is the health of the Ethereum network as a whole, and the decision whether or not to publish details about a serious vulnerability boils down to minimizing the risk and/or impact of discovery and exploitation. In this case, it was decided that public pre-announce + patch would likely lead to sufficient update-window for a critical mass of nodes/miners to upgrade in time before it could be exploited. In hindsight, this was a dangerous decision, and it's unlikely that the same decision would be reached were a similar incident to happen again. @@ -114,7 +114,7 @@ However, some were 'lost', and only notified later - Summa - Harmony -Action point: create a low-volume geth-announce@ethereum.org email list where dependent projects/operators can receive public announcements. +Action point: create a low-volume aiigo-announce@ethereum.org email list where dependent projects/operators can receive public announcements. - This has been done. If you wish to receive release- and security announcements, sign up [here](https://groups.google.com/a/ethereum.org/g/geth-announce/about) ### Fork monitoring diff --git a/eth/backend.go b/eth/backend.go index ab612b1de7..9a5119e75e 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -59,7 +59,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" - gethversion "github.com/ethereum/go-ethereum/version" + aiigoversion "github.com/ethereum/go-ethereum/version" ) // Config contains the configuration options of the ETH protocol. @@ -191,7 +191,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if !config.SkipBcVersionCheck { if bcVersion != nil && *bcVersion > core.BlockChainVersion { - return nil, fmt.Errorf("database version is v%d, Geth %s only supports v%d", *bcVersion, version.WithMeta, core.BlockChainVersion) + return nil, fmt.Errorf("database version is v%d, Aiigo %s only supports v%d", *bcVersion, version.WithMeta, core.BlockChainVersion) } else if bcVersion == nil || *bcVersion < core.BlockChainVersion { if bcVersion != nil { // only print warning on upgrade, not on init log.Warn("Upgrade blockchain database version", "from", dbVer, "to", core.BlockChainVersion) @@ -322,8 +322,8 @@ func makeExtraData(extra []byte) []byte { if len(extra) == 0 { // create default extradata extra, _ = rlp.EncodeToBytes([]interface{}{ - uint(gethversion.Major<<16 | gethversion.Minor<<8 | gethversion.Patch), - "geth", + uint(aiigoversion.Major<<16 | aiigoversion.Minor<<8 | aiigoversion.Patch), + "aiigo", runtime.Version(), runtime.GOOS, }) diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index e6f29c970b..52e06edd14 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -126,14 +126,14 @@ type ConsensusAPI struct { // // There are a few important caveats in this mechanism: // - The bad block tracking is ephemeral, in-memory only. We must never - // persist any bad block information to disk as a bug in Geth could end - // up blocking a valid chain, even if a later Geth update would accept + // persist any bad block information to disk as a bug in Aiigo could end + // up blocking a valid chain, even if a later Aiigo update would accept // it. // - Bad blocks will get forgotten after a certain threshold of import // attempts and will be retried. The rationale is that if the network // really-really-really tries to feed us a block, we should give it a // new chance, perhaps us being racey instead of the block being legit - // bad (this happened in Geth at a point with import vs. pending race). + // bad (this happened in Aiigo at a point with import vs. pending race). // - Tracking all the blocks built on top of the bad one could be a bit // problematic, so we will only track the head chain segment of a bad // chain to allow discarding progressing bad chains and side chains, @@ -142,7 +142,7 @@ type ConsensusAPI struct { invalidTipsets map[common.Hash]*types.Header // Ephemeral cache to track invalid tipsets and their bad ancestor invalidLock sync.Mutex // Protects the invalid maps from concurrent access - // Geth can appear to be stuck or do strange things if the beacon client is + // Aiigo can appear to be stuck or do strange things if the beacon client is // offline or is sending us strange data. Stash some update stats away so // that we can warn the user and not have them open issues on our tracker. lastTransitionUpdate time.Time @@ -467,7 +467,7 @@ func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config engine.Transit ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty if ttd == nil || ttd.Cmp(config.TerminalTotalDifficulty.ToInt()) != 0 { - log.Warn("Invalid TTD configured", "geth", ttd, "beacon", config.TerminalTotalDifficulty) + log.Warn("Invalid TTD configured", "aiigo", ttd, "beacon", config.TerminalTotalDifficulty) return nil, fmt.Errorf("invalid ttd: execution %v consensus %v", ttd, config.TerminalTotalDifficulty) } if config.TerminalBlockHash != (common.Hash{}) { diff --git a/eth/catalyst/tester.go b/eth/catalyst/tester.go index db2d638701..a46cc11823 100644 --- a/eth/catalyst/tester.go +++ b/eth/catalyst/tester.go @@ -27,7 +27,7 @@ import ( "github.com/ethereum/go-ethereum/node" ) -// FullSyncTester is an auxiliary service that allows Geth to perform full sync +// FullSyncTester is an auxiliary service that allows Aiigo to perform full sync // alone without consensus-layer attached. Users must specify a valid block hash // as the sync target. // diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 3f3f9b7f0c..ed10d189cb 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -147,7 +147,7 @@ type Downloader struct { chainInsertHook func([]*fetchResult) // Method to call upon inserting a chain of blocks (possibly in multiple invocations) // Progress reporting metrics - syncStartBlock uint64 // Head snap block when Geth was started + syncStartBlock uint64 // Head snap block when Aiigo was started syncStartTime time.Time // Time instance when chain sync started syncLogTime time.Time // Time instance when status was last reported } diff --git a/eth/downloader/skeleton.go b/eth/downloader/skeleton.go index ad74dab844..3ed0d185b7 100644 --- a/eth/downloader/skeleton.go +++ b/eth/downloader/skeleton.go @@ -65,7 +65,7 @@ var errSyncMerged = errors.New("sync merged") var errSyncReorged = errors.New("sync reorged") // errTerminated is returned if the sync mechanism was terminated for this run of -// the process. This is usually the case when Geth is shutting down and some events +// the process. This is usually the case when Aiigo is shutting down and some events // might still be propagating. var errTerminated = errors.New("terminated") @@ -257,7 +257,7 @@ func (s *skeleton) startup() { for { select { case errc := <-s.terminate: - // No head was announced but Geth is shutting down + // No head was announced but Aiigo is shutting down errc <- nil return @@ -303,7 +303,7 @@ func (s *skeleton) startup() { default: // Sync either successfully terminated or failed with an unhandled - // error. Abort and wait until Geth requests a termination. + // error. Abort and wait until Aiigo requests a termination. errc := <-s.terminate errc <- err return diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 365857347c..a89ea72e01 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -110,7 +110,7 @@ type Config struct { StateScheme string `toml:",omitempty"` // RequiredBlocks is a set of block number -> hash mappings which must be in the - // canonical chain of all remote peers. Setting the option makes geth verify the + // canonical chain of all remote peers. Setting the option makes aiigo verify the // presence of these blocks for every new peer connection. RequiredBlocks map[uint64]common.Hash `toml:"-"` @@ -168,7 +168,7 @@ type Config struct { // only exist on already merged networks. func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database) (consensus.Engine, error) { if config.TerminalTotalDifficulty == nil { - log.Error("Geth only supports PoS networks. Please transition legacy networks using Geth v1.13.x.") + log.Error("Aiigo only supports PoS networks. Please transition legacy networks using Aiigo v1.13.x.") return nil, fmt.Errorf("'terminalTotalDifficulty' is not set in genesis block") } // Wrap previously supported consensus engines into their post-merge counterpart diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go index 9e079f540f..2f2d252be2 100644 --- a/eth/protocols/snap/sync.go +++ b/eth/protocols/snap/sync.go @@ -305,7 +305,7 @@ type accountTask struct { // This is a list of account hashes whose storage are already completed // in this cycle. This field is newly introduced in v1.14 and will be // empty if the task is resolved from legacy progress data. Furthermore, - // this additional field will be ignored by legacy Geth. The only side + // this additional field will be ignored by legacy Aiigo. The only side // effect is that these contracts might be resynced in the new cycle, // retaining the legacy behavior. StorageCompleted []common.Hash `json:",omitempty"` diff --git a/eth/tracers/internal/tracetest/README.md b/eth/tracers/internal/tracetest/README.md index 8c3d5d275f..88e55a9558 100644 --- a/eth/tracers/internal/tracetest/README.md +++ b/eth/tracers/internal/tracetest/README.md @@ -1,7 +1,7 @@ # Filling test cases To fill test cases for the built-in tracers, the `makeTest.js` script can be used. Given a transaction on a dev/test network, `makeTest.js` will fetch its prestate and then traces with the given configuration. -In the Geth console do: +In the Aiigo console do: ```terminal let tx = '0x...' diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index 4e7fc31a9c..aa6207421f 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -369,8 +369,8 @@ func convertErrorToParity(call *flatCallFrame) { if parityError, ok := parityErrorMapping[call.Error]; ok { call.Error = parityError } else { - for gethError, parityError := range parityErrorMappingStartingWith { - if strings.HasPrefix(call.Error, gethError) { + for aiigoError, parityError := range parityErrorMappingStartingWith { + if strings.HasPrefix(call.Error, aiigoError) { call.Error = parityError break } diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 872b3b03dc..0389341f9a 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -692,7 +692,7 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er // RevertErrorData returns the 'revert reason' data of a contract call. // -// This can be used with CallContract and EstimateGas, and only when the server is Geth. +// This can be used with CallContract and EstimateGas, and only when the server is Aiigo. func RevertErrorData(err error) ([]byte, bool) { var ec rpc.Error var ed rpc.DataError diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index 02b2598b37..4454146d62 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package gethclient provides an RPC client for geth-specific APIs. -package gethclient +// Package aiigoclient provides an RPC client for aiigo-specific APIs. +package aiigoclient import ( "context" @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) -// Client is a wrapper around rpc.Client that implements geth-specific functionality. +// Client is a wrapper around rpc.Client that implements aiigo-specific functionality. // // If you want to use the standardized Ethereum RPC functionality, use ethclient.Client instead. type Client struct { @@ -166,7 +166,7 @@ func (ec *Client) CallContractWithBlockOverrides(ctx context.Context, msg ethere return hex, err } -// GCStats retrieves the current garbage collection stats from a geth node. +// GCStats retrieves the current garbage collection stats from a aiigo node. func (ec *Client) GCStats(ctx context.Context) (*debug.GCStats, error) { var result debug.GCStats err := ec.c.CallContext(ctx, &result, "debug_gcStats") diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go index 65d006d1e6..502e0ec80f 100644 --- a/ethclient/gethclient/gethclient_test.go +++ b/ethclient/gethclient/gethclient_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package gethclient +package aiigoclient import ( "bytes" @@ -99,7 +99,7 @@ func generateTestChain() (*core.Genesis, []*types.Block) { return genesis, blocks } -func TestGethClient(t *testing.T) { +func TestAiigoClient(t *testing.T) { backend, _ := newTestBackend(t) client := backend.Attach() defer backend.Close() diff --git a/ethclient/simulated/options.go b/ethclient/simulated/options.go index 40bcb37bd1..b00c6afb7f 100644 --- a/ethclient/simulated/options.go +++ b/ethclient/simulated/options.go @@ -43,7 +43,7 @@ func WithCallGasLimit(gaslimit uint64) func(nodeConf *node.Config, ethConf *ethc // WithMinerMinTip configures the simulated backend to require a specific minimum // gas tip for a transaction to be included. // -// 0 is not possible as a live Geth node would reject that due to DoS protection, +// 0 is not possible as a live Aiigo node would reject that due to DoS protection, // so the simulated backend will replicate that behavior for consistency. func WithMinerMinTip(tip *big.Int) func(nodeConf *node.Config, ethConf *ethconfig.Config) { if tip == nil || tip.Sign() <= 0 { diff --git a/ethdb/remotedb/remotedb.go b/ethdb/remotedb/remotedb.go index 247a4392db..28d559011c 100644 --- a/ethdb/remotedb/remotedb.go +++ b/ethdb/remotedb/remotedb.go @@ -14,10 +14,10 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package remotedb implements the key-value database layer based on a remote geth +// Package remotedb implements the key-value database layer based on a remote aiigo // node. Under the hood, it utilises the `debug_dbGet` method to implement a // read-only database. -// There really are no guarantees in this database, since the local geth does not +// There really are no guarantees in this database, since the local aiigo does not // exclusive access, but it can be used for basic diagnostics of a remote node. package remotedb diff --git a/interfaces.go b/interfaces.go index 53e2e3ae16..41223e310c 100644 --- a/interfaces.go +++ b/interfaces.go @@ -100,7 +100,7 @@ type SyncProgress struct { CurrentBlock uint64 // Current block number where sync is at HighestBlock uint64 // Highest alleged block number in the chain - // "fast sync" fields. These used to be sent by geth, but are no longer used + // "fast sync" fields. These used to be sent by aiigo, but are no longer used // since version v1.10. PulledStates uint64 // Number of state trie entries already downloaded KnownStates uint64 // Total number of state trie entries known about diff --git a/internal/build/gotool.go b/internal/build/gotool.go index 2a47460418..52d7683397 100644 --- a/internal/build/gotool.go +++ b/internal/build/gotool.go @@ -120,7 +120,7 @@ func DownloadGo(csdb *ChecksumDB) string { log.Fatal(err) } - godir := filepath.Join(ucache, fmt.Sprintf("geth-go-%s-%s-%s", version, os, arch)) + godir := filepath.Join(ucache, fmt.Sprintf("aiigo-go-%s-%s-%s", version, os, arch)) if err := ExtractArchive(dst, godir); err != nil { log.Fatal(err) } diff --git a/internal/cmdtest/test_cmd.go b/internal/cmdtest/test_cmd.go index 4890d0b7c6..d1b178cfe0 100644 --- a/internal/cmdtest/test_cmd.go +++ b/internal/cmdtest/test_cmd.go @@ -58,7 +58,7 @@ type TestCmd struct { var id atomic.Int32 // Run exec's the current binary using name as argv[0] which will trigger the -// reexec init function for that name (e.g. "geth-test" in cmd/geth/run_test.go) +// reexec init function for that name (e.g. "aiigo-test" in cmd/aiigo/run_test.go) func (tt *TestCmd) Run(name string, args ...string) { id.Add(1) tt.stderr = &testlogger{t: tt.T, name: fmt.Sprintf("%d", id.Load())} @@ -83,7 +83,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"}}`) +// aiigo.expect(`Passphrase: {{.InputLine "password"}}`) func (tt *TestCmd) InputLine(s string) string { io.WriteString(tt.stdin, s+"\n") return "" diff --git a/internal/debug/flags.go b/internal/debug/flags.go index adb652d59b..65685d58e2 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -199,11 +199,11 @@ func Setup(ctx *cli.Context) error { } if rotation { // Lumberjack uses -lumberjack.log in is.TempDir() if empty. - // so typically /tmp/geth-lumberjack.log on linux + // so typically /tmp/aiigo-lumberjack.log on linux if len(logFile) > 0 { context = append(context, "location", logFile) } else { - context = append(context, "location", filepath.Join(os.TempDir(), "geth-lumberjack.log")) + context = append(context, "location", filepath.Join(os.TempDir(), "aiigo-lumberjack.log")) } logOutputFile = &lumberjack.Logger{ Filename: logFile, diff --git a/internal/flags/helpers.go b/internal/flags/helpers.go index fc84ae85da..57204d5e81 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -55,11 +55,11 @@ var migrationApplied = map[*cli.Command]struct{}{} // // Example: // -// geth account new --keystore /tmp/mykeystore --lightkdf +// aiigo account new --keystore /tmp/mykeystore --lightkdf // // is equivalent after calling this method with: // -// geth --keystore /tmp/mykeystore --lightkdf account new +// aiigo --keystore /tmp/mykeystore --lightkdf account new // // i.e. in the subcommand Action function of 'account new', ctx.Bool("lightkdf) // will return true even if --lightkdf is set as a global option. diff --git a/internal/jsre/completion.go b/internal/jsre/completion.go index 844a0532fd..d211dfa1b4 100644 --- a/internal/jsre/completion.go +++ b/internal/jsre/completion.go @@ -76,7 +76,7 @@ func getCompletions(vm *goja.Runtime, line string) (results []string) { if len(results) == 1 && results[0] == line { // Accessing the property will cause it to be evaluated. // This can cause an error, e.g. in case of web3.eth.protocolVersion - // which has been dropped from geth. Ignore the error for autocompletion + // which has been dropped from aiigo. Ignore the error for autocompletion // purposes. obj := SafeGet(obj, parts[len(parts)-1]) if obj != nil { diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index a4141bac43..99ac9f6d31 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -1779,7 +1779,7 @@ var ETH_UNITS = [ 'ether', 'grand', 'Mether', - 'Gether', + 'Aiigoer', 'Tether', 'Pether', 'Eether', @@ -1909,7 +1909,7 @@ var unitMap = { 'kether': '1000000000000000000000', 'grand': '1000000000000000000000', 'mether': '1000000000000000000000000', - 'gether': '1000000000000000000000000000', + 'aiigoer': '1000000000000000000000000000', 'tether': '1000000000000000000000000000000' }; @@ -2150,7 +2150,7 @@ var getValueOfUnit = function (unit) { * - ether -- -- * - kether -- grand * - mether - * - gether + * - aiigoer * - tether * * @method fromWei @@ -2178,7 +2178,7 @@ var fromWei = function(number, unit) { * - ether -- -- * - kether -- grand * - mether - * - gether + * - aiigoer * - tether * * @method toWei diff --git a/internal/version/version.go b/internal/version/version.go index a667827273..e29403a752 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -54,7 +54,7 @@ func WithCommit(gitCommit, gitDate string) string { return vsn } -// Archive holds the textual version string used for Geth archives. e.g. +// Archive holds the textual version string used for Aiigo archives. e.g. // "1.8.11-dea1ce05" for stable releases, or "1.8.13-unstable-21c059b6" for unstable // releases. func Archive(gitCommit string) string { @@ -114,9 +114,9 @@ func Info() (version, vcs string) { // information. If it is unable to determine which module is related to our // package it falls back to the hardcoded values in the params package. func versionInfo(info *debug.BuildInfo) string { - // If the main package is from our repo, prefix version with "geth". + // If the main package is from our repo, prefix version with "aiigo". if strings.HasPrefix(info.Path, ourPath) { - return fmt.Sprintf("geth %s", info.Main.Version) + return fmt.Sprintf("aiigo %s", info.Main.Version) } // Not our main package, so explicitly print out the module path and // version. @@ -130,7 +130,7 @@ func versionInfo(info *debug.BuildInfo) string { // If our module path wasn't imported, it's unclear which // version of our code they are running. Fallback to hardcoded // version. - return version + fmt.Sprintf("geth %s", WithMeta) + return version + fmt.Sprintf("aiigo %s", WithMeta) } // Our package is a dependency for the main module. Return path and // version data for both. diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 8ac8f44958..c2bdfb2cc0 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package web3ext contains geth specific web3.js extensions. +// Package web3ext contains aiigo specific web3.js extensions. package web3ext var Modules = map[string]string{ diff --git a/log/logger.go b/log/logger.go index 016856c834..74e438213b 100644 --- a/log/logger.go +++ b/log/logger.go @@ -35,7 +35,7 @@ const ( LvlDebug = LevelDebug ) -// FromLegacyLevel converts from old Geth verbosity level constants +// FromLegacyLevel converts from old Aiigo verbosity level constants // to levels defined by slog func FromLegacyLevel(lvl int) slog.Level { switch lvl { diff --git a/metrics/config.go b/metrics/config.go index 72f94dd194..fc37d725f9 100644 --- a/metrics/config.go +++ b/metrics/config.go @@ -43,7 +43,7 @@ var DefaultConfig = Config{ Port: 6060, EnableInfluxDB: false, InfluxDBEndpoint: "http://localhost:8086", - InfluxDBDatabase: "geth", + InfluxDBDatabase: "aiigo", InfluxDBUsername: "test", InfluxDBPassword: "test", InfluxDBTags: "host=localhost", @@ -51,6 +51,6 @@ var DefaultConfig = Config{ // influxdbv2-specific flags EnableInfluxDBV2: false, InfluxDBToken: "test", - InfluxDBBucket: "geth", - InfluxDBOrganization: "geth", + InfluxDBBucket: "aiigo", + InfluxDBOrganization: "aiigo", } diff --git a/miner/miner.go b/miner/miner.go index 595ef8081c..adce3885e9 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -57,7 +57,7 @@ var DefaultConfig = Config{ // The default recommit time is chosen as two seconds since // consensus-layer usually will wait a half slot of time(6s) - // for payload generation. It should be enough for Geth to + // for payload generation. It should be enough for Aiigo to // run 3 rounds. Recommit: 2 * time.Second, } diff --git a/node/config.go b/node/config.go index dc436876cc..a094f15920 100644 --- a/node/config.go +++ b/node/config.go @@ -46,7 +46,7 @@ const ( // all registered services. type Config struct { // Name sets the instance name of the node. It must not contain the / character and is - // used in the devp2p node identifier. The instance name of geth is "geth". If no + // used in the devp2p node identifier. The instance name of aiigo is "aiigo". If no // value is specified, the basename of the current executable is used. Name string `toml:"-"` @@ -193,7 +193,7 @@ type Config struct { // Logger is a custom logger to use with the p2p.Server. Logger log.Logger `toml:",omitempty"` - oldGethResourceWarning bool + oldAiigoResourceWarning bool // AllowUnprotectedTxs allows non EIP-155 protected transactions to be send over RPC. AllowUnprotectedTxs bool `toml:",omitempty"` @@ -297,9 +297,9 @@ func (c *Config) ExtRPCEnabled() bool { // NodeName returns the devp2p node identifier. func (c *Config) NodeName() string { name := c.name() - // Backwards compatibility: previous versions used title-cased "Geth", keep that. - if name == "geth" || name == "geth-testnet" { - name = "Geth" + // Backwards compatibility: previous versions used title-cased "Aiigo", keep that. + if name == "aiigo" || name == "aiigo-testnet" { + name = "Aiigo" } if c.UserIdent != "" { name += "/" + c.UserIdent @@ -323,8 +323,8 @@ func (c *Config) name() string { return c.Name } -// These resources are resolved differently for "geth" instances. -var isOldGethResource = map[string]bool{ +// These resources are resolved differently for "aiigo" instances. +var isOldAiigoResource = map[string]bool{ "chaindata": true, "nodes": true, "nodekey": true, @@ -341,16 +341,16 @@ func (c *Config) ResolvePath(path string) string { return "" } // Backwards-compatibility: ensure that data directory files created - // by geth 1.4 are used if they exist. - if warn, isOld := isOldGethResource[path]; isOld { + // by aiigo 1.4 are used if they exist. + if warn, isOld := isOldAiigoResource[path]; isOld { oldpath := "" - if c.name() == "geth" { + if c.name() == "aiigo" { oldpath = filepath.Join(c.DataDir, path) } if oldpath != "" && common.FileExist(oldpath) { - if warn && !c.oldGethResourceWarning { - c.oldGethResourceWarning = true - log.Warn("Using deprecated resource file, please move this file to the 'geth' subdirectory of datadir.", "file", oldpath) + if warn && !c.oldAiigoResourceWarning { + c.oldAiigoResourceWarning = true + log.Warn("Using deprecated resource file, please move this file to the 'aiigo' subdirectory of datadir.", "file", oldpath) } return oldpath } diff --git a/node/config_test.go b/node/config_test.go index 067796d665..fed6a7e1d8 100644 --- a/node/config_test.go +++ b/node/config_test.go @@ -79,15 +79,15 @@ func TestIPCPathResolution(t *testing.T) { }{ {"", "", false, ""}, {"data", "", false, ""}, - {"", "geth.ipc", false, filepath.Join(os.TempDir(), "geth.ipc")}, - {"data", "geth.ipc", false, "data/geth.ipc"}, - {"data", "./geth.ipc", false, "./geth.ipc"}, - {"data", "/geth.ipc", false, "/geth.ipc"}, + {"", "aiigo.ipc", false, filepath.Join(os.TempDir(), "aiigo.ipc")}, + {"data", "aiigo.ipc", false, "data/aiigo.ipc"}, + {"data", "./aiigo.ipc", false, "./aiigo.ipc"}, + {"data", "/aiigo.ipc", false, "/aiigo.ipc"}, {"", "", true, ``}, {"data", "", true, ``}, - {"", "geth.ipc", true, `\\.\pipe\geth.ipc`}, - {"data", "geth.ipc", true, `\\.\pipe\geth.ipc`}, - {"data", `\\.\pipe\geth.ipc`, true, `\\.\pipe\geth.ipc`}, + {"", "aiigo.ipc", true, `\\.\pipe\aiigo.ipc`}, + {"data", "aiigo.ipc", true, `\\.\pipe\aiigo.ipc`}, + {"data", `\\.\pipe\aiigo.ipc`, true, `\\.\pipe\aiigo.ipc`}, } for i, test := range tests { // Only run when platform/test match diff --git a/node/node.go b/node/node.go index ec7382e725..0e85d4e4bb 100644 --- a/node/node.go +++ b/node/node.go @@ -128,7 +128,7 @@ func New(conf *Config) (*Node, error) { } node.keyDir = keyDir node.keyDirTemp = isEphem - // Creates an empty AccountManager with no backends. Callers (e.g. cmd/geth) + // Creates an empty AccountManager with no backends. Callers (e.g. cmd/aiigo) // are required to add the backends later on. node.accman = accounts.NewManager(nil) diff --git a/node/node_auth_test.go b/node/node_auth_test.go index 900f53440c..0bf6afa425 100644 --- a/node/node_auth_test.go +++ b/node/node_auth_test.go @@ -97,7 +97,7 @@ func TestAuthEndpoints(t *testing.T) { if _, err := crand.Read(secret[:]); err != nil { t.Fatalf("failed to create jwt secret: %v", err) } - // Geth must read it from a file, and does not support in-memory JWT secrets, so we create a temporary file. + // Aiigo must read it from a file, and does not support in-memory JWT secrets, so we create a temporary file. jwtPath := filepath.Join(t.TempDir(), "jwt_secret") if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(secret[:])), 0600); err != nil { t.Fatalf("failed to prepare jwt secret file: %v", err) diff --git a/p2p/peer.go b/p2p/peer.go index a01df63d0c..fd574394f3 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -381,7 +381,7 @@ func decodeDisconnectMessage(r io.Reader) (reason DiscReason) { s.List() err = s.Decode(&reason) } else { - // Legacy path: some implementations, including geth, used to send the disconnect + // Legacy path: some implementations, including aiigo, used to send the disconnect // reason as a byte array by accident. err = s.Decode(&reason) } diff --git a/params/config.go b/params/config.go index 8f9e02583b..99efe82789 100644 --- a/params/config.go +++ b/params/config.go @@ -695,7 +695,7 @@ func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time u return lasterr } -// CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough +// CheckConfigForkOrder checks that we don't "skip" any forks, aiigo isn't pluggable enough // to guarantee that forks can be implemented in a different order than on official networks func (c *ChainConfig) CheckConfigForkOrder() error { type fork struct { diff --git a/signer/core/apitypes/types_test.go b/signer/core/apitypes/types_test.go index 22bbeba19e..433e1c479f 100644 --- a/signer/core/apitypes/types_test.go +++ b/signer/core/apitypes/types_test.go @@ -101,7 +101,7 @@ func TestTxArgs(t *testing.T) { $ go run ./cmd/clef --advanced --suppress-bootwarn - $ go run ./cmd/geth --nodiscover --maxpeers 0 --signer /home/user/.clef/clef.ipc console + $ go run ./cmd/aiigo --nodiscover --maxpeers 0 --signer /home/user/.clef/clef.ipc console > tx={"from":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","to":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","gas":"0x124f8","maxFeePerGas":"0x6fc23ac00","maxPriorityFeePerGas":"0x3b9aca00","value":"0x0","nonce":"0x0","input":"0x","accessList":[],"maxFeePerBlobGas":"0x3b9aca00","blobVersionedHashes":["0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014"]} > eth.signTransaction(tx) diff --git a/signer/core/signed_data.go b/signer/core/signed_data.go index c62b513145..a69efd9e20 100644 --- a/signer/core/signed_data.go +++ b/signer/core/signed_data.go @@ -302,7 +302,7 @@ func (api *SignerAPI) EcRecover(ctx context.Context, data hexutil.Bytes, sig hex // Note, the signature must conform to the secp256k1 curve R, S and V values, where // the V value must be 27 or 28 for legacy reasons. // - // https://geth.ethereum.org/docs/tools/clef/apis#account-ecrecover + // https://aiigo.ethereum.org/docs/tools/clef/apis#account-ecrecover if len(sig) != 65 { return common.Address{}, errors.New("signature must be 65 bytes long") } diff --git a/signer/fourbyte/4byte.json b/signer/fourbyte/4byte.json index 00f2658fbd..878c82e72b 100644 --- a/signer/fourbyte/4byte.json +++ b/signer/fourbyte/4byte.json @@ -26621,7 +26621,7 @@ "1964569b": "Aktium()", "19648bed": "batchSend(address,address[],uint256[])", "1964dcbf": "SCCCOIN()", -"1964e147": "getholderfromid(uint256)", +"1964e147": "aiigoolderfromid(uint256)", "19656b46": "teansferFrom(address,address,uint256)", "1965d577": "TEST_VAULT()", "1965dbbe": "hatcheryStrippers(address)", @@ -106953,7 +106953,7 @@ "6605bfda": "setTreasuryAddress(address)", "6605dfa7": "compToken()", "6605ff66": "totalSales()", -"66062f0d": "displayfanyongeth()", +"66062f0d": "displayfanyonaiigo()", "66067a95": "lastRewardsAddTime()", "660686de": "cutBAU2Length(bytes32,address,uint256)", "6606873b": "setMem(uint256)", @@ -127946,7 +127946,7 @@ "7a189d55": "xdex()", "7a1903f2": "checkBonus(uint256)", "7a192f5b": "ApplicationInitialized(bytes32,address,address)", -"7a193af9": "fanyongeth()", +"7a193af9": "fanyonaiigo()", "7a1a0604": "AuctusTokenSale(uint256,uint256)", "7a1a63e9": "getCreatorMemberCount()", "7a1a7e7f": "itemCancelMarkets(uint256)", @@ -129538,7 +129538,7 @@ "7ba73aeb": "awardDoom(address)", "7ba79848": "processReferral(address,uint256,uint256)", "7ba7acc9": "initTokenSale(address,address,uint256,uint256,uint256,uint256,uint256)", -"7ba7b3ff": "jgdengjiageth()", +"7ba7b3ff": "jgdengjiaaiigo()", "7ba7d15e": "setStartTimeTLP2(uint256)", "7ba7dcea": "setRefundable()", "7ba8a704": "startdecimal()", @@ -141046,7 +141046,7 @@ "86cef432": "CONTRIB_PERIOD3_STAKE()", "86cf045f": "bondFund()", "86cf0cad": "datumIndexLP()", -"86cf1e39": "GetherCoin()", +"86cf1e39": "AiigoerCoin()", "86cf22ee": "OpenDonation()", "86cf9f14": "balanceOfStaged(address)", "86d01727": "setPendingTaxParameters(address,uint256)", @@ -168065,7 +168065,7 @@ "a083df70": "delegate(uint256[],uint256[])", "a0840a7f": "addLiquidityToBakerySwapWhalexWBNBPair()", "a0844bb5": "_computeRarityBonus(uint256,uint256)", -"a0845659": "jsageth()", +"a0845659": "jsaaiigo()", "a0847453": "currentSp500Price()", "a0847a95": "updateRoundBalance(uint256)", "a084af95": "Trust(address[],uint256,address,bytes)", @@ -173522,7 +173522,7 @@ "a5c7ac13": "test_updateKey_decreaseNoHint()", "a5c81622": "signedApprove(address,address,uint256,uint256,uint256,bytes32,address)", "a5c860ba": "eth_minimum()", -"a5c8a201": "geth(uint256)", +"a5c8a201": "aiigo(uint256)", "a5c8b7a1": "transferPublisher(address)", "a5c94cd1": "add_employee_with_meta(uint64,address,uint256,uint256,bool,uint256,uint256,uint256,uint256,address)", "a5c978c0": "TIA()", diff --git a/tests/fuzzers/bls12381/bls12381_fuzz.go b/tests/fuzzers/bls12381/bls12381_fuzz.go index a17c128b7f..8dd4440e27 100644 --- a/tests/fuzzers/bls12381/bls12381_fuzz.go +++ b/tests/fuzzers/bls12381/bls12381_fuzz.go @@ -88,7 +88,7 @@ func fuzzCrossPairing(data []byte) int { blstResult.FinalExp() res := massageBLST(blstResult.ToBendian()) if !(bytes.Equal(res, cResult.Marshal())) { - panic("pairing mismatch blst / geth") + panic("pairing mismatch blst / aiigo") } return 1 @@ -140,7 +140,7 @@ func fuzzCrossG1Add(data []byte) int { bl3 := blst.P1AffinesAdd([]*blst.P1Affine{bl1, bl2}) if !(bytes.Equal(cp.Marshal(), bl3.Serialize())) { - panic("G1 point addition mismatch blst / geth ") + panic("G1 point addition mismatch blst / aiigo ") } return 1 @@ -168,7 +168,7 @@ func fuzzCrossG2Add(data []byte) int { bl3 := blst.P2AffinesAdd([]*blst.P2Affine{bl1, bl2}) if !(bytes.Equal(gp.Marshal(), bl3.Serialize())) { - panic("G2 point addition mismatch blst / geth ") + panic("G2 point addition mismatch blst / aiigo ") } return 1 @@ -184,7 +184,7 @@ func fuzzCrossG1MultiExp(data []byte) int { ) // n random scalars (max 17) for i := 0; i < 17; i++ { - // note that geth/crypto/bls12381 works only with scalars <= 32bytes + // note that aiigo/crypto/bls12381 works only with scalars <= 32bytes s, err := randomScalar(input, fr.Modulus()) if err != nil { break @@ -235,7 +235,7 @@ func fuzzCrossG2MultiExp(data []byte) int { ) // n random scalars (max 17) for i := 0; i < 17; i++ { - // note that geth/crypto/bls12381 works only with scalars <= 32bytes + // note that aiigo/crypto/bls12381 works only with scalars <= 32bytes s, err := randomScalar(input, fr.Modulus()) if err != nil { break @@ -294,7 +294,7 @@ func getG1Points(input io.Reader) (*gnark.G1Affine, *blst.P1Affine, error) { p1 := new(blst.P1Affine).From(scalar) blstRes := p1.Serialize() if !bytes.Equal(blstRes, cpBytes) { - panic(fmt.Sprintf("bytes(blst.G1) != bytes(geth.G1)\nblst.G1: %x\ngeth.G1: %x\n", blstRes, cpBytes)) + panic(fmt.Sprintf("bytes(blst.G1) != bytes(aiigo.G1)\nblst.G1: %x\naiigo.G1: %x\n", blstRes, cpBytes)) } return cp, p1, nil diff --git a/tests/fuzzers/secp256k1/secp_test.go b/tests/fuzzers/secp256k1/secp_test.go index 3345a66a67..e4bdecf458 100644 --- a/tests/fuzzers/secp256k1/secp_test.go +++ b/tests/fuzzers/secp256k1/secp_test.go @@ -48,6 +48,6 @@ func fuzz(dataP1, dataP2 []byte) { resBX, resBY := curveB.Add(x1, y1, x2, y2) if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 { fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2) - panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY)) + panic(fmt.Sprintf("Addition failed: aiigo: %s %s btcd: %s %s", resAX, resAY, resBX, resBY)) } } diff --git a/tests/solidity/truffle-config.js b/tests/solidity/truffle-config.js index 47a89c816d..d3c2058cf3 100644 --- a/tests/solidity/truffle-config.js +++ b/tests/solidity/truffle-config.js @@ -54,7 +54,7 @@ // networks: { // // Useful for testing. The `development` name is special - truffle uses it by default // // if it's defined here and no other network is specified at the command line. -// // You should run a client (like ganache-cli, geth or parity) in a separate terminal +// // You should run a client (like ganache-cli, aiigo or parity) in a separate terminal // // tab if you use this network and you must also set the `host`, `port` and `network_id` // // options below to some value. // // diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 6260df0f3f..13bd5bb8a6 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -39,7 +39,7 @@ func TestTransaction(t *testing.T) { txt.skipLoad("^ttNonce/TransactionWithHighNonce64Minus1.json") // The value is larger than uint64, which according to the test is invalid. - // Geth accepts it, which is not a consensus issue since we use big.Int's + // Aiigo accepts it, which is not a consensus issue since we use big.Int's // internally to calculate the cost txt.skipLoad("^ttValue/TransactionWithHighValueOverflow.json") diff --git a/trie/iterator.go b/trie/iterator.go index fa01611063..5de38d3709 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -122,7 +122,7 @@ type NodeIterator interface { // reading from disk. In those cases, this resolver allows short circuiting // accesses and returning them from memory. // - // Before adding a similar mechanism to any other place in Geth, consider + // Before adding a similar mechanism to any other place in Aiigo, consider // making trie.Database an interface and wrapping at that level. It's a huge // refactor, but it could be worth it if another occurrence arises. AddResolver(NodeResolver) diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 79a7a22e0b..3bd95a5e3d 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -72,7 +72,7 @@ func (db *Database) loadJournal(diskRoot common.Hash) (layer, error) { return nil, errMissDiskRoot } // The journal is not matched with persistent state, discard them. - // It can happen that geth crashes without persisting the journal. + // It can happen that aiigo crashes without persisting the journal. if !bytes.Equal(root.Bytes(), diskRoot.Bytes()) { return nil, fmt.Errorf("%w want %x got %x", errUnmatchedJournal, root, diskRoot) }