Compare commits

...

47 Commits

Author SHA1 Message Date
j75689
880667e77f fix: bug in determining breathe block 2023-12-12 12:23:56 +08:00
j75689
f599fee78c fix: add TokenHubContract bytecode 2023-12-12 01:50:49 +08:00
j75689
eb93010928 fix: add BerlinBlock and LondonBlock to rialto 2023-12-12 01:50:49 +08:00
j75689
d94cb56ae9 fix: upgrade config 2023-12-12 01:50:49 +08:00
j75689
0438b61114 fix: hardfork setting for rialto 2023-12-12 01:50:49 +08:00
j75689
c73b11055e fix: _hertz_upgrade_block_ 2023-12-12 01:50:49 +08:00
j75689
54f334a95f fix: HertzBlock setup 2023-12-12 01:50:48 +08:00
j75689
f2e38fec9a fix: add ShanghaiTime, KeplerTime 2023-12-12 01:50:48 +08:00
j75689
d1118313ce fix: add _rialto_upgrade_height_ 2023-12-12 01:50:48 +08:00
j75689
288b4f9926 test: bytecode template for rialto net 2023-12-12 01:50:48 +08:00
Roshan
6744d7c15f chore: modify breath block interval for test (#2054) 2023-12-11 17:12:42 +08:00
zjubfd
3414e5672a Merge pull request #2048 from Pythonberg1997/bc-fusion
chore: merge with develop branch
2023-12-08 16:26:32 +08:00
Roshan
8f3c525adc chore: resolve merge conflicts and fix review comments 2023-12-08 16:20:30 +08:00
Roshan
3e9e6423c0 Merge remote-tracking branch 'BNBChain/develop' into bc-fusion
# Conflicts:
#	cmd/geth/blsaccountcmd.go
#	params/config.go
2023-12-07 18:25:45 +08:00
buddho
e3ef62f3bd rpc,eth: output more info about failed txs(#2041) 2023-12-07 16:07:48 +08:00
buddh0
fa5d0cf287 core/systemcontracts: update CommitUrl for keplerUpgrade 2023-12-07 15:53:25 +08:00
buddh0
6c788d7675 tests/truffle: adapt changes in bsc-genesis-contracts 2023-12-07 14:57:55 +08:00
buddho
a30beeba59 core/txpool/legacypool: respect nolocals-setting (#2037) 2023-12-06 17:05:13 +08:00
lx
aa15df2814 config: setup Kepler/Shanghai hardfork date
expected hard fork date:
- Testnet: 19th Dec 2023, 2pm UTC+8, Tuesday
- Mainnet: 23th Jan 2024, 4pm UTC+8, Tuesday
2023-12-05 17:41:28 +08:00
larry.lx
195ae35130 release: prepare for release v1.3.5 2023-12-05 17:41:28 +08:00
buddho
5db73c9837 cmd/geth: standardize the action of importing bls account (#2020)
* cmd/geth: standardize the action of importing bls account
* rename bLSAccountPasswordFileFlag to blsAccountPasswordFileFlag
* use password of wallet as account password when new an account or importing a raw key
2023-12-05 16:37:19 +08:00
zzzckck
7e6b43a5c7 Merge pull request #2033 from bnb-chain/develop_lock_v1.3.4_merge
merge v1.3.4 into develop branch
2023-12-05 12:04:39 +08:00
Roshan
5743b067ba feat: add generate-proof to geth cmd (#2028)
* feat: add `generate-proof` to geth cmd

* chore: rename variable
2023-12-05 11:46:54 +08:00
zzzckck
5b78f5761a Merge branch 'develop' into develop_lock_v1.3.4_merge 2023-12-05 11:29:13 +08:00
larry.lx
885de2c1ca fix: failed ut 2023-12-04 19:06:48 +08:00
larry.lx
afc3b42241 fix: disable flag --pipecommit 2023-12-04 19:06:48 +08:00
larry.lx
a2f9ac0c8b release: prepare v1.3.4 2023-12-04 19:06:48 +08:00
larry.lx
761563155c fork: add hardfork Hertzfix 2023-12-04 19:06:48 +08:00
larry.lx
8b00720640 fix: remove pipecommit in miner 2023-12-04 19:06:48 +08:00
larry.lx
a8409158a5 release: draft v1.3.3 2023-12-04 19:06:48 +08:00
Ng Wei Han
a3507cc2c1 cmd/utils: exit process if txlookuplimit flag is set (#2000) 2023-12-04 19:06:48 +08:00
Ng Wei Han
b494339e10 fix(cmd): check pruneancient when creating db (#1986) 2023-12-04 19:06:48 +08:00
larry.lx
f7e9adc2c8 fix: remove sharedPool 2023-12-04 19:06:48 +08:00
Roshan
d3f882d799 chore: update contracts code (#2024) 2023-12-04 10:43:23 +08:00
Roshan
030e41607e feat: add new fork block and precompile contract for BEP294 and BEP299 (#1874) 2023-11-30 19:36:54 +08:00
lx
70ccc3d1fe Merge pull request #2019 from bnb-chain/develop_lock_v1.3.3 2023-11-30 15:17:47 +08:00
lx
20dcaabfdc Merge branch 'develop' into develop_lock_v1.3.3 2023-11-30 10:14:39 +08:00
buddho
1edb34fd67 consensus/parlia: recover faster when snapshot of parlia is gone in disk (#2008) 2023-11-28 14:03:05 +08:00
buddho
789442372d consensus/parlia: increase size of snapshot cache in parlia (#2007) 2023-11-28 13:56:01 +08:00
Ng Wei Han
c92b6ce2ad cmd/utils: exit process if txlookuplimit flag is set (#2000) 2023-11-25 20:57:23 +08:00
buddh0
cd0356b106 core/systemcontracts: include BEP-319 on kepler hardfork 2023-11-22 19:09:34 +08:00
buddho
0224d48df4 core: enable Shanghai EIPs (#1970) 2023-11-20 19:19:26 +08:00
wayen
497fdf8358 fix: upgrade pebble and improve config (#1979) 2023-11-20 14:28:01 +08:00
Ng Wei Han
8b94dd6b59 fix(cmd): check pruneancient when creating db (#1986) 2023-11-14 20:10:41 +08:00
buddho
4be9481558 internal/ethapi: fix null effectiveGasPrice in GetTransactionReceipt (#1980) 2023-11-14 16:40:25 +08:00
buddho
3fc9f750d1 consensus/parlia: hardfork block can be epoch block (#1964) 2023-11-14 16:33:57 +08:00
joey
72ffb0cbed doc: add instructions for starting fullnode with pbss (#1977) 2023-11-10 19:23:14 +08:00
66 changed files with 5770 additions and 2102 deletions

View File

@@ -7,7 +7,7 @@ on:
- develop
pull_request:
branches:
branches:
- master
- develop
@@ -47,5 +47,3 @@ jobs:
run: |
go mod download
make geth

View File

@@ -7,7 +7,7 @@ on:
- develop
pull_request:
branches:
branches:
- master
- develop

View File

@@ -7,7 +7,7 @@ on:
- develop
pull_request:
branches:
branches:
- master
- develop

View File

@@ -7,7 +7,7 @@ on:
- develop
pull_request:
branches:
branches:
- master
- develop
@@ -44,7 +44,7 @@ jobs:
${{ runner.os }}-go-
- run: |
go mod download
go mod tidy
- name: golangci-lint
uses: golangci/golangci-lint-action@v3

View File

@@ -7,7 +7,7 @@ on:
- develop
pull_request:
branches:
branches:
- master
- develop
@@ -49,6 +49,6 @@ jobs:
CGO_CFLAGS_ALLOW: "-O -D__BLST_PORTABLE__"
ANDROID_HOME: "" # Skip android test
run: |
git submodule update --init --depth 1 --recursive
go mod download
make test

1
.gitignore vendored
View File

@@ -14,7 +14,6 @@
*/**/*tx_database*
*/**/*dapps*
build/_vendor/pkg
/tests/truffle/storage
#*
.#*

View File

@@ -1,14 +1,36 @@
# Changelog
## v1.3.3
IMPROVEMENT
* [\#2000](https://github.com/bnb-chain/bsc/pull/2000) cmd/utils: exit process if txlookuplimit flag is set
## 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
* 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
FEATURE

View File

@@ -150,14 +150,27 @@ unzip testnet.zip
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.
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
```shell
./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 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
Monitor the log from **./node/bsc.log** by default. When the node has started syncing, should be able to see the following output:

View File

@@ -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)
}
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
if out, err := replacer.CombinedOutput(); err != nil {
t.Fatalf("failed to replace tendermint dependency to bnb-chain source: %v\n%s", err, out)

View File

@@ -5,6 +5,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
"os"
"path/filepath"
"strings"
@@ -15,6 +16,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v4/io/prompt"
"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/iface"
"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/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/signer/core"
)
@@ -35,19 +39,20 @@ const (
)
var (
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: "",
}
au = aurora.NewAurora(true)
showPrivateKeyFlag = &cli.BoolFlag{
Name: "show-private-key",
Usage: "Show the BLS12-381 private key you will encrypt into a keystore file",
Name: "show-private-key",
Usage: "Show the BLS12-381 private key you will encrypt into a keystore file",
Category: flags.AccountCategory,
}
BLSAccountPasswordFileFlag = &cli.StringFlag{
Name: "blsaccountpassword",
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",
importedAccountPasswordFileFlag = &cli.StringFlag{
Name: "importedaccountpassword",
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",
Flags: []cli.Flag{
utils.DataDirFlag,
privateKeyFlag,
showPrivateKeyFlag,
utils.BLSPasswordFileFlag,
BLSAccountPasswordFileFlag,
},
Description: `
geth bls account new
@@ -149,17 +152,17 @@ You must remember this password to unlock your account in the future.`,
Name: "import",
Usage: "Import a BLS account",
Action: blsAccountImport,
ArgsUsage: "<keystore file>",
ArgsUsage: "<keyFile>",
Category: "BLS ACCOUNT COMMANDS",
Flags: []cli.Flag{
utils.DataDirFlag,
utils.BLSPasswordFileFlag,
BLSAccountPasswordFileFlag,
importedAccountPasswordFileFlag,
},
Description: `
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.`,
},
@@ -193,6 +196,22 @@ Print summary of existing BLS accounts in the current 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.")
}
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 = append(opts, accounts.WithWalletDir(dir))
@@ -249,7 +271,10 @@ func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, e
}
if !dirExists {
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 = append(opts, accounts.WithWalletDir(walletDir))
@@ -269,7 +294,7 @@ func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, e
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{
WalletDir: walletDir,
WalletPassword: walletPassword,
@@ -309,27 +334,11 @@ func blsAccountCreate(ctx *cli.Context) error {
if err := os.MkdirAll(keystoreDir, 0755); err != nil {
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))
if err := core.ValidatePasswordFormat(accountPassword); err != nil {
utils.Fatalf("Password invalid: %v.", err)
}
accountPassword := w.Password()
encryptor := keystorev4.New()
secretKey, err := bls.RandKey()
privateKeyString := ctx.String(privateKeyFlag.Name)
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 {
if err != nil {
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.
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()}
// Load config 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")
}
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...")
statuses, err := accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{
Importer: k,
Keystores: []*keymanager.Keystore{keystore},
AccountPassword: password,
AccountPassword: importedAccountPassword,
})
if err != nil {
utils.Fatalf("Import BLS account failed: %v.", err)
@@ -458,7 +491,7 @@ func blsAccountList(ctx *cli.Context) error {
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{
WalletDir: walletDir,
WalletPassword: walletPassword,
@@ -537,7 +570,7 @@ func blsAccountDelete(ctx *cli.Context) error {
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{
WalletDir: walletDir,
WalletPassword: walletPassword,
@@ -599,26 +632,78 @@ func blsAccountDelete(ctx *cli.Context) error {
return nil
}
func GetBLSPassword(ctx *cli.Context) []string {
path := ctx.String(utils.BLSPasswordFileFlag.Name)
if path == "" {
return nil
// blsAccountGenerateProof generate ownership proof for a selected BLS account.
func blsAccountGenerateProof(ctx *cli.Context) error {
if ctx.Args().Len() == 0 {
utils.Fatalf("No BLS account specified.")
}
text, err := os.ReadFile(path)
if err != nil {
utils.Fatalf("Failed to read wallet password file: %v", err)
var filteredPubKeys []bls.PublicKey
for _, str := range ctx.Args().Slice() {
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 {
path := ctx.String(BLSAccountPasswordFileFlag.Name)
if path == "" {
return nil
cfg := gethConfig{Node: defaultNodeConfig()}
// Load config file.
if file := ctx.String(configFileFlag.Name); file != "" {
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 {
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
}

View 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

View File

@@ -1092,14 +1092,14 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
BLSPasswordFileFlag = &cli.StringFlag{
Name: "blspassword",
Usage: "File path for the BLS password, which contains the password to unlock BLS wallet for managing votes in fast_finality feature",
Category: flags.FastFinalityCategory,
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.AccountCategory,
}
BLSWalletDirFlag = &flags.DirectoryFlag{
Name: "blswallet",
Usage: "Path for the blsWallet dir in fast finality feature (default = inside the datadir)",
Category: flags.FastFinalityCategory,
Category: flags.AccountCategory,
}
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.
func MakePasswordList(ctx *cli.Context) []string {
path := ctx.Path(PasswordFileFlag.Name)
return MakePasswordListFromPath(ctx.Path(PasswordFileFlag.Name))
}
func MakePasswordListFromPath(path string) []string {
if path == "" {
return nil
}
@@ -1919,7 +1922,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.EnableTrustProtocol = ctx.IsSet(EnableTrustProtocolFlag.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) {
cfg.RangeLimit = ctx.Bool(RangeLimitFlag.Name)

View File

@@ -21,6 +21,8 @@ import (
"fmt"
"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/params"
)
@@ -45,5 +47,45 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
// CalcBaseFee calculates the basefee of the header.
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)
}
}

View File

@@ -51,6 +51,11 @@ func copyConfig(original *params.ChainConfig) *params.ChainConfig {
func config() *params.ChainConfig {
config := copyConfig(params.TestChainConfig)
config.Ethash = nil
config.Parlia = &params.ParliaConfig{
Period: 3,
Epoch: 200,
}
config.LondonBlock = big.NewInt(5)
return config
}

File diff suppressed because it is too large Load Diff

View 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
}

View 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())
}
}
}
}

View File

@@ -6,7 +6,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"io"
"math"
"math/big"
"math/rand"
@@ -48,7 +47,7 @@ import (
)
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
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.RelayerIncentivizeContract): 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:]
// 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 {
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.
func ParliaRLP(header *types.Header, chainId *big.Int) []byte {
b := new(bytes.Buffer)
encodeSigHeader(b, header, chainId)
types.EncodeSigHeader(b, header, chainId)
return b.Bytes()
}
@@ -227,6 +230,7 @@ type Parlia struct {
validatorSetABIBeforeLuban abi.ABI
validatorSetABI abi.ABI
slashABI abi.ABI
stakeHubABI abi.ABI
// The fields below are for testing only
fakeDiff bool // Skip difficulty verifications
@@ -268,6 +272,10 @@ func New(
if err != nil {
panic(err)
}
stABI, err := abi.JSON(strings.NewReader(stakeABI))
if err != nil {
panic(err)
}
c := &Parlia{
chainConfig: chainConfig,
config: parliaConfig,
@@ -279,6 +287,7 @@ func New(
validatorSetABIBeforeLuban: vABIBeforeLuban,
validatorSetABI: vABI,
slashABI: sABI,
stakeHubABI: stABI,
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
// piled up more headers than allowed to be reorged (chain reinit from a freezer),
// 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)
if checkpoint != nil {
// get checkpoint data
@@ -694,10 +703,12 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
// new snapshot
snap = newSnapshot(p.config, p.signatures, number, hash, validators, voteAddrs, p.ethAPI)
if err := snap.store(p.db); err != nil {
return nil, err
if snap.Number%checkpointInterval == 0 { // snapshot will only be loaded when snap.Number%checkpointInterval == 0
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
}
}
@@ -828,6 +839,13 @@ func (p *Parlia) prepareValidators(header *types.Header) error {
}
} else {
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 {
header.Extra = append(header.Extra, 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.
for _, valInfo := range snap.Validators {
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)})
@@ -989,6 +1007,13 @@ func (p *Parlia) verifyValidators(header *types.Header) error {
return errMismatchingEpochValidators
}
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 {
copy(validatorsBytes[i*validatorBytesLength:], 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
}
}
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 {
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
if header.GasLimit < header.GasUsed {
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 {
case results <- block.WithSeal(header):
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
func (p *Parlia) SealHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewLegacyKeccak256()
encodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
types.EncodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
hasher.Sum(hash[:0])
return hash
}
@@ -1533,16 +1603,15 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNum *big.Int)
var valSet []common.Address
var voteAddrSet []types.BLSPublicKey
if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, result); err != nil {
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++ {
voteAddrmap[valSet[i]] = &(voteAddrSet)[i]
voteAddrMap[valSet[i]] = &(voteAddrSet)[i]
}
return valSet, voteAddrmap, nil
return valSet, voteAddrMap, nil
}
// 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.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 {
var rewards = new(big.Int)
rewards := new(big.Int)
rewards = rewards.Rsh(balance, systemRewardPercent)
if rewards.Cmp(common.Big0) > 0 {
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 ==========================
// 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 {
if snap.inturn(val) {
return 0

View File

@@ -199,6 +199,9 @@ func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *params.C
}
// 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 {
s.Attestation.TargetNumber = attestation.Data.TargetNumber
s.Attestation.TargetHash = attestation.Data.TargetHash

View File

@@ -552,7 +552,7 @@ func (bc *BlockChain) GetVMConfig() *vm.Config {
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
// 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.
@@ -563,6 +563,16 @@ func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts) {
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)
}
@@ -2049,7 +2059,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
vtime := time.Since(vstart)
proctime := time.Since(start) // processing + validation
bc.cacheReceipts(block.Hash(), receipts)
bc.cacheBlock(block.Hash(), block)
// 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 {
return it.index, err
}
bc.cacheReceipts(block.Hash(), receipts, block)
// Update the metrics touched during block commit
accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them
storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them

View File

@@ -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 {
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
if gen != nil {
gen(i, b)

View File

@@ -19,6 +19,7 @@ func preHertzConfig() *params.ChainConfig {
config.LondonBlock = nil
config.BerlinBlock = nil
config.HertzBlock = nil
config.HertzfixBlock = nil
return &config
}

View File

@@ -534,7 +534,7 @@ func (g *Genesis) ToBlock() *types.Block {
var withdrawals []*types.Withdrawal
if conf := g.Config; conf != nil {
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
withdrawals = make([]*types.Withdrawal, 0)
}

View File

@@ -59,7 +59,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
for i := 0; i < prefetchThread; i++ {
go func() {
newStatedb := statedb.CopyDoPrefetch()
if header.Number.Uint64() < 33968300 {
if !p.config.IsHertzfix(header.Number) {
newStatedb.EnableWriteOnSharedStorage()
}
gaspool := new(GasPool).AddGas(block.GasLimit())
@@ -108,7 +108,7 @@ func (p *statePrefetcher) PrefetchMining(txs TransactionsByPriceAndNonce, header
go func(startCh <-chan *types.Transaction, stopCh <-chan struct{}) {
idx := 0
newStatedb := statedb.CopyDoPrefetch()
if header.Number.Uint64() < 33968300 {
if !p.config.IsHertzfix(header.Number) {
newStatedb.EnableWriteOnSharedStorage()
}
gaspool := new(GasPool).AddGas(gasLimit)

View File

@@ -74,7 +74,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
misc.ApplyDAOHardFork(statedb)
}
// 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 (
context = NewEVMBlockContext(header, p.bc, nil)

View File

@@ -13,4 +13,10 @@ const (
TokenManagerContract = "0x0000000000000000000000000000000000001008"
CrossChainContract = "0x0000000000000000000000000000000000002000"
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

View File

@@ -1027,6 +1027,9 @@ func (pool *LegacyPool) addRemoteSync(tx *types.Transaction) error {
// addTxs attempts to queue a batch of transactions if they are valid.
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
var (
errs = make([]error, len(txs))

View File

@@ -26,6 +26,8 @@ import (
"sync/atomic"
"time"
"golang.org/x/crypto/sha3"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"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 {
return err
}
d.BlockHash, d.Number, d.Codes, d.Destructs, d.Accounts, d.Storages =
ed.BlockHash, ed.Number, ed.Codes, ed.Destructs, ed.Accounts, ed.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
d.Receipts = make([]*Receipt, len(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.Vals[i], storage.Vals[j] = storage.Vals[j], storage.Vals[i]
}
func (storage *DiffStorage) Less(i, j int) bool {
return string(storage.Keys[i][:]) < string(storage.Keys[j][:])
}
@@ -622,3 +624,64 @@ type DiffAccountsInBlock struct {
BlockHash common.Hash
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())
}
}

View File

@@ -17,23 +17,28 @@
package vm
import (
"bytes"
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
"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/math"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/blake2b"
"github.com/ethereum/go-ethereum/crypto/bls12381"
"github.com/ethereum/go-ethereum/crypto/bn256"
"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/params"
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
"golang.org/x/crypto/ripemd160"
"github.com/ethereum/go-ethereum/rlp"
)
// 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{},
}
// 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
// contracts specified in EIP-2537. These are exported for testing purposes.
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
@@ -245,6 +271,7 @@ var (
PrecompiledAddressesIstanbul []common.Address
PrecompiledAddressesByzantium []common.Address
PrecompiledAddressesHomestead []common.Address
PrecompiledAddressesFeynman []common.Address
)
func init() {
@@ -281,11 +308,16 @@ func init() {
for k := range PrecompiledContractsCancun {
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
}
for k := range PrecompiledContractsFeynman {
PrecompiledAddressesFeynman = append(PrecompiledAddressesFeynman, k)
}
}
// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address {
switch {
case rules.IsFeynman:
return PrecompiledAddressesFeynman
case rules.IsCancun:
return PrecompiledAddressesCancun
case rules.IsHertz:
@@ -561,7 +593,7 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) {
// Modulo 0 is undefined, return zero
return common.LeftPadBytes([]byte{}, int(modLen)), nil
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()
default:
v = base.Exp(base, exp, mod).Bytes()
@@ -1355,3 +1387,92 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
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
}

View File

@@ -8,8 +8,10 @@ import (
"github.com/tendermint/iavl"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/secp256k1"
cmn "github.com/tendermint/tendermint/libs/common"
//nolint:staticcheck
v1 "github.com/ethereum/go-ethereum/core/vm/lightclient/v1"
v2 "github.com/ethereum/go-ethereum/core/vm/lightclient/v2"
"github.com/ethereum/go-ethereum/params"
@@ -104,7 +106,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
return result, nil
}
//------------------------------------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------------------------------------------------
// iavlMerkleProofValidate implemented as a native contract.
type iavlMerkleProofValidate struct {
@@ -397,3 +399,40 @@ type cometBFTLightBlockValidateHertz struct {
func (c *cometBFTLightBlockValidateHertz) Run(input []byte) (result []byte, err error) {
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
}

View File

@@ -373,3 +373,42 @@ func TestCometBFTLightBlockValidateHertz(t *testing.T) {
require.NoError(t, err)
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)
}
}

View File

@@ -67,6 +67,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{},
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
common.BytesToAddress([]byte{104}): &verifyDoubleSignEvidence{},
}
// EIP-152 test vectors
@@ -405,3 +406,14 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
}
benchmarkPrecompiled("0f", testcase, b)
}
func TestDoubleSignSlash(t *testing.T) {
tc := precompiledTest{
Input: "f906278202cab9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494976ea74026e726554db657fa54763abd0c3a0aa9a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a804ae755e0fe64b59753f4db6308a1f679747bce186aa2c62b95fa6eeff3fbd08f3b0667e45428a54ade15bad19f49641c499b431b36f65803ea71b379e6b61de501a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094976ea74026e726554db657fa54763abd0c3a0aa9a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a80c0b17bfe88534296ff064cb7156548f6deba2d6310d5044ed6485f087dc6ef232e051c28e1909c2b50a3b4f29345d66681c319bef653e52e5d746480d5a3983b00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000",
Expected: "15d34aaf54267db7d7c367839aaf71a00a2c6a65000000000000000000000000000000000000000000000000000000006555fa64",
Gas: 1000,
Name: "",
}
testPrecompiled("68", tc, t)
}

View File

@@ -48,6 +48,8 @@ type (
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract
switch {
case evm.chainRules.IsFeynman:
precompiles = PrecompiledContractsFeynman
case evm.chainRules.IsCancun:
precompiles = PrecompiledContractsCancun
case evm.chainRules.IsHertz:

View File

@@ -90,7 +90,7 @@ func newCancunInstructionSet() JumpTable {
}
func newShanghaiInstructionSet() JumpTable {
instructionSet := newMergeInstructionSet()
instructionSet := newLondonInstructionSet()
enable3855(&instructionSet) // PUSH0 instruction
enable3860(&instructionSet) // Limit and meter initcode

View File

@@ -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 \
&& cd /root/genesis && npm install
#RUN curl -L https://foundry.paradigm.xyz | bash
COPY --from=bsc /usr/local/bin/geth /usr/local/bin/geth

View File

@@ -170,9 +170,9 @@ type TxFetcher struct {
alternates map[common.Hash]map[string]struct{} // In-flight transaction alternate origins if retrieval fails
// Callbacks
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
fetchTxs func(string, []common.Hash) error // Retrieves a set of txs from a remote peer
hasTx func(common.Hash) bool // Retrieves a tx from the 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
step chan struct{} // Notification channel when the fetcher loop iterates
clock mclock.Clock // Time wrapper to simulate in tests
@@ -181,14 +181,14 @@ type TxFetcher struct {
// NewTxFetcher creates a transaction fetcher to retrieve transaction
// 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)
}
// NewTxFetcherForTests is a testing method to mock out the realtime clock with
// a simulated version and the internal randomness with a deterministic one.
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 {
return &TxFetcher{
notify: make(chan *txAnnounce),
@@ -300,7 +300,7 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool)
for j, tx := range batch {
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.
// Avoid re-request this transaction when we receive another
// announcement.

View File

@@ -378,7 +378,7 @@ func TestTransactionFetcherCleanup(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -417,7 +417,7 @@ func TestTransactionFetcherCleanupEmpty(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -455,7 +455,7 @@ func TestTransactionFetcherMissingRescheduling(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -501,7 +501,7 @@ func TestTransactionFetcherMissingCleanup(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -539,7 +539,7 @@ func TestTransactionFetcherBroadcasts(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -644,7 +644,7 @@ func TestTransactionFetcherTimeoutRescheduling(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -865,7 +865,7 @@ func TestTransactionFetcherUnderpricedDedup(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
errs := make([]error, len(txs))
for i := 0; i < len(errs); i++ {
if i%2 == 0 {
@@ -938,7 +938,7 @@ func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
errs := make([]error, len(txs))
for i := 0; i < len(errs); i++ {
errs[i] = txpool.ErrUnderpriced
@@ -964,7 +964,7 @@ func TestTransactionFetcherOutOfBoundDeliveries(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -1017,7 +1017,7 @@ func TestTransactionFetcherDrop(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -1083,7 +1083,7 @@ func TestTransactionFetcherDropRescheduling(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -1128,7 +1128,7 @@ func TestTransactionFetcherFuzzCrash01(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -1155,7 +1155,7 @@ func TestTransactionFetcherFuzzCrash02(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -1184,7 +1184,7 @@ func TestTransactionFetcherFuzzCrash03(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },
@@ -1217,7 +1217,7 @@ func TestTransactionFetcherFuzzCrash04(t *testing.T) {
init: func() *TxFetcher {
return NewTxFetcher(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error {

View File

@@ -118,42 +118,40 @@ func TestFilters(t *testing.T) {
contract = common.Address{0xfe}
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"}]`
// 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
pragma solidity >=0.7.0 <0.9.0;
contract Logger {
function log0() external {
assembly {
log0(0, 0)
}
}
function log0() external {
assembly {
log0(0, 0)
}
}
function log1(uint t1) external {
assembly {
log1(0, 0, t1)
}
}
function log1(uint t1) external {
assembly {
log1(0, 0, t1)
}
}
function log2(uint t1, uint t2) external {
assembly {
log2(0, 0, t1, t2)
}
}
function log2(uint t1, uint t2) external {
assembly {
log2(0, 0, t1, t2)
}
}
function log3(uint t1, uint t2, uint t3) external {
assembly {
log3(0, 0, t1, t2, t3)
}
}
function log3(uint t1, uint t2, uint t3) external {
assembly {
log3(0, 0, t1, t2, t3)
}
}
function log4(uint t1, uint t2, uint t3, uint t4) external {
assembly {
log4(0, 0, t1, t2, t3, t4)
}
}
function log4(uint t1, uint t2, uint t3, uint t4) external {
assembly {
log4(0, 0, t1, t2, t3, t4)
}
}
}
*/
bytecode = common.FromHex("608060405234801561001057600080fd5b50600436106100575760003560e01c80630aa731851461005c5780632a4c08961461006657806378b9a1f314610082578063c670f8641461009e578063c683d6a3146100ba575b600080fd5b6100646100d6565b005b610080600480360381019061007b9190610143565b6100dc565b005b61009c60048036038101906100979190610196565b6100e8565b005b6100b860048036038101906100b391906101d6565b6100f2565b005b6100d460048036038101906100cf9190610203565b6100fa565b005b600080a0565b808284600080a3505050565b8082600080a25050565b80600080a150565b80828486600080a450505050565b600080fd5b6000819050919050565b6101208161010d565b811461012b57600080fd5b50565b60008135905061013d81610117565b92915050565b60008060006060848603121561015c5761015b610108565b5b600061016a8682870161012e565b935050602061017b8682870161012e565b925050604061018c8682870161012e565b9150509250925092565b600080604083850312156101ad576101ac610108565b5b60006101bb8582860161012e565b92505060206101cc8582860161012e565b9150509250929050565b6000602082840312156101ec576101eb610108565b5b60006101fa8482850161012e565b91505092915050565b6000806000806080858703121561021d5761021c610108565b5b600061022b8782880161012e565b945050602061023c8782880161012e565b935050604061024d8782880161012e565b925050606061025e8782880161012e565b9150509295919450925056fea264697066735822122073a4b156f487e59970dc1ef449cc0d51467268f676033a17188edafcee861f9864736f6c63430008110033")
@@ -171,9 +169,7 @@ func TestFilters(t *testing.T) {
contract: {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.InitialBaseFee),
BaseFee: gasPrice1Gwei,
BaseFee: big.NewInt(params.InitialBaseFeeForEthMainnet),
}
)
@@ -197,7 +193,7 @@ func TestFilters(t *testing.T) {
}
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
Nonce: 0,
GasPrice: gasPrice1Gwei,
GasPrice: gen.BaseFee(),
Gas: 30000,
To: &contract,
Data: data,
@@ -205,7 +201,7 @@ func TestFilters(t *testing.T) {
gen.AddTx(tx)
tx2, _ := types.SignTx(types.NewTx(&types.LegacyTx{
Nonce: 1,
GasPrice: gasPrice1Gwei,
GasPrice: gen.BaseFee(),
Gas: 30000,
To: &contract2,
Data: data,
@@ -218,7 +214,7 @@ func TestFilters(t *testing.T) {
}
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
Nonce: 2,
GasPrice: gasPrice1Gwei,
GasPrice: gen.BaseFee(),
Gas: 30000,
To: &contract,
Data: data,
@@ -231,7 +227,7 @@ func TestFilters(t *testing.T) {
}
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
Nonce: 3,
GasPrice: gasPrice1Gwei,
GasPrice: gen.BaseFee(),
Gas: 30000,
To: &contract2,
Data: data,
@@ -244,7 +240,7 @@ func TestFilters(t *testing.T) {
}
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
Nonce: 4,
GasPrice: gasPrice1Gwei,
GasPrice: gen.BaseFee(),
Gas: 30000,
To: &contract,
Data: data,
@@ -290,61 +286,74 @@ func TestFilters(t *testing.T) {
}{
{
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),
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(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),
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),
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), []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(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),
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),
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0xcaea5cabe64d59ac0c74ca2eed41b1ef36dc996415ca085396d0f5acb0094935","transactionIndex":"0x0","blockHash":"0xf926a72aac711b12c385bdb7e935c49c3b77b4a857e4c924d9bfcf940694f3c1","logIndex":"0x0","removed":false}]`,
}, {
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil, false),
}, {
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, 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),
},
{
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
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",
}, {
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",
},
*/
{
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),
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),
err: "invalid block range",
},

View File

@@ -146,6 +146,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
config.LubanBlock = nil
config.PlatoBlock = nil
config.HertzBlock = nil
config.HertzfixBlock = nil
config.TerminalTotalDifficulty = common.Big0
engine := ethash.NewFaker()

View File

@@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/core/monitor"
"github.com/ethereum/go-ethereum/core/rawdb"
"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/eth/downloader"
"github.com/ethereum/go-ethereum/eth/fetcher"
@@ -65,7 +66,8 @@ const (
)
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
@@ -342,8 +344,21 @@ func newHandler(config *handlerConfig) (*handler, error) {
}
return p.RequestTxs(hashes)
}
addTxs := func(txs []*txpool.Transaction) []error {
return h.txpool.Add(txs, false, false)
addTxs := func(peer string, txs []*txpool.Transaction) []error {
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.chainSync = newChainSyncer(h)

View File

@@ -17,6 +17,8 @@
package eth
import (
"net"
"github.com/ethereum/go-ethereum/eth/protocols/bsc"
"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
// about a connected peer.
type snapPeerInfo struct {

View File

@@ -27,6 +27,7 @@ import (
"sync/atomic"
"time"
"github.com/cockroachdb/errors"
"github.com/cockroachdb/pebble"
"github.com/cockroachdb/pebble/bloom"
"github.com/ethereum/go-ethereum/common"
@@ -116,6 +117,16 @@ func (d *Database) onWriteStallEnd() {
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
// metrics reporting should use for surfacing internal stats.
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
}
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
// 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 {
memTableSize = maxMemTableSize
}
logger.Info("Allocated cache and file handles", "cache", common.StorageSize(cache*1024*1024),
"handles", handles, "memory table", common.StorageSize(memTableSize))
db := &Database{
fn: file,
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).
// 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
// 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
// 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,
EventListener: &pebble.EventListener{
CompactionBegin: db.onCompactionBegin,
@@ -186,7 +191,21 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
WriteStallBegin: db.onWriteStallBegin,
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
// for more details.
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
// which turns out a lot faster than leveldb. It's performant enough to construct
// batch object without any pre-allocated space.
func (d *Database) NewBatchWithSize(_ int) ethdb.Batch {
func (d *Database) NewBatchWithSize(size int) ethdb.Batch {
return &batch{
b: d.db.NewBatch(),
b: d.db.NewBatchWithSize(size),
db: d,
}
}
@@ -576,7 +595,7 @@ type pebbleIterator struct {
// of database content with a particular key prefix, starting at a particular
// initial key (or after, if it does not exist).
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...),
UpperBound: upperBound(prefix),
})

7
go.mod
View File

@@ -13,7 +13,8 @@ require (
github.com/btcsuite/btcd/btcec/v2 v2.3.2
github.com/cespare/cp v1.1.1
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/consensys/gnark-crypto v0.10.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/v2 v2.2.0 // 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/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/containerd/cgroups v1.1.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/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/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
View File

@@ -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/ics23 v0.1.0 h1:DvjGOts2FBfbxB48384CYD1LbcrfjThFz8kowY/7KxU=
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.15/go.mod h1:cmt8HHmQUSVaWQ/hoTefRxsh5X3ERaM1zCUIR0DPbFU=
github.com/bnb-chain/tendermint v0.31.16 h1:rOO6WG61JDAuRCCL8TKnGhorJftQDVygq0mqR7A0ck4=
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/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=
@@ -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/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.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/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-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
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-20230906160148-46873a6a7a06/go.mod h1:bynZ3gvVyhlvjLI7PT6dmZ7g76xzJ7HpxfjgkzCGz6s=
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A=
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/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/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=

View File

@@ -711,11 +711,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
gasLimit := env.header.GasLimit
if env.gasPool == nil {
env.gasPool = new(core.GasPool).AddGas(gasLimit)
if w.chain.Config().IsEuler(env.header.Number) {
env.gasPool.SubGas(params.SystemTxsGas * 3)
} else {
env.gasPool.SubGas(params.SystemTxsGas)
}
env.gasPool.SubGas(params.SystemTxsGas * 5)
}
var coalescedLogs []*types.Log
@@ -728,7 +724,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
stopPrefetchCh := make(chan struct{})
defer close(stopPrefetchCh)
//prefetch txs from all pending txs
// prefetch txs from all pending txs
txsPrefetch := txs.Copy()
tx := txsPrefetch.PeekWithUnwrap()
if tx != nil {
@@ -914,7 +910,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
}
// 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
}
@@ -1163,12 +1159,14 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti
if interval != nil {
interval()
}
/*
err := env.state.WaitPipeVerification()
if err != nil {
return err
}
env.state.CorrectAccountsRoot(w.chain.CurrentBlock().Root)
err := env.state.WaitPipeVerification()
if err != nil {
return err
}
env.state.CorrectAccountsRoot(w.chain.CurrentBlock().Root)
*/
// Withdrawals are set to nil here, because this is only called in PoW.
finalizeStart := time.Now()

View File

@@ -210,6 +210,9 @@ func (p *Peer) RemoteAddr() net.Addr {
}
log.Warn("RemoteAddr", "invalid testRemoteAddr", p.testRemoteAddr)
}
if p.rw == nil {
return nil
}
return p.rw.fd.RemoteAddr()
}

View File

@@ -159,15 +159,18 @@ var (
MoranBlock: big.NewInt(22107423),
GibbsBlock: big.NewInt(23846001),
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 Caution !!! it should be very careful !!!
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),
// TODO
FeynmanTime: nil,
Parlia: &ParliaConfig{
Period: 3,
@@ -195,15 +198,18 @@ var (
NanoBlock: big.NewInt(23482428),
MoranBlock: big.NewInt(23603940),
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 Caution !!! it should be very careful !!!
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),
// TODO
FeynmanTime: nil,
Parlia: &ParliaConfig{
Period: 3,
@@ -212,7 +218,7 @@ var (
}
RialtoChainConfig = &ChainConfig{
ChainID: big.NewInt(1417),
ChainID: big.NewInt(714),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
@@ -222,21 +228,26 @@ var (
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
RamanujanBlock: big.NewInt(400),
RamanujanBlock: big.NewInt(0),
NielsBlock: big.NewInt(0),
MirrorSyncBlock: big.NewInt(400),
BrunoBlock: big.NewInt(400),
EulerBlock: big.NewInt(400),
GibbsBlock: big.NewInt(400),
MirrorSyncBlock: big.NewInt(1),
BrunoBlock: big.NewInt(1),
EulerBlock: big.NewInt(2),
GibbsBlock: big.NewInt(3),
NanoBlock: nil,
MoranBlock: nil,
PlanckBlock: nil,
MoranBlock: big.NewInt(4),
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
LubanBlock: nil,
PlatoBlock: nil,
BerlinBlock: nil,
HertzBlock: nil,
ShanghaiTime: _rialto_upgrade_height_,
KeplerTime: _rialto_upgrade_height_,
FeynmanTime: _rialto_upgrade_height_,
Parlia: &ParliaConfig{
Period: 3,
@@ -269,7 +280,7 @@ var (
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
HertzBlock: big.NewInt(0),
HertzfixBlock: big.NewInt(0),
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
@@ -458,6 +469,8 @@ type ChainConfig struct {
// 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)
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)
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)
@@ -483,7 +496,7 @@ type ChainConfig struct {
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)
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
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
Clique *CliqueConfig `json:"clique,omitempty" toml:",omitempty"`
@@ -540,7 +553,22 @@ func (c *ChainConfig) String() string {
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.HomesteadBlock,
c.DAOForkBlock,
@@ -571,6 +599,10 @@ func (c *ChainConfig) String() string {
c.LubanBlock,
c.PlatoBlock,
c.HertzBlock,
c.HertzfixBlock,
ShanghaiTime,
KeplerTime,
FeynmanTime,
engine,
)
}
@@ -690,6 +722,14 @@ func (c *ChainConfig) IsOnHertz(num *big.Int) bool {
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.
func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
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)
}
// 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.
func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
@@ -837,7 +905,10 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{name: "lubanBlock", block: c.LubanBlock},
{name: "platoBlock", block: c.PlatoBlock},
{name: "hertzBlock", block: c.HertzBlock},
{name: "hertzfixBlock", block: c.HertzfixBlock},
{name: "shanghaiTime", timestamp: c.ShanghaiTime},
{name: "keplerTime", timestamp: c.KeplerTime},
{name: "feynmanTime", timestamp: c.FeynmanTime},
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
{name: "pragueTime", timestamp: c.PragueTime, 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) {
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) {
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) {
return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime)
}
@@ -1131,7 +1211,8 @@ type Rules struct {
IsLuban bool
IsPlato bool
IsHertz bool
IsShanghai, IsCancun, IsPrague bool
IsHertzfix bool
IsShanghai, IsKepler, IsFeynman, IsCancun, IsPrague bool
IsVerkle bool
}
@@ -1160,7 +1241,10 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
IsLuban: c.IsLuban(num),
IsPlato: c.IsPlato(num),
IsHertz: c.IsHertz(num),
IsHertzfix: c.IsHertzfix(num),
IsShanghai: c.IsShanghai(num, timestamp),
IsKepler: c.IsKepler(num, timestamp),
IsFeynman: c.IsFeynman(num, timestamp),
IsCancun: c.IsCancun(num, timestamp),
IsPrague: c.IsPrague(num, timestamp),
IsVerkle: c.IsVerkle(num, timestamp),

View File

@@ -144,6 +144,7 @@ const (
IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation
BlsSignatureVerifyBaseGas uint64 = 1000 // base 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
Bn256AddGasIstanbul uint64 = 150 // Gas needed for an elliptic curve addition

View File

@@ -23,7 +23,7 @@ import (
const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 3 // Minor version component of the current release
VersionPatch = 3 // 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
)

View File

@@ -26,10 +26,15 @@ import (
"time"
"github.com/ethereum/go-ethereum/common/gopool"
"github.com/ethereum/go-ethereum/metrics"
"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 is not safe for concurrent use. Message handling never blocks indefinitely
// 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")
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)
if resp.Error.Data != nil {
ctx = append(ctx, "errdata", resp.Error.Data)

View File

@@ -262,7 +262,7 @@ func parliaHeaderHashAndRlp(header *types.Header, chainId *big.Int) (hash, rlp [
return
}
rlp = parlia.ParliaRLP(header, chainId)
hash = parlia.SealHash(header, chainId).Bytes()
hash = types.SealHash(header, chainId).Bytes()
return hash, rlp, err
}

View File

@@ -30,7 +30,7 @@ func TestBlockchain(t *testing.T) {
// 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
// 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
bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`)
@@ -49,6 +49,9 @@ func TestBlockchain(t *testing.T) {
// using 4.6 TGas
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) {
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil)); err != nil {
t.Errorf("test in hash mode without snapshotter failed: %v", err)

View File

@@ -80,7 +80,7 @@ func Fuzz(input []byte) int {
f := fetcher.NewTxFetcherForTests(
func(common.Hash) bool { return false },
func(txs []*txpool.Transaction) []error {
func(peer string, txs []*txpool.Transaction) []error {
return make([]error, len(txs))
},
func(string, []common.Hash) error { return nil },

View File

@@ -93,7 +93,7 @@ type testMatcher struct {
failpat []testFailure
skiploadpat []*regexp.Regexp
slowpat []*regexp.Regexp
runonlylistpat *regexp.Regexp
runonlylistpat []*regexp.Regexp
}
type testConfig struct {
@@ -127,7 +127,7 @@ func (tm *testMatcher) fails(pattern string, reason 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.
@@ -220,7 +220,14 @@ func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest inte
t.Skip(r)
}
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")
}
}

View File

@@ -68,6 +68,8 @@ func TestState(t *testing.T) {
st.fails(`stEIP4844-blobtransactions/opcodeBlobhashOutOfRange.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 _, dir := range []string{
filepath.Join(baseDir, "EIPTests", "StateTests"),

View File

@@ -300,7 +300,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
// And _now_ get the state root
root := statedb.IntermediateRoot(config.IsEIP158(block.Number()))
statedb.SetExpectedStateRoot(root)
root, _, err = statedb.Commit(block.NumberU64(), nil)
root, _, _ = statedb.Commit(block.NumberU64(), nil)
return triedb, snaps, statedb, root, err
}

View File

@@ -1,4 +1,4 @@
BSC_CHAIN_ID=99
BSC_CHAIN_ID=714
CLUSTER_CIDR=99.1.0.0/16
BOOTSTRAP_PUB_KEY=177ae5db445a2f70db781b019aedd928f5b1528a7a43448840b022408f9a21509adcce0b37c87d59da68d47a16879cc1e95a62bbac9723f7b22f4365b2afabbe
BOOTSTRAP_TCP_PORT=30311

View File

@@ -7,26 +7,29 @@ function prepare() {
echo "geth do not exist!"
exit 1
fi
rm -rf ${workspace}/storage/*
cd ${workspace}/genesis
rm -rf validators.conf
cp ${workspace}/storage/genesis.json ${workspace}/genesis/genesis.json
}
function init_validator() {
node_id=$1
rm -rf ${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
validatorAddr=`cat ${workspace}/storage/${node_id}Info|grep 'Public address of the key'|awk '{print $6}'`
echo "${validatorAddr},${validatorAddr},${validatorAddr},0x0000000010000000" >> ${workspace}/genesis/validators.conf
echo ${validatorAddr} > ${workspace}/storage/${node_id}/address
cp -r ${workspace}/storage/keystore ${workspace}/storage/${node_id}/
cp ${workspace}/storage/address ${workspace}/storage/${node_id}/address
}
function generate_genesis() {
cd ${workspace}/genesis/scripts/
node generate-validator.js
INIT_HOLDER_ADDRESSES=$(ls ${workspace}/init-holders | tr '\n' ',')
INIT_HOLDER_ADDRESSES=${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() {
@@ -43,8 +46,8 @@ function init_genesis_data() {
function prepareBLSWallet(){
node_id=$1
echo "123456" > ${workspace}/storage/${node_id}/blspassword.txt
expect ${workspace}/scripts/create_bls_key.sh ${workspace}/storage/${node_id}
echo "1234567890" > ${workspace}/storage/${node_id}/blspassword.txt
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
PassWordPath="/root/.ethereum/blspassword.txt"
@@ -54,14 +57,14 @@ function prepareBLSWallet(){
}
prepare
NUMS_OF_VALIDATOR=1
# Step 1, generate config for each validator
for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do
init_validator "bsc-validator${i}"
done
# Step 2, use validator configs to generate genesis file
generate_genesis
#generate_genesis
# Step 3, use genesis file to init cluster data
init_genesis_data bsc-rpc bsc-rpc

View File

@@ -13,4 +13,4 @@ done
geth --config ${DATA_DIR}/config.toml --datadir ${DATA_DIR} --netrestrict ${CLUSTER_CIDR} \
--verbosity ${VERBOSE} --nousb \
--rpc.allow-unprotected-txs --history.transactions 15768000 \
-unlock ${unlock_sequences} --password /dev/null
-unlock ${unlock_sequences} --password /dev/null >${DATA_DIR}/bscnode-rpc.log

View File

@@ -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} \
--mine -unlock ${VALIDATOR_ADDR} --miner.etherbase ${VALIDATOR_ADDR} --password /dev/null \
--light.serve 50 \
--rpc.allow-unprotected-txs --history.transactions 15768000
--rpc.allow-unprotected-txs --history.transactions 15768000 >${DATA_DIR}/bscnode-validator.log

View File

@@ -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

View File

@@ -0,0 +1 @@
0x03735c2ED70a56CD221e0024eB4bF90243C9d6E9

File diff suppressed because one or more lines are too long

View File

@@ -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}

View File

@@ -172,7 +172,7 @@ func New(diskdb ethdb.Database, config *Config) *Database {
// mechanism also ensures that at most one **non-readOnly** database
// is opened at the same time to prevent accidental mutation.
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)
if err != nil {
log.Crit("Failed to open state history freezer", "err", err)