Compare commits
51 Commits
v1.3.1-bet
...
bc-fusion-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
880667e77f | ||
|
|
f599fee78c | ||
|
|
eb93010928 | ||
|
|
d94cb56ae9 | ||
|
|
0438b61114 | ||
|
|
c73b11055e | ||
|
|
54f334a95f | ||
|
|
f2e38fec9a | ||
|
|
d1118313ce | ||
|
|
288b4f9926 | ||
|
|
6744d7c15f | ||
|
|
3414e5672a | ||
|
|
8f3c525adc | ||
|
|
3e9e6423c0 | ||
|
|
e3ef62f3bd | ||
|
|
fa5d0cf287 | ||
|
|
6c788d7675 | ||
|
|
a30beeba59 | ||
|
|
aa15df2814 | ||
|
|
195ae35130 | ||
|
|
5db73c9837 | ||
|
|
7e6b43a5c7 | ||
|
|
5743b067ba | ||
|
|
5b78f5761a | ||
|
|
885de2c1ca | ||
|
|
afc3b42241 | ||
|
|
a2f9ac0c8b | ||
|
|
761563155c | ||
|
|
8b00720640 | ||
|
|
a8409158a5 | ||
|
|
a3507cc2c1 | ||
|
|
b494339e10 | ||
|
|
f7e9adc2c8 | ||
|
|
d3f882d799 | ||
|
|
030e41607e | ||
|
|
70ccc3d1fe | ||
|
|
20dcaabfdc | ||
|
|
c409eb6ac6 | ||
|
|
cf80501de5 | ||
|
|
3ce568ff44 | ||
|
|
8e19728ea7 | ||
|
|
1edb34fd67 | ||
|
|
789442372d | ||
|
|
c92b6ce2ad | ||
|
|
cd0356b106 | ||
|
|
0224d48df4 | ||
|
|
497fdf8358 | ||
|
|
8b94dd6b59 | ||
|
|
4be9481558 | ||
|
|
3fc9f750d1 | ||
|
|
72ffb0cbed |
2
.github/workflows/build-test.yml
vendored
2
.github/workflows/build-test.yml
vendored
@@ -47,5 +47,3 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
go mod download
|
go mod download
|
||||||
make geth
|
make geth
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
|||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
go mod download
|
go mod tidy
|
||||||
|
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v3
|
||||||
|
|||||||
2
.github/workflows/unit-test.yml
vendored
2
.github/workflows/unit-test.yml
vendored
@@ -49,6 +49,6 @@ jobs:
|
|||||||
CGO_CFLAGS_ALLOW: "-O -D__BLST_PORTABLE__"
|
CGO_CFLAGS_ALLOW: "-O -D__BLST_PORTABLE__"
|
||||||
ANDROID_HOME: "" # Skip android test
|
ANDROID_HOME: "" # Skip android test
|
||||||
run: |
|
run: |
|
||||||
|
git submodule update --init --depth 1 --recursive
|
||||||
go mod download
|
go mod download
|
||||||
make test
|
make test
|
||||||
|
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,7 +14,6 @@
|
|||||||
*/**/*tx_database*
|
*/**/*tx_database*
|
||||||
*/**/*dapps*
|
*/**/*dapps*
|
||||||
build/_vendor/pkg
|
build/_vendor/pkg
|
||||||
/tests/truffle/storage
|
|
||||||
|
|
||||||
#*
|
#*
|
||||||
.#*
|
.#*
|
||||||
|
|||||||
33
CHANGELOG.md
33
CHANGELOG.md
@@ -1,4 +1,37 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## v1.3.5
|
||||||
|
FEATURE
|
||||||
|
* [\#1970](https://github.com/bnb-chain/bsc/pull/1970) core: enable Shanghai EIPs
|
||||||
|
* [\#1973](https://github.com/bnb-chain/bsc/pull/1973) core/systemcontracts: include BEP-319 on kepler hardfork
|
||||||
|
|
||||||
|
BUGFIX
|
||||||
|
* [\#1964](https://github.com/bnb-chain/bsc/pull/1964) consensus/parlia: hardfork block can be epoch block
|
||||||
|
* [\#1979](https://github.com/bnb-chain/bsc/pull/1979) fix: upgrade pebble and improve config
|
||||||
|
* [\#1980](https://github.com/bnb-chain/bsc/pull/1980) internal/ethapi: fix null effectiveGasPrice in GetTransactionReceipt
|
||||||
|
|
||||||
|
IMPROVEMENT
|
||||||
|
* [\#1977](https://github.com/bnb-chain/bsc/pull/1977) doc: add instructions for starting fullnode with pbss
|
||||||
|
|
||||||
|
## v1.3.4
|
||||||
|
BUGFIX
|
||||||
|
* fix: remove pipecommit in miner
|
||||||
|
* add a hard fork: Hertzfix
|
||||||
|
|
||||||
|
## v1.3.3
|
||||||
|
BUGFIX
|
||||||
|
* [\#1986](https://github.com/bnb-chain/bsc/pull/1986) fix(cmd): check pruneancient when creating db
|
||||||
|
|
||||||
|
IMPROVEMENT
|
||||||
|
* [\#2000](https://github.com/bnb-chain/bsc/pull/2000) cmd/utils: exit process if txlookuplimit flag is set
|
||||||
|
|
||||||
|
## v1.3.2
|
||||||
|
BUGFIX
|
||||||
|
* fix: remove sharedPool
|
||||||
|
|
||||||
|
IMPROVEMENT
|
||||||
|
* [\#2007](https://github.com/bnb-chain/bsc/pull/2007) consensus/parlia: increase size of snapshot cache in parlia
|
||||||
|
* [\#2008](https://github.com/bnb-chain/bsc/pull/2008) consensus/parlia: recover faster when snapshot of parlia is gone in disk
|
||||||
|
|
||||||
## v1.3.1
|
## v1.3.1
|
||||||
FEATURE
|
FEATURE
|
||||||
* [\#1881](https://github.com/bnb-chain/bsc/pull/1881) feat: active pbss
|
* [\#1881](https://github.com/bnb-chain/bsc/pull/1881) feat: active pbss
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -150,13 +150,25 @@ unzip testnet.zip
|
|||||||
Download latest chaindata snapshot from [here](https://github.com/bnb-chain/bsc-snapshots). Follow the guide to structure your files.
|
Download latest chaindata snapshot from [here](https://github.com/bnb-chain/bsc-snapshots). Follow the guide to structure your files.
|
||||||
|
|
||||||
Note: if you can not download the chaindata snapshot and want to sync from genesis, you have to generate the genesis block first, you have already get the genesis.json in Step 2.
|
Note: if you can not download the chaindata snapshot and want to sync from genesis, you have to generate the genesis block first, you have already get the genesis.json in Step 2.
|
||||||
So just run: `geth --datadir <datadir> init ./genesis.json`
|
So just run:
|
||||||
|
``` shell
|
||||||
|
## It will init genesis with Hash-Base Storage Scheme by default.
|
||||||
|
geth --datadir <datadir> init ./genesis.json
|
||||||
|
|
||||||
|
## It will init genesis with Path-Base Storage Scheme.
|
||||||
|
geth --datadir <datadir> --state.scheme path init ./genesis.json
|
||||||
|
```
|
||||||
#### 4. Start a full node
|
#### 4. Start a full node
|
||||||
```shell
|
```shell
|
||||||
./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --txlookuplimit 0
|
./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0
|
||||||
|
|
||||||
## It is recommand to run fullnode with `--tries-verify-mode none` if you want high performance and care little about state consistency
|
## It is recommand to run fullnode with `--tries-verify-mode none` if you want high performance and care little about state consistency
|
||||||
./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --txlookuplimit 0 --tries-verify-mode none
|
## It will run with Hash-Base Storage Scheme by default
|
||||||
|
./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --tries-verify-mode none
|
||||||
|
|
||||||
|
## It runs fullnode with Path-Base Storage Scheme.
|
||||||
|
## It will enable inline state prune, keeping the latest 90000 blocks' history state by default.
|
||||||
|
./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --history.transactions 0 --tries-verify-mode none --state.scheme path
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 5. Monitor node status
|
#### 5. Monitor node status
|
||||||
|
|||||||
@@ -2127,7 +2127,7 @@ func TestGolangBindings(t *testing.T) {
|
|||||||
t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out)
|
t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.15") // Repo root
|
replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.16") // Repo root
|
||||||
replacer.Dir = pkg
|
replacer.Dir = pkg
|
||||||
if out, err := replacer.CombinedOutput(); err != nil {
|
if out, err := replacer.CombinedOutput(); err != nil {
|
||||||
t.Fatalf("failed to replace tendermint dependency to bnb-chain source: %v\n%s", err, out)
|
t.Fatalf("failed to replace tendermint dependency to bnb-chain source: %v\n%s", err, out)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/v4/io/prompt"
|
"github.com/prysmaticlabs/prysm/v4/io/prompt"
|
||||||
"github.com/prysmaticlabs/prysm/v4/proto/eth/service"
|
"github.com/prysmaticlabs/prysm/v4/proto/eth/service"
|
||||||
|
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
|
||||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts/iface"
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts/iface"
|
||||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts/petnames"
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts/petnames"
|
||||||
@@ -26,6 +28,8 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/signer/core"
|
"github.com/ethereum/go-ethereum/signer/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,19 +39,20 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
au = aurora.NewAurora(true)
|
au = aurora.NewAurora(true)
|
||||||
privateKeyFlag = &cli.StringFlag{
|
|
||||||
Name: "private-key",
|
|
||||||
Usage: "Hex string for the BLS12-381 private key you wish encrypt into a keystore file",
|
|
||||||
Value: "",
|
|
||||||
}
|
|
||||||
showPrivateKeyFlag = &cli.BoolFlag{
|
showPrivateKeyFlag = &cli.BoolFlag{
|
||||||
Name: "show-private-key",
|
Name: "show-private-key",
|
||||||
Usage: "Show the BLS12-381 private key you will encrypt into a keystore file",
|
Usage: "Show the BLS12-381 private key you will encrypt into a keystore file",
|
||||||
|
Category: flags.AccountCategory,
|
||||||
}
|
}
|
||||||
BLSAccountPasswordFileFlag = &cli.StringFlag{
|
importedAccountPasswordFileFlag = &cli.StringFlag{
|
||||||
Name: "blsaccountpassword",
|
Name: "importedaccountpassword",
|
||||||
Usage: "File path for the BLS account password, which contains the password to encrypt private key into keystore file for managing votes in fast_finality feature",
|
Usage: "Password file path for the imported BLS account , which contains the password to get the private key by decrypting the keystore file",
|
||||||
|
Category: flags.AccountCategory,
|
||||||
|
}
|
||||||
|
chainIdFlag = &cli.Int64Flag{
|
||||||
|
Name: "chain-id",
|
||||||
|
Usage: "The chain id of the network that the validator will be created at",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -130,10 +135,8 @@ Make sure you backup your BLS keys regularly.`,
|
|||||||
Category: "BLS ACCOUNT COMMANDS",
|
Category: "BLS ACCOUNT COMMANDS",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
utils.DataDirFlag,
|
utils.DataDirFlag,
|
||||||
privateKeyFlag,
|
|
||||||
showPrivateKeyFlag,
|
showPrivateKeyFlag,
|
||||||
utils.BLSPasswordFileFlag,
|
utils.BLSPasswordFileFlag,
|
||||||
BLSAccountPasswordFileFlag,
|
|
||||||
},
|
},
|
||||||
Description: `
|
Description: `
|
||||||
geth bls account new
|
geth bls account new
|
||||||
@@ -149,17 +152,17 @@ You must remember this password to unlock your account in the future.`,
|
|||||||
Name: "import",
|
Name: "import",
|
||||||
Usage: "Import a BLS account",
|
Usage: "Import a BLS account",
|
||||||
Action: blsAccountImport,
|
Action: blsAccountImport,
|
||||||
ArgsUsage: "<keystore file>",
|
ArgsUsage: "<keyFile>",
|
||||||
Category: "BLS ACCOUNT COMMANDS",
|
Category: "BLS ACCOUNT COMMANDS",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
utils.DataDirFlag,
|
utils.DataDirFlag,
|
||||||
utils.BLSPasswordFileFlag,
|
utils.BLSPasswordFileFlag,
|
||||||
BLSAccountPasswordFileFlag,
|
importedAccountPasswordFileFlag,
|
||||||
},
|
},
|
||||||
Description: `
|
Description: `
|
||||||
geth bls account import <keyFile>
|
geth bls account import <keyFile>
|
||||||
|
|
||||||
Import a encrypted BLS account from keystore file <keyFile> into the BLS wallet.
|
Import a encrypted BLS account or a BLS12-381 private key from file <keyFile> into the BLS wallet.
|
||||||
|
|
||||||
If the BLS wallet not created yet, it will try to create BLS wallet first.`,
|
If the BLS wallet not created yet, it will try to create BLS wallet first.`,
|
||||||
},
|
},
|
||||||
@@ -193,6 +196,22 @@ Print summary of existing BLS accounts in the current BLS wallet.`,
|
|||||||
|
|
||||||
Delete the selected BLS account from the BLS wallet.`,
|
Delete the selected BLS account from the BLS wallet.`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "generate-proof",
|
||||||
|
Usage: "Generate ownership proof for the selected BLS account from the BLS wallet",
|
||||||
|
Action: blsAccountGenerateProof,
|
||||||
|
ArgsUsage: "<BLS pubkey>",
|
||||||
|
Category: "BLS ACCOUNT COMMANDS",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
utils.DataDirFlag,
|
||||||
|
utils.BLSPasswordFileFlag,
|
||||||
|
chainIdFlag,
|
||||||
|
},
|
||||||
|
Description: `
|
||||||
|
geth bls account generate-proof
|
||||||
|
|
||||||
|
Generate ownership proof for the selected BLS account from the BLS wallet. The proof is used to prove the ownership of the BLS account when creating validator on BSC after feynman upgrade.`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -219,7 +238,10 @@ func blsWalletCreate(ctx *cli.Context) error {
|
|||||||
utils.Fatalf("BLS wallet already exists in <DATADIR>/bls/wallet.")
|
utils.Fatalf("BLS wallet already exists in <DATADIR>/bls/wallet.")
|
||||||
}
|
}
|
||||||
|
|
||||||
password := utils.GetPassPhraseWithList("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true, 0, GetBLSPassword(ctx))
|
password := utils.GetPassPhraseWithList("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordListFromPath(ctx.String(utils.BLSPasswordFileFlag.Name)))
|
||||||
|
if err := core.ValidatePasswordFormat(password); err != nil {
|
||||||
|
utils.Fatalf("Password invalid: %v.", err)
|
||||||
|
}
|
||||||
|
|
||||||
opts := []accounts.Option{}
|
opts := []accounts.Option{}
|
||||||
opts = append(opts, accounts.WithWalletDir(dir))
|
opts = append(opts, accounts.WithWalletDir(dir))
|
||||||
@@ -249,7 +271,10 @@ func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, e
|
|||||||
}
|
}
|
||||||
if !dirExists {
|
if !dirExists {
|
||||||
fmt.Println("BLS wallet not exists, creating BLS wallet...")
|
fmt.Println("BLS wallet not exists, creating BLS wallet...")
|
||||||
password := utils.GetPassPhraseWithList("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true, 0, GetBLSPassword(ctx))
|
password := utils.GetPassPhraseWithList("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordListFromPath(ctx.String(utils.BLSPasswordFileFlag.Name)))
|
||||||
|
if err := core.ValidatePasswordFormat(password); err != nil {
|
||||||
|
utils.Fatalf("Password invalid: %v.", err)
|
||||||
|
}
|
||||||
|
|
||||||
opts := []accounts.Option{}
|
opts := []accounts.Option{}
|
||||||
opts = append(opts, accounts.WithWalletDir(walletDir))
|
opts = append(opts, accounts.WithWalletDir(walletDir))
|
||||||
@@ -269,7 +294,7 @@ func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, e
|
|||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, GetBLSPassword(ctx))
|
walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, utils.MakePasswordListFromPath(ctx.String(utils.BLSPasswordFileFlag.Name)))
|
||||||
w, err = wallet.OpenWallet(context.Background(), &wallet.Config{
|
w, err = wallet.OpenWallet(context.Background(), &wallet.Config{
|
||||||
WalletDir: walletDir,
|
WalletDir: walletDir,
|
||||||
WalletPassword: walletPassword,
|
WalletPassword: walletPassword,
|
||||||
@@ -309,27 +334,11 @@ func blsAccountCreate(ctx *cli.Context) error {
|
|||||||
if err := os.MkdirAll(keystoreDir, 0755); err != nil {
|
if err := os.MkdirAll(keystoreDir, 0755); err != nil {
|
||||||
utils.Fatalf("Could not access keystore dir: %v.", err)
|
utils.Fatalf("Could not access keystore dir: %v.", err)
|
||||||
}
|
}
|
||||||
accountPassword := utils.GetPassPhraseWithList("Your new BLS account will be encrypted with a password. Please give a password. Do not forget this password.", true, 0, GetBLSAccountPassword(ctx))
|
accountPassword := w.Password()
|
||||||
if err := core.ValidatePasswordFormat(accountPassword); err != nil {
|
|
||||||
utils.Fatalf("Password invalid: %v.", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
encryptor := keystorev4.New()
|
encryptor := keystorev4.New()
|
||||||
secretKey, err := bls.RandKey()
|
secretKey, err := bls.RandKey()
|
||||||
privateKeyString := ctx.String(privateKeyFlag.Name)
|
if err != nil {
|
||||||
if privateKeyString != "" {
|
|
||||||
if len(privateKeyString) > 2 && strings.Contains(privateKeyString, "0x") {
|
|
||||||
privateKeyString = privateKeyString[2:] // Strip the 0x prefix, if any.
|
|
||||||
}
|
|
||||||
bytesValue, err := hex.DecodeString(privateKeyString)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("could not decode as hex string: %s", privateKeyString)
|
|
||||||
}
|
|
||||||
secretKey, err = bls.SecretKeyFromBytes(bytesValue)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("not a valid BLS12-381 private key")
|
|
||||||
}
|
|
||||||
} else if err != nil {
|
|
||||||
utils.Fatalf("Could not generate BLS secret key: %v.", err)
|
utils.Fatalf("Could not generate BLS secret key: %v.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,22 +392,6 @@ func blsAccountCreate(ctx *cli.Context) error {
|
|||||||
|
|
||||||
// blsAccountImport imports a BLS account into the BLS wallet.
|
// blsAccountImport imports a BLS account into the BLS wallet.
|
||||||
func blsAccountImport(ctx *cli.Context) error {
|
func blsAccountImport(ctx *cli.Context) error {
|
||||||
keyfile := ctx.Args().First()
|
|
||||||
if len(keyfile) == 0 {
|
|
||||||
utils.Fatalf("The keystore file must be given as argument.")
|
|
||||||
}
|
|
||||||
keyJSON, err := os.ReadFile(keyfile)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("Could not read keystore file: %v", err)
|
|
||||||
}
|
|
||||||
keystore := &keymanager.Keystore{}
|
|
||||||
if err := json.Unmarshal(keyJSON, keystore); err != nil {
|
|
||||||
utils.Fatalf("Could not decode keystore file: %v.", err)
|
|
||||||
}
|
|
||||||
if keystore.Pubkey == "" {
|
|
||||||
utils.Fatalf(" Missing public key, wrong keystore file.")
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := gethConfig{Node: defaultNodeConfig()}
|
cfg := gethConfig{Node: defaultNodeConfig()}
|
||||||
// Load config file.
|
// Load config file.
|
||||||
if file := ctx.String(configFileFlag.Name); file != "" {
|
if file := ctx.String(configFileFlag.Name); file != "" {
|
||||||
@@ -421,13 +414,53 @@ func blsAccountImport(ctx *cli.Context) error {
|
|||||||
utils.Fatalf("The BLS keymanager cannot import keystores")
|
utils.Fatalf("The BLS keymanager cannot import keystores")
|
||||||
}
|
}
|
||||||
|
|
||||||
password := utils.GetPassPhraseWithList("Enter the password for your imported account.", false, 0, GetBLSAccountPassword(ctx))
|
keyfile := ctx.Args().First()
|
||||||
|
if len(keyfile) == 0 {
|
||||||
|
utils.Fatalf("The keystore file must be given as argument.")
|
||||||
|
}
|
||||||
|
keyInfo, err := os.ReadFile(keyfile)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Could not read keystore file: %v", err)
|
||||||
|
}
|
||||||
|
keystore := &keymanager.Keystore{}
|
||||||
|
var importedAccountPassword string
|
||||||
|
if err := json.Unmarshal(keyInfo, keystore); err != nil {
|
||||||
|
secretKey, err := bls.SecretKeyFromBytes(common.FromHex(strings.TrimRight(string(keyInfo), "\r\n")))
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("keyFile is neither a keystore file or include a valid BLS12-381 private key: %v.", err)
|
||||||
|
}
|
||||||
|
pubKeyBytes := secretKey.PublicKey().Marshal()
|
||||||
|
encryptor := keystorev4.New()
|
||||||
|
importedAccountPassword = w.Password()
|
||||||
|
cryptoFields, err := encryptor.Encrypt(secretKey.Marshal(), importedAccountPassword)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Could not encrypt secret key: %v.", err)
|
||||||
|
}
|
||||||
|
id, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Could not generate uuid: %v.", err)
|
||||||
|
}
|
||||||
|
keystore = &keymanager.Keystore{
|
||||||
|
Crypto: cryptoFields,
|
||||||
|
ID: id.String(),
|
||||||
|
Pubkey: fmt.Sprintf("%x", pubKeyBytes),
|
||||||
|
Version: encryptor.Version(),
|
||||||
|
Name: encryptor.Name(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if keystore.Pubkey == "" {
|
||||||
|
utils.Fatalf(" Missing public key, wrong keystore file.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if importedAccountPassword == "" {
|
||||||
|
importedAccountPassword = utils.GetPassPhraseWithList("Enter the password for your imported account.", false, 0, utils.MakePasswordListFromPath(ctx.String(importedAccountPasswordFileFlag.Name)))
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println("Importing BLS account, this may take a while...")
|
fmt.Println("Importing BLS account, this may take a while...")
|
||||||
statuses, err := accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{
|
statuses, err := accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{
|
||||||
Importer: k,
|
Importer: k,
|
||||||
Keystores: []*keymanager.Keystore{keystore},
|
Keystores: []*keymanager.Keystore{keystore},
|
||||||
AccountPassword: password,
|
AccountPassword: importedAccountPassword,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Import BLS account failed: %v.", err)
|
utils.Fatalf("Import BLS account failed: %v.", err)
|
||||||
@@ -458,7 +491,7 @@ func blsAccountList(ctx *cli.Context) error {
|
|||||||
utils.Fatalf("BLS wallet not exists.")
|
utils.Fatalf("BLS wallet not exists.")
|
||||||
}
|
}
|
||||||
|
|
||||||
walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, GetBLSPassword(ctx))
|
walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, utils.MakePasswordListFromPath(ctx.String(utils.BLSPasswordFileFlag.Name)))
|
||||||
w, err := wallet.OpenWallet(context.Background(), &wallet.Config{
|
w, err := wallet.OpenWallet(context.Background(), &wallet.Config{
|
||||||
WalletDir: walletDir,
|
WalletDir: walletDir,
|
||||||
WalletPassword: walletPassword,
|
WalletPassword: walletPassword,
|
||||||
@@ -537,7 +570,7 @@ func blsAccountDelete(ctx *cli.Context) error {
|
|||||||
utils.Fatalf("BLS wallet not exists.")
|
utils.Fatalf("BLS wallet not exists.")
|
||||||
}
|
}
|
||||||
|
|
||||||
walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, GetBLSPassword(ctx))
|
walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, utils.MakePasswordListFromPath(ctx.String(utils.BLSPasswordFileFlag.Name)))
|
||||||
w, err := wallet.OpenWallet(context.Background(), &wallet.Config{
|
w, err := wallet.OpenWallet(context.Background(), &wallet.Config{
|
||||||
WalletDir: walletDir,
|
WalletDir: walletDir,
|
||||||
WalletPassword: walletPassword,
|
WalletPassword: walletPassword,
|
||||||
@@ -599,26 +632,78 @@ func blsAccountDelete(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBLSPassword(ctx *cli.Context) []string {
|
// blsAccountGenerateProof generate ownership proof for a selected BLS account.
|
||||||
path := ctx.String(utils.BLSPasswordFileFlag.Name)
|
func blsAccountGenerateProof(ctx *cli.Context) error {
|
||||||
if path == "" {
|
if ctx.Args().Len() == 0 {
|
||||||
return nil
|
utils.Fatalf("No BLS account specified.")
|
||||||
}
|
}
|
||||||
text, err := os.ReadFile(path)
|
var filteredPubKeys []bls.PublicKey
|
||||||
if err != nil {
|
for _, str := range ctx.Args().Slice() {
|
||||||
utils.Fatalf("Failed to read wallet password file: %v", err)
|
pkString := str
|
||||||
|
if strings.Contains(pkString, "0x") {
|
||||||
|
pkString = pkString[2:]
|
||||||
|
}
|
||||||
|
pubKeyBytes, err := hex.DecodeString(pkString)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Could not decode string %s as hex.", pkString)
|
||||||
|
}
|
||||||
|
blsPublicKey, err := bls.PublicKeyFromBytes(pubKeyBytes)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("%#x is not a valid BLS public key.", pubKeyBytes)
|
||||||
|
}
|
||||||
|
filteredPubKeys = append(filteredPubKeys, blsPublicKey)
|
||||||
}
|
}
|
||||||
return []string{string(text)}
|
if len(filteredPubKeys) > 1 {
|
||||||
}
|
utils.Fatalf("Only support one BLS account specified.")
|
||||||
|
}
|
||||||
|
pubkeyBz := filteredPubKeys[0].Marshal()
|
||||||
|
|
||||||
func GetBLSAccountPassword(ctx *cli.Context) []string {
|
cfg := gethConfig{Node: defaultNodeConfig()}
|
||||||
path := ctx.String(BLSAccountPasswordFileFlag.Name)
|
// Load config file.
|
||||||
if path == "" {
|
if file := ctx.String(configFileFlag.Name); file != "" {
|
||||||
return nil
|
if err := loadConfig(file, &cfg); err != nil {
|
||||||
|
utils.Fatalf("%v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
text, err := os.ReadFile(path)
|
utils.SetNodeConfig(ctx, &cfg.Node)
|
||||||
|
|
||||||
|
walletDir := filepath.Join(cfg.Node.DataDir, BLSWalletPath)
|
||||||
|
dirExists, err := wallet.Exists(walletDir)
|
||||||
|
if err != nil || !dirExists {
|
||||||
|
utils.Fatalf("BLS wallet not exists.")
|
||||||
|
}
|
||||||
|
|
||||||
|
walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, utils.MakePasswordListFromPath(ctx.String(utils.BLSPasswordFileFlag.Name)))
|
||||||
|
w, err := wallet.OpenWallet(context.Background(), &wallet.Config{
|
||||||
|
WalletDir: walletDir,
|
||||||
|
WalletPassword: walletPassword,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to read account password file: %v", err)
|
utils.Fatalf("Open BLS wallet failed: %v.", err)
|
||||||
}
|
}
|
||||||
return []string{string(text)}
|
km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false})
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Initialize key manager failed: %v.", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
chainIdInt64 := ctx.Int64(chainIdFlag.Name)
|
||||||
|
if chainIdInt64 == 0 {
|
||||||
|
utils.Fatalf("Chain id is required.")
|
||||||
|
}
|
||||||
|
chainId := new(big.Int).SetInt64(chainIdInt64)
|
||||||
|
paddedChainIdBytes := make([]byte, 32)
|
||||||
|
copy(paddedChainIdBytes[32-len(chainId.Bytes()):], chainId.Bytes())
|
||||||
|
msgHash := crypto.Keccak256(append(pubkeyBz, paddedChainIdBytes...))
|
||||||
|
|
||||||
|
req := &validatorpb.SignRequest{
|
||||||
|
PublicKey: pubkeyBz,
|
||||||
|
SigningRoot: msgHash,
|
||||||
|
}
|
||||||
|
sig, err := km.Sign(context.Background(), req)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Generate signature failed: %v.", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Proof: %#x\n", sig.Marshal())
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
33
cmd/geth/testdata/bls-account-usage-demo.sh
vendored
Normal file
33
cmd/geth/testdata/bls-account-usage-demo.sh
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
echo "0. prepare---------------------------------------------------------------------------------"
|
||||||
|
echo 123abc7890 > bls-password.txt
|
||||||
|
echo 123abc7891 > bls-password1.txt
|
||||||
|
basedir=$(cd `dirname $0`; pwd)
|
||||||
|
workspace=${basedir}/../../../
|
||||||
|
|
||||||
|
echo "1. create a bls account--------------------------------------------------------------------"
|
||||||
|
${workspace}/build/bin/geth bls account new --blspassword ./bls-password.txt --datadir ./bls
|
||||||
|
${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt --datadir ./bls
|
||||||
|
|
||||||
|
echo "2. import a bls account by passing file including a private key-----------------------------"
|
||||||
|
secretKey=`${workspace}/build/bin/geth bls account new --show-private-key --blspassword ./bls-password1.txt --datadir ./bls1 | grep private | awk '{print $NF}'`
|
||||||
|
echo ${secretKey} > ./bls1/secretKey
|
||||||
|
${workspace}/build/bin/geth bls account import --blspassword ./bls-password.txt --datadir ./bls ./bls1/secretKey
|
||||||
|
${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt --datadir ./bls
|
||||||
|
|
||||||
|
echo "3. delete the imported account above--------------------------------------------------------"
|
||||||
|
publicKey=`${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt --datadir ./bls |grep public | tail -1 | awk '{print $NF}'`
|
||||||
|
${workspace}/build/bin/geth bls account delete --blspassword ./bls-password.txt --datadir ./bls ${publicKey}
|
||||||
|
${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt --datadir ./bls
|
||||||
|
|
||||||
|
echo "4. import a bls account by passing a keystore file------------------------------------------"
|
||||||
|
keystoreFile=`ls bls1/bls/keystore`
|
||||||
|
${workspace}/build/bin/geth bls account import --importedaccountpassword ./bls-password1.txt --blspassword ./bls-password.txt --datadir ./bls ./bls1/bls/keystore/${keystoreFile}
|
||||||
|
${workspace}/build/bin/geth bls account list --blspassword ./bls-password.txt --datadir ./bls
|
||||||
|
|
||||||
|
echo "5. clearup----------------------------------------------------------------------------------"
|
||||||
|
rm -rf bls
|
||||||
|
rm -rf bls1
|
||||||
|
rm -rf bls-password.txt
|
||||||
|
rm -rf bls-password1.txt
|
||||||
@@ -1092,14 +1092,14 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
|
|||||||
|
|
||||||
BLSPasswordFileFlag = &cli.StringFlag{
|
BLSPasswordFileFlag = &cli.StringFlag{
|
||||||
Name: "blspassword",
|
Name: "blspassword",
|
||||||
Usage: "File path for the BLS password, which contains the password to unlock BLS wallet for managing votes in fast_finality feature",
|
Usage: "Password file path for the BLS wallet, which contains the password to unlock BLS wallet for managing votes in fast_finality feature",
|
||||||
Category: flags.FastFinalityCategory,
|
Category: flags.AccountCategory,
|
||||||
}
|
}
|
||||||
|
|
||||||
BLSWalletDirFlag = &flags.DirectoryFlag{
|
BLSWalletDirFlag = &flags.DirectoryFlag{
|
||||||
Name: "blswallet",
|
Name: "blswallet",
|
||||||
Usage: "Path for the blsWallet dir in fast finality feature (default = inside the datadir)",
|
Usage: "Path for the blsWallet dir in fast finality feature (default = inside the datadir)",
|
||||||
Category: flags.FastFinalityCategory,
|
Category: flags.AccountCategory,
|
||||||
}
|
}
|
||||||
|
|
||||||
VoteJournalDirFlag = &flags.DirectoryFlag{
|
VoteJournalDirFlag = &flags.DirectoryFlag{
|
||||||
@@ -1462,7 +1462,10 @@ func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
|
|||||||
|
|
||||||
// MakePasswordList reads password lines from the file specified by the global --password flag.
|
// MakePasswordList reads password lines from the file specified by the global --password flag.
|
||||||
func MakePasswordList(ctx *cli.Context) []string {
|
func MakePasswordList(ctx *cli.Context) []string {
|
||||||
path := ctx.Path(PasswordFileFlag.Name)
|
return MakePasswordListFromPath(ctx.Path(PasswordFileFlag.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePasswordListFromPath(path string) []string {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1919,7 +1922,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||||||
cfg.EnableTrustProtocol = ctx.IsSet(EnableTrustProtocolFlag.Name)
|
cfg.EnableTrustProtocol = ctx.IsSet(EnableTrustProtocolFlag.Name)
|
||||||
}
|
}
|
||||||
if ctx.IsSet(PipeCommitFlag.Name) {
|
if ctx.IsSet(PipeCommitFlag.Name) {
|
||||||
cfg.PipeCommit = ctx.Bool(PipeCommitFlag.Name)
|
log.Warn("The --pipecommit flag is deprecated and could be removed in the future!")
|
||||||
}
|
}
|
||||||
if ctx.IsSet(RangeLimitFlag.Name) {
|
if ctx.IsSet(RangeLimitFlag.Name) {
|
||||||
cfg.RangeLimit = ctx.Bool(RangeLimitFlag.Name)
|
cfg.RangeLimit = ctx.Bool(RangeLimitFlag.Name)
|
||||||
@@ -1948,14 +1951,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||||||
// Parse transaction history flag, if user is still using legacy config
|
// Parse transaction history flag, if user is still using legacy config
|
||||||
// file with 'TxLookupLimit' configured, copy the value to 'TransactionHistory'.
|
// file with 'TxLookupLimit' configured, copy the value to 'TransactionHistory'.
|
||||||
if cfg.TransactionHistory == ethconfig.Defaults.TransactionHistory && cfg.TxLookupLimit != ethconfig.Defaults.TxLookupLimit {
|
if cfg.TransactionHistory == ethconfig.Defaults.TransactionHistory && cfg.TxLookupLimit != ethconfig.Defaults.TxLookupLimit {
|
||||||
log.Warn("The config option 'TxLookupLimit' is deprecated and will be removed, please use 'TransactionHistory'")
|
log.Crit("The config option 'TxLookupLimit' is deprecated and may cause unexpected performance degradation issues, please use 'TransactionHistory' instead")
|
||||||
cfg.TransactionHistory = cfg.TxLookupLimit
|
|
||||||
}
|
}
|
||||||
if ctx.IsSet(TransactionHistoryFlag.Name) {
|
if ctx.IsSet(TransactionHistoryFlag.Name) {
|
||||||
cfg.TransactionHistory = ctx.Uint64(TransactionHistoryFlag.Name)
|
cfg.TransactionHistory = ctx.Uint64(TransactionHistoryFlag.Name)
|
||||||
} else if ctx.IsSet(TxLookupLimitFlag.Name) {
|
} else if ctx.IsSet(TxLookupLimitFlag.Name) {
|
||||||
log.Warn("The flag --txlookuplimit is deprecated and will be removed, please use --history.transactions")
|
log.Crit("The flag --txlookuplimit is deprecated and may cause unexpected performance degradation issues. Please use --history.transactions instead")
|
||||||
cfg.TransactionHistory = ctx.Uint64(TransactionHistoryFlag.Name)
|
|
||||||
}
|
}
|
||||||
if ctx.IsSet(PathDBSyncFlag.Name) {
|
if ctx.IsSet(PathDBSyncFlag.Name) {
|
||||||
cfg.PathSyncFlush = true
|
cfg.PathSyncFlush = true
|
||||||
@@ -2355,7 +2356,7 @@ func tryMakeReadOnlyDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database
|
|||||||
// If datadir doesn't exist we need to open db in write-mode
|
// If datadir doesn't exist we need to open db in write-mode
|
||||||
// so database engine can create files.
|
// so database engine can create files.
|
||||||
readonly := true
|
readonly := true
|
||||||
if !common.FileExist(stack.ResolvePath("chaindata")) {
|
if !common.FileExist(stack.ResolvePath("chaindata")) || ctx.Bool(PruneAncientDataFlag.Name) {
|
||||||
readonly = false
|
readonly = false
|
||||||
}
|
}
|
||||||
return MakeChainDatabase(ctx, stack, readonly, false)
|
return MakeChainDatabase(ctx, stack, readonly, false)
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
@@ -45,5 +47,45 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
|
|||||||
|
|
||||||
// CalcBaseFee calculates the basefee of the header.
|
// CalcBaseFee calculates the basefee of the header.
|
||||||
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
||||||
return new(big.Int).SetUint64(params.InitialBaseFee)
|
if config.Parlia != nil {
|
||||||
|
return new(big.Int).SetUint64(params.InitialBaseFee)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
||||||
|
if !config.IsLondon(parent.Number) {
|
||||||
|
return new(big.Int).SetUint64(params.InitialBaseFee)
|
||||||
|
}
|
||||||
|
|
||||||
|
parentGasTarget := parent.GasLimit / config.ElasticityMultiplier()
|
||||||
|
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
|
||||||
|
if parent.GasUsed == parentGasTarget {
|
||||||
|
return new(big.Int).Set(parent.BaseFee)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
num = new(big.Int)
|
||||||
|
denom = new(big.Int)
|
||||||
|
)
|
||||||
|
|
||||||
|
if parent.GasUsed > parentGasTarget {
|
||||||
|
// If the parent block used more gas than its target, the baseFee should increase.
|
||||||
|
// max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
|
||||||
|
num.SetUint64(parent.GasUsed - parentGasTarget)
|
||||||
|
num.Mul(num, parent.BaseFee)
|
||||||
|
num.Div(num, denom.SetUint64(parentGasTarget))
|
||||||
|
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
|
||||||
|
baseFeeDelta := math.BigMax(num, common.Big1)
|
||||||
|
|
||||||
|
return num.Add(parent.BaseFee, baseFeeDelta)
|
||||||
|
} else {
|
||||||
|
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
|
||||||
|
// max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
|
||||||
|
num.SetUint64(parentGasTarget - parent.GasUsed)
|
||||||
|
num.Mul(num, parent.BaseFee)
|
||||||
|
num.Div(num, denom.SetUint64(parentGasTarget))
|
||||||
|
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
|
||||||
|
baseFee := num.Sub(parent.BaseFee, num)
|
||||||
|
|
||||||
|
return math.BigMax(baseFee, common.Big0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ func copyConfig(original *params.ChainConfig) *params.ChainConfig {
|
|||||||
|
|
||||||
func config() *params.ChainConfig {
|
func config() *params.ChainConfig {
|
||||||
config := copyConfig(params.TestChainConfig)
|
config := copyConfig(params.TestChainConfig)
|
||||||
|
config.Ethash = nil
|
||||||
|
config.Parlia = ¶ms.ParliaConfig{
|
||||||
|
Period: 3,
|
||||||
|
Epoch: 200,
|
||||||
|
}
|
||||||
config.LondonBlock = big.NewInt(5)
|
config.LondonBlock = big.NewInt(5)
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
223
consensus/parlia/feynmanfork.go
Normal file
223
consensus/parlia/feynmanfork.go
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
package parlia
|
||||||
|
|
||||||
|
import (
|
||||||
|
"container/heap"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"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/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/systemcontracts"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// initializeFeynmanContract initialize new contracts of Feynman fork
|
||||||
|
func (p *Parlia) initializeFeynmanContract(state *state.StateDB, header *types.Header, chain core.ChainContext,
|
||||||
|
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool,
|
||||||
|
) error {
|
||||||
|
// method
|
||||||
|
method := "initialize"
|
||||||
|
|
||||||
|
// initialize contracts
|
||||||
|
contracts := []string{
|
||||||
|
systemcontracts.StakeHubContract,
|
||||||
|
systemcontracts.GovernorContract,
|
||||||
|
systemcontracts.GovTokenContract,
|
||||||
|
systemcontracts.TimelockContract,
|
||||||
|
}
|
||||||
|
// get packed data
|
||||||
|
data, err := p.stakeHubABI.Pack(method)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for initialize feynman contracts", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, c := range contracts {
|
||||||
|
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(c), data, common.Big0)
|
||||||
|
// apply message
|
||||||
|
log.Info("initialize feynman contract", "block number", header.Number.Uint64(), "contract", c)
|
||||||
|
err = p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidatorItem struct {
|
||||||
|
address common.Address
|
||||||
|
votingPower *big.Int
|
||||||
|
voteAddress []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ValidatorHeap is a max-heap of validator's votingPower.
|
||||||
|
type ValidatorHeap []ValidatorItem
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Len() int { return len(*h) }
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Less(i, j int) bool {
|
||||||
|
// We want topK validators with max voting power, so we need a max-heap
|
||||||
|
if (*h)[i].votingPower.Cmp((*h)[j].votingPower) == 0 {
|
||||||
|
return (*h)[i].address.Hex() < (*h)[j].address.Hex()
|
||||||
|
} else {
|
||||||
|
return (*h)[i].votingPower.Cmp((*h)[j].votingPower) == 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Swap(i, j int) { (*h)[i], (*h)[j] = (*h)[j], (*h)[i] }
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Push(x interface{}) {
|
||||||
|
*h = append(*h, x.(ValidatorItem))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Pop() interface{} {
|
||||||
|
old := *h
|
||||||
|
n := len(old)
|
||||||
|
x := old[n-1]
|
||||||
|
*h = old[0 : n-1]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) updateValidatorSetV2(state *state.StateDB, header *types.Header, chain core.ChainContext,
|
||||||
|
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool,
|
||||||
|
) error {
|
||||||
|
// 1. get all validators and its voting power
|
||||||
|
blockNr := rpc.BlockNumberOrHashWithHash(header.ParentHash, false)
|
||||||
|
validatorItems, err := p.getValidatorElectionInfo(blockNr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
maxElectedValidators, err := p.getMaxElectedValidators(blockNr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. sort by voting power
|
||||||
|
eValidators, eVotingPowers, eVoteAddrs := getTopValidatorsByVotingPower(validatorItems, maxElectedValidators)
|
||||||
|
|
||||||
|
// 3. update validator set to system contract
|
||||||
|
method := "updateValidatorSetV2"
|
||||||
|
data, err := p.validatorSetABI.Pack(method, eValidators, eVotingPowers, eVoteAddrs)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for updateValidatorSetV2", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// get system message
|
||||||
|
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, common.Big0)
|
||||||
|
// apply message
|
||||||
|
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) getValidatorElectionInfo(blockNr rpc.BlockNumberOrHash) ([]ValidatorItem, error) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
method := "getValidatorElectionInfo"
|
||||||
|
toAddress := common.HexToAddress(systemcontracts.StakeHubContract)
|
||||||
|
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
|
||||||
|
|
||||||
|
data, err := p.stakeHubABI.Pack(method, big.NewInt(0), big.NewInt(0))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for getValidatorElectionInfo", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
msgData := (hexutil.Bytes)(data)
|
||||||
|
|
||||||
|
result, err := p.ethAPI.Call(ctx, ethapi.TransactionArgs{
|
||||||
|
Gas: &gas,
|
||||||
|
To: &toAddress,
|
||||||
|
Data: &msgData,
|
||||||
|
}, blockNr, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var validators []common.Address
|
||||||
|
var votingPowers []*big.Int
|
||||||
|
var voteAddrs [][]byte
|
||||||
|
var totalLength *big.Int
|
||||||
|
if err := p.stakeHubABI.UnpackIntoInterface(&[]interface{}{&validators, &votingPowers, &voteAddrs, &totalLength}, method, result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if totalLength.Int64() != int64(len(validators)) || totalLength.Int64() != int64(len(votingPowers)) || totalLength.Int64() != int64(len(voteAddrs)) {
|
||||||
|
return nil, fmt.Errorf("validator length not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
validatorItems := make([]ValidatorItem, len(validators))
|
||||||
|
for i := 0; i < len(validators); i++ {
|
||||||
|
validatorItems[i] = ValidatorItem{
|
||||||
|
address: validators[i],
|
||||||
|
votingPower: votingPowers[i],
|
||||||
|
voteAddress: voteAddrs[i],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return validatorItems, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) getMaxElectedValidators(blockNr rpc.BlockNumberOrHash) (maxElectedValidators *big.Int, err error) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
method := "maxElectedValidators"
|
||||||
|
toAddress := common.HexToAddress(systemcontracts.StakeHubContract)
|
||||||
|
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
|
||||||
|
|
||||||
|
data, err := p.stakeHubABI.Pack(method)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for maxElectedValidators", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
msgData := (hexutil.Bytes)(data)
|
||||||
|
|
||||||
|
result, err := p.ethAPI.Call(ctx, ethapi.TransactionArgs{
|
||||||
|
Gas: &gas,
|
||||||
|
To: &toAddress,
|
||||||
|
Data: &msgData,
|
||||||
|
}, blockNr, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.stakeHubABI.UnpackIntoInterface(&maxElectedValidators, method, result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxElectedValidators, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTopValidatorsByVotingPower(validatorItems []ValidatorItem, maxElectedValidators *big.Int) ([]common.Address, []uint64, [][]byte) {
|
||||||
|
var validatorHeap ValidatorHeap
|
||||||
|
for i := 0; i < len(validatorItems); i++ {
|
||||||
|
// only keep validators with voting power > 0
|
||||||
|
if validatorItems[i].votingPower.Cmp(big.NewInt(0)) == 1 {
|
||||||
|
validatorHeap = append(validatorHeap, validatorItems[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hp := &validatorHeap
|
||||||
|
heap.Init(hp)
|
||||||
|
|
||||||
|
topN := int(maxElectedValidators.Int64())
|
||||||
|
if topN > len(validatorHeap) {
|
||||||
|
topN = len(validatorHeap)
|
||||||
|
}
|
||||||
|
eValidators := make([]common.Address, topN)
|
||||||
|
eVotingPowers := make([]uint64, topN)
|
||||||
|
eVoteAddrs := make([][]byte, topN)
|
||||||
|
for i := 0; i < topN; i++ {
|
||||||
|
item := heap.Pop(hp).(ValidatorItem)
|
||||||
|
eValidators[i] = item.address
|
||||||
|
// as the decimal in BNB Beacon Chain is 1e8 and in BNB Smart Chain is 1e18, we need to divide it by 1e10
|
||||||
|
eVotingPowers[i] = new(big.Int).Div(item.votingPower, big.NewInt(1e10)).Uint64()
|
||||||
|
eVoteAddrs[i] = item.voteAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
return eValidators, eVotingPowers, eVoteAddrs
|
||||||
|
}
|
||||||
166
consensus/parlia/feynmanfork_test.go
Normal file
166
consensus/parlia/feynmanfork_test.go
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package parlia
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidatorHeap(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
description string
|
||||||
|
k int64
|
||||||
|
validators []ValidatorItem
|
||||||
|
expected []common.Address
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "normal case",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(200), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(100), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
common.HexToAddress("0x2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "same voting power",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(100), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(100), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
common.HexToAddress("0x2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "zero voting power and k > len(validators)",
|
||||||
|
k: 5,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x4"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "zero voting power and k < len(validators)",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x4"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "all zero voting power",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x4"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
eligibleValidators, _, _ := getTopValidatorsByVotingPower(tc.validators, big.NewInt(tc.k))
|
||||||
|
|
||||||
|
// check
|
||||||
|
if len(eligibleValidators) != len(tc.expected) {
|
||||||
|
t.Errorf("expected %d, got %d", len(tc.expected), len(eligibleValidators))
|
||||||
|
}
|
||||||
|
for i := 0; i < len(tc.expected); i++ {
|
||||||
|
if eligibleValidators[i] != tc.expected[i] {
|
||||||
|
t.Errorf("expected %s, got %s", tc.expected[i].Hex(), eligibleValidators[i].Hex())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -48,7 +47,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
inMemorySnapshots = 128 // Number of recent snapshots to keep in memory
|
inMemorySnapshots = 256 // Number of recent snapshots to keep in memory
|
||||||
inMemorySignatures = 4096 // Number of recent block signatures to keep in memory
|
inMemorySignatures = 4096 // Number of recent block signatures to keep in memory
|
||||||
|
|
||||||
checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database
|
checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database
|
||||||
@@ -91,6 +90,10 @@ var (
|
|||||||
common.HexToAddress(systemcontracts.TokenHubContract): true,
|
common.HexToAddress(systemcontracts.TokenHubContract): true,
|
||||||
common.HexToAddress(systemcontracts.RelayerIncentivizeContract): true,
|
common.HexToAddress(systemcontracts.RelayerIncentivizeContract): true,
|
||||||
common.HexToAddress(systemcontracts.CrossChainContract): true,
|
common.HexToAddress(systemcontracts.CrossChainContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.StakeHubContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.GovernorContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.GovTokenContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.TimelockContract): true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -180,7 +183,7 @@ func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (
|
|||||||
signature := header.Extra[len(header.Extra)-extraSeal:]
|
signature := header.Extra[len(header.Extra)-extraSeal:]
|
||||||
|
|
||||||
// Recover the public key and the Ethereum address
|
// Recover the public key and the Ethereum address
|
||||||
pubkey, err := crypto.Ecrecover(SealHash(header, chainId).Bytes(), signature)
|
pubkey, err := crypto.Ecrecover(types.SealHash(header, chainId).Bytes(), signature)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
@@ -200,7 +203,7 @@ func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (
|
|||||||
// or not), which could be abused to produce different hashes for the same header.
|
// or not), which could be abused to produce different hashes for the same header.
|
||||||
func ParliaRLP(header *types.Header, chainId *big.Int) []byte {
|
func ParliaRLP(header *types.Header, chainId *big.Int) []byte {
|
||||||
b := new(bytes.Buffer)
|
b := new(bytes.Buffer)
|
||||||
encodeSigHeader(b, header, chainId)
|
types.EncodeSigHeader(b, header, chainId)
|
||||||
return b.Bytes()
|
return b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,6 +230,7 @@ type Parlia struct {
|
|||||||
validatorSetABIBeforeLuban abi.ABI
|
validatorSetABIBeforeLuban abi.ABI
|
||||||
validatorSetABI abi.ABI
|
validatorSetABI abi.ABI
|
||||||
slashABI abi.ABI
|
slashABI abi.ABI
|
||||||
|
stakeHubABI abi.ABI
|
||||||
|
|
||||||
// The fields below are for testing only
|
// The fields below are for testing only
|
||||||
fakeDiff bool // Skip difficulty verifications
|
fakeDiff bool // Skip difficulty verifications
|
||||||
@@ -268,6 +272,10 @@ func New(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
stABI, err := abi.JSON(strings.NewReader(stakeABI))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
c := &Parlia{
|
c := &Parlia{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
config: parliaConfig,
|
config: parliaConfig,
|
||||||
@@ -279,6 +287,7 @@ func New(
|
|||||||
validatorSetABIBeforeLuban: vABIBeforeLuban,
|
validatorSetABIBeforeLuban: vABIBeforeLuban,
|
||||||
validatorSetABI: vABI,
|
validatorSetABI: vABI,
|
||||||
slashABI: sABI,
|
slashABI: sABI,
|
||||||
|
stakeHubABI: stABI,
|
||||||
signer: types.LatestSigner(chainConfig),
|
signer: types.LatestSigner(chainConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,7 +689,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
|
|||||||
// If we're at the genesis, snapshot the initial state. Alternatively if we have
|
// If we're at the genesis, snapshot the initial state. Alternatively if we have
|
||||||
// piled up more headers than allowed to be reorged (chain reinit from a freezer),
|
// piled up more headers than allowed to be reorged (chain reinit from a freezer),
|
||||||
// consider the checkpoint trusted and snapshot it.
|
// consider the checkpoint trusted and snapshot it.
|
||||||
if number == 0 || (number%p.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold)) {
|
if number == 0 || (number%p.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold/10)) {
|
||||||
checkpoint := chain.GetHeaderByNumber(number)
|
checkpoint := chain.GetHeaderByNumber(number)
|
||||||
if checkpoint != nil {
|
if checkpoint != nil {
|
||||||
// get checkpoint data
|
// get checkpoint data
|
||||||
@@ -694,10 +703,12 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
|
|||||||
|
|
||||||
// new snapshot
|
// new snapshot
|
||||||
snap = newSnapshot(p.config, p.signatures, number, hash, validators, voteAddrs, p.ethAPI)
|
snap = newSnapshot(p.config, p.signatures, number, hash, validators, voteAddrs, p.ethAPI)
|
||||||
if err := snap.store(p.db); err != nil {
|
if snap.Number%checkpointInterval == 0 { // snapshot will only be loaded when snap.Number%checkpointInterval == 0
|
||||||
return nil, err
|
if err := snap.store(p.db); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash)
|
||||||
}
|
}
|
||||||
log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -828,6 +839,13 @@ func (p *Parlia) prepareValidators(header *types.Header) error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
header.Extra = append(header.Extra, byte(len(newValidators)))
|
header.Extra = append(header.Extra, byte(len(newValidators)))
|
||||||
|
if p.chainConfig.IsOnLuban(header.Number) {
|
||||||
|
voteAddressMap = make(map[common.Address]*types.BLSPublicKey, len(newValidators))
|
||||||
|
var zeroBlsKey types.BLSPublicKey
|
||||||
|
for _, validator := range newValidators {
|
||||||
|
voteAddressMap[validator] = &zeroBlsKey
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, validator := range newValidators {
|
for _, validator := range newValidators {
|
||||||
header.Extra = append(header.Extra, validator.Bytes()...)
|
header.Extra = append(header.Extra, validator.Bytes()...)
|
||||||
header.Extra = append(header.Extra, voteAddressMap[validator].Bytes()...)
|
header.Extra = append(header.Extra, voteAddressMap[validator].Bytes()...)
|
||||||
@@ -894,7 +912,7 @@ func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, head
|
|||||||
// Prepare vote address bitset.
|
// Prepare vote address bitset.
|
||||||
for _, valInfo := range snap.Validators {
|
for _, valInfo := range snap.Validators {
|
||||||
if _, ok := voteAddrSet[valInfo.VoteAddress]; ok {
|
if _, ok := voteAddrSet[valInfo.VoteAddress]; ok {
|
||||||
attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) //Index is offset by 1
|
attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) // Index is offset by 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)})
|
validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)})
|
||||||
@@ -989,6 +1007,13 @@ func (p *Parlia) verifyValidators(header *types.Header) error {
|
|||||||
return errMismatchingEpochValidators
|
return errMismatchingEpochValidators
|
||||||
}
|
}
|
||||||
validatorsBytes = make([]byte, validatorsNumber*validatorBytesLength)
|
validatorsBytes = make([]byte, validatorsNumber*validatorBytesLength)
|
||||||
|
if p.chainConfig.IsOnLuban(header.Number) {
|
||||||
|
voteAddressMap = make(map[common.Address]*types.BLSPublicKey, len(newValidators))
|
||||||
|
var zeroBlsKey types.BLSPublicKey
|
||||||
|
for _, validator := range newValidators {
|
||||||
|
voteAddressMap[validator] = &zeroBlsKey
|
||||||
|
}
|
||||||
|
}
|
||||||
for i, validator := range newValidators {
|
for i, validator := range newValidators {
|
||||||
copy(validatorsBytes[i*validatorBytesLength:], validator.Bytes())
|
copy(validatorsBytes[i*validatorBytesLength:], validator.Bytes())
|
||||||
copy(validatorsBytes[i*validatorBytesLength+common.AddressLength:], voteAddressMap[validator].Bytes())
|
copy(validatorsBytes[i*validatorBytesLength+common.AddressLength:], voteAddressMap[validator].Bytes())
|
||||||
@@ -1137,6 +1162,29 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent := chain.GetHeaderByHash(header.ParentHash)
|
||||||
|
if parent == nil {
|
||||||
|
return errors.New("parent not found")
|
||||||
|
}
|
||||||
|
if p.chainConfig.IsOnFeynman(header.Number, parent.Time, header.Time) {
|
||||||
|
err := p.initializeFeynmanContract(state, header, cx, txs, receipts, systemTxs, usedGas, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("init feynman contract failed", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update validators every day
|
||||||
|
if p.chainConfig.IsFeynman(header.Number, header.Time) {
|
||||||
|
// TODO: revert this
|
||||||
|
// if time.Unix(int64(parent.Time), 0).Day() < time.Unix(int64(header.Time), 0).Day() {
|
||||||
|
if time.Unix(int64(header.Time), 0).Minute() != time.Unix(int64(parent.Time), 0).Minute() {
|
||||||
|
if err := p.updateValidatorSetV2(state, header, cx, txs, receipts, systemTxs, usedGas, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(*systemTxs) > 0 {
|
if len(*systemTxs) > 0 {
|
||||||
return errors.New("the length of systemTxs do not match")
|
return errors.New("the length of systemTxs do not match")
|
||||||
}
|
}
|
||||||
@@ -1199,6 +1247,28 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent := chain.GetHeaderByHash(header.ParentHash)
|
||||||
|
if parent == nil {
|
||||||
|
return nil, nil, errors.New("parent not found")
|
||||||
|
}
|
||||||
|
if p.chainConfig.IsOnFeynman(header.Number, parent.Time, header.Time) {
|
||||||
|
err := p.initializeFeynmanContract(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("init feynman contract failed", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update validators every day
|
||||||
|
if p.chainConfig.IsFeynman(header.Number, header.Time) {
|
||||||
|
// TODO: revert this
|
||||||
|
// if time.Unix(int64(parent.Time), 0).Day() < time.Unix(int64(header.Time), 0).Day() {
|
||||||
|
if time.Unix(int64(header.Time), 0).Minute() != time.Unix(int64(parent.Time), 0).Minute() {
|
||||||
|
if err := p.updateValidatorSetV2(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// should not happen. Once happen, stop the node is better than broadcast the block
|
// should not happen. Once happen, stop the node is better than broadcast the block
|
||||||
if header.GasLimit < header.GasUsed {
|
if header.GasLimit < header.GasUsed {
|
||||||
return nil, nil, errors.New("gas consumption of system txs exceed the gas limit")
|
return nil, nil, errors.New("gas consumption of system txs exceed the gas limit")
|
||||||
@@ -1401,7 +1471,7 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res
|
|||||||
select {
|
select {
|
||||||
case results <- block.WithSeal(header):
|
case results <- block.WithSeal(header):
|
||||||
default:
|
default:
|
||||||
log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header, p.chainConfig.ChainID))
|
log.Warn("Sealing result is not read by miner", "sealhash", types.SealHash(header, p.chainConfig.ChainID))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -1475,7 +1545,7 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
|
|||||||
// So it's not the real hash of a block, just used as unique id to distinguish task
|
// So it's not the real hash of a block, just used as unique id to distinguish task
|
||||||
func (p *Parlia) SealHash(header *types.Header) (hash common.Hash) {
|
func (p *Parlia) SealHash(header *types.Header) (hash common.Hash) {
|
||||||
hasher := sha3.NewLegacyKeccak256()
|
hasher := sha3.NewLegacyKeccak256()
|
||||||
encodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
|
types.EncodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
|
||||||
hasher.Sum(hash[:0])
|
hasher.Sum(hash[:0])
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
@@ -1533,16 +1603,15 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNum *big.Int)
|
|||||||
|
|
||||||
var valSet []common.Address
|
var valSet []common.Address
|
||||||
var voteAddrSet []types.BLSPublicKey
|
var voteAddrSet []types.BLSPublicKey
|
||||||
|
|
||||||
if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, result); err != nil {
|
if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, result); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
voteAddrmap := make(map[common.Address]*types.BLSPublicKey, len(valSet))
|
voteAddrMap := make(map[common.Address]*types.BLSPublicKey, len(valSet))
|
||||||
for i := 0; i < len(valSet); i++ {
|
for i := 0; i < len(valSet); i++ {
|
||||||
voteAddrmap[valSet[i]] = &(voteAddrSet)[i]
|
voteAddrMap[valSet[i]] = &(voteAddrSet)[i]
|
||||||
}
|
}
|
||||||
return valSet, voteAddrmap, nil
|
return valSet, voteAddrMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// slash spoiled validators
|
// slash spoiled validators
|
||||||
@@ -1556,9 +1625,10 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he
|
|||||||
state.SetBalance(consensus.SystemAddress, big.NewInt(0))
|
state.SetBalance(consensus.SystemAddress, big.NewInt(0))
|
||||||
state.AddBalance(coinbase, balance)
|
state.AddBalance(coinbase, balance)
|
||||||
|
|
||||||
doDistributeSysReward := state.GetBalance(common.HexToAddress(systemcontracts.SystemRewardContract)).Cmp(maxSystemBalance) < 0
|
doDistributeSysReward := !p.chainConfig.IsKepler(header.Number, header.Time) &&
|
||||||
|
state.GetBalance(common.HexToAddress(systemcontracts.SystemRewardContract)).Cmp(maxSystemBalance) < 0
|
||||||
if doDistributeSysReward {
|
if doDistributeSysReward {
|
||||||
var rewards = new(big.Int)
|
rewards := new(big.Int)
|
||||||
rewards = rewards.Rsh(balance, systemRewardPercent)
|
rewards = rewards.Rsh(balance, systemRewardPercent)
|
||||||
if rewards.Cmp(common.Big0) > 0 {
|
if rewards.Cmp(common.Big0) > 0 {
|
||||||
err := p.distributeToSystem(rewards, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
err := p.distributeToSystem(rewards, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
||||||
@@ -1778,62 +1848,6 @@ func (p *Parlia) GetFinalizedHeader(chain consensus.ChainHeaderReader, header *t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =========================== utility function ==========================
|
// =========================== utility function ==========================
|
||||||
// SealHash returns the hash of a block prior to it being sealed.
|
|
||||||
func SealHash(header *types.Header, chainId *big.Int) (hash common.Hash) {
|
|
||||||
hasher := sha3.NewLegacyKeccak256()
|
|
||||||
encodeSigHeader(hasher, header, chainId)
|
|
||||||
hasher.Sum(hash[:0])
|
|
||||||
return hash
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) {
|
|
||||||
err := rlp.Encode(w, []interface{}{
|
|
||||||
chainId,
|
|
||||||
header.ParentHash,
|
|
||||||
header.UncleHash,
|
|
||||||
header.Coinbase,
|
|
||||||
header.Root,
|
|
||||||
header.TxHash,
|
|
||||||
header.ReceiptHash,
|
|
||||||
header.Bloom,
|
|
||||||
header.Difficulty,
|
|
||||||
header.Number,
|
|
||||||
header.GasLimit,
|
|
||||||
header.GasUsed,
|
|
||||||
header.Time,
|
|
||||||
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
|
|
||||||
header.MixDigest,
|
|
||||||
header.Nonce,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic("can't encode: " + err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeSigHeaderWithoutVoteAttestation(w io.Writer, header *types.Header, chainId *big.Int) {
|
|
||||||
err := rlp.Encode(w, []interface{}{
|
|
||||||
chainId,
|
|
||||||
header.ParentHash,
|
|
||||||
header.UncleHash,
|
|
||||||
header.Coinbase,
|
|
||||||
header.Root,
|
|
||||||
header.TxHash,
|
|
||||||
header.ReceiptHash,
|
|
||||||
header.Bloom,
|
|
||||||
header.Difficulty,
|
|
||||||
header.Number,
|
|
||||||
header.GasLimit,
|
|
||||||
header.GasUsed,
|
|
||||||
header.Time,
|
|
||||||
header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation
|
|
||||||
header.MixDigest,
|
|
||||||
header.Nonce,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic("can't encode: " + err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Address) uint64 {
|
func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Address) uint64 {
|
||||||
if snap.inturn(val) {
|
if snap.inturn(val) {
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -199,6 +199,9 @@ func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *params.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update attestation
|
// Update attestation
|
||||||
|
// Two scenarios for s.Attestation being nil:
|
||||||
|
// 1) The first attestation is assembled.
|
||||||
|
// 2) The snapshot on disk is missing, prompting the creation of a new snapshot using `newSnapshot`.
|
||||||
if s.Attestation != nil && attestation.Data.SourceNumber+1 != attestation.Data.TargetNumber {
|
if s.Attestation != nil && attestation.Data.SourceNumber+1 != attestation.Data.TargetNumber {
|
||||||
s.Attestation.TargetNumber = attestation.Data.TargetNumber
|
s.Attestation.TargetNumber = attestation.Data.TargetNumber
|
||||||
s.Attestation.TargetHash = attestation.Data.TargetHash
|
s.Attestation.TargetHash = attestation.Data.TargetHash
|
||||||
|
|||||||
@@ -552,7 +552,7 @@ func (bc *BlockChain) GetVMConfig() *vm.Config {
|
|||||||
return &bc.vmConfig
|
return &bc.vmConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts) {
|
func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts, block *types.Block) {
|
||||||
// TODO, This is a hot fix for the block hash of logs is `0x0000000000000000000000000000000000000000000000000000000000000000` for system tx
|
// TODO, This is a hot fix for the block hash of logs is `0x0000000000000000000000000000000000000000000000000000000000000000` for system tx
|
||||||
// Please check details in https://github.com/bnb-chain/bsc/issues/443
|
// Please check details in https://github.com/bnb-chain/bsc/issues/443
|
||||||
// This is a temporary fix, the official fix should be a hard fork.
|
// This is a temporary fix, the official fix should be a hard fork.
|
||||||
@@ -563,6 +563,16 @@ func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts) {
|
|||||||
receipts[i].Logs[j].BlockHash = hash
|
receipts[i].Logs[j].BlockHash = hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
txs := block.Transactions()
|
||||||
|
if len(txs) != len(receipts) {
|
||||||
|
log.Warn("transaction and receipt count mismatch")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i, receipt := range receipts {
|
||||||
|
receipt.EffectiveGasPrice = txs[i].EffectiveGasTipValue(block.BaseFee()) // basefee is supposed to be nil or zero
|
||||||
|
}
|
||||||
|
|
||||||
bc.receiptsCache.Add(hash, receipts)
|
bc.receiptsCache.Add(hash, receipts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2049,7 +2059,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||||||
vtime := time.Since(vstart)
|
vtime := time.Since(vstart)
|
||||||
proctime := time.Since(start) // processing + validation
|
proctime := time.Since(start) // processing + validation
|
||||||
|
|
||||||
bc.cacheReceipts(block.Hash(), receipts)
|
|
||||||
bc.cacheBlock(block.Hash(), block)
|
bc.cacheBlock(block.Hash(), block)
|
||||||
|
|
||||||
// Update the metrics touched during block processing and validation
|
// Update the metrics touched during block processing and validation
|
||||||
@@ -2082,6 +2091,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return it.index, err
|
return it.index, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bc.cacheReceipts(block.Hash(), receipts, block)
|
||||||
|
|
||||||
// Update the metrics touched during block commit
|
// Update the metrics touched during block commit
|
||||||
accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them
|
accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them
|
||||||
storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them
|
storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||||||
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
|
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
systemcontracts.UpgradeBuildInSystemContract(config, b.header.Number, statedb)
|
systemcontracts.UpgradeBuildInSystemContract(config, b.header.Number, parent.Time(), b.header.Time, statedb)
|
||||||
// Execute any user modifications to the block
|
// Execute any user modifications to the block
|
||||||
if gen != nil {
|
if gen != nil {
|
||||||
gen(i, b)
|
gen(i, b)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ func preHertzConfig() *params.ChainConfig {
|
|||||||
config.LondonBlock = nil
|
config.LondonBlock = nil
|
||||||
config.BerlinBlock = nil
|
config.BerlinBlock = nil
|
||||||
config.HertzBlock = nil
|
config.HertzBlock = nil
|
||||||
|
config.HertzfixBlock = nil
|
||||||
return &config
|
return &config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -534,7 +534,7 @@ func (g *Genesis) ToBlock() *types.Block {
|
|||||||
var withdrawals []*types.Withdrawal
|
var withdrawals []*types.Withdrawal
|
||||||
if conf := g.Config; conf != nil {
|
if conf := g.Config; conf != nil {
|
||||||
num := big.NewInt(int64(g.Number))
|
num := big.NewInt(int64(g.Number))
|
||||||
if conf.IsShanghai(num, g.Timestamp) {
|
if conf.Parlia == nil && conf.IsShanghai(num, g.Timestamp) {
|
||||||
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
|
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
|
||||||
withdrawals = make([]*types.Withdrawal, 0)
|
withdrawals = make([]*types.Withdrawal, 0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,9 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
|||||||
for i := 0; i < prefetchThread; i++ {
|
for i := 0; i < prefetchThread; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
newStatedb := statedb.CopyDoPrefetch()
|
newStatedb := statedb.CopyDoPrefetch()
|
||||||
newStatedb.EnableWriteOnSharedStorage()
|
if !p.config.IsHertzfix(header.Number) {
|
||||||
|
newStatedb.EnableWriteOnSharedStorage()
|
||||||
|
}
|
||||||
gaspool := new(GasPool).AddGas(block.GasLimit())
|
gaspool := new(GasPool).AddGas(block.GasLimit())
|
||||||
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
||||||
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, *cfg)
|
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, *cfg)
|
||||||
@@ -106,7 +108,9 @@ func (p *statePrefetcher) PrefetchMining(txs TransactionsByPriceAndNonce, header
|
|||||||
go func(startCh <-chan *types.Transaction, stopCh <-chan struct{}) {
|
go func(startCh <-chan *types.Transaction, stopCh <-chan struct{}) {
|
||||||
idx := 0
|
idx := 0
|
||||||
newStatedb := statedb.CopyDoPrefetch()
|
newStatedb := statedb.CopyDoPrefetch()
|
||||||
newStatedb.EnableWriteOnSharedStorage()
|
if !p.config.IsHertzfix(header.Number) {
|
||||||
|
newStatedb.EnableWriteOnSharedStorage()
|
||||||
|
}
|
||||||
gaspool := new(GasPool).AddGas(gasLimit)
|
gaspool := new(GasPool).AddGas(gasLimit)
|
||||||
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
||||||
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
|
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
|
||||||
|
|||||||
@@ -74,7 +74,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
// Handle upgrade build-in system contract code
|
// Handle upgrade build-in system contract code
|
||||||
systemcontracts.UpgradeBuildInSystemContract(p.config, block.Number(), statedb)
|
lastBlock := p.bc.GetBlockByHash(block.ParentHash())
|
||||||
|
if lastBlock == nil {
|
||||||
|
return statedb, nil, nil, 0, fmt.Errorf("could not get parent block")
|
||||||
|
}
|
||||||
|
systemcontracts.UpgradeBuildInSystemContract(p.config, blockNumber, lastBlock.Time(), block.Time(), statedb)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
context = NewEVMBlockContext(header, p.bc, nil)
|
context = NewEVMBlockContext(header, p.bc, nil)
|
||||||
|
|||||||
@@ -13,4 +13,10 @@ const (
|
|||||||
TokenManagerContract = "0x0000000000000000000000000000000000001008"
|
TokenManagerContract = "0x0000000000000000000000000000000000001008"
|
||||||
CrossChainContract = "0x0000000000000000000000000000000000002000"
|
CrossChainContract = "0x0000000000000000000000000000000000002000"
|
||||||
StakingContract = "0x0000000000000000000000000000000000002001"
|
StakingContract = "0x0000000000000000000000000000000000002001"
|
||||||
|
StakeHubContract = "0x0000000000000000000000000000000000002002"
|
||||||
|
StakeCreditContract = "0x0000000000000000000000000000000000002003"
|
||||||
|
GovernorContract = "0x0000000000000000000000000000000000002004"
|
||||||
|
GovTokenContract = "0x0000000000000000000000000000000000002005"
|
||||||
|
TimelockContract = "0x0000000000000000000000000000000000002006"
|
||||||
|
TokenRecoverPortalContract = "0x0000000000000000000000000000000000003000"
|
||||||
)
|
)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1027,6 +1027,9 @@ func (pool *LegacyPool) addRemoteSync(tx *types.Transaction) error {
|
|||||||
|
|
||||||
// addTxs attempts to queue a batch of transactions if they are valid.
|
// addTxs attempts to queue a batch of transactions if they are valid.
|
||||||
func (pool *LegacyPool) addTxs(txs []*types.Transaction, local, sync bool) []error {
|
func (pool *LegacyPool) addTxs(txs []*types.Transaction, local, sync bool) []error {
|
||||||
|
// Do not treat as local if local transactions have been disabled
|
||||||
|
local = local && !pool.config.NoLocals
|
||||||
|
|
||||||
// Filter out known ones without obtaining the pool lock or recovering signatures
|
// Filter out known ones without obtaining the pool lock or recovering signatures
|
||||||
var (
|
var (
|
||||||
errs = make([]error, len(txs))
|
errs = make([]error, len(txs))
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
@@ -560,8 +562,7 @@ func (d *DiffLayer) DecodeRLP(s *rlp.Stream) error {
|
|||||||
if err := s.Decode(&ed); err != nil {
|
if err := s.Decode(&ed); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
d.BlockHash, d.Number, d.Codes, d.Destructs, d.Accounts, d.Storages =
|
d.BlockHash, d.Number, d.Codes, d.Destructs, d.Accounts, d.Storages = ed.BlockHash, ed.Number, ed.Codes, ed.Destructs, ed.Accounts, ed.Storages
|
||||||
ed.BlockHash, ed.Number, ed.Codes, ed.Destructs, ed.Accounts, ed.Storages
|
|
||||||
|
|
||||||
d.Receipts = make([]*Receipt, len(ed.Receipts))
|
d.Receipts = make([]*Receipt, len(ed.Receipts))
|
||||||
for i, storageReceipt := range ed.Receipts {
|
for i, storageReceipt := range ed.Receipts {
|
||||||
@@ -608,6 +609,7 @@ func (storage *DiffStorage) Swap(i, j int) {
|
|||||||
storage.Keys[i], storage.Keys[j] = storage.Keys[j], storage.Keys[i]
|
storage.Keys[i], storage.Keys[j] = storage.Keys[j], storage.Keys[i]
|
||||||
storage.Vals[i], storage.Vals[j] = storage.Vals[j], storage.Vals[i]
|
storage.Vals[i], storage.Vals[j] = storage.Vals[j], storage.Vals[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *DiffStorage) Less(i, j int) bool {
|
func (storage *DiffStorage) Less(i, j int) bool {
|
||||||
return string(storage.Keys[i][:]) < string(storage.Keys[j][:])
|
return string(storage.Keys[i][:]) < string(storage.Keys[j][:])
|
||||||
}
|
}
|
||||||
@@ -622,3 +624,64 @@ type DiffAccountsInBlock struct {
|
|||||||
BlockHash common.Hash
|
BlockHash common.Hash
|
||||||
Transactions []DiffAccountsInTx
|
Transactions []DiffAccountsInTx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
|
||||||
|
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
|
||||||
|
)
|
||||||
|
|
||||||
|
// SealHash returns the hash of a block prior to it being sealed.
|
||||||
|
func SealHash(header *Header, chainId *big.Int) (hash common.Hash) {
|
||||||
|
hasher := sha3.NewLegacyKeccak256()
|
||||||
|
EncodeSigHeader(hasher, header, chainId)
|
||||||
|
hasher.Sum(hash[:0])
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeSigHeader(w io.Writer, header *Header, chainId *big.Int) {
|
||||||
|
err := rlp.Encode(w, []interface{}{
|
||||||
|
chainId,
|
||||||
|
header.ParentHash,
|
||||||
|
header.UncleHash,
|
||||||
|
header.Coinbase,
|
||||||
|
header.Root,
|
||||||
|
header.TxHash,
|
||||||
|
header.ReceiptHash,
|
||||||
|
header.Bloom,
|
||||||
|
header.Difficulty,
|
||||||
|
header.Number,
|
||||||
|
header.GasLimit,
|
||||||
|
header.GasUsed,
|
||||||
|
header.Time,
|
||||||
|
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
|
||||||
|
header.MixDigest,
|
||||||
|
header.Nonce,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic("can't encode: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeSigHeaderWithoutVoteAttestation(w io.Writer, header *Header, chainId *big.Int) {
|
||||||
|
err := rlp.Encode(w, []interface{}{
|
||||||
|
chainId,
|
||||||
|
header.ParentHash,
|
||||||
|
header.UncleHash,
|
||||||
|
header.Coinbase,
|
||||||
|
header.Root,
|
||||||
|
header.TxHash,
|
||||||
|
header.ReceiptHash,
|
||||||
|
header.Bloom,
|
||||||
|
header.Difficulty,
|
||||||
|
header.Number,
|
||||||
|
header.GasLimit,
|
||||||
|
header.GasUsed,
|
||||||
|
header.Time,
|
||||||
|
header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation
|
||||||
|
header.MixDigest,
|
||||||
|
header.Nonce,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic("can't encode: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,23 +17,28 @@
|
|||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
||||||
|
"golang.org/x/crypto/ripemd160"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
||||||
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
||||||
"github.com/ethereum/go-ethereum/crypto/bn256"
|
"github.com/ethereum/go-ethereum/crypto/bn256"
|
||||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/crypto/ripemd160"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrecompiledContract is the basic interface for native Go contracts. The implementation
|
// PrecompiledContract is the basic interface for native Go contracts. The implementation
|
||||||
@@ -219,6 +224,27 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{
|
|||||||
common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
|
common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrecompiledContractsFeynman contains the default set of pre-compiled Ethereum
|
||||||
|
// contracts used in the Feynman release.
|
||||||
|
var PrecompiledContractsFeynman = map[common.Address]PrecompiledContract{
|
||||||
|
common.BytesToAddress([]byte{1}): &ecrecover{},
|
||||||
|
common.BytesToAddress([]byte{2}): &sha256hash{},
|
||||||
|
common.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||||
|
common.BytesToAddress([]byte{4}): &dataCopy{},
|
||||||
|
common.BytesToAddress([]byte{5}): &bigModExp{},
|
||||||
|
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{9}): &blake2F{},
|
||||||
|
|
||||||
|
common.BytesToAddress([]byte{100}): &tmHeaderValidate{},
|
||||||
|
common.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlato{},
|
||||||
|
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
|
||||||
|
common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
|
||||||
|
common.BytesToAddress([]byte{104}): &verifyDoubleSignEvidence{},
|
||||||
|
common.BytesToAddress([]byte{105}): &secp256k1SignatureRecover{},
|
||||||
|
}
|
||||||
|
|
||||||
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
|
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
|
||||||
// contracts specified in EIP-2537. These are exported for testing purposes.
|
// contracts specified in EIP-2537. These are exported for testing purposes.
|
||||||
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
||||||
@@ -245,6 +271,7 @@ var (
|
|||||||
PrecompiledAddressesIstanbul []common.Address
|
PrecompiledAddressesIstanbul []common.Address
|
||||||
PrecompiledAddressesByzantium []common.Address
|
PrecompiledAddressesByzantium []common.Address
|
||||||
PrecompiledAddressesHomestead []common.Address
|
PrecompiledAddressesHomestead []common.Address
|
||||||
|
PrecompiledAddressesFeynman []common.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -281,11 +308,16 @@ func init() {
|
|||||||
for k := range PrecompiledContractsCancun {
|
for k := range PrecompiledContractsCancun {
|
||||||
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
|
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
|
||||||
}
|
}
|
||||||
|
for k := range PrecompiledContractsFeynman {
|
||||||
|
PrecompiledAddressesFeynman = append(PrecompiledAddressesFeynman, k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
||||||
func ActivePrecompiles(rules params.Rules) []common.Address {
|
func ActivePrecompiles(rules params.Rules) []common.Address {
|
||||||
switch {
|
switch {
|
||||||
|
case rules.IsFeynman:
|
||||||
|
return PrecompiledAddressesFeynman
|
||||||
case rules.IsCancun:
|
case rules.IsCancun:
|
||||||
return PrecompiledAddressesCancun
|
return PrecompiledAddressesCancun
|
||||||
case rules.IsHertz:
|
case rules.IsHertz:
|
||||||
@@ -561,7 +593,7 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) {
|
|||||||
// Modulo 0 is undefined, return zero
|
// Modulo 0 is undefined, return zero
|
||||||
return common.LeftPadBytes([]byte{}, int(modLen)), nil
|
return common.LeftPadBytes([]byte{}, int(modLen)), nil
|
||||||
case base.BitLen() == 1: // a bit length of 1 means it's 1 (or -1).
|
case base.BitLen() == 1: // a bit length of 1 means it's 1 (or -1).
|
||||||
//If base == 1, then we can just return base % mod (if mod >= 1, which it is)
|
// If base == 1, then we can just return base % mod (if mod >= 1, which it is)
|
||||||
v = base.Mod(base, mod).Bytes()
|
v = base.Mod(base, mod).Bytes()
|
||||||
default:
|
default:
|
||||||
v = base.Exp(base, exp, mod).Bytes()
|
v = base.Exp(base, exp, mod).Bytes()
|
||||||
@@ -1355,3 +1387,92 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
|
|||||||
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verifyDoubleSignEvidence implements bsc header verification precompile.
|
||||||
|
type verifyDoubleSignEvidence struct{}
|
||||||
|
|
||||||
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||||
|
func (c *verifyDoubleSignEvidence) RequiredGas(input []byte) uint64 {
|
||||||
|
return params.DoubleSignEvidenceVerifyGas
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
extraSeal = 65
|
||||||
|
)
|
||||||
|
|
||||||
|
type DoubleSignEvidence struct {
|
||||||
|
ChainId *big.Int
|
||||||
|
HeaderBytes1 []byte
|
||||||
|
HeaderBytes2 []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run input: rlp encoded DoubleSignEvidence
|
||||||
|
// return:
|
||||||
|
// signer address| evidence time|
|
||||||
|
// 20 bytes | 32 bytes |
|
||||||
|
func (c *verifyDoubleSignEvidence) Run(input []byte) ([]byte, error) {
|
||||||
|
evidence := &DoubleSignEvidence{}
|
||||||
|
err := rlp.DecodeBytes(input, evidence)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
header1 := &types.Header{}
|
||||||
|
err = rlp.DecodeBytes(evidence.HeaderBytes1, header1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
header2 := &types.Header{}
|
||||||
|
err = rlp.DecodeBytes(evidence.HeaderBytes2, header2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic check
|
||||||
|
if header1.Number.Uint64() != header2.Number.Uint64() {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
if header1.ParentHash != header2.ParentHash {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(header1.Extra) < extraSeal || len(header2.Extra) < extraSeal {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
sig1 := header1.Extra[len(header1.Extra)-extraSeal:]
|
||||||
|
sig2 := header2.Extra[len(header2.Extra)-extraSeal:]
|
||||||
|
if bytes.Equal(sig1, sig2) {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
evidenceTime := header1.Time
|
||||||
|
if evidenceTime < header2.Time {
|
||||||
|
evidenceTime = header2.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// check sig
|
||||||
|
msgHash1 := types.SealHash(header1, evidence.ChainId)
|
||||||
|
msgHash2 := types.SealHash(header2, evidence.ChainId)
|
||||||
|
if bytes.Equal(msgHash1.Bytes(), msgHash2.Bytes()) {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
pubkey1, err := secp256k1.RecoverPubkey(msgHash1.Bytes(), sig1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
pubkey2, err := secp256k1.RecoverPubkey(msgHash2.Bytes(), sig2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
if !bytes.Equal(pubkey1, pubkey2) {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
returnBz := make([]byte, 52) // 20 + 32
|
||||||
|
signerAddr := crypto.Keccak256(pubkey1[1:])[12:]
|
||||||
|
evidenceTimeBz := big.NewInt(int64(evidenceTime)).Bytes()
|
||||||
|
copy(returnBz[:20], signerAddr)
|
||||||
|
copy(returnBz[52-len(evidenceTimeBz):], evidenceTimeBz)
|
||||||
|
|
||||||
|
return returnBz, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import (
|
|||||||
|
|
||||||
"github.com/tendermint/iavl"
|
"github.com/tendermint/iavl"
|
||||||
"github.com/tendermint/tendermint/crypto/merkle"
|
"github.com/tendermint/tendermint/crypto/merkle"
|
||||||
|
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
|
|
||||||
|
//nolint:staticcheck
|
||||||
v1 "github.com/ethereum/go-ethereum/core/vm/lightclient/v1"
|
v1 "github.com/ethereum/go-ethereum/core/vm/lightclient/v1"
|
||||||
v2 "github.com/ethereum/go-ethereum/core/vm/lightclient/v2"
|
v2 "github.com/ethereum/go-ethereum/core/vm/lightclient/v2"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
@@ -104,7 +106,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// iavlMerkleProofValidate implemented as a native contract.
|
// iavlMerkleProofValidate implemented as a native contract.
|
||||||
type iavlMerkleProofValidate struct {
|
type iavlMerkleProofValidate struct {
|
||||||
@@ -397,3 +399,40 @@ type cometBFTLightBlockValidateHertz struct {
|
|||||||
func (c *cometBFTLightBlockValidateHertz) Run(input []byte) (result []byte, err error) {
|
func (c *cometBFTLightBlockValidateHertz) Run(input []byte) (result []byte, err error) {
|
||||||
return c.run(input, true)
|
return c.run(input, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// secp256k1SignatureRecover implemented as a native contract.
|
||||||
|
type secp256k1SignatureRecover struct{}
|
||||||
|
|
||||||
|
func (c *secp256k1SignatureRecover) RequiredGas(input []byte) uint64 {
|
||||||
|
return params.EcrecoverGas
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
tmPubKeyLength uint8 = 33
|
||||||
|
tmSignatureLength uint8 = 64
|
||||||
|
tmSignatureMsgHashLength uint8 = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
// input:
|
||||||
|
// | tmPubKey | tmSignature | tmSignatureMsgHash |
|
||||||
|
// | 33 bytes | 64 bytes | 32 bytes |
|
||||||
|
func (c *secp256k1SignatureRecover) Run(input []byte) (result []byte, err error) {
|
||||||
|
if len(input) != int(tmPubKeyLength)+int(tmSignatureLength)+int(tmSignatureMsgHashLength) {
|
||||||
|
return nil, fmt.Errorf("invalid input")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.runTMSecp256k1Signature(
|
||||||
|
input[:tmPubKeyLength],
|
||||||
|
input[tmPubKeyLength:tmPubKeyLength+tmSignatureLength],
|
||||||
|
input[tmPubKeyLength+tmSignatureLength:],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *secp256k1SignatureRecover) runTMSecp256k1Signature(pubkey, signatureStr, msgHash []byte) (result []byte, err error) {
|
||||||
|
tmPubKey := secp256k1.PubKeySecp256k1(pubkey)
|
||||||
|
ok := tmPubKey.VerifyBytesWithMsgHash(msgHash, signatureStr)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("invalid signature")
|
||||||
|
}
|
||||||
|
return tmPubKey.Address().Bytes(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -373,3 +373,42 @@ func TestCometBFTLightBlockValidateHertz(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, expectOutputStr, hex.EncodeToString(res))
|
require.Equal(t, expectOutputStr, hex.EncodeToString(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSecp256k1SignatureRecover(t *testing.T) {
|
||||||
|
// local key
|
||||||
|
{
|
||||||
|
pubKey, err := hex.DecodeString("0278caa4d6321aa856d6341dd3e8bcdfe0b55901548871c63c3f5cec43c2ae88a9")
|
||||||
|
require.NoError(t, err)
|
||||||
|
sig, err := hex.DecodeString("0cb78be0d8eaeab991907b06c61240c04f4ca83f54b7799ce77cf029b837988038c4b3b7f5df231695b0d14499b716e1fd6504860eb3c9244ecb4e569d44c062")
|
||||||
|
require.NoError(t, err)
|
||||||
|
msghash, err := hex.DecodeString("b6ac827edff4bbbf23579720782dbef40b65780af292cc66849e7e5944f1230f")
|
||||||
|
require.NoError(t, err)
|
||||||
|
expectedAddr, err := hex.DecodeString("fa3B227adFf8EA1706098928715076D76959Ae6c")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
input := append(append(pubKey, sig...), msghash...)
|
||||||
|
contract := &secp256k1SignatureRecover{}
|
||||||
|
res, err := contract.Run(input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, expectedAddr, res)
|
||||||
|
}
|
||||||
|
// ledger
|
||||||
|
{
|
||||||
|
pubKey, err := hex.DecodeString("02d63ee39adb1779353b4393dd5ea9d6d2b6df63b71d168571803cc7b9a0a20e98")
|
||||||
|
require.NoError(t, err)
|
||||||
|
sig, err := hex.DecodeString("66bdb5d381b2773c0f569858c7ee143959522d7c1f46dc656c325cb7353ec40c28ec22dff3650b34c096c5b12e702d7237d409f1ebaaa6dd1128a8f2d401fd5b")
|
||||||
|
require.NoError(t, err)
|
||||||
|
msghash, err := hex.DecodeString("c45e8f0dc7c054c31912beeffd6f10f1c585606d61e252e97968cd66661c2571")
|
||||||
|
require.NoError(t, err)
|
||||||
|
expectedAddr, err := hex.DecodeString("65a284146b84210a01add088954bb52d88b230af")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
input := append(append(pubKey, sig...), msghash...)
|
||||||
|
contract := &secp256k1SignatureRecover{}
|
||||||
|
res, err := contract.Run(input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, expectedAddr, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
|
|||||||
common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{},
|
common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{},
|
||||||
common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{},
|
common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{},
|
||||||
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
|
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
|
||||||
|
common.BytesToAddress([]byte{104}): &verifyDoubleSignEvidence{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// EIP-152 test vectors
|
// EIP-152 test vectors
|
||||||
@@ -405,3 +406,14 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
|
|||||||
}
|
}
|
||||||
benchmarkPrecompiled("0f", testcase, b)
|
benchmarkPrecompiled("0f", testcase, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDoubleSignSlash(t *testing.T) {
|
||||||
|
tc := precompiledTest{
|
||||||
|
Input: "f906278202cab9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494976ea74026e726554db657fa54763abd0c3a0aa9a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a804ae755e0fe64b59753f4db6308a1f679747bce186aa2c62b95fa6eeff3fbd08f3b0667e45428a54ade15bad19f49641c499b431b36f65803ea71b379e6b61de501a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094976ea74026e726554db657fa54763abd0c3a0aa9a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a80c0b17bfe88534296ff064cb7156548f6deba2d6310d5044ed6485f087dc6ef232e051c28e1909c2b50a3b4f29345d66681c319bef653e52e5d746480d5a3983b00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000",
|
||||||
|
Expected: "15d34aaf54267db7d7c367839aaf71a00a2c6a65000000000000000000000000000000000000000000000000000000006555fa64",
|
||||||
|
Gas: 1000,
|
||||||
|
Name: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrecompiled("68", tc, t)
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ type (
|
|||||||
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
||||||
var precompiles map[common.Address]PrecompiledContract
|
var precompiles map[common.Address]PrecompiledContract
|
||||||
switch {
|
switch {
|
||||||
|
case evm.chainRules.IsFeynman:
|
||||||
|
precompiles = PrecompiledContractsFeynman
|
||||||
case evm.chainRules.IsCancun:
|
case evm.chainRules.IsCancun:
|
||||||
precompiles = PrecompiledContractsCancun
|
precompiles = PrecompiledContractsCancun
|
||||||
case evm.chainRules.IsHertz:
|
case evm.chainRules.IsHertz:
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func newCancunInstructionSet() JumpTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newShanghaiInstructionSet() JumpTable {
|
func newShanghaiInstructionSet() JumpTable {
|
||||||
instructionSet := newMergeInstructionSet()
|
instructionSet := newLondonInstructionSet()
|
||||||
enable3855(&instructionSet) // PUSH0 instruction
|
enable3855(&instructionSet) // PUSH0 instruction
|
||||||
enable3860(&instructionSet) // Limit and meter initcode
|
enable3860(&instructionSet) // Limit and meter initcode
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ RUN apk add --no-cache ca-certificates npm nodejs bash alpine-sdk expect
|
|||||||
|
|
||||||
RUN git clone https://github.com/bnb-chain/bsc-genesis-contract.git /root/genesis \
|
RUN git clone https://github.com/bnb-chain/bsc-genesis-contract.git /root/genesis \
|
||||||
&& cd /root/genesis && npm install
|
&& cd /root/genesis && npm install
|
||||||
|
#RUN curl -L https://foundry.paradigm.xyz | bash
|
||||||
|
|
||||||
COPY --from=bsc /usr/local/bin/geth /usr/local/bin/geth
|
COPY --from=bsc /usr/local/bin/geth /usr/local/bin/geth
|
||||||
|
|
||||||
|
|||||||
@@ -170,9 +170,9 @@ type TxFetcher struct {
|
|||||||
alternates map[common.Hash]map[string]struct{} // In-flight transaction alternate origins if retrieval fails
|
alternates map[common.Hash]map[string]struct{} // In-flight transaction alternate origins if retrieval fails
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
hasTx func(common.Hash) bool // Retrieves a tx from the local txpool
|
hasTx func(common.Hash) bool // Retrieves a tx from the local txpool
|
||||||
addTxs func([]*txpool.Transaction) []error // Insert a batch of transactions into local txpool
|
addTxs func(string, []*txpool.Transaction) []error // Insert a batch of transactions into local txpool
|
||||||
fetchTxs func(string, []common.Hash) error // Retrieves a set of txs from a remote peer
|
fetchTxs func(string, []common.Hash) error // Retrieves a set of txs from a remote peer
|
||||||
|
|
||||||
step chan struct{} // Notification channel when the fetcher loop iterates
|
step chan struct{} // Notification channel when the fetcher loop iterates
|
||||||
clock mclock.Clock // Time wrapper to simulate in tests
|
clock mclock.Clock // Time wrapper to simulate in tests
|
||||||
@@ -181,14 +181,14 @@ type TxFetcher struct {
|
|||||||
|
|
||||||
// NewTxFetcher creates a transaction fetcher to retrieve transaction
|
// NewTxFetcher creates a transaction fetcher to retrieve transaction
|
||||||
// based on hash announcements.
|
// based on hash announcements.
|
||||||
func NewTxFetcher(hasTx func(common.Hash) bool, addTxs func([]*txpool.Transaction) []error, fetchTxs func(string, []common.Hash) error) *TxFetcher {
|
func NewTxFetcher(hasTx func(common.Hash) bool, addTxs func(string, []*txpool.Transaction) []error, fetchTxs func(string, []common.Hash) error) *TxFetcher {
|
||||||
return NewTxFetcherForTests(hasTx, addTxs, fetchTxs, mclock.System{}, nil)
|
return NewTxFetcherForTests(hasTx, addTxs, fetchTxs, mclock.System{}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTxFetcherForTests is a testing method to mock out the realtime clock with
|
// NewTxFetcherForTests is a testing method to mock out the realtime clock with
|
||||||
// a simulated version and the internal randomness with a deterministic one.
|
// a simulated version and the internal randomness with a deterministic one.
|
||||||
func NewTxFetcherForTests(
|
func NewTxFetcherForTests(
|
||||||
hasTx func(common.Hash) bool, addTxs func([]*txpool.Transaction) []error, fetchTxs func(string, []common.Hash) error,
|
hasTx func(common.Hash) bool, addTxs func(string, []*txpool.Transaction) []error, fetchTxs func(string, []common.Hash) error,
|
||||||
clock mclock.Clock, rand *mrand.Rand) *TxFetcher {
|
clock mclock.Clock, rand *mrand.Rand) *TxFetcher {
|
||||||
return &TxFetcher{
|
return &TxFetcher{
|
||||||
notify: make(chan *txAnnounce),
|
notify: make(chan *txAnnounce),
|
||||||
@@ -300,7 +300,7 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool)
|
|||||||
for j, tx := range batch {
|
for j, tx := range batch {
|
||||||
wrapped[j] = &txpool.Transaction{Tx: tx}
|
wrapped[j] = &txpool.Transaction{Tx: tx}
|
||||||
}
|
}
|
||||||
for j, err := range f.addTxs(wrapped) {
|
for j, err := range f.addTxs(peer, wrapped) {
|
||||||
// Track the transaction hash if the price is too low for us.
|
// Track the transaction hash if the price is too low for us.
|
||||||
// Avoid re-request this transaction when we receive another
|
// Avoid re-request this transaction when we receive another
|
||||||
// announcement.
|
// announcement.
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ func TestTransactionFetcherCleanup(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -417,7 +417,7 @@ func TestTransactionFetcherCleanupEmpty(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -455,7 +455,7 @@ func TestTransactionFetcherMissingRescheduling(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -501,7 +501,7 @@ func TestTransactionFetcherMissingCleanup(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -539,7 +539,7 @@ func TestTransactionFetcherBroadcasts(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -644,7 +644,7 @@ func TestTransactionFetcherTimeoutRescheduling(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -865,7 +865,7 @@ func TestTransactionFetcherUnderpricedDedup(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
errs := make([]error, len(txs))
|
errs := make([]error, len(txs))
|
||||||
for i := 0; i < len(errs); i++ {
|
for i := 0; i < len(errs); i++ {
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
@@ -938,7 +938,7 @@ func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
errs := make([]error, len(txs))
|
errs := make([]error, len(txs))
|
||||||
for i := 0; i < len(errs); i++ {
|
for i := 0; i < len(errs); i++ {
|
||||||
errs[i] = txpool.ErrUnderpriced
|
errs[i] = txpool.ErrUnderpriced
|
||||||
@@ -964,7 +964,7 @@ func TestTransactionFetcherOutOfBoundDeliveries(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -1017,7 +1017,7 @@ func TestTransactionFetcherDrop(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -1083,7 +1083,7 @@ func TestTransactionFetcherDropRescheduling(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -1128,7 +1128,7 @@ func TestTransactionFetcherFuzzCrash01(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -1155,7 +1155,7 @@ func TestTransactionFetcherFuzzCrash02(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -1184,7 +1184,7 @@ func TestTransactionFetcherFuzzCrash03(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
@@ -1217,7 +1217,7 @@ func TestTransactionFetcherFuzzCrash04(t *testing.T) {
|
|||||||
init: func() *TxFetcher {
|
init: func() *TxFetcher {
|
||||||
return NewTxFetcher(
|
return NewTxFetcher(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error {
|
func(string, []common.Hash) error {
|
||||||
|
|||||||
@@ -118,42 +118,40 @@ func TestFilters(t *testing.T) {
|
|||||||
contract = common.Address{0xfe}
|
contract = common.Address{0xfe}
|
||||||
contract2 = common.Address{0xff}
|
contract2 = common.Address{0xff}
|
||||||
abiStr = `[{"inputs":[],"name":"log0","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"}],"name":"log1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"}],"name":"log2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"}],"name":"log3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"},{"internalType":"uint256","name":"t4","type":"uint256"}],"name":"log4","outputs":[],"stateMutability":"nonpayable","type":"function"}]`
|
abiStr = `[{"inputs":[],"name":"log0","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"}],"name":"log1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"}],"name":"log2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"}],"name":"log3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"},{"internalType":"uint256","name":"t4","type":"uint256"}],"name":"log4","outputs":[],"stateMutability":"nonpayable","type":"function"}]`
|
||||||
// BaseFee in BSC is 0 now, use 1Gwei instead for test here to avoid 0 gasPrice
|
|
||||||
gasPrice1Gwei = big.NewInt(params.GWei)
|
|
||||||
/*
|
/*
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.7.0 <0.9.0;
|
pragma solidity >=0.7.0 <0.9.0;
|
||||||
|
|
||||||
contract Logger {
|
contract Logger {
|
||||||
function log0() external {
|
function log0() external {
|
||||||
assembly {
|
assembly {
|
||||||
log0(0, 0)
|
log0(0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log1(uint t1) external {
|
function log1(uint t1) external {
|
||||||
assembly {
|
assembly {
|
||||||
log1(0, 0, t1)
|
log1(0, 0, t1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log2(uint t1, uint t2) external {
|
function log2(uint t1, uint t2) external {
|
||||||
assembly {
|
assembly {
|
||||||
log2(0, 0, t1, t2)
|
log2(0, 0, t1, t2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log3(uint t1, uint t2, uint t3) external {
|
function log3(uint t1, uint t2, uint t3) external {
|
||||||
assembly {
|
assembly {
|
||||||
log3(0, 0, t1, t2, t3)
|
log3(0, 0, t1, t2, t3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log4(uint t1, uint t2, uint t3, uint t4) external {
|
function log4(uint t1, uint t2, uint t3, uint t4) external {
|
||||||
assembly {
|
assembly {
|
||||||
log4(0, 0, t1, t2, t3, t4)
|
log4(0, 0, t1, t2, t3, t4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
bytecode = common.FromHex("608060405234801561001057600080fd5b50600436106100575760003560e01c80630aa731851461005c5780632a4c08961461006657806378b9a1f314610082578063c670f8641461009e578063c683d6a3146100ba575b600080fd5b6100646100d6565b005b610080600480360381019061007b9190610143565b6100dc565b005b61009c60048036038101906100979190610196565b6100e8565b005b6100b860048036038101906100b391906101d6565b6100f2565b005b6100d460048036038101906100cf9190610203565b6100fa565b005b600080a0565b808284600080a3505050565b8082600080a25050565b80600080a150565b80828486600080a450505050565b600080fd5b6000819050919050565b6101208161010d565b811461012b57600080fd5b50565b60008135905061013d81610117565b92915050565b60008060006060848603121561015c5761015b610108565b5b600061016a8682870161012e565b935050602061017b8682870161012e565b925050604061018c8682870161012e565b9150509250925092565b600080604083850312156101ad576101ac610108565b5b60006101bb8582860161012e565b92505060206101cc8582860161012e565b9150509250929050565b6000602082840312156101ec576101eb610108565b5b60006101fa8482850161012e565b91505092915050565b6000806000806080858703121561021d5761021c610108565b5b600061022b8782880161012e565b945050602061023c8782880161012e565b935050604061024d8782880161012e565b925050606061025e8782880161012e565b9150509295919450925056fea264697066735822122073a4b156f487e59970dc1ef449cc0d51467268f676033a17188edafcee861f9864736f6c63430008110033")
|
bytecode = common.FromHex("608060405234801561001057600080fd5b50600436106100575760003560e01c80630aa731851461005c5780632a4c08961461006657806378b9a1f314610082578063c670f8641461009e578063c683d6a3146100ba575b600080fd5b6100646100d6565b005b610080600480360381019061007b9190610143565b6100dc565b005b61009c60048036038101906100979190610196565b6100e8565b005b6100b860048036038101906100b391906101d6565b6100f2565b005b6100d460048036038101906100cf9190610203565b6100fa565b005b600080a0565b808284600080a3505050565b8082600080a25050565b80600080a150565b80828486600080a450505050565b600080fd5b6000819050919050565b6101208161010d565b811461012b57600080fd5b50565b60008135905061013d81610117565b92915050565b60008060006060848603121561015c5761015b610108565b5b600061016a8682870161012e565b935050602061017b8682870161012e565b925050604061018c8682870161012e565b9150509250925092565b600080604083850312156101ad576101ac610108565b5b60006101bb8582860161012e565b92505060206101cc8582860161012e565b9150509250929050565b6000602082840312156101ec576101eb610108565b5b60006101fa8482850161012e565b91505092915050565b6000806000806080858703121561021d5761021c610108565b5b600061022b8782880161012e565b945050602061023c8782880161012e565b935050604061024d8782880161012e565b925050606061025e8782880161012e565b9150509295919450925056fea264697066735822122073a4b156f487e59970dc1ef449cc0d51467268f676033a17188edafcee861f9864736f6c63430008110033")
|
||||||
@@ -171,9 +169,7 @@ func TestFilters(t *testing.T) {
|
|||||||
contract: {Balance: big.NewInt(0), Code: bytecode},
|
contract: {Balance: big.NewInt(0), Code: bytecode},
|
||||||
contract2: {Balance: big.NewInt(0), Code: bytecode},
|
contract2: {Balance: big.NewInt(0), Code: bytecode},
|
||||||
},
|
},
|
||||||
// Ethereum's InitialBaseFee is 1000000000, while BSC is 0, here is to fix CI
|
BaseFee: big.NewInt(params.InitialBaseFeeForEthMainnet),
|
||||||
// BaseFee: big.NewInt(params.InitialBaseFee),
|
|
||||||
BaseFee: gasPrice1Gwei,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -197,7 +193,7 @@ func TestFilters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
GasPrice: gasPrice1Gwei,
|
GasPrice: gen.BaseFee(),
|
||||||
Gas: 30000,
|
Gas: 30000,
|
||||||
To: &contract,
|
To: &contract,
|
||||||
Data: data,
|
Data: data,
|
||||||
@@ -205,7 +201,7 @@ func TestFilters(t *testing.T) {
|
|||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
tx2, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
tx2, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
||||||
Nonce: 1,
|
Nonce: 1,
|
||||||
GasPrice: gasPrice1Gwei,
|
GasPrice: gen.BaseFee(),
|
||||||
Gas: 30000,
|
Gas: 30000,
|
||||||
To: &contract2,
|
To: &contract2,
|
||||||
Data: data,
|
Data: data,
|
||||||
@@ -218,7 +214,7 @@ func TestFilters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
||||||
Nonce: 2,
|
Nonce: 2,
|
||||||
GasPrice: gasPrice1Gwei,
|
GasPrice: gen.BaseFee(),
|
||||||
Gas: 30000,
|
Gas: 30000,
|
||||||
To: &contract,
|
To: &contract,
|
||||||
Data: data,
|
Data: data,
|
||||||
@@ -231,7 +227,7 @@ func TestFilters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
||||||
Nonce: 3,
|
Nonce: 3,
|
||||||
GasPrice: gasPrice1Gwei,
|
GasPrice: gen.BaseFee(),
|
||||||
Gas: 30000,
|
Gas: 30000,
|
||||||
To: &contract2,
|
To: &contract2,
|
||||||
Data: data,
|
Data: data,
|
||||||
@@ -244,7 +240,7 @@ func TestFilters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
|
||||||
Nonce: 4,
|
Nonce: 4,
|
||||||
GasPrice: gasPrice1Gwei,
|
GasPrice: gen.BaseFee(),
|
||||||
Gas: 30000,
|
Gas: 30000,
|
||||||
To: &contract,
|
To: &contract,
|
||||||
Data: data,
|
Data: data,
|
||||||
@@ -290,61 +286,74 @@ func TestFilters(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil),
|
f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0x0dc0e230687c0b67421b862b6ac7af9d21c157fd5f41d35266bf148f21c754b4","transactionIndex":"0x0","blockHash":"0x552c4d4884746b710049d85c8d6e3c420ff021ff65244672fcdcd82154c9292b","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}, false),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}, false),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0x251cd3065f17245a0a6d528d74ae8bd6f008813e19319d14154bfda99b2e742d","transactionIndex":"0x0","blockHash":"0x41f1a563f54d6ce4330db1ad87c51b8ac3b68b9379e35b51e8c5e9b030b1f1b1","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0x0dc0e230687c0b67421b862b6ac7af9d21c157fd5f41d35266bf148f21c754b4","transactionIndex":"0x0","blockHash":"0x552c4d4884746b710049d85c8d6e3c420ff021ff65244672fcdcd82154c9292b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x71bbc18e2797e26e27fef2e9dd6a65e1eff6421735e9568ea805fc4a57f20482","transactionIndex":"0x0","blockHash":"0x7f0be2e908e7a6b2bcbab9dc574a9050338ed6c6db592bd97be21d4f1a69518a","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}, false),
|
f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}, false),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}, false),
|
f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}, false),
|
||||||
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0xcaea5cabe64d59ac0c74ca2eed41b1ef36dc996415ca085396d0f5acb0094935","transactionIndex":"0x0","blockHash":"0xf926a72aac711b12c385bdb7e935c49c3b77b4a857e4c924d9bfcf940694f3c1","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}, false),
|
f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}, false),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0x0dc0e230687c0b67421b862b6ac7af9d21c157fd5f41d35266bf148f21c754b4","transactionIndex":"0x0","blockHash":"0x552c4d4884746b710049d85c8d6e3c420ff021ff65244672fcdcd82154c9292b","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}, false),
|
f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}, false),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0x251cd3065f17245a0a6d528d74ae8bd6f008813e19319d14154bfda99b2e742d","transactionIndex":"0x0","blockHash":"0x41f1a563f54d6ce4330db1ad87c51b8ac3b68b9379e35b51e8c5e9b030b1f1b1","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0x7afd31c9d543a1056ca2d35ce106408f1cb925546fc3a97f337122ca5a9e515e","transactionIndex":"0x1","blockHash":"0x41f1a563f54d6ce4330db1ad87c51b8ac3b68b9379e35b51e8c5e9b030b1f1b1","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0x0dc0e230687c0b67421b862b6ac7af9d21c157fd5f41d35266bf148f21c754b4","transactionIndex":"0x0","blockHash":"0x552c4d4884746b710049d85c8d6e3c420ff021ff65244672fcdcd82154c9292b","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}, false),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}, false),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil, false),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil, false),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}, false),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}, false),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false),
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x71bbc18e2797e26e27fef2e9dd6a65e1eff6421735e9568ea805fc4a57f20482","transactionIndex":"0x0","blockHash":"0x7f0be2e908e7a6b2bcbab9dc574a9050338ed6c6db592bd97be21d4f1a69518a","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
// BSC's finalize logic is different from Ethereum, it is achieved from snapshot, no SetFinalized
|
|
||||||
// So skip finality related cases
|
|
||||||
{
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false),
|
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false),
|
||||||
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0xcaea5cabe64d59ac0c74ca2eed41b1ef36dc996415ca085396d0f5acb0094935","transactionIndex":"0x0","blockHash":"0xf926a72aac711b12c385bdb7e935c49c3b77b4a857e4c924d9bfcf940694f3c1","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x71bbc18e2797e26e27fef2e9dd6a65e1eff6421735e9568ea805fc4a57f20482","transactionIndex":"0x0","blockHash":"0x7f0be2e908e7a6b2bcbab9dc574a9050338ed6c6db592bd97be21d4f1a69518a","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil, false),
|
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil, false),
|
||||||
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0xcaea5cabe64d59ac0c74ca2eed41b1ef36dc996415ca085396d0f5acb0094935","transactionIndex":"0x0","blockHash":"0xf926a72aac711b12c385bdb7e935c49c3b77b4a857e4c924d9bfcf940694f3c1","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil, false),
|
{
|
||||||
}, {
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
|
||||||
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false),
|
},
|
||||||
|
{
|
||||||
|
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
||||||
err: "safe header not found",
|
err: "safe header not found",
|
||||||
}, {
|
},
|
||||||
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil, false),
|
{
|
||||||
|
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
|
||||||
err: "safe header not found",
|
err: "safe header not found",
|
||||||
}, {
|
},
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil, false),
|
{
|
||||||
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
|
||||||
err: "safe header not found",
|
err: "safe header not found",
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false),
|
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0xb2bb61fcb8a26dae28e833ba97e2e87cfb8d3dcdfe77f9375b8a5a2e62a890e9","transactionIndex":"0x0","blockHash":"0x53a4ca36e4e3108ce28f140f80327c4851a5eb5717abd8324d3bb6fc07fdc328","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xc7245899e5817f16fa99cf5ad2d9c1e4b98443a565a673ec9c764640443ef037","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false),
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, false),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x71bbc18e2797e26e27fef2e9dd6a65e1eff6421735e9568ea805fc4a57f20482","transactionIndex":"0x0","blockHash":"0x7f0be2e908e7a6b2bcbab9dc574a9050338ed6c6db592bd97be21d4f1a69518a","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0xb2bb61fcb8a26dae28e833ba97e2e87cfb8d3dcdfe77f9375b8a5a2e62a890e9","transactionIndex":"0x0","blockHash":"0x53a4ca36e4e3108ce28f140f80327c4851a5eb5717abd8324d3bb6fc07fdc328","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xc7245899e5817f16fa99cf5ad2d9c1e4b98443a565a673ec9c764640443ef037","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false),
|
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, false),
|
||||||
err: "invalid block range",
|
err: "invalid block range",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
|
|||||||
config.LubanBlock = nil
|
config.LubanBlock = nil
|
||||||
config.PlatoBlock = nil
|
config.PlatoBlock = nil
|
||||||
config.HertzBlock = nil
|
config.HertzBlock = nil
|
||||||
|
config.HertzfixBlock = nil
|
||||||
config.TerminalTotalDifficulty = common.Big0
|
config.TerminalTotalDifficulty = common.Big0
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/monitor"
|
"github.com/ethereum/go-ethereum/core/monitor"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/txpool"
|
"github.com/ethereum/go-ethereum/core/txpool"
|
||||||
|
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/eth/fetcher"
|
"github.com/ethereum/go-ethereum/eth/fetcher"
|
||||||
@@ -65,7 +66,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
syncChallengeTimeout = 15 * time.Second // Time allowance for a node to reply to the sync progress challenge
|
syncChallengeTimeout = 15 * time.Second // Time allowance for a node to reply to the sync progress challenge
|
||||||
|
accountBlacklistPeerCounter = metrics.NewRegisteredCounter("eth/count/blacklist", nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// txPool defines the methods needed from a transaction pool implementation to
|
// txPool defines the methods needed from a transaction pool implementation to
|
||||||
@@ -342,8 +344,21 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
|||||||
}
|
}
|
||||||
return p.RequestTxs(hashes)
|
return p.RequestTxs(hashes)
|
||||||
}
|
}
|
||||||
addTxs := func(txs []*txpool.Transaction) []error {
|
addTxs := func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return h.txpool.Add(txs, false, false)
|
errors := h.txpool.Add(txs, false, false)
|
||||||
|
for _, err := range errors {
|
||||||
|
if err == legacypool.ErrInBlackList {
|
||||||
|
accountBlacklistPeerCounter.Inc(1)
|
||||||
|
p := h.peers.peer(peer)
|
||||||
|
if p != nil {
|
||||||
|
remoteAddr := p.remoteAddr()
|
||||||
|
if remoteAddr != nil {
|
||||||
|
log.Warn("blacklist account detected from other peer", "remoteAddr", remoteAddr, "ID", p.ID())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors
|
||||||
}
|
}
|
||||||
h.txFetcher = fetcher.NewTxFetcher(h.txpool.Has, addTxs, fetchTx)
|
h.txFetcher = fetcher.NewTxFetcher(h.txpool.Has, addTxs, fetchTx)
|
||||||
h.chainSync = newChainSyncer(h)
|
h.chainSync = newChainSyncer(h)
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/eth/protocols/bsc"
|
"github.com/ethereum/go-ethereum/eth/protocols/bsc"
|
||||||
"github.com/ethereum/go-ethereum/eth/protocols/trust"
|
"github.com/ethereum/go-ethereum/eth/protocols/trust"
|
||||||
|
|
||||||
@@ -45,6 +47,13 @@ func (p *ethPeer) info() *ethPeerInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ethPeer) remoteAddr() net.Addr {
|
||||||
|
if p.Peer != nil && p.Peer.Peer != nil {
|
||||||
|
return p.Peer.Peer.RemoteAddr()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// snapPeerInfo represents a short summary of the `snap` sub-protocol metadata known
|
// snapPeerInfo represents a short summary of the `snap` sub-protocol metadata known
|
||||||
// about a connected peer.
|
// about a connected peer.
|
||||||
type snapPeerInfo struct {
|
type snapPeerInfo struct {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/cockroachdb/errors"
|
||||||
"github.com/cockroachdb/pebble"
|
"github.com/cockroachdb/pebble"
|
||||||
"github.com/cockroachdb/pebble/bloom"
|
"github.com/cockroachdb/pebble/bloom"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@@ -116,6 +117,16 @@ func (d *Database) onWriteStallEnd() {
|
|||||||
d.writeDelayTime.Add(int64(time.Since(d.writeDelayStartTime)))
|
d.writeDelayTime.Add(int64(time.Since(d.writeDelayStartTime)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// panicLogger is just a noop logger to disable Pebble's internal logger.
|
||||||
|
type panicLogger struct{}
|
||||||
|
|
||||||
|
func (l panicLogger) Infof(format string, args ...interface{}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l panicLogger) Fatalf(format string, args ...interface{}) {
|
||||||
|
panic(errors.Errorf("fatal: "+format, args...))
|
||||||
|
}
|
||||||
|
|
||||||
// New returns a wrapped pebble DB object. The namespace is the prefix that the
|
// New returns a wrapped pebble DB object. The namespace is the prefix that the
|
||||||
// metrics reporting should use for surfacing internal stats.
|
// metrics reporting should use for surfacing internal stats.
|
||||||
func New(file string, cache int, handles int, namespace string, readonly bool) (*Database, error) {
|
func New(file string, cache int, handles int, namespace string, readonly bool) (*Database, error) {
|
||||||
@@ -127,7 +138,6 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
|
|||||||
handles = minHandles
|
handles = minHandles
|
||||||
}
|
}
|
||||||
logger := log.New("database", file)
|
logger := log.New("database", file)
|
||||||
logger.Info("Allocated cache and file handles", "cache", common.StorageSize(cache*1024*1024), "handles", handles)
|
|
||||||
|
|
||||||
// The max memtable size is limited by the uint32 offsets stored in
|
// The max memtable size is limited by the uint32 offsets stored in
|
||||||
// internal/arenaskl.node, DeferredBatchOp, and flushableBatchEntry.
|
// internal/arenaskl.node, DeferredBatchOp, and flushableBatchEntry.
|
||||||
@@ -141,6 +151,10 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
|
|||||||
if memTableSize > maxMemTableSize {
|
if memTableSize > maxMemTableSize {
|
||||||
memTableSize = maxMemTableSize
|
memTableSize = maxMemTableSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Info("Allocated cache and file handles", "cache", common.StorageSize(cache*1024*1024),
|
||||||
|
"handles", handles, "memory table", common.StorageSize(memTableSize))
|
||||||
|
|
||||||
db := &Database{
|
db := &Database{
|
||||||
fn: file,
|
fn: file,
|
||||||
log: logger,
|
log: logger,
|
||||||
@@ -155,7 +169,7 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
|
|||||||
|
|
||||||
// The size of memory table(as well as the write buffer).
|
// The size of memory table(as well as the write buffer).
|
||||||
// Note, there may have more than two memory tables in the system.
|
// Note, there may have more than two memory tables in the system.
|
||||||
MemTableSize: memTableSize,
|
MemTableSize: uint64(memTableSize),
|
||||||
|
|
||||||
// MemTableStopWritesThreshold places a hard limit on the size
|
// MemTableStopWritesThreshold places a hard limit on the size
|
||||||
// of the existent MemTables(including the frozen one).
|
// of the existent MemTables(including the frozen one).
|
||||||
@@ -170,15 +184,6 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
|
|||||||
|
|
||||||
// Per-level options. Options for at least one level must be specified. The
|
// Per-level options. Options for at least one level must be specified. The
|
||||||
// options for the last level are used for all subsequent levels.
|
// options for the last level are used for all subsequent levels.
|
||||||
Levels: []pebble.LevelOptions{
|
|
||||||
{TargetFileSize: 2 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)},
|
|
||||||
{TargetFileSize: 2 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)},
|
|
||||||
{TargetFileSize: 2 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)},
|
|
||||||
{TargetFileSize: 2 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)},
|
|
||||||
{TargetFileSize: 2 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)},
|
|
||||||
{TargetFileSize: 2 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)},
|
|
||||||
{TargetFileSize: 2 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)},
|
|
||||||
},
|
|
||||||
ReadOnly: readonly,
|
ReadOnly: readonly,
|
||||||
EventListener: &pebble.EventListener{
|
EventListener: &pebble.EventListener{
|
||||||
CompactionBegin: db.onCompactionBegin,
|
CompactionBegin: db.onCompactionBegin,
|
||||||
@@ -186,7 +191,21 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
|
|||||||
WriteStallBegin: db.onWriteStallBegin,
|
WriteStallBegin: db.onWriteStallBegin,
|
||||||
WriteStallEnd: db.onWriteStallEnd,
|
WriteStallEnd: db.onWriteStallEnd,
|
||||||
},
|
},
|
||||||
|
Logger: panicLogger{}, // TODO(karalabe): Delete when this is upstreamed in Pebble
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(opt.Levels); i++ {
|
||||||
|
l := &opt.Levels[i]
|
||||||
|
l.BlockSize = 32 << 10 // 32 KB
|
||||||
|
l.IndexBlockSize = 256 << 10 // 256 KB
|
||||||
|
l.FilterPolicy = bloom.FilterPolicy(10)
|
||||||
|
l.FilterType = pebble.TableFilter
|
||||||
|
if i > 0 {
|
||||||
|
l.TargetFileSize = opt.Levels[i-1].TargetFileSize * 2
|
||||||
|
}
|
||||||
|
l.EnsureDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
// Disable seek compaction explicitly. Check https://github.com/ethereum/go-ethereum/pull/20130
|
// Disable seek compaction explicitly. Check https://github.com/ethereum/go-ethereum/pull/20130
|
||||||
// for more details.
|
// for more details.
|
||||||
opt.Experimental.ReadSamplingMultiplier = -1
|
opt.Experimental.ReadSamplingMultiplier = -1
|
||||||
@@ -305,9 +324,9 @@ func (d *Database) NewBatch() ethdb.Batch {
|
|||||||
// It's not supported by pebble, but pebble has better memory allocation strategy
|
// It's not supported by pebble, but pebble has better memory allocation strategy
|
||||||
// which turns out a lot faster than leveldb. It's performant enough to construct
|
// which turns out a lot faster than leveldb. It's performant enough to construct
|
||||||
// batch object without any pre-allocated space.
|
// batch object without any pre-allocated space.
|
||||||
func (d *Database) NewBatchWithSize(_ int) ethdb.Batch {
|
func (d *Database) NewBatchWithSize(size int) ethdb.Batch {
|
||||||
return &batch{
|
return &batch{
|
||||||
b: d.db.NewBatch(),
|
b: d.db.NewBatchWithSize(size),
|
||||||
db: d,
|
db: d,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -576,7 +595,7 @@ type pebbleIterator struct {
|
|||||||
// of database content with a particular key prefix, starting at a particular
|
// of database content with a particular key prefix, starting at a particular
|
||||||
// initial key (or after, if it does not exist).
|
// initial key (or after, if it does not exist).
|
||||||
func (d *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
|
func (d *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
|
||||||
iter := d.db.NewIter(&pebble.IterOptions{
|
iter, _ := d.db.NewIter(&pebble.IterOptions{
|
||||||
LowerBound: append(prefix, start...),
|
LowerBound: append(prefix, start...),
|
||||||
UpperBound: upperBound(prefix),
|
UpperBound: upperBound(prefix),
|
||||||
})
|
})
|
||||||
|
|||||||
7
go.mod
7
go.mod
@@ -13,7 +13,8 @@ require (
|
|||||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2
|
github.com/btcsuite/btcd/btcec/v2 v2.3.2
|
||||||
github.com/cespare/cp v1.1.1
|
github.com/cespare/cp v1.1.1
|
||||||
github.com/cloudflare/cloudflare-go v0.14.0
|
github.com/cloudflare/cloudflare-go v0.14.0
|
||||||
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06
|
github.com/cockroachdb/errors v1.9.1
|
||||||
|
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593
|
||||||
github.com/cometbft/cometbft v0.37.0
|
github.com/cometbft/cometbft v0.37.0
|
||||||
github.com/consensys/gnark-crypto v0.10.0
|
github.com/consensys/gnark-crypto v0.10.0
|
||||||
github.com/crate-crypto/go-kzg-4844 v0.3.0
|
github.com/crate-crypto/go-kzg-4844 v0.3.0
|
||||||
@@ -109,9 +110,9 @@ require (
|
|||||||
github.com/cespare/xxhash v1.1.0 // indirect
|
github.com/cespare/xxhash v1.1.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/chzyer/readline v1.5.1 // indirect
|
github.com/chzyer/readline v1.5.1 // indirect
|
||||||
github.com/cockroachdb/errors v1.9.1 // indirect
|
|
||||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
||||||
github.com/cockroachdb/redact v1.1.3 // indirect
|
github.com/cockroachdb/redact v1.1.3 // indirect
|
||||||
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
||||||
github.com/consensys/bavard v0.1.13 // indirect
|
github.com/consensys/bavard v0.1.13 // indirect
|
||||||
github.com/containerd/cgroups v1.1.0 // indirect
|
github.com/containerd/cgroups v1.1.0 // indirect
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||||
@@ -294,5 +295,5 @@ replace (
|
|||||||
github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2
|
github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1
|
github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1
|
||||||
github.com/syndtr/goleveldb v1.0.1 => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
github.com/syndtr/goleveldb v1.0.1 => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
||||||
github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15
|
github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.16
|
||||||
)
|
)
|
||||||
|
|||||||
12
go.sum
12
go.sum
@@ -188,8 +188,8 @@ github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2 h1
|
|||||||
github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs=
|
github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs=
|
||||||
github.com/bnb-chain/ics23 v0.1.0 h1:DvjGOts2FBfbxB48384CYD1LbcrfjThFz8kowY/7KxU=
|
github.com/bnb-chain/ics23 v0.1.0 h1:DvjGOts2FBfbxB48384CYD1LbcrfjThFz8kowY/7KxU=
|
||||||
github.com/bnb-chain/ics23 v0.1.0/go.mod h1:cU6lTGolbbLFsGCgceNB2AzplH1xecLp6+KXvxM32nI=
|
github.com/bnb-chain/ics23 v0.1.0/go.mod h1:cU6lTGolbbLFsGCgceNB2AzplH1xecLp6+KXvxM32nI=
|
||||||
github.com/bnb-chain/tendermint v0.31.15 h1:Xyn/Hifb/7X4E1zSuMdnZdMSoM2Fx6cZuKCNnqIxbNU=
|
github.com/bnb-chain/tendermint v0.31.16 h1:rOO6WG61JDAuRCCL8TKnGhorJftQDVygq0mqR7A0ck4=
|
||||||
github.com/bnb-chain/tendermint v0.31.15/go.mod h1:cmt8HHmQUSVaWQ/hoTefRxsh5X3ERaM1zCUIR0DPbFU=
|
github.com/bnb-chain/tendermint v0.31.16/go.mod h1:cmt8HHmQUSVaWQ/hoTefRxsh5X3ERaM1zCUIR0DPbFU=
|
||||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||||
@@ -247,16 +247,18 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
|
|||||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
|
github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
|
||||||
github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o=
|
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
|
||||||
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
|
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
|
||||||
github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk=
|
github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk=
|
||||||
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
||||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
|
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
|
||||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
||||||
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06 h1:T+Np/xtzIjYM/P5NAw0e2Rf1FGvzDau1h54MKvx8G7w=
|
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A=
|
||||||
github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06/go.mod h1:bynZ3gvVyhlvjLI7PT6dmZ7g76xzJ7HpxfjgkzCGz6s=
|
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo=
|
||||||
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
|
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
|
||||||
github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
|
github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
|
||||||
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
|
||||||
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
|
||||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||||
github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=
|
github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package log
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -105,6 +106,7 @@ func Error(msg string, ctx ...interface{}) {
|
|||||||
// log.Crit("msg", "key1", val1, "key2", val2)
|
// log.Crit("msg", "key1", val1, "key2", val2)
|
||||||
func Crit(msg string, ctx ...interface{}) {
|
func Crit(msg string, ctx ...interface{}) {
|
||||||
root.write(msg, LvlCrit, ctx, skipLevel)
|
root.write(msg, LvlCrit, ctx, skipLevel)
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -711,11 +711,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||||||
gasLimit := env.header.GasLimit
|
gasLimit := env.header.GasLimit
|
||||||
if env.gasPool == nil {
|
if env.gasPool == nil {
|
||||||
env.gasPool = new(core.GasPool).AddGas(gasLimit)
|
env.gasPool = new(core.GasPool).AddGas(gasLimit)
|
||||||
if w.chain.Config().IsEuler(env.header.Number) {
|
env.gasPool.SubGas(params.SystemTxsGas * 5)
|
||||||
env.gasPool.SubGas(params.SystemTxsGas * 3)
|
|
||||||
} else {
|
|
||||||
env.gasPool.SubGas(params.SystemTxsGas)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var coalescedLogs []*types.Log
|
var coalescedLogs []*types.Log
|
||||||
@@ -728,7 +724,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||||||
|
|
||||||
stopPrefetchCh := make(chan struct{})
|
stopPrefetchCh := make(chan struct{})
|
||||||
defer close(stopPrefetchCh)
|
defer close(stopPrefetchCh)
|
||||||
//prefetch txs from all pending txs
|
// prefetch txs from all pending txs
|
||||||
txsPrefetch := txs.Copy()
|
txsPrefetch := txs.Copy()
|
||||||
tx := txsPrefetch.PeekWithUnwrap()
|
tx := txsPrefetch.PeekWithUnwrap()
|
||||||
if tx != nil {
|
if tx != nil {
|
||||||
@@ -914,7 +910,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle upgrade build-in system contract code
|
// Handle upgrade build-in system contract code
|
||||||
systemcontracts.UpgradeBuildInSystemContract(w.chainConfig, header.Number, env.state)
|
systemcontracts.UpgradeBuildInSystemContract(w.chainConfig, header.Number, parent.Time, header.Time, env.state)
|
||||||
|
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
@@ -1163,12 +1159,14 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti
|
|||||||
if interval != nil {
|
if interval != nil {
|
||||||
interval()
|
interval()
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
err := env.state.WaitPipeVerification()
|
err := env.state.WaitPipeVerification()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
env.state.CorrectAccountsRoot(w.chain.CurrentBlock().Root)
|
env.state.CorrectAccountsRoot(w.chain.CurrentBlock().Root)
|
||||||
|
*/
|
||||||
|
|
||||||
// Withdrawals are set to nil here, because this is only called in PoW.
|
// Withdrawals are set to nil here, because this is only called in PoW.
|
||||||
finalizeStart := time.Now()
|
finalizeStart := time.Now()
|
||||||
|
|||||||
@@ -210,6 +210,9 @@ func (p *Peer) RemoteAddr() net.Addr {
|
|||||||
}
|
}
|
||||||
log.Warn("RemoteAddr", "invalid testRemoteAddr", p.testRemoteAddr)
|
log.Warn("RemoteAddr", "invalid testRemoteAddr", p.testRemoteAddr)
|
||||||
}
|
}
|
||||||
|
if p.rw == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return p.rw.fd.RemoteAddr()
|
return p.rw.fd.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
148
params/config.go
148
params/config.go
@@ -159,15 +159,18 @@ var (
|
|||||||
MoranBlock: big.NewInt(22107423),
|
MoranBlock: big.NewInt(22107423),
|
||||||
GibbsBlock: big.NewInt(23846001),
|
GibbsBlock: big.NewInt(23846001),
|
||||||
PlanckBlock: big.NewInt(27281024),
|
PlanckBlock: big.NewInt(27281024),
|
||||||
|
LubanBlock: big.NewInt(29020050),
|
||||||
|
PlatoBlock: big.NewInt(30720096),
|
||||||
|
BerlinBlock: big.NewInt(31302048),
|
||||||
|
LondonBlock: big.NewInt(31302048),
|
||||||
|
HertzBlock: big.NewInt(31302048),
|
||||||
|
HertzfixBlock: big.NewInt(34140700),
|
||||||
|
// UnixTime: 1705996800 is January 23, 2024 8:00:00 AM UTC
|
||||||
|
ShanghaiTime: newUint64(1705996800),
|
||||||
|
KeplerTime: newUint64(1705996800),
|
||||||
|
|
||||||
// TODO modify blockNumber, make sure the blockNumber is not an integer multiple of 200 (epoch number)
|
// TODO
|
||||||
// TODO Caution !!! it should be very careful !!!
|
FeynmanTime: nil,
|
||||||
LubanBlock: big.NewInt(29020050),
|
|
||||||
PlatoBlock: big.NewInt(30720096),
|
|
||||||
// TODO modify blockNumber, make sure HertzBlock=BerlinBlock=LondonBlock to enable Berlin and London EIPs
|
|
||||||
BerlinBlock: big.NewInt(31302048),
|
|
||||||
LondonBlock: big.NewInt(31302048),
|
|
||||||
HertzBlock: big.NewInt(31302048),
|
|
||||||
|
|
||||||
Parlia: &ParliaConfig{
|
Parlia: &ParliaConfig{
|
||||||
Period: 3,
|
Period: 3,
|
||||||
@@ -195,15 +198,18 @@ var (
|
|||||||
NanoBlock: big.NewInt(23482428),
|
NanoBlock: big.NewInt(23482428),
|
||||||
MoranBlock: big.NewInt(23603940),
|
MoranBlock: big.NewInt(23603940),
|
||||||
PlanckBlock: big.NewInt(28196022),
|
PlanckBlock: big.NewInt(28196022),
|
||||||
|
LubanBlock: big.NewInt(29295050),
|
||||||
|
PlatoBlock: big.NewInt(29861024),
|
||||||
|
BerlinBlock: big.NewInt(31103030),
|
||||||
|
LondonBlock: big.NewInt(31103030),
|
||||||
|
HertzBlock: big.NewInt(31103030),
|
||||||
|
HertzfixBlock: big.NewInt(35682300),
|
||||||
|
// UnixTime: 1702972800 is December 19, 2023 8:00:00 AM UTC
|
||||||
|
ShanghaiTime: newUint64(1702972800),
|
||||||
|
KeplerTime: newUint64(1702972800),
|
||||||
|
|
||||||
// TODO modify blockNumber, make sure the blockNumber is not an integer multiple of 200 (epoch number)
|
// TODO
|
||||||
// TODO Caution !!! it should be very careful !!!
|
FeynmanTime: nil,
|
||||||
LubanBlock: big.NewInt(29295050),
|
|
||||||
PlatoBlock: big.NewInt(29861024),
|
|
||||||
// TODO modify blockNumber, make sure HertzBlock=BerlinBlock=LondonBlock to enable Berlin and London EIPs
|
|
||||||
BerlinBlock: big.NewInt(31103030),
|
|
||||||
LondonBlock: big.NewInt(31103030),
|
|
||||||
HertzBlock: big.NewInt(31103030),
|
|
||||||
|
|
||||||
Parlia: &ParliaConfig{
|
Parlia: &ParliaConfig{
|
||||||
Period: 3,
|
Period: 3,
|
||||||
@@ -212,7 +218,7 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
RialtoChainConfig = &ChainConfig{
|
RialtoChainConfig = &ChainConfig{
|
||||||
ChainID: big.NewInt(1417),
|
ChainID: big.NewInt(714),
|
||||||
HomesteadBlock: big.NewInt(0),
|
HomesteadBlock: big.NewInt(0),
|
||||||
EIP150Block: big.NewInt(0),
|
EIP150Block: big.NewInt(0),
|
||||||
EIP155Block: big.NewInt(0),
|
EIP155Block: big.NewInt(0),
|
||||||
@@ -222,21 +228,26 @@ var (
|
|||||||
PetersburgBlock: big.NewInt(0),
|
PetersburgBlock: big.NewInt(0),
|
||||||
IstanbulBlock: big.NewInt(0),
|
IstanbulBlock: big.NewInt(0),
|
||||||
MuirGlacierBlock: big.NewInt(0),
|
MuirGlacierBlock: big.NewInt(0),
|
||||||
RamanujanBlock: big.NewInt(400),
|
RamanujanBlock: big.NewInt(0),
|
||||||
NielsBlock: big.NewInt(0),
|
NielsBlock: big.NewInt(0),
|
||||||
MirrorSyncBlock: big.NewInt(400),
|
MirrorSyncBlock: big.NewInt(1),
|
||||||
BrunoBlock: big.NewInt(400),
|
BrunoBlock: big.NewInt(1),
|
||||||
EulerBlock: big.NewInt(400),
|
EulerBlock: big.NewInt(2),
|
||||||
GibbsBlock: big.NewInt(400),
|
GibbsBlock: big.NewInt(3),
|
||||||
NanoBlock: nil,
|
NanoBlock: nil,
|
||||||
MoranBlock: nil,
|
MoranBlock: big.NewInt(4),
|
||||||
PlanckBlock: nil,
|
PlanckBlock: big.NewInt(5),
|
||||||
|
LubanBlock: big.NewInt(6),
|
||||||
|
PlatoBlock: big.NewInt(7),
|
||||||
|
BerlinBlock: _hertz_upgrade_block_,
|
||||||
|
LondonBlock: _hertz_upgrade_block_,
|
||||||
|
HertzBlock: _hertz_upgrade_block_,
|
||||||
|
HertzfixBlock: _hertz_upgrade_block_,
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
LubanBlock: nil,
|
ShanghaiTime: _rialto_upgrade_height_,
|
||||||
PlatoBlock: nil,
|
KeplerTime: _rialto_upgrade_height_,
|
||||||
BerlinBlock: nil,
|
FeynmanTime: _rialto_upgrade_height_,
|
||||||
HertzBlock: nil,
|
|
||||||
|
|
||||||
Parlia: &ParliaConfig{
|
Parlia: &ParliaConfig{
|
||||||
Period: 3,
|
Period: 3,
|
||||||
@@ -269,7 +280,7 @@ var (
|
|||||||
BerlinBlock: big.NewInt(0),
|
BerlinBlock: big.NewInt(0),
|
||||||
LondonBlock: big.NewInt(0),
|
LondonBlock: big.NewInt(0),
|
||||||
HertzBlock: big.NewInt(0),
|
HertzBlock: big.NewInt(0),
|
||||||
|
HertzfixBlock: big.NewInt(0),
|
||||||
Parlia: &ParliaConfig{
|
Parlia: &ParliaConfig{
|
||||||
Period: 3,
|
Period: 3,
|
||||||
Epoch: 200,
|
Epoch: 200,
|
||||||
@@ -458,6 +469,8 @@ type ChainConfig struct {
|
|||||||
// Fork scheduling was switched from blocks to timestamps here
|
// Fork scheduling was switched from blocks to timestamps here
|
||||||
|
|
||||||
ShanghaiTime *uint64 `json:"shanghaiTime,omitempty" toml:",omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai)
|
ShanghaiTime *uint64 `json:"shanghaiTime,omitempty" toml:",omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai)
|
||||||
|
KeplerTime *uint64 `json:"keplerTime,omitempty" toml:",omitempty"` // Kepler switch time (nil = no fork, 0 = already activated)
|
||||||
|
FeynmanTime *uint64 `json:"feynmanTime,omitempty" toml:",omitempty"` // Feynman switch time (nil = no fork, 0 = already activated)
|
||||||
CancunTime *uint64 `json:"cancunTime,omitempty" toml:",omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun)
|
CancunTime *uint64 `json:"cancunTime,omitempty" toml:",omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun)
|
||||||
PragueTime *uint64 `json:"pragueTime,omitempty" toml:",omitempty"` // Prague switch time (nil = no fork, 0 = already on prague)
|
PragueTime *uint64 `json:"pragueTime,omitempty" toml:",omitempty"` // Prague switch time (nil = no fork, 0 = already on prague)
|
||||||
VerkleTime *uint64 `json:"verkleTime,omitempty" toml:",omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
|
VerkleTime *uint64 `json:"verkleTime,omitempty" toml:",omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
|
||||||
@@ -483,7 +496,7 @@ type ChainConfig struct {
|
|||||||
LubanBlock *big.Int `json:"lubanBlock,omitempty" toml:",omitempty"` // lubanBlock switch block (nil = no fork, 0 = already activated)
|
LubanBlock *big.Int `json:"lubanBlock,omitempty" toml:",omitempty"` // lubanBlock switch block (nil = no fork, 0 = already activated)
|
||||||
PlatoBlock *big.Int `json:"platoBlock,omitempty" toml:",omitempty"` // platoBlock switch block (nil = no fork, 0 = already activated)
|
PlatoBlock *big.Int `json:"platoBlock,omitempty" toml:",omitempty"` // platoBlock switch block (nil = no fork, 0 = already activated)
|
||||||
HertzBlock *big.Int `json:"hertzBlock,omitempty" toml:",omitempty"` // hertzBlock switch block (nil = no fork, 0 = already activated)
|
HertzBlock *big.Int `json:"hertzBlock,omitempty" toml:",omitempty"` // hertzBlock switch block (nil = no fork, 0 = already activated)
|
||||||
|
HertzfixBlock *big.Int `json:"hertzfixBlock,omitempty" toml:",omitempty"` // hertzfixBlock switch block (nil = no fork, 0 = already activated)
|
||||||
// Various consensus engines
|
// Various consensus engines
|
||||||
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
|
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
|
||||||
Clique *CliqueConfig `json:"clique,omitempty" toml:",omitempty"`
|
Clique *CliqueConfig `json:"clique,omitempty" toml:",omitempty"`
|
||||||
@@ -540,7 +553,22 @@ func (c *ChainConfig) String() string {
|
|||||||
engine = "unknown"
|
engine = "unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Engine: %v}",
|
var ShanghaiTime *big.Int
|
||||||
|
if c.ShanghaiTime != nil {
|
||||||
|
ShanghaiTime = big.NewInt(0).SetUint64(*c.ShanghaiTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
var KeplerTime *big.Int
|
||||||
|
if c.KeplerTime != nil {
|
||||||
|
KeplerTime = big.NewInt(0).SetUint64(*c.KeplerTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
var FeynmanTime *big.Int
|
||||||
|
if c.FeynmanTime != nil {
|
||||||
|
FeynmanTime = big.NewInt(0).SetUint64(*c.FeynmanTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Hertzfix: %v, ShanghaiTime: %v, KeplerTime: %v, FeynmanTime: %v, Engine: %v}",
|
||||||
c.ChainID,
|
c.ChainID,
|
||||||
c.HomesteadBlock,
|
c.HomesteadBlock,
|
||||||
c.DAOForkBlock,
|
c.DAOForkBlock,
|
||||||
@@ -571,6 +599,10 @@ func (c *ChainConfig) String() string {
|
|||||||
c.LubanBlock,
|
c.LubanBlock,
|
||||||
c.PlatoBlock,
|
c.PlatoBlock,
|
||||||
c.HertzBlock,
|
c.HertzBlock,
|
||||||
|
c.HertzfixBlock,
|
||||||
|
ShanghaiTime,
|
||||||
|
KeplerTime,
|
||||||
|
FeynmanTime,
|
||||||
engine,
|
engine,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -690,6 +722,14 @@ func (c *ChainConfig) IsOnHertz(num *big.Int) bool {
|
|||||||
return configBlockEqual(c.HertzBlock, num)
|
return configBlockEqual(c.HertzBlock, num)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ChainConfig) IsHertzfix(num *big.Int) bool {
|
||||||
|
return isBlockForked(c.HertzfixBlock, num)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChainConfig) IsOnHertzfix(num *big.Int) bool {
|
||||||
|
return configBlockEqual(c.HertzfixBlock, num)
|
||||||
|
}
|
||||||
|
|
||||||
// IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
|
// IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
|
||||||
func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
|
func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
|
||||||
return isBlockForked(c.MuirGlacierBlock, num)
|
return isBlockForked(c.MuirGlacierBlock, num)
|
||||||
@@ -774,6 +814,34 @@ func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool {
|
|||||||
return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time)
|
return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsKepler returns whether time is either equal to the kepler fork time or greater.
|
||||||
|
func (c *ChainConfig) IsKepler(num *big.Int, time uint64) bool {
|
||||||
|
return c.IsLondon(num) && isTimestampForked(c.KeplerTime, time)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsOnKepler returns whether currentBlockTime is either equal to the kepler fork time or greater firstly.
|
||||||
|
func (c *ChainConfig) IsOnKepler(currentBlockNumber *big.Int, lastBlockTime uint64, currentBlockTime uint64) bool {
|
||||||
|
lastBlockNumber := new(big.Int)
|
||||||
|
if currentBlockNumber.Cmp(big.NewInt(1)) >= 0 {
|
||||||
|
lastBlockNumber.Sub(currentBlockNumber, big.NewInt(1))
|
||||||
|
}
|
||||||
|
return !c.IsKepler(lastBlockNumber, lastBlockTime) && c.IsKepler(currentBlockNumber, currentBlockTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFeynman returns whether time is either equal to the Feynman fork time or greater.
|
||||||
|
func (c *ChainConfig) IsFeynman(num *big.Int, time uint64) bool {
|
||||||
|
return c.IsLondon(num) && isTimestampForked(c.FeynmanTime, time)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsOnFeynman returns whether currentBlockTime is either equal to the Feynman fork time or greater firstly.
|
||||||
|
func (c *ChainConfig) IsOnFeynman(currentBlockNumber *big.Int, lastBlockTime uint64, currentBlockTime uint64) bool {
|
||||||
|
lastBlockNumber := new(big.Int)
|
||||||
|
if currentBlockNumber.Cmp(big.NewInt(1)) >= 0 {
|
||||||
|
lastBlockNumber.Sub(currentBlockNumber, big.NewInt(1))
|
||||||
|
}
|
||||||
|
return !c.IsFeynman(lastBlockNumber, lastBlockTime) && c.IsFeynman(currentBlockNumber, currentBlockTime)
|
||||||
|
}
|
||||||
|
|
||||||
// IsCancun returns whether num is either equal to the Cancun fork time or greater.
|
// IsCancun returns whether num is either equal to the Cancun fork time or greater.
|
||||||
func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
|
func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
|
||||||
return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
|
return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
|
||||||
@@ -837,7 +905,10 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
|
|||||||
{name: "lubanBlock", block: c.LubanBlock},
|
{name: "lubanBlock", block: c.LubanBlock},
|
||||||
{name: "platoBlock", block: c.PlatoBlock},
|
{name: "platoBlock", block: c.PlatoBlock},
|
||||||
{name: "hertzBlock", block: c.HertzBlock},
|
{name: "hertzBlock", block: c.HertzBlock},
|
||||||
|
{name: "hertzfixBlock", block: c.HertzfixBlock},
|
||||||
{name: "shanghaiTime", timestamp: c.ShanghaiTime},
|
{name: "shanghaiTime", timestamp: c.ShanghaiTime},
|
||||||
|
{name: "keplerTime", timestamp: c.KeplerTime},
|
||||||
|
{name: "feynmanTime", timestamp: c.FeynmanTime},
|
||||||
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
|
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
|
||||||
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
|
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
|
||||||
{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
|
{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
|
||||||
@@ -968,9 +1039,18 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
|
|||||||
if isForkBlockIncompatible(c.HertzBlock, newcfg.HertzBlock, headNumber) {
|
if isForkBlockIncompatible(c.HertzBlock, newcfg.HertzBlock, headNumber) {
|
||||||
return newBlockCompatError("hertz fork block", c.HertzBlock, newcfg.HertzBlock)
|
return newBlockCompatError("hertz fork block", c.HertzBlock, newcfg.HertzBlock)
|
||||||
}
|
}
|
||||||
|
if isForkBlockIncompatible(c.HertzfixBlock, newcfg.HertzfixBlock, headNumber) {
|
||||||
|
return newBlockCompatError("hertzfix fork block", c.HertzfixBlock, newcfg.HertzfixBlock)
|
||||||
|
}
|
||||||
if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) {
|
if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) {
|
||||||
return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime)
|
return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime)
|
||||||
}
|
}
|
||||||
|
if isForkTimestampIncompatible(c.KeplerTime, newcfg.KeplerTime, headTimestamp) {
|
||||||
|
return newTimestampCompatError("Kepler fork timestamp", c.KeplerTime, newcfg.KeplerTime)
|
||||||
|
}
|
||||||
|
if isForkTimestampIncompatible(c.FeynmanTime, newcfg.FeynmanTime, headTimestamp) {
|
||||||
|
return newTimestampCompatError("Feynman fork timestamp", c.FeynmanTime, newcfg.FeynmanTime)
|
||||||
|
}
|
||||||
if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) {
|
if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) {
|
||||||
return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime)
|
return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime)
|
||||||
}
|
}
|
||||||
@@ -1131,7 +1211,8 @@ type Rules struct {
|
|||||||
IsLuban bool
|
IsLuban bool
|
||||||
IsPlato bool
|
IsPlato bool
|
||||||
IsHertz bool
|
IsHertz bool
|
||||||
IsShanghai, IsCancun, IsPrague bool
|
IsHertzfix bool
|
||||||
|
IsShanghai, IsKepler, IsFeynman, IsCancun, IsPrague bool
|
||||||
IsVerkle bool
|
IsVerkle bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1160,7 +1241,10 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
|
|||||||
IsLuban: c.IsLuban(num),
|
IsLuban: c.IsLuban(num),
|
||||||
IsPlato: c.IsPlato(num),
|
IsPlato: c.IsPlato(num),
|
||||||
IsHertz: c.IsHertz(num),
|
IsHertz: c.IsHertz(num),
|
||||||
|
IsHertzfix: c.IsHertzfix(num),
|
||||||
IsShanghai: c.IsShanghai(num, timestamp),
|
IsShanghai: c.IsShanghai(num, timestamp),
|
||||||
|
IsKepler: c.IsKepler(num, timestamp),
|
||||||
|
IsFeynman: c.IsFeynman(num, timestamp),
|
||||||
IsCancun: c.IsCancun(num, timestamp),
|
IsCancun: c.IsCancun(num, timestamp),
|
||||||
IsPrague: c.IsPrague(num, timestamp),
|
IsPrague: c.IsPrague(num, timestamp),
|
||||||
IsVerkle: c.IsVerkle(num, timestamp),
|
IsVerkle: c.IsVerkle(num, timestamp),
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ const (
|
|||||||
IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation
|
IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation
|
||||||
BlsSignatureVerifyBaseGas uint64 = 1000 // base price for a BLS signature verify operation
|
BlsSignatureVerifyBaseGas uint64 = 1000 // base price for a BLS signature verify operation
|
||||||
BlsSignatureVerifyPerKeyGas uint64 = 3500 // Per-key price for a BLS signature verify operation
|
BlsSignatureVerifyPerKeyGas uint64 = 3500 // Per-key price for a BLS signature verify operation
|
||||||
|
DoubleSignEvidenceVerifyGas uint64 = 1000 // Gas for verify double sign evidence
|
||||||
|
|
||||||
Bn256AddGasByzantium uint64 = 500 // Byzantium gas needed for an elliptic curve addition
|
Bn256AddGasByzantium uint64 = 500 // Byzantium gas needed for an elliptic curve addition
|
||||||
Bn256AddGasIstanbul uint64 = 150 // Gas needed for an elliptic curve addition
|
Bn256AddGasIstanbul uint64 = 150 // Gas needed for an elliptic curve addition
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
VersionMajor = 1 // Major version component of the current release
|
VersionMajor = 1 // Major version component of the current release
|
||||||
VersionMinor = 3 // Minor version component of the current release
|
VersionMinor = 3 // Minor version component of the current release
|
||||||
VersionPatch = 1 // Patch version component of the current release
|
VersionPatch = 5 // Patch version component of the current release
|
||||||
VersionMeta = "" // Version metadata to append to the version string
|
VersionMeta = "" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/gopool"
|
"github.com/ethereum/go-ethereum/common/gopool"
|
||||||
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
accountBlacklistRpcCounter = metrics.NewRegisteredCounter("rpc/count/blacklist", nil)
|
||||||
|
)
|
||||||
|
|
||||||
// handler handles JSON-RPC messages. There is one handler per connection. Note that
|
// handler handles JSON-RPC messages. There is one handler per connection. Note that
|
||||||
// handler is not safe for concurrent use. Message handling never blocks indefinitely
|
// handler is not safe for concurrent use. Message handling never blocks indefinitely
|
||||||
// because RPCs are processed on background goroutines launched by handler.
|
// because RPCs are processed on background goroutines launched by handler.
|
||||||
@@ -476,6 +481,11 @@ func (h *handler) handleCallMsg(ctx *callProc, reqCtx context.Context, msg *json
|
|||||||
xForward := reqCtx.Value("X-Forwarded-For")
|
xForward := reqCtx.Value("X-Forwarded-For")
|
||||||
h.log.Warn("Served "+msg.Method, "reqid", idForLog{msg.ID}, "t", time.Since(start), "err", resp.Error.Message, "X-Forwarded-For", xForward)
|
h.log.Warn("Served "+msg.Method, "reqid", idForLog{msg.ID}, "t", time.Since(start), "err", resp.Error.Message, "X-Forwarded-For", xForward)
|
||||||
|
|
||||||
|
monitoredError := "sender or to in black list" // using legacypool.ErrInBlackList.Error() will cause `import cycle`
|
||||||
|
if strings.Contains(resp.Error.Message, monitoredError) {
|
||||||
|
accountBlacklistRpcCounter.Inc(1)
|
||||||
|
log.Warn("blacklist account detected from direct rpc", "remoteAddr", h.conn.remoteAddr())
|
||||||
|
}
|
||||||
ctx = append(ctx, "err", resp.Error.Message)
|
ctx = append(ctx, "err", resp.Error.Message)
|
||||||
if resp.Error.Data != nil {
|
if resp.Error.Data != nil {
|
||||||
ctx = append(ctx, "errdata", resp.Error.Data)
|
ctx = append(ctx, "errdata", resp.Error.Data)
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ func parliaHeaderHashAndRlp(header *types.Header, chainId *big.Int) (hash, rlp [
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
rlp = parlia.ParliaRLP(header, chainId)
|
rlp = parlia.ParliaRLP(header, chainId)
|
||||||
hash = parlia.SealHash(header, chainId).Bytes()
|
hash = types.SealHash(header, chainId).Bytes()
|
||||||
return hash, rlp, err
|
return hash, rlp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func TestBlockchain(t *testing.T) {
|
|||||||
// For speedier CI-runs, the line below can be uncommented, so those are skipped.
|
// For speedier CI-runs, the line below can be uncommented, so those are skipped.
|
||||||
// For now, in hardfork-times (Berlin), we run the tests both as StateTests and
|
// For now, in hardfork-times (Berlin), we run the tests both as StateTests and
|
||||||
// as blockchain tests, since the latter also covers things like receipt root
|
// as blockchain tests, since the latter also covers things like receipt root
|
||||||
bt.skipLoad(`^GeneralStateTests/`)
|
// bt.skipLoad(`^GeneralStateTests/`)
|
||||||
|
|
||||||
// Skip random failures due to selfish mining test
|
// Skip random failures due to selfish mining test
|
||||||
bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`)
|
bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`)
|
||||||
@@ -49,6 +49,9 @@ func TestBlockchain(t *testing.T) {
|
|||||||
// using 4.6 TGas
|
// using 4.6 TGas
|
||||||
bt.skipLoad(`.*randomStatetest94.json.*`)
|
bt.skipLoad(`.*randomStatetest94.json.*`)
|
||||||
|
|
||||||
|
bt.runonly(`^GeneralStateTests/Shanghai`)
|
||||||
|
bt.runonly(`^Pyspecs/shanghai/eip3.*`)
|
||||||
|
|
||||||
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
||||||
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil)); err != nil {
|
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil)); err != nil {
|
||||||
t.Errorf("test in hash mode without snapshotter failed: %v", err)
|
t.Errorf("test in hash mode without snapshotter failed: %v", err)
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func Fuzz(input []byte) int {
|
|||||||
|
|
||||||
f := fetcher.NewTxFetcherForTests(
|
f := fetcher.NewTxFetcherForTests(
|
||||||
func(common.Hash) bool { return false },
|
func(common.Hash) bool { return false },
|
||||||
func(txs []*txpool.Transaction) []error {
|
func(peer string, txs []*txpool.Transaction) []error {
|
||||||
return make([]error, len(txs))
|
return make([]error, len(txs))
|
||||||
},
|
},
|
||||||
func(string, []common.Hash) error { return nil },
|
func(string, []common.Hash) error { return nil },
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ type testMatcher struct {
|
|||||||
failpat []testFailure
|
failpat []testFailure
|
||||||
skiploadpat []*regexp.Regexp
|
skiploadpat []*regexp.Regexp
|
||||||
slowpat []*regexp.Regexp
|
slowpat []*regexp.Regexp
|
||||||
runonlylistpat *regexp.Regexp
|
runonlylistpat []*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
type testConfig struct {
|
type testConfig struct {
|
||||||
@@ -127,7 +127,7 @@ func (tm *testMatcher) fails(pattern string, reason string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tm *testMatcher) runonly(pattern string) {
|
func (tm *testMatcher) runonly(pattern string) {
|
||||||
tm.runonlylistpat = regexp.MustCompile(pattern)
|
tm.runonlylistpat = append(tm.runonlylistpat, regexp.MustCompile(pattern))
|
||||||
}
|
}
|
||||||
|
|
||||||
// config defines chain config for tests matching the pattern.
|
// config defines chain config for tests matching the pattern.
|
||||||
@@ -220,7 +220,14 @@ func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest inte
|
|||||||
t.Skip(r)
|
t.Skip(r)
|
||||||
}
|
}
|
||||||
if tm.runonlylistpat != nil {
|
if tm.runonlylistpat != nil {
|
||||||
if !tm.runonlylistpat.MatchString(name) {
|
match := false
|
||||||
|
for _, pat := range tm.runonlylistpat {
|
||||||
|
if pat.MatchString(name) {
|
||||||
|
match = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !match {
|
||||||
t.Skip("Skipped by runonly")
|
t.Skip("Skipped by runonly")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ func TestState(t *testing.T) {
|
|||||||
st.fails(`stEIP4844-blobtransactions/opcodeBlobhashOutOfRange.json`, "test has incorrect state root")
|
st.fails(`stEIP4844-blobtransactions/opcodeBlobhashOutOfRange.json`, "test has incorrect state root")
|
||||||
st.fails(`stEIP4844-blobtransactions/opcodeBlobhBounds.json`, "test has incorrect state root")
|
st.fails(`stEIP4844-blobtransactions/opcodeBlobhBounds.json`, "test has incorrect state root")
|
||||||
|
|
||||||
|
st.runonly(`^Shanghai`)
|
||||||
|
|
||||||
// For Istanbul, older tests were moved into LegacyTests
|
// For Istanbul, older tests were moved into LegacyTests
|
||||||
for _, dir := range []string{
|
for _, dir := range []string{
|
||||||
filepath.Join(baseDir, "EIPTests", "StateTests"),
|
filepath.Join(baseDir, "EIPTests", "StateTests"),
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
|||||||
// And _now_ get the state root
|
// And _now_ get the state root
|
||||||
root := statedb.IntermediateRoot(config.IsEIP158(block.Number()))
|
root := statedb.IntermediateRoot(config.IsEIP158(block.Number()))
|
||||||
statedb.SetExpectedStateRoot(root)
|
statedb.SetExpectedStateRoot(root)
|
||||||
root, _, err = statedb.Commit(block.NumberU64(), nil)
|
root, _, _ = statedb.Commit(block.NumberU64(), nil)
|
||||||
return triedb, snaps, statedb, root, err
|
return triedb, snaps, statedb, root, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
BSC_CHAIN_ID=99
|
BSC_CHAIN_ID=714
|
||||||
CLUSTER_CIDR=99.1.0.0/16
|
CLUSTER_CIDR=99.1.0.0/16
|
||||||
BOOTSTRAP_PUB_KEY=177ae5db445a2f70db781b019aedd928f5b1528a7a43448840b022408f9a21509adcce0b37c87d59da68d47a16879cc1e95a62bbac9723f7b22f4365b2afabbe
|
BOOTSTRAP_PUB_KEY=177ae5db445a2f70db781b019aedd928f5b1528a7a43448840b022408f9a21509adcce0b37c87d59da68d47a16879cc1e95a62bbac9723f7b22f4365b2afabbe
|
||||||
BOOTSTRAP_TCP_PORT=30311
|
BOOTSTRAP_TCP_PORT=30311
|
||||||
|
|||||||
@@ -7,26 +7,29 @@ function prepare() {
|
|||||||
echo "geth do not exist!"
|
echo "geth do not exist!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
rm -rf ${workspace}/storage/*
|
|
||||||
cd ${workspace}/genesis
|
cd ${workspace}/genesis
|
||||||
rm -rf validators.conf
|
cp ${workspace}/storage/genesis.json ${workspace}/genesis/genesis.json
|
||||||
}
|
}
|
||||||
|
|
||||||
function init_validator() {
|
function init_validator() {
|
||||||
node_id=$1
|
node_id=$1
|
||||||
|
rm -rf ${workspace}/storage/${node_id}
|
||||||
mkdir -p ${workspace}/storage/${node_id}
|
mkdir -p ${workspace}/storage/${node_id}
|
||||||
geth --datadir ${workspace}/storage/${node_id} account new --password /dev/null > ${workspace}/storage/${node_id}Info
|
cp -r ${workspace}/storage/keystore ${workspace}/storage/${node_id}/
|
||||||
validatorAddr=`cat ${workspace}/storage/${node_id}Info|grep 'Public address of the key'|awk '{print $6}'`
|
cp ${workspace}/storage/address ${workspace}/storage/${node_id}/address
|
||||||
echo "${validatorAddr},${validatorAddr},${validatorAddr},0x0000000010000000" >> ${workspace}/genesis/validators.conf
|
|
||||||
echo ${validatorAddr} > ${workspace}/storage/${node_id}/address
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function generate_genesis() {
|
function generate_genesis() {
|
||||||
|
cd ${workspace}/genesis/scripts/
|
||||||
node generate-validator.js
|
node generate-validator.js
|
||||||
INIT_HOLDER_ADDRESSES=$(ls ${workspace}/init-holders | tr '\n' ',')
|
INIT_HOLDER_ADDRESSES=$(ls ${workspace}/init-holders | tr '\n' ',')
|
||||||
INIT_HOLDER_ADDRESSES=${INIT_HOLDER_ADDRESSES/%,/}
|
INIT_HOLDER_ADDRESSES=${INIT_HOLDER_ADDRESSES/%,/}
|
||||||
node generate-initHolders.js --initHolders ${INIT_HOLDER_ADDRESSES}
|
node generate-initHolders.js --initHolders ${INIT_HOLDER_ADDRESSES}
|
||||||
node generate-genesis.js --chainid ${BSC_CHAIN_ID}
|
|
||||||
|
cd ${workspace}/genesis
|
||||||
|
#source /root/.profile && foundryup
|
||||||
|
#forge install --no-git --no-commit foundry-rs/forge-std@v1.1.1
|
||||||
|
bash ${workspace}/genesis/scripts/generate.sh local
|
||||||
}
|
}
|
||||||
|
|
||||||
function init_genesis_data() {
|
function init_genesis_data() {
|
||||||
@@ -43,8 +46,8 @@ function init_genesis_data() {
|
|||||||
|
|
||||||
function prepareBLSWallet(){
|
function prepareBLSWallet(){
|
||||||
node_id=$1
|
node_id=$1
|
||||||
echo "123456" > ${workspace}/storage/${node_id}/blspassword.txt
|
echo "1234567890" > ${workspace}/storage/${node_id}/blspassword.txt
|
||||||
expect ${workspace}/scripts/create_bls_key.sh ${workspace}/storage/${node_id}
|
geth bls account new --datadir ${workspace}/storage/${node_id} --blspassword ${workspace}/storage/${node_id}/blspassword.txt
|
||||||
|
|
||||||
sed -i -e 's/DataDir/BLSPasswordFile = \"{{BLSPasswordFile}}\"\nBLSWalletDir = \"{{BLSWalletDir}}\"\nDataDir/g' ${workspace}/storage/${node_id}/config.toml
|
sed -i -e 's/DataDir/BLSPasswordFile = \"{{BLSPasswordFile}}\"\nBLSWalletDir = \"{{BLSWalletDir}}\"\nDataDir/g' ${workspace}/storage/${node_id}/config.toml
|
||||||
PassWordPath="/root/.ethereum/blspassword.txt"
|
PassWordPath="/root/.ethereum/blspassword.txt"
|
||||||
@@ -54,14 +57,14 @@ function prepareBLSWallet(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
prepare
|
prepare
|
||||||
|
NUMS_OF_VALIDATOR=1
|
||||||
# Step 1, generate config for each validator
|
# Step 1, generate config for each validator
|
||||||
for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do
|
for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do
|
||||||
init_validator "bsc-validator${i}"
|
init_validator "bsc-validator${i}"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Step 2, use validator configs to generate genesis file
|
# Step 2, use validator configs to generate genesis file
|
||||||
generate_genesis
|
#generate_genesis
|
||||||
|
|
||||||
# Step 3, use genesis file to init cluster data
|
# Step 3, use genesis file to init cluster data
|
||||||
init_genesis_data bsc-rpc bsc-rpc
|
init_genesis_data bsc-rpc bsc-rpc
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ done
|
|||||||
|
|
||||||
geth --config ${DATA_DIR}/config.toml --datadir ${DATA_DIR} --netrestrict ${CLUSTER_CIDR} \
|
geth --config ${DATA_DIR}/config.toml --datadir ${DATA_DIR} --netrestrict ${CLUSTER_CIDR} \
|
||||||
--verbosity ${VERBOSE} --nousb \
|
--verbosity ${VERBOSE} --nousb \
|
||||||
--rpc.allow-unprotected-txs --txlookuplimit 15768000 \
|
--rpc.allow-unprotected-txs --history.transactions 15768000 \
|
||||||
-unlock ${unlock_sequences} --password /dev/null
|
-unlock ${unlock_sequences} --password /dev/null >${DATA_DIR}/bscnode-rpc.log
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ geth --config ${DATA_DIR}/config.toml --datadir ${DATA_DIR} --netrestrict ${CLUS
|
|||||||
--bootnodes enode://${BOOTSTRAP_PUB_KEY}@${BOOTSTRAP_IP}:${BOOTSTRAP_TCP_PORT} \
|
--bootnodes enode://${BOOTSTRAP_PUB_KEY}@${BOOTSTRAP_IP}:${BOOTSTRAP_TCP_PORT} \
|
||||||
--mine -unlock ${VALIDATOR_ADDR} --miner.etherbase ${VALIDATOR_ADDR} --password /dev/null \
|
--mine -unlock ${VALIDATOR_ADDR} --miner.etherbase ${VALIDATOR_ADDR} --password /dev/null \
|
||||||
--light.serve 50 \
|
--light.serve 50 \
|
||||||
--rpc.allow-unprotected-txs --txlookuplimit 15768000
|
--rpc.allow-unprotected-txs --history.transactions 15768000 >${DATA_DIR}/bscnode-validator.log
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
#!/usr/bin/expect
|
|
||||||
# 6 num wanted
|
|
||||||
set wallet_password 123456
|
|
||||||
# 10 characters at least wanted
|
|
||||||
set account_password 1234567890
|
|
||||||
|
|
||||||
set timeout 5
|
|
||||||
spawn geth bls account new --datadir [lindex $argv 0]
|
|
||||||
expect "*assword:*"
|
|
||||||
send "$wallet_password\r"
|
|
||||||
expect "*assword:*"
|
|
||||||
send "$wallet_password\r"
|
|
||||||
expect "*assword:*"
|
|
||||||
send "$account_password\r"
|
|
||||||
expect "*assword:*"
|
|
||||||
send "$account_password\r"
|
|
||||||
expect EOF
|
|
||||||
1
tests/truffle/storage/address
Normal file
1
tests/truffle/storage/address
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0x03735c2ED70a56CD221e0024eB4bF90243C9d6E9
|
||||||
130
tests/truffle/storage/genesis.json
Normal file
130
tests/truffle/storage/genesis.json
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
{"address":"03735c2ed70a56cd221e0024eb4bf90243c9d6e9","crypto":{"cipher":"aes-128-ctr","ciphertext":"b66550ef67345005ead82c9e2835d311fb0e8787191af3696119977064f6120e","cipherparams":{"iv":"5b8f4ed6026ab6c733857e3bed90a869"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"68fc3d0829122badcf8c6efd40c6f2e086a5167db489bed099e3d2b97c1be496"},"mac":"71fd9f23862f7252ca88a6ea2c29fd0ab3527c5b9f5d1f827856263247c92f46"},"id":"7f75b57a-a4ba-4877-a42b-652f966d8aa6","version":3}
|
||||||
@@ -172,7 +172,7 @@ func New(diskdb ethdb.Database, config *Config) *Database {
|
|||||||
// mechanism also ensures that at most one **non-readOnly** database
|
// mechanism also ensures that at most one **non-readOnly** database
|
||||||
// is opened at the same time to prevent accidental mutation.
|
// is opened at the same time to prevent accidental mutation.
|
||||||
if ancient, err := diskdb.AncientDatadir(); err == nil && ancient != "" && !db.readOnly {
|
if ancient, err := diskdb.AncientDatadir(); err == nil && ancient != "" && !db.readOnly {
|
||||||
offset := uint64(0) //TODO(Nathan): just for passing compilation
|
offset := uint64(0) // differ from in block data, only metadata is used in state data
|
||||||
freezer, err := rawdb.NewStateFreezer(ancient, false, offset)
|
freezer, err := rawdb.NewStateFreezer(ancient, false, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to open state history freezer", "err", err)
|
log.Crit("Failed to open state history freezer", "err", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user