Compare commits
17 Commits
v1.3.6
...
bc-fusion-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
880667e77f | ||
|
|
f599fee78c | ||
|
|
eb93010928 | ||
|
|
d94cb56ae9 | ||
|
|
0438b61114 | ||
|
|
c73b11055e | ||
|
|
54f334a95f | ||
|
|
f2e38fec9a | ||
|
|
d1118313ce | ||
|
|
288b4f9926 | ||
|
|
6744d7c15f | ||
|
|
3414e5672a | ||
|
|
8f3c525adc | ||
|
|
3e9e6423c0 | ||
|
|
5743b067ba | ||
|
|
d3f882d799 | ||
|
|
030e41607e |
4
.github/workflows/build-test.yml
vendored
4
.github/workflows/build-test.yml
vendored
@@ -7,7 +7,7 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
|
|
||||||
@@ -47,5 +47,3 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
go mod download
|
go mod download
|
||||||
make geth
|
make geth
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/commit-lint.yml
vendored
2
.github/workflows/commit-lint.yml
vendored
@@ -7,7 +7,7 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/integration-test.yml
vendored
2
.github/workflows/integration-test.yml
vendored
@@ -7,7 +7,7 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
@@ -7,7 +7,7 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
go mod download
|
go mod tidy
|
||||||
|
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v3
|
||||||
|
|||||||
3
.github/workflows/unit-test.yml
vendored
3
.github/workflows/unit-test.yml
vendored
@@ -7,7 +7,7 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
|
|
||||||
@@ -52,4 +52,3 @@ jobs:
|
|||||||
git submodule update --init --depth 1 --recursive
|
git submodule update --init --depth 1 --recursive
|
||||||
go mod download
|
go mod download
|
||||||
make test
|
make test
|
||||||
|
|
||||||
|
|||||||
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,22 +1,4 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
## v1.3.6
|
|
||||||
FEATURE
|
|
||||||
* [\#2012](https://github.com/bnb-chain/bsc/pull/2012) cmd, core, ethdb: enable Pebble on 32 bits and OpenBSD
|
|
||||||
* [\#2063](https://github.com/bnb-chain/bsc/pull/2063) log: support to disable log rotate by hours
|
|
||||||
* [\#2064](https://github.com/bnb-chain/bsc/pull/2064) log: limit rotateHours in range [0,23]
|
|
||||||
|
|
||||||
BUGFIX
|
|
||||||
* [\#2058](https://github.com/bnb-chain/bsc/pull/2058) params: set default hardfork times
|
|
||||||
|
|
||||||
IMPROVEMENT
|
|
||||||
* [\#2015](https://github.com/bnb-chain/bsc/pull/2015) cmd, core, eth: change default network from ETH to BSC
|
|
||||||
* [\#2036](https://github.com/bnb-chain/bsc/pull/2036) cmd/jsutils: add 2 tools get validator version and block txs number
|
|
||||||
* [\#2037](https://github.com/bnb-chain/bsc/pull/2037) core/txpool/legacypool: respect nolocals-setting
|
|
||||||
* [\#2042](https://github.com/bnb-chain/bsc/pull/2042) core/systemcontracts: update CommitUrl for keplerUpgrade
|
|
||||||
* [\#2043](https://github.com/bnb-chain/bsc/pull/2043) tests/truffle: adapt changes in bsc-genesis-contracts
|
|
||||||
* [\#2051](https://github.com/bnb-chain/bsc/pull/2051) core/vote: wait some blocks before voting since mining begin
|
|
||||||
* [\#2060](https://github.com/bnb-chain/bsc/pull/2060) cmd/utils: allow HTTPHost and WSHost flags precede
|
|
||||||
|
|
||||||
## v1.3.5
|
## v1.3.5
|
||||||
FEATURE
|
FEATURE
|
||||||
* [\#1970](https://github.com/bnb-chain/bsc/pull/1970) core: enable Shanghai EIPs
|
* [\#1970](https://github.com/bnb-chain/bsc/pull/1970) core: enable Shanghai EIPs
|
||||||
|
|||||||
@@ -110,15 +110,15 @@ on how you can run your own `geth` instance.
|
|||||||
|
|
||||||
The hardware must meet certain requirements to run a full node on mainnet:
|
The hardware must meet certain requirements to run a full node on mainnet:
|
||||||
- VPS running recent versions of Mac OS X, Linux, or Windows.
|
- VPS running recent versions of Mac OS X, Linux, or Windows.
|
||||||
- IMPORTANT 3 TB(Dec 2023) of free disk space, solid-state drive(SSD), gp3, 8k IOPS, 500 MB/S throughput, read latency <1ms. (if node is started with snap sync, it will need NVMe SSD)
|
- IMPORTANT 2.5 TB(May 2023) of free disk space, solid-state drive(SSD), gp3, 8k IOPS, 250 MB/S throughput, read latency <1ms. (if node is started with snap sync, it will need NVMe SSD)
|
||||||
- 16 cores of CPU and 64 GB of memory (RAM)
|
- 16 cores of CPU and 64 GB of memory (RAM)
|
||||||
- Suggest m5zn.6xlarge or r7iz.4xlarge instance type on AWS, c2-standard-16 on Google cloud.
|
- Suggest m5zn.3xlarge instance type on AWS, c2-standard-16 on Google cloud.
|
||||||
- A broadband Internet connection with upload/download speeds of 5 MB/S
|
- A broadband Internet connection with upload/download speeds of 5 MB/S
|
||||||
|
|
||||||
The requirement for testnet:
|
The requirement for testnet:
|
||||||
- VPS running recent versions of Mac OS X, Linux, or Windows.
|
- VPS running recent versions of Mac OS X, Linux, or Windows.
|
||||||
- 500G of storage for testnet.
|
- 500G of storage for testnet.
|
||||||
- 4 cores of CPU and 16 gigabytes of memory (RAM).
|
- 4 cores of CPU and 8 gigabytes of memory (RAM).
|
||||||
|
|
||||||
### Steps to Run a Fullnode
|
### Steps to Run a Fullnode
|
||||||
|
|
||||||
|
|||||||
@@ -2127,7 +2127,7 @@ func TestGolangBindings(t *testing.T) {
|
|||||||
t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out)
|
t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.15") // Repo root
|
replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.16") // Repo root
|
||||||
replacer.Dir = pkg
|
replacer.Dir = pkg
|
||||||
if out, err := replacer.CombinedOutput(); err != nil {
|
if out, err := replacer.CombinedOutput(); err != nil {
|
||||||
t.Fatalf("failed to replace tendermint dependency to bnb-chain source: %v\n%s", err, out)
|
t.Fatalf("failed to replace tendermint dependency to bnb-chain source: %v\n%s", err, out)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ set to standard output. The following filters are supported:
|
|||||||
- `-limit <N>` limits the output set to N entries, taking the top N nodes by score
|
- `-limit <N>` limits the output set to N entries, taking the top N nodes by score
|
||||||
- `-ip <CIDR>` filters nodes by IP subnet
|
- `-ip <CIDR>` filters nodes by IP subnet
|
||||||
- `-min-age <duration>` filters nodes by 'first seen' time
|
- `-min-age <duration>` filters nodes by 'first seen' time
|
||||||
- `-eth-network <mainnet/goerli/sepolia/holesky>` filters nodes by "eth" ENR entry
|
- `-eth-network <mainnet/goerli/sepolia>` filters nodes by "eth" ENR entry
|
||||||
- `-les-server` filters nodes by LES server support
|
- `-les-server` filters nodes by LES server support
|
||||||
- `-snap` filters nodes by snap protocol support
|
- `-snap` filters nodes by snap protocol support
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/v4/io/prompt"
|
"github.com/prysmaticlabs/prysm/v4/io/prompt"
|
||||||
"github.com/prysmaticlabs/prysm/v4/proto/eth/service"
|
"github.com/prysmaticlabs/prysm/v4/proto/eth/service"
|
||||||
|
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
|
||||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts/iface"
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts/iface"
|
||||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts/petnames"
|
"github.com/prysmaticlabs/prysm/v4/validator/accounts/petnames"
|
||||||
@@ -26,6 +28,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/signer/core"
|
"github.com/ethereum/go-ethereum/signer/core"
|
||||||
)
|
)
|
||||||
@@ -47,6 +50,10 @@ var (
|
|||||||
Usage: "Password file path for the imported BLS account , which contains the password to get the private key by decrypting the keystore file",
|
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,
|
Category: flags.AccountCategory,
|
||||||
}
|
}
|
||||||
|
chainIdFlag = &cli.Int64Flag{
|
||||||
|
Name: "chain-id",
|
||||||
|
Usage: "The chain id of the network that the validator will be created at",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -189,6 +196,22 @@ Print summary of existing BLS accounts in the current BLS wallet.`,
|
|||||||
|
|
||||||
Delete the selected BLS account from the BLS wallet.`,
|
Delete the selected BLS account from the BLS wallet.`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "generate-proof",
|
||||||
|
Usage: "Generate ownership proof for the selected BLS account from the BLS wallet",
|
||||||
|
Action: blsAccountGenerateProof,
|
||||||
|
ArgsUsage: "<BLS pubkey>",
|
||||||
|
Category: "BLS ACCOUNT COMMANDS",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
utils.DataDirFlag,
|
||||||
|
utils.BLSPasswordFileFlag,
|
||||||
|
chainIdFlag,
|
||||||
|
},
|
||||||
|
Description: `
|
||||||
|
geth bls account generate-proof
|
||||||
|
|
||||||
|
Generate ownership proof for the selected BLS account from the BLS wallet. The proof is used to prove the ownership of the BLS account when creating validator on BSC after feynman upgrade.`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -608,3 +631,79 @@ func blsAccountDelete(ctx *cli.Context) error {
|
|||||||
|
|
||||||
return nil
|
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.")
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
if len(filteredPubKeys) > 1 {
|
||||||
|
utils.Fatalf("Only support one BLS account specified.")
|
||||||
|
}
|
||||||
|
pubkeyBz := filteredPubKeys[0].Marshal()
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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("Open BLS wallet failed: %v.", err)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ func TestConsoleWelcome(t *testing.T) {
|
|||||||
geth.SetTemplateFunc("gover", runtime.Version)
|
geth.SetTemplateFunc("gover", runtime.Version)
|
||||||
geth.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
geth.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
||||||
geth.SetTemplateFunc("niltime", func() string {
|
geth.SetTemplateFunc("niltime", func() string {
|
||||||
return time.Unix(0x5e9da7ce, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
return time.Unix(0, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
||||||
})
|
})
|
||||||
geth.SetTemplateFunc("apis", func() string { return ipcAPIs })
|
geth.SetTemplateFunc("apis", func() string { return ipcAPIs })
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) {
|
|||||||
attach.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
attach.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
||||||
attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase })
|
attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase })
|
||||||
attach.SetTemplateFunc("niltime", func() string {
|
attach.SetTemplateFunc("niltime", func() string {
|
||||||
return time.Unix(0x5e9da7ce, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
return time.Unix(0, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
||||||
})
|
})
|
||||||
attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") })
|
attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") })
|
||||||
attach.SetTemplateFunc("datadir", func() string { return geth.Datadir })
|
attach.SetTemplateFunc("datadir", func() string { return geth.Datadir })
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ a data corruption.`,
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
utils.DataDirFlag,
|
utils.DataDirFlag,
|
||||||
utils.SyncModeFlag,
|
utils.SyncModeFlag,
|
||||||
utils.BSCMainnetFlag,
|
utils.MainnetFlag,
|
||||||
utils.StateSchemeFlag,
|
utils.StateSchemeFlag,
|
||||||
},
|
},
|
||||||
Description: "This command looks up the specified trie node key from the database.",
|
Description: "This command looks up the specified trie node key from the database.",
|
||||||
@@ -132,7 +132,7 @@ a data corruption.`,
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
utils.DataDirFlag,
|
utils.DataDirFlag,
|
||||||
utils.SyncModeFlag,
|
utils.SyncModeFlag,
|
||||||
utils.BSCMainnetFlag,
|
utils.MainnetFlag,
|
||||||
utils.StateSchemeFlag,
|
utils.StateSchemeFlag,
|
||||||
},
|
},
|
||||||
Description: "This command delete the specify trie node from the database.",
|
Description: "This command delete the specify trie node from the database.",
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ func TestCustomBackend(t *testing.T) {
|
|||||||
initExpect: `Fatal: Invalid choice for db.engine 'mssql', allowed 'leveldb' or 'pebble'`,
|
initExpect: `Fatal: Invalid choice for db.engine 'mssql', allowed 'leveldb' or 'pebble'`,
|
||||||
// Since the init fails, this will return the (default) mainnet genesis
|
// Since the init fails, this will return the (default) mainnet genesis
|
||||||
// block nonce
|
// block nonce
|
||||||
execExpect: `0x0000000000000000`,
|
execExpect: `0x0000000000000042`,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
if err := testfunc(t, tt); err != nil {
|
if err := testfunc(t, tt); err != nil {
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ func prepare(ctx *cli.Context) {
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
case !ctx.IsSet(utils.NetworkIdFlag.Name):
|
case !ctx.IsSet(utils.NetworkIdFlag.Name):
|
||||||
log.Info("Starting Geth on BSC mainnet...")
|
log.Info("Starting Geth on Ethereum mainnet...")
|
||||||
}
|
}
|
||||||
// If we're a full node on mainnet without --cache specified, bump default cache allowance
|
// If we're a full node on mainnet without --cache specified, bump default cache allowance
|
||||||
if ctx.String(utils.SyncModeFlag.Name) != "light" && !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) {
|
if ctx.String(utils.SyncModeFlag.Name) != "light" && !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) {
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
## Requirement
|
|
||||||
|
|
||||||
- nodejs: v20.10.0
|
|
||||||
- npm: v10.2.3
|
|
||||||
|
|
||||||
## Prepare
|
|
||||||
Recommend use [nvm](https://github.com/nvm-sh/nvm) to manage node version.
|
|
||||||
|
|
||||||
Install node.js dependency:
|
|
||||||
```shell script
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
## Run
|
|
||||||
mainnet validators version
|
|
||||||
```bash
|
|
||||||
npm run startMainnet
|
|
||||||
```
|
|
||||||
testnet validators version
|
|
||||||
```bash
|
|
||||||
npm run startTestnet
|
|
||||||
```
|
|
||||||
Transaction count
|
|
||||||
```bash
|
|
||||||
node gettxcount.js --rpc ${url} --startNum ${start} --endNum ${end}
|
|
||||||
```
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { ethers } from "ethers";
|
|
||||||
import program from "commander";
|
|
||||||
|
|
||||||
program.option("--rpc <rpc>", "Rpc");
|
|
||||||
program.option("--startNum <startNum>", "start num")
|
|
||||||
program.option("--endNum <endNum>", "end num")
|
|
||||||
program.parse(process.argv);
|
|
||||||
|
|
||||||
const provider = new ethers.JsonRpcProvider(program.rpc)
|
|
||||||
|
|
||||||
const main = async () => {
|
|
||||||
let txCount = 0;
|
|
||||||
let num = 0;
|
|
||||||
console.log("Find the max txs count between", program.startNum, "and", program.endNum);
|
|
||||||
for (let i = program.startNum; i < program.endNum; i++) {
|
|
||||||
let x = await provider.send("eth_getBlockTransactionCountByNumber", [
|
|
||||||
ethers.toQuantity(i)]);
|
|
||||||
let a = ethers.toNumber(x)
|
|
||||||
if (a > txCount) {
|
|
||||||
num = i;
|
|
||||||
txCount = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("BlockNum = ", num, "TxCount =", txCount);
|
|
||||||
};
|
|
||||||
|
|
||||||
main().then(() => process.exit(0))
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { ethers } from "ethers";
|
|
||||||
import program from "commander";
|
|
||||||
|
|
||||||
program.option("--Rpc <Rpc>", "Rpc");
|
|
||||||
program.option("--Num <Num>", "validator num", 21)
|
|
||||||
program.parse(process.argv);
|
|
||||||
|
|
||||||
const provider = new ethers.JsonRpcProvider(program.Rpc);
|
|
||||||
|
|
||||||
const main = async () => {
|
|
||||||
const blockNum = await provider.getBlockNumber();
|
|
||||||
console.log(blockNum);
|
|
||||||
for (let i = 0; i < program.Num; i++) {
|
|
||||||
let blockData = await provider.getBlock(blockNum - i);
|
|
||||||
let major = ethers.toNumber(ethers.dataSlice(blockData.extraData, 2, 3))
|
|
||||||
let minor = ethers.toNumber(ethers.dataSlice(blockData.extraData, 3, 4))
|
|
||||||
let patch = ethers.toNumber(ethers.dataSlice(blockData.extraData, 4, 5))
|
|
||||||
console.log(blockData.miner, "version =", major + "." + minor + "." + patch)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
main().then(() => process.exit(0))
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "jsutils",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"description": "jsUtils for bsc",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"startMainnet": "node getvalidatorversion.js --Rpc https://bsc-dataseed.bnbchain.org --Num 21",
|
|
||||||
"startTestnet": "node getvalidatorversion.js --Rpc https://bsc-testnet-dataseed.bnbchain.org --Num 7"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"commander": "^3.0.1",
|
|
||||||
"ethers": "^6.2.3"
|
|
||||||
},
|
|
||||||
"author": "BNB Chain"
|
|
||||||
}
|
|
||||||
@@ -165,13 +165,13 @@ var (
|
|||||||
}
|
}
|
||||||
NetworkIdFlag = &cli.Uint64Flag{
|
NetworkIdFlag = &cli.Uint64Flag{
|
||||||
Name: "networkid",
|
Name: "networkid",
|
||||||
Usage: "Explicitly set network id (integer)(For testnets: use --goerli, --sepolia, --holesky instead)",
|
Usage: "Explicitly set network id (integer)(For testnets: use --goerli, --sepolia instead)",
|
||||||
Value: ethconfig.Defaults.NetworkId,
|
Value: ethconfig.Defaults.NetworkId,
|
||||||
Category: flags.EthCategory,
|
Category: flags.EthCategory,
|
||||||
}
|
}
|
||||||
BSCMainnetFlag = &cli.BoolFlag{
|
MainnetFlag = &cli.BoolFlag{
|
||||||
Name: "bsc",
|
Name: "mainnet",
|
||||||
Usage: "BSC mainnet",
|
Usage: "Ethereum mainnet",
|
||||||
Category: flags.EthCategory,
|
Category: flags.EthCategory,
|
||||||
}
|
}
|
||||||
DeveloperFlag = &cli.BoolFlag{
|
DeveloperFlag = &cli.BoolFlag{
|
||||||
@@ -1113,18 +1113,23 @@ var (
|
|||||||
// TestnetFlags is the flag group of all built-in supported testnets.
|
// TestnetFlags is the flag group of all built-in supported testnets.
|
||||||
TestnetFlags = []cli.Flag{}
|
TestnetFlags = []cli.Flag{}
|
||||||
// NetworkFlags is the flag group of all built-in supported networks.
|
// NetworkFlags is the flag group of all built-in supported networks.
|
||||||
NetworkFlags = append([]cli.Flag{BSCMainnetFlag}, TestnetFlags...)
|
NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...)
|
||||||
|
|
||||||
// DatabasePathFlags is the flag group of all database path flags.
|
// DatabasePathFlags is the flag group of all database path flags.
|
||||||
DatabasePathFlags = []cli.Flag{
|
DatabasePathFlags = []cli.Flag{
|
||||||
DataDirFlag,
|
DataDirFlag,
|
||||||
AncientFlag,
|
AncientFlag,
|
||||||
RemoteDBFlag,
|
RemoteDBFlag,
|
||||||
DBEngineFlag,
|
|
||||||
HttpHeaderFlag,
|
HttpHeaderFlag,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if rawdb.PebbleEnabled {
|
||||||
|
DatabasePathFlags = append(DatabasePathFlags, DBEngineFlag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MakeDataDir retrieves the currently requested data directory, terminating
|
// MakeDataDir retrieves the currently requested data directory, terminating
|
||||||
// if none (or the empty string) is specified. If the node is starting a testnet,
|
// if none (or the empty string) is specified. If the node is starting a testnet,
|
||||||
// then a subdirectory of the specified datadir will be used.
|
// then a subdirectory of the specified datadir will be used.
|
||||||
@@ -1254,10 +1259,8 @@ func SplitAndTrim(input string) (ret []string) {
|
|||||||
// setHTTP creates the HTTP RPC listener interface string from the set
|
// setHTTP creates the HTTP RPC listener interface string from the set
|
||||||
// command line flags, returning empty if the HTTP endpoint is disabled.
|
// command line flags, returning empty if the HTTP endpoint is disabled.
|
||||||
func setHTTP(ctx *cli.Context, cfg *node.Config) {
|
func setHTTP(ctx *cli.Context, cfg *node.Config) {
|
||||||
if ctx.Bool(HTTPEnabledFlag.Name) {
|
if ctx.Bool(HTTPEnabledFlag.Name) && cfg.HTTPHost == "" {
|
||||||
if cfg.HTTPHost == "" {
|
cfg.HTTPHost = "127.0.0.1"
|
||||||
cfg.HTTPHost = "127.0.0.1"
|
|
||||||
}
|
|
||||||
if ctx.IsSet(HTTPListenAddrFlag.Name) {
|
if ctx.IsSet(HTTPListenAddrFlag.Name) {
|
||||||
cfg.HTTPHost = ctx.String(HTTPListenAddrFlag.Name)
|
cfg.HTTPHost = ctx.String(HTTPListenAddrFlag.Name)
|
||||||
}
|
}
|
||||||
@@ -1321,10 +1324,8 @@ func setGraphQL(ctx *cli.Context, cfg *node.Config) {
|
|||||||
// setWS creates the WebSocket RPC listener interface string from the set
|
// setWS creates the WebSocket RPC listener interface string from the set
|
||||||
// command line flags, returning empty if the HTTP endpoint is disabled.
|
// command line flags, returning empty if the HTTP endpoint is disabled.
|
||||||
func setWS(ctx *cli.Context, cfg *node.Config) {
|
func setWS(ctx *cli.Context, cfg *node.Config) {
|
||||||
if ctx.Bool(WSEnabledFlag.Name) {
|
if ctx.Bool(WSEnabledFlag.Name) && cfg.WSHost == "" {
|
||||||
if cfg.WSHost == "" {
|
cfg.WSHost = "127.0.0.1"
|
||||||
cfg.WSHost = "127.0.0.1"
|
|
||||||
}
|
|
||||||
if ctx.IsSet(WSListenAddrFlag.Name) {
|
if ctx.IsSet(WSListenAddrFlag.Name) {
|
||||||
cfg.WSHost = ctx.String(WSListenAddrFlag.Name)
|
cfg.WSHost = ctx.String(WSListenAddrFlag.Name)
|
||||||
}
|
}
|
||||||
@@ -1844,7 +1845,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
|
|||||||
// SetEthConfig applies eth-related command line flags to the config.
|
// SetEthConfig applies eth-related command line flags to the config.
|
||||||
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
// Avoid conflicting network flags
|
// Avoid conflicting network flags
|
||||||
CheckExclusive(ctx, BSCMainnetFlag, DeveloperFlag)
|
CheckExclusive(ctx, MainnetFlag, DeveloperFlag)
|
||||||
CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
|
CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
|
||||||
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
|
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
|
||||||
|
|
||||||
@@ -2033,12 +2034,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||||||
}
|
}
|
||||||
// Override any default configs for hard coded networks.
|
// Override any default configs for hard coded networks.
|
||||||
switch {
|
switch {
|
||||||
case ctx.Bool(BSCMainnetFlag.Name):
|
case ctx.Bool(MainnetFlag.Name):
|
||||||
if !ctx.IsSet(NetworkIdFlag.Name) {
|
if !ctx.IsSet(NetworkIdFlag.Name) {
|
||||||
cfg.NetworkId = 56
|
cfg.NetworkId = 1
|
||||||
}
|
}
|
||||||
cfg.Genesis = core.DefaultBSCGenesisBlock()
|
cfg.Genesis = core.DefaultGenesisBlock()
|
||||||
SetDNSDiscoveryDefaults(cfg, params.BSCGenesisHash)
|
SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash)
|
||||||
case ctx.Bool(DeveloperFlag.Name):
|
case ctx.Bool(DeveloperFlag.Name):
|
||||||
if !ctx.IsSet(NetworkIdFlag.Name) {
|
if !ctx.IsSet(NetworkIdFlag.Name) {
|
||||||
cfg.NetworkId = 1337
|
cfg.NetworkId = 1337
|
||||||
@@ -2398,8 +2399,8 @@ func DialRPCWithHeaders(endpoint string, headers []string) (*rpc.Client, error)
|
|||||||
func MakeGenesis(ctx *cli.Context) *core.Genesis {
|
func MakeGenesis(ctx *cli.Context) *core.Genesis {
|
||||||
var genesis *core.Genesis
|
var genesis *core.Genesis
|
||||||
switch {
|
switch {
|
||||||
case ctx.Bool(BSCMainnetFlag.Name):
|
case ctx.Bool(MainnetFlag.Name):
|
||||||
genesis = core.DefaultBSCGenesisBlock()
|
genesis = core.DefaultGenesisBlock()
|
||||||
case ctx.Bool(DeveloperFlag.Name):
|
case ctx.Bool(DeveloperFlag.Name):
|
||||||
Fatalf("Developer chains are ephemeral")
|
Fatalf("Developer chains are ephemeral")
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
223
consensus/parlia/feynmanfork.go
Normal file
223
consensus/parlia/feynmanfork.go
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
package parlia
|
||||||
|
|
||||||
|
import (
|
||||||
|
"container/heap"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/systemcontracts"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// initializeFeynmanContract initialize new contracts of Feynman fork
|
||||||
|
func (p *Parlia) initializeFeynmanContract(state *state.StateDB, header *types.Header, chain core.ChainContext,
|
||||||
|
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool,
|
||||||
|
) error {
|
||||||
|
// method
|
||||||
|
method := "initialize"
|
||||||
|
|
||||||
|
// initialize contracts
|
||||||
|
contracts := []string{
|
||||||
|
systemcontracts.StakeHubContract,
|
||||||
|
systemcontracts.GovernorContract,
|
||||||
|
systemcontracts.GovTokenContract,
|
||||||
|
systemcontracts.TimelockContract,
|
||||||
|
}
|
||||||
|
// get packed data
|
||||||
|
data, err := p.stakeHubABI.Pack(method)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for initialize feynman contracts", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, c := range contracts {
|
||||||
|
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(c), data, common.Big0)
|
||||||
|
// apply message
|
||||||
|
log.Info("initialize feynman contract", "block number", header.Number.Uint64(), "contract", c)
|
||||||
|
err = p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidatorItem struct {
|
||||||
|
address common.Address
|
||||||
|
votingPower *big.Int
|
||||||
|
voteAddress []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ValidatorHeap is a max-heap of validator's votingPower.
|
||||||
|
type ValidatorHeap []ValidatorItem
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Len() int { return len(*h) }
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Less(i, j int) bool {
|
||||||
|
// We want topK validators with max voting power, so we need a max-heap
|
||||||
|
if (*h)[i].votingPower.Cmp((*h)[j].votingPower) == 0 {
|
||||||
|
return (*h)[i].address.Hex() < (*h)[j].address.Hex()
|
||||||
|
} else {
|
||||||
|
return (*h)[i].votingPower.Cmp((*h)[j].votingPower) == 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Swap(i, j int) { (*h)[i], (*h)[j] = (*h)[j], (*h)[i] }
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Push(x interface{}) {
|
||||||
|
*h = append(*h, x.(ValidatorItem))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ValidatorHeap) Pop() interface{} {
|
||||||
|
old := *h
|
||||||
|
n := len(old)
|
||||||
|
x := old[n-1]
|
||||||
|
*h = old[0 : n-1]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) updateValidatorSetV2(state *state.StateDB, header *types.Header, chain core.ChainContext,
|
||||||
|
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool,
|
||||||
|
) error {
|
||||||
|
// 1. get all validators and its voting power
|
||||||
|
blockNr := rpc.BlockNumberOrHashWithHash(header.ParentHash, false)
|
||||||
|
validatorItems, err := p.getValidatorElectionInfo(blockNr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
maxElectedValidators, err := p.getMaxElectedValidators(blockNr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. sort by voting power
|
||||||
|
eValidators, eVotingPowers, eVoteAddrs := getTopValidatorsByVotingPower(validatorItems, maxElectedValidators)
|
||||||
|
|
||||||
|
// 3. update validator set to system contract
|
||||||
|
method := "updateValidatorSetV2"
|
||||||
|
data, err := p.validatorSetABI.Pack(method, eValidators, eVotingPowers, eVoteAddrs)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for updateValidatorSetV2", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// get system message
|
||||||
|
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, common.Big0)
|
||||||
|
// apply message
|
||||||
|
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) getValidatorElectionInfo(blockNr rpc.BlockNumberOrHash) ([]ValidatorItem, error) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
method := "getValidatorElectionInfo"
|
||||||
|
toAddress := common.HexToAddress(systemcontracts.StakeHubContract)
|
||||||
|
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
|
||||||
|
|
||||||
|
data, err := p.stakeHubABI.Pack(method, big.NewInt(0), big.NewInt(0))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for getValidatorElectionInfo", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
msgData := (hexutil.Bytes)(data)
|
||||||
|
|
||||||
|
result, err := p.ethAPI.Call(ctx, ethapi.TransactionArgs{
|
||||||
|
Gas: &gas,
|
||||||
|
To: &toAddress,
|
||||||
|
Data: &msgData,
|
||||||
|
}, blockNr, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var validators []common.Address
|
||||||
|
var votingPowers []*big.Int
|
||||||
|
var voteAddrs [][]byte
|
||||||
|
var totalLength *big.Int
|
||||||
|
if err := p.stakeHubABI.UnpackIntoInterface(&[]interface{}{&validators, &votingPowers, &voteAddrs, &totalLength}, method, result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if totalLength.Int64() != int64(len(validators)) || totalLength.Int64() != int64(len(votingPowers)) || totalLength.Int64() != int64(len(voteAddrs)) {
|
||||||
|
return nil, fmt.Errorf("validator length not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
validatorItems := make([]ValidatorItem, len(validators))
|
||||||
|
for i := 0; i < len(validators); i++ {
|
||||||
|
validatorItems[i] = ValidatorItem{
|
||||||
|
address: validators[i],
|
||||||
|
votingPower: votingPowers[i],
|
||||||
|
voteAddress: voteAddrs[i],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return validatorItems, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) getMaxElectedValidators(blockNr rpc.BlockNumberOrHash) (maxElectedValidators *big.Int, err error) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
method := "maxElectedValidators"
|
||||||
|
toAddress := common.HexToAddress(systemcontracts.StakeHubContract)
|
||||||
|
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
|
||||||
|
|
||||||
|
data, err := p.stakeHubABI.Pack(method)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to pack tx for maxElectedValidators", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
msgData := (hexutil.Bytes)(data)
|
||||||
|
|
||||||
|
result, err := p.ethAPI.Call(ctx, ethapi.TransactionArgs{
|
||||||
|
Gas: &gas,
|
||||||
|
To: &toAddress,
|
||||||
|
Data: &msgData,
|
||||||
|
}, blockNr, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.stakeHubABI.UnpackIntoInterface(&maxElectedValidators, method, result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxElectedValidators, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTopValidatorsByVotingPower(validatorItems []ValidatorItem, maxElectedValidators *big.Int) ([]common.Address, []uint64, [][]byte) {
|
||||||
|
var validatorHeap ValidatorHeap
|
||||||
|
for i := 0; i < len(validatorItems); i++ {
|
||||||
|
// only keep validators with voting power > 0
|
||||||
|
if validatorItems[i].votingPower.Cmp(big.NewInt(0)) == 1 {
|
||||||
|
validatorHeap = append(validatorHeap, validatorItems[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hp := &validatorHeap
|
||||||
|
heap.Init(hp)
|
||||||
|
|
||||||
|
topN := int(maxElectedValidators.Int64())
|
||||||
|
if topN > len(validatorHeap) {
|
||||||
|
topN = len(validatorHeap)
|
||||||
|
}
|
||||||
|
eValidators := make([]common.Address, topN)
|
||||||
|
eVotingPowers := make([]uint64, topN)
|
||||||
|
eVoteAddrs := make([][]byte, topN)
|
||||||
|
for i := 0; i < topN; i++ {
|
||||||
|
item := heap.Pop(hp).(ValidatorItem)
|
||||||
|
eValidators[i] = item.address
|
||||||
|
// as the decimal in BNB Beacon Chain is 1e8 and in BNB Smart Chain is 1e18, we need to divide it by 1e10
|
||||||
|
eVotingPowers[i] = new(big.Int).Div(item.votingPower, big.NewInt(1e10)).Uint64()
|
||||||
|
eVoteAddrs[i] = item.voteAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
return eValidators, eVotingPowers, eVoteAddrs
|
||||||
|
}
|
||||||
166
consensus/parlia/feynmanfork_test.go
Normal file
166
consensus/parlia/feynmanfork_test.go
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package parlia
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidatorHeap(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
description string
|
||||||
|
k int64
|
||||||
|
validators []ValidatorItem
|
||||||
|
expected []common.Address
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "normal case",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(200), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(100), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
common.HexToAddress("0x2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "same voting power",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(100), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(100), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
common.HexToAddress("0x2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "zero voting power and k > len(validators)",
|
||||||
|
k: 5,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x4"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "zero voting power and k < len(validators)",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: new(big.Int).Mul(big.NewInt(300), big.NewInt(1e10)),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x4"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{
|
||||||
|
common.HexToAddress("0x1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "all zero voting power",
|
||||||
|
k: 2,
|
||||||
|
validators: []ValidatorItem{
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x1"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x2"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x3"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x3"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: common.HexToAddress("0x4"),
|
||||||
|
votingPower: big.NewInt(0),
|
||||||
|
voteAddress: []byte("0x4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []common.Address{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
eligibleValidators, _, _ := getTopValidatorsByVotingPower(tc.validators, big.NewInt(tc.k))
|
||||||
|
|
||||||
|
// check
|
||||||
|
if len(eligibleValidators) != len(tc.expected) {
|
||||||
|
t.Errorf("expected %d, got %d", len(tc.expected), len(eligibleValidators))
|
||||||
|
}
|
||||||
|
for i := 0; i < len(tc.expected); i++ {
|
||||||
|
if eligibleValidators[i] != tc.expected[i] {
|
||||||
|
t.Errorf("expected %s, got %s", tc.expected[i].Hex(), eligibleValidators[i].Hex())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -91,6 +90,10 @@ var (
|
|||||||
common.HexToAddress(systemcontracts.TokenHubContract): true,
|
common.HexToAddress(systemcontracts.TokenHubContract): true,
|
||||||
common.HexToAddress(systemcontracts.RelayerIncentivizeContract): true,
|
common.HexToAddress(systemcontracts.RelayerIncentivizeContract): true,
|
||||||
common.HexToAddress(systemcontracts.CrossChainContract): true,
|
common.HexToAddress(systemcontracts.CrossChainContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.StakeHubContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.GovernorContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.GovTokenContract): true,
|
||||||
|
common.HexToAddress(systemcontracts.TimelockContract): true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -180,7 +183,7 @@ func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (
|
|||||||
signature := header.Extra[len(header.Extra)-extraSeal:]
|
signature := header.Extra[len(header.Extra)-extraSeal:]
|
||||||
|
|
||||||
// Recover the public key and the Ethereum address
|
// Recover the public key and the Ethereum address
|
||||||
pubkey, err := crypto.Ecrecover(SealHash(header, chainId).Bytes(), signature)
|
pubkey, err := crypto.Ecrecover(types.SealHash(header, chainId).Bytes(), signature)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
@@ -200,7 +203,7 @@ func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (
|
|||||||
// or not), which could be abused to produce different hashes for the same header.
|
// or not), which could be abused to produce different hashes for the same header.
|
||||||
func ParliaRLP(header *types.Header, chainId *big.Int) []byte {
|
func ParliaRLP(header *types.Header, chainId *big.Int) []byte {
|
||||||
b := new(bytes.Buffer)
|
b := new(bytes.Buffer)
|
||||||
encodeSigHeader(b, header, chainId)
|
types.EncodeSigHeader(b, header, chainId)
|
||||||
return b.Bytes()
|
return b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,6 +230,7 @@ type Parlia struct {
|
|||||||
validatorSetABIBeforeLuban abi.ABI
|
validatorSetABIBeforeLuban abi.ABI
|
||||||
validatorSetABI abi.ABI
|
validatorSetABI abi.ABI
|
||||||
slashABI abi.ABI
|
slashABI abi.ABI
|
||||||
|
stakeHubABI abi.ABI
|
||||||
|
|
||||||
// The fields below are for testing only
|
// The fields below are for testing only
|
||||||
fakeDiff bool // Skip difficulty verifications
|
fakeDiff bool // Skip difficulty verifications
|
||||||
@@ -268,6 +272,10 @@ func New(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
stABI, err := abi.JSON(strings.NewReader(stakeABI))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
c := &Parlia{
|
c := &Parlia{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
config: parliaConfig,
|
config: parliaConfig,
|
||||||
@@ -279,6 +287,7 @@ func New(
|
|||||||
validatorSetABIBeforeLuban: vABIBeforeLuban,
|
validatorSetABIBeforeLuban: vABIBeforeLuban,
|
||||||
validatorSetABI: vABI,
|
validatorSetABI: vABI,
|
||||||
slashABI: sABI,
|
slashABI: sABI,
|
||||||
|
stakeHubABI: stABI,
|
||||||
signer: types.LatestSigner(chainConfig),
|
signer: types.LatestSigner(chainConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -903,7 +912,7 @@ func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, head
|
|||||||
// Prepare vote address bitset.
|
// Prepare vote address bitset.
|
||||||
for _, valInfo := range snap.Validators {
|
for _, valInfo := range snap.Validators {
|
||||||
if _, ok := voteAddrSet[valInfo.VoteAddress]; ok {
|
if _, ok := voteAddrSet[valInfo.VoteAddress]; ok {
|
||||||
attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) //Index is offset by 1
|
attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) // Index is offset by 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)})
|
validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)})
|
||||||
@@ -1153,6 +1162,29 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent := chain.GetHeaderByHash(header.ParentHash)
|
||||||
|
if parent == nil {
|
||||||
|
return errors.New("parent not found")
|
||||||
|
}
|
||||||
|
if p.chainConfig.IsOnFeynman(header.Number, parent.Time, header.Time) {
|
||||||
|
err := p.initializeFeynmanContract(state, header, cx, txs, receipts, systemTxs, usedGas, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("init feynman contract failed", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update validators every day
|
||||||
|
if p.chainConfig.IsFeynman(header.Number, header.Time) {
|
||||||
|
// TODO: revert this
|
||||||
|
// if time.Unix(int64(parent.Time), 0).Day() < time.Unix(int64(header.Time), 0).Day() {
|
||||||
|
if time.Unix(int64(header.Time), 0).Minute() != time.Unix(int64(parent.Time), 0).Minute() {
|
||||||
|
if err := p.updateValidatorSetV2(state, header, cx, txs, receipts, systemTxs, usedGas, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(*systemTxs) > 0 {
|
if len(*systemTxs) > 0 {
|
||||||
return errors.New("the length of systemTxs do not match")
|
return errors.New("the length of systemTxs do not match")
|
||||||
}
|
}
|
||||||
@@ -1215,6 +1247,28 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent := chain.GetHeaderByHash(header.ParentHash)
|
||||||
|
if parent == nil {
|
||||||
|
return nil, nil, errors.New("parent not found")
|
||||||
|
}
|
||||||
|
if p.chainConfig.IsOnFeynman(header.Number, parent.Time, header.Time) {
|
||||||
|
err := p.initializeFeynmanContract(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("init feynman contract failed", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update validators every day
|
||||||
|
if p.chainConfig.IsFeynman(header.Number, header.Time) {
|
||||||
|
// TODO: revert this
|
||||||
|
// if time.Unix(int64(parent.Time), 0).Day() < time.Unix(int64(header.Time), 0).Day() {
|
||||||
|
if time.Unix(int64(header.Time), 0).Minute() != time.Unix(int64(parent.Time), 0).Minute() {
|
||||||
|
if err := p.updateValidatorSetV2(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// should not happen. Once happen, stop the node is better than broadcast the block
|
// should not happen. Once happen, stop the node is better than broadcast the block
|
||||||
if header.GasLimit < header.GasUsed {
|
if header.GasLimit < header.GasUsed {
|
||||||
return nil, nil, errors.New("gas consumption of system txs exceed the gas limit")
|
return nil, nil, errors.New("gas consumption of system txs exceed the gas limit")
|
||||||
@@ -1417,7 +1471,7 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res
|
|||||||
select {
|
select {
|
||||||
case results <- block.WithSeal(header):
|
case results <- block.WithSeal(header):
|
||||||
default:
|
default:
|
||||||
log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header, p.chainConfig.ChainID))
|
log.Warn("Sealing result is not read by miner", "sealhash", types.SealHash(header, p.chainConfig.ChainID))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -1491,7 +1545,7 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
|
|||||||
// So it's not the real hash of a block, just used as unique id to distinguish task
|
// So it's not the real hash of a block, just used as unique id to distinguish task
|
||||||
func (p *Parlia) SealHash(header *types.Header) (hash common.Hash) {
|
func (p *Parlia) SealHash(header *types.Header) (hash common.Hash) {
|
||||||
hasher := sha3.NewLegacyKeccak256()
|
hasher := sha3.NewLegacyKeccak256()
|
||||||
encodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
|
types.EncodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID)
|
||||||
hasher.Sum(hash[:0])
|
hasher.Sum(hash[:0])
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
@@ -1549,16 +1603,15 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNum *big.Int)
|
|||||||
|
|
||||||
var valSet []common.Address
|
var valSet []common.Address
|
||||||
var voteAddrSet []types.BLSPublicKey
|
var voteAddrSet []types.BLSPublicKey
|
||||||
|
|
||||||
if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, result); err != nil {
|
if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, result); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
voteAddrmap := make(map[common.Address]*types.BLSPublicKey, len(valSet))
|
voteAddrMap := make(map[common.Address]*types.BLSPublicKey, len(valSet))
|
||||||
for i := 0; i < len(valSet); i++ {
|
for i := 0; i < len(valSet); i++ {
|
||||||
voteAddrmap[valSet[i]] = &(voteAddrSet)[i]
|
voteAddrMap[valSet[i]] = &(voteAddrSet)[i]
|
||||||
}
|
}
|
||||||
return valSet, voteAddrmap, nil
|
return valSet, voteAddrMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// slash spoiled validators
|
// slash spoiled validators
|
||||||
@@ -1575,7 +1628,7 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he
|
|||||||
doDistributeSysReward := !p.chainConfig.IsKepler(header.Number, header.Time) &&
|
doDistributeSysReward := !p.chainConfig.IsKepler(header.Number, header.Time) &&
|
||||||
state.GetBalance(common.HexToAddress(systemcontracts.SystemRewardContract)).Cmp(maxSystemBalance) < 0
|
state.GetBalance(common.HexToAddress(systemcontracts.SystemRewardContract)).Cmp(maxSystemBalance) < 0
|
||||||
if doDistributeSysReward {
|
if doDistributeSysReward {
|
||||||
var rewards = new(big.Int)
|
rewards := new(big.Int)
|
||||||
rewards = rewards.Rsh(balance, systemRewardPercent)
|
rewards = rewards.Rsh(balance, systemRewardPercent)
|
||||||
if rewards.Cmp(common.Big0) > 0 {
|
if rewards.Cmp(common.Big0) > 0 {
|
||||||
err := p.distributeToSystem(rewards, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
err := p.distributeToSystem(rewards, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
|
||||||
@@ -1795,62 +1848,6 @@ func (p *Parlia) GetFinalizedHeader(chain consensus.ChainHeaderReader, header *t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =========================== utility function ==========================
|
// =========================== utility function ==========================
|
||||||
// SealHash returns the hash of a block prior to it being sealed.
|
|
||||||
func SealHash(header *types.Header, chainId *big.Int) (hash common.Hash) {
|
|
||||||
hasher := sha3.NewLegacyKeccak256()
|
|
||||||
encodeSigHeader(hasher, header, chainId)
|
|
||||||
hasher.Sum(hash[:0])
|
|
||||||
return hash
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) {
|
|
||||||
err := rlp.Encode(w, []interface{}{
|
|
||||||
chainId,
|
|
||||||
header.ParentHash,
|
|
||||||
header.UncleHash,
|
|
||||||
header.Coinbase,
|
|
||||||
header.Root,
|
|
||||||
header.TxHash,
|
|
||||||
header.ReceiptHash,
|
|
||||||
header.Bloom,
|
|
||||||
header.Difficulty,
|
|
||||||
header.Number,
|
|
||||||
header.GasLimit,
|
|
||||||
header.GasUsed,
|
|
||||||
header.Time,
|
|
||||||
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
|
|
||||||
header.MixDigest,
|
|
||||||
header.Nonce,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic("can't encode: " + err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeSigHeaderWithoutVoteAttestation(w io.Writer, header *types.Header, chainId *big.Int) {
|
|
||||||
err := rlp.Encode(w, []interface{}{
|
|
||||||
chainId,
|
|
||||||
header.ParentHash,
|
|
||||||
header.UncleHash,
|
|
||||||
header.Coinbase,
|
|
||||||
header.Root,
|
|
||||||
header.TxHash,
|
|
||||||
header.ReceiptHash,
|
|
||||||
header.Bloom,
|
|
||||||
header.Difficulty,
|
|
||||||
header.Number,
|
|
||||||
header.GasLimit,
|
|
||||||
header.GasUsed,
|
|
||||||
header.Time,
|
|
||||||
header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation
|
|
||||||
header.MixDigest,
|
|
||||||
header.Nonce,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic("can't encode: " + err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Address) uint64 {
|
func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Address) uint64 {
|
||||||
if snap.inturn(val) {
|
if snap.inturn(val) {
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -202,8 +202,8 @@ func CommitGenesisState(db ethdb.Database, triedb *trie.Database, blockhash comm
|
|||||||
// - private network, can't recover
|
// - private network, can't recover
|
||||||
var genesis *Genesis
|
var genesis *Genesis
|
||||||
switch blockhash {
|
switch blockhash {
|
||||||
case params.BSCGenesisHash:
|
case params.MainnetGenesisHash:
|
||||||
genesis = DefaultBSCGenesisBlock()
|
genesis = DefaultGenesisBlock()
|
||||||
}
|
}
|
||||||
if genesis != nil {
|
if genesis != nil {
|
||||||
alloc = genesis.Alloc
|
alloc = genesis.Alloc
|
||||||
@@ -318,8 +318,8 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
|||||||
systemcontracts.GenesisHash = stored
|
systemcontracts.GenesisHash = stored
|
||||||
if (stored == common.Hash{}) {
|
if (stored == common.Hash{}) {
|
||||||
if genesis == nil {
|
if genesis == nil {
|
||||||
log.Info("Writing default BSC mainnet genesis block")
|
log.Info("Writing default main-net genesis block")
|
||||||
genesis = DefaultBSCGenesisBlock()
|
genesis = DefaultGenesisBlock()
|
||||||
} else {
|
} else {
|
||||||
log.Info("Writing custom genesis block")
|
log.Info("Writing custom genesis block")
|
||||||
}
|
}
|
||||||
@@ -328,7 +328,6 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
|||||||
return genesis.Config, common.Hash{}, err
|
return genesis.Config, common.Hash{}, err
|
||||||
}
|
}
|
||||||
applyOverrides(genesis.Config)
|
applyOverrides(genesis.Config)
|
||||||
log.Info("genesis block hash", "hash", block.Hash())
|
|
||||||
return genesis.Config, block.Hash(), nil
|
return genesis.Config, block.Hash(), nil
|
||||||
}
|
}
|
||||||
// The genesis block is present(perhaps in ancient database) while the
|
// The genesis block is present(perhaps in ancient database) while the
|
||||||
@@ -338,7 +337,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen
|
|||||||
header := rawdb.ReadHeader(db, stored, 0)
|
header := rawdb.ReadHeader(db, stored, 0)
|
||||||
if header.Root != types.EmptyRootHash && !triedb.Initialized(header.Root) {
|
if header.Root != types.EmptyRootHash && !triedb.Initialized(header.Root) {
|
||||||
if genesis == nil {
|
if genesis == nil {
|
||||||
genesis = DefaultBSCGenesisBlock()
|
genesis = DefaultGenesisBlock()
|
||||||
}
|
}
|
||||||
// Ensure the stored genesis matches with the given one.
|
// Ensure the stored genesis matches with the given one.
|
||||||
hash := genesis.ToBlock().Hash()
|
hash := genesis.ToBlock().Hash()
|
||||||
@@ -432,37 +431,33 @@ func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig,
|
|||||||
return params.BSCChainConfig, params.BSCGenesisHash, nil
|
return params.BSCChainConfig, params.BSCGenesisHash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// For any block or time in g.Config which is nil but the same field in defaultConfig is not
|
// For any block in g.Config which is nil but the same block in defaultConfig is not
|
||||||
// set the field in genesis config to the field in defaultConfig.
|
// set the block in genesis config to the block in defaultConfig.
|
||||||
// Reflection is used to avoid a long series of if statements with hardcoded block names.
|
// Reflection is used to avoid a long series of if statements with hardcoded block names.
|
||||||
func (g *Genesis) setDefaultHardforkValues(defaultConfig *params.ChainConfig) {
|
func (g *Genesis) setDefaultBlockValues(defaultConfig *params.ChainConfig) {
|
||||||
// Regex to match Block names or Time names
|
// Regex to match block names
|
||||||
hardforkPattern := []string{`.*Block$`, `.*Time$`}
|
blockRegex := regexp.MustCompile(`.*Block$`)
|
||||||
|
|
||||||
for _, pat := range hardforkPattern {
|
// Get reflect values
|
||||||
hardforkRegex := regexp.MustCompile(pat)
|
gConfigElem := reflect.ValueOf(g.Config).Elem()
|
||||||
|
defaultConfigElem := reflect.ValueOf(defaultConfig).Elem()
|
||||||
|
|
||||||
// Get reflect values
|
// Iterate over fields in config
|
||||||
gConfigElem := reflect.ValueOf(g.Config).Elem()
|
for i := 0; i < gConfigElem.NumField(); i++ {
|
||||||
defaultConfigElem := reflect.ValueOf(defaultConfig).Elem()
|
gConfigField := gConfigElem.Field(i)
|
||||||
|
defaultConfigField := defaultConfigElem.Field(i)
|
||||||
|
fieldName := gConfigElem.Type().Field(i).Name
|
||||||
|
|
||||||
// Iterate over fields in config
|
// Use the regex to check if the field is a Block field
|
||||||
for i := 0; i < gConfigElem.NumField(); i++ {
|
if gConfigField.Kind() == reflect.Ptr && blockRegex.MatchString(fieldName) {
|
||||||
gConfigField := gConfigElem.Field(i)
|
if gConfigField.IsNil() {
|
||||||
defaultConfigField := defaultConfigElem.Field(i)
|
gConfigField.Set(defaultConfigField)
|
||||||
fieldName := gConfigElem.Type().Field(i).Name
|
|
||||||
|
|
||||||
// Use the regex to check if the field is a Block or Time field
|
|
||||||
if gConfigField.Kind() == reflect.Ptr && hardforkRegex.MatchString(fieldName) {
|
|
||||||
if gConfigField.IsNil() {
|
|
||||||
gConfigField.Set(defaultConfigField)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hard fork field specified in config.toml has higher priority, but
|
// Hard fork block height specified in config.toml has higher priority, but
|
||||||
// if it is not specified in config.toml, use the default height in code.
|
// if it is not specified in config.toml, use the default height in code.
|
||||||
func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
||||||
var defaultConfig *params.ChainConfig
|
var defaultConfig *params.ChainConfig
|
||||||
@@ -486,7 +481,7 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
|||||||
return defaultConfig
|
return defaultConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
g.setDefaultHardforkValues(defaultConfig)
|
g.setDefaultBlockValues(defaultConfig)
|
||||||
|
|
||||||
// BSC Parlia set up
|
// BSC Parlia set up
|
||||||
if g.Config.Parlia == nil {
|
if g.Config.Parlia == nil {
|
||||||
@@ -613,22 +608,6 @@ func DefaultGenesisBlock() *Genesis {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBSCGenesisBlock returns the BSC mainnet genesis block.
|
|
||||||
func DefaultBSCGenesisBlock() *Genesis {
|
|
||||||
alloc := decodePrealloc(bscMainnetAllocData)
|
|
||||||
return &Genesis{
|
|
||||||
Config: params.BSCChainConfig,
|
|
||||||
Nonce: 0,
|
|
||||||
ExtraData: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000002a7cdd959bfe8d9487b2a43b33565295a698f7e26488aa4d1955ee33403f8ccb1d4de5fb97c7ade29ef9f4360c606c7ab4db26b016007d3ad0ab86a0ee01c3b1283aa067c58eab4709f85e99d46de5fe685b1ded8013785d6623cc18d214320b6bb6475978f3adfc719c99674c072166708589033e2d9afec2be4ec20253b8642161bc3f444f53679c1f3d472f7be8361c80a4c1e7e9aaf001d0877f1cfde218ce2fd7544e0b2cc94692d4a704debef7bcb61328b8f7166496996a7da21cf1f1b04d9b3e26a3d0772d4c407bbe49438ed859fe965b140dcf1aab71a96bbad7cf34b5fa511d8e963dbba288b1960e75d64430b3230294d12c6ab2aac5c2cd68e80b16b581ea0a6e3c511bbd10f4519ece37dc24887e11b55d7ae2f5b9e386cd1b50a4550696d957cb4900f03a82012708dafc9e1b880fd083b32182b869be8e0922b81f8e175ffde54d797fe11eb03f9e3bf75f1d68bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d8c4d90829ce8f72d0163c1d5cf348a862d55063035e7a025f4da968de7e4d7e4004197917f4070f1d6caa02bbebaebb5d7e581e4b66559e635f805ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
|
|
||||||
GasLimit: 40000000,
|
|
||||||
Difficulty: big.NewInt(1),
|
|
||||||
Mixhash: common.Hash(hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000")),
|
|
||||||
Coinbase: common.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE"),
|
|
||||||
Timestamp: 0x5e9da7ce,
|
|
||||||
Alloc: alloc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
|
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
|
||||||
func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
|
func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
|
||||||
// Override the default period to the user requested one
|
// Override the default period to the user requested one
|
||||||
@@ -656,34 +635,13 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func decodePrealloc(data string) GenesisAlloc {
|
func decodePrealloc(data string) GenesisAlloc {
|
||||||
var p []struct {
|
var p []struct{ Addr, Balance *big.Int }
|
||||||
Addr *big.Int
|
|
||||||
Balance *big.Int
|
|
||||||
Misc *struct {
|
|
||||||
Nonce uint64
|
|
||||||
Code []byte
|
|
||||||
Slots []struct {
|
|
||||||
Key common.Hash
|
|
||||||
Val common.Hash
|
|
||||||
}
|
|
||||||
} `rlp:"optional"`
|
|
||||||
}
|
|
||||||
if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
|
if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
ga := make(GenesisAlloc, len(p))
|
ga := make(GenesisAlloc, len(p))
|
||||||
for _, account := range p {
|
for _, account := range p {
|
||||||
acc := GenesisAccount{Balance: account.Balance}
|
ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
|
||||||
if account.Misc != nil {
|
|
||||||
acc.Nonce = account.Misc.Nonce
|
|
||||||
acc.Code = account.Misc.Code
|
|
||||||
|
|
||||||
acc.Storage = make(map[common.Hash]common.Hash)
|
|
||||||
for _, slot := range account.Misc.Slots {
|
|
||||||
acc.Storage[slot.Key] = slot.Val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ga[common.BigToAddress(account.Addr)] = acc
|
|
||||||
}
|
}
|
||||||
return ga
|
return ga
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -71,8 +71,8 @@ func testSetupGenesis(t *testing.T, scheme string) {
|
|||||||
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
|
||||||
return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), nil)
|
return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), nil)
|
||||||
},
|
},
|
||||||
wantHash: params.BSCGenesisHash,
|
wantHash: params.MainnetGenesisHash,
|
||||||
wantConfig: params.BSCChainConfig,
|
wantConfig: params.MainnetChainConfig,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mainnet block in DB, genesis == nil",
|
name: "mainnet block in DB, genesis == nil",
|
||||||
@@ -258,9 +258,9 @@ func TestConfigOrDefault(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultHardforkValues(t *testing.T) {
|
func TestSetDefaultBlockValues(t *testing.T) {
|
||||||
genesis := &Genesis{Config: ¶ms.ChainConfig{ChainID: big.NewInt(66), HomesteadBlock: big.NewInt(11)}}
|
genesis := &Genesis{Config: ¶ms.ChainConfig{ChainID: big.NewInt(66), HomesteadBlock: big.NewInt(11)}}
|
||||||
genesis.setDefaultHardforkValues(params.BSCChainConfig)
|
genesis.setDefaultBlockValues(params.BSCChainConfig)
|
||||||
|
|
||||||
// Make sure the non-nil block was not modified
|
// Make sure the non-nil block was not modified
|
||||||
if genesis.Config.HomesteadBlock.Cmp(big.NewInt(11)) != 0 {
|
if genesis.Config.HomesteadBlock.Cmp(big.NewInt(11)) != 0 {
|
||||||
@@ -280,14 +280,6 @@ func TestSetDefaultHardforkValues(t *testing.T) {
|
|||||||
t.Errorf("Nano block not matching: in genesis = %v , in defaultConfig = %v", genesis.Config.PlanckBlock, params.BSCChainConfig.PlanckBlock)
|
t.Errorf("Nano block not matching: in genesis = %v , in defaultConfig = %v", genesis.Config.PlanckBlock, params.BSCChainConfig.PlanckBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spot check a few times
|
|
||||||
if *genesis.Config.ShanghaiTime != *params.BSCChainConfig.ShanghaiTime {
|
|
||||||
t.Errorf("Shanghai Time not matching: in genesis = %d , in defaultConfig = %d", *genesis.Config.ShanghaiTime, *params.BSCChainConfig.ShanghaiTime)
|
|
||||||
}
|
|
||||||
if *genesis.Config.KeplerTime != *params.BSCChainConfig.KeplerTime {
|
|
||||||
t.Errorf("Kepler Time not matching: in genesis = %d , in defaultConfig = %d", *genesis.Config.KeplerTime, *params.BSCChainConfig.KeplerTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lastly make sure non-block fields such as ChainID have not been modified
|
// Lastly make sure non-block fields such as ChainID have not been modified
|
||||||
if genesis.Config.ChainID.Cmp(big.NewInt(66)) != 0 {
|
if genesis.Config.ChainID.Cmp(big.NewInt(66)) != 0 {
|
||||||
t.Errorf("ChainID should not have been modified. ChainID = %v", genesis.Config.ChainID)
|
t.Errorf("ChainID should not have been modified. ChainID = %v", genesis.Config.ChainID)
|
||||||
|
|||||||
@@ -32,51 +32,24 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
type allocItem struct {
|
type allocItem struct{ Addr, Balance *big.Int }
|
||||||
Addr *big.Int
|
|
||||||
Balance *big.Int
|
|
||||||
Misc *allocItemMisc `rlp:"optional"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type allocItemMisc struct {
|
|
||||||
Nonce uint64
|
|
||||||
Code []byte
|
|
||||||
Slots []allocItemStorageItem
|
|
||||||
}
|
|
||||||
|
|
||||||
type allocItemStorageItem struct {
|
|
||||||
Key common.Hash
|
|
||||||
Val common.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
func makelist(g *core.Genesis) []allocItem {
|
func makelist(g *core.Genesis) []allocItem {
|
||||||
items := make([]allocItem, 0, len(g.Alloc))
|
items := make([]allocItem, 0, len(g.Alloc))
|
||||||
for addr, account := range g.Alloc {
|
for addr, account := range g.Alloc {
|
||||||
var misc *allocItemMisc
|
|
||||||
if len(account.Storage) > 0 || len(account.Code) > 0 || account.Nonce != 0 {
|
if len(account.Storage) > 0 || len(account.Code) > 0 || account.Nonce != 0 {
|
||||||
misc = &allocItemMisc{
|
panic(fmt.Sprintf("can't encode account %x", addr))
|
||||||
Nonce: account.Nonce,
|
|
||||||
Code: account.Code,
|
|
||||||
Slots: make([]allocItemStorageItem, 0, len(account.Storage)),
|
|
||||||
}
|
|
||||||
for key, val := range account.Storage {
|
|
||||||
misc.Slots = append(misc.Slots, allocItemStorageItem{key, val})
|
|
||||||
}
|
|
||||||
slices.SortFunc(misc.Slots, func(a, b allocItemStorageItem) int {
|
|
||||||
return a.Key.Cmp(b.Key)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
bigAddr := new(big.Int).SetBytes(addr.Bytes())
|
bigAddr := new(big.Int).SetBytes(addr.Bytes())
|
||||||
items = append(items, allocItem{bigAddr, account.Balance, misc})
|
items = append(items, allocItem{bigAddr, account.Balance})
|
||||||
}
|
}
|
||||||
slices.SortFunc(items, func(a, b allocItem) int {
|
slices.SortFunc(items, func(a, b allocItem) bool {
|
||||||
return a.Addr.Cmp(b.Addr)
|
return a.Addr.Cmp(b.Addr) < 0
|
||||||
})
|
})
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/leveldb"
|
"github.com/ethereum/go-ethereum/ethdb/leveldb"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/pebble"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -426,16 +425,6 @@ func NewLevelDBDatabaseWithFreezer(file string, cache int, handles int, ancient
|
|||||||
return frdb, nil
|
return frdb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPebbleDBDatabase creates a persistent key-value database without a freezer
|
|
||||||
// moving immutable chain segments into cold storage.
|
|
||||||
func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) {
|
|
||||||
db, err := pebble.New(file, cache, handles, namespace, readonly)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return NewDatabase(db), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
dbPebble = "pebble"
|
dbPebble = "pebble"
|
||||||
dbLeveldb = "leveldb"
|
dbLeveldb = "leveldb"
|
||||||
@@ -491,8 +480,12 @@ func openKeyValueDatabase(o OpenOptions) (ethdb.Database, error) {
|
|||||||
return nil, fmt.Errorf("db.engine choice was %v but found pre-existing %v database in specified data directory", o.Type, existingDb)
|
return nil, fmt.Errorf("db.engine choice was %v but found pre-existing %v database in specified data directory", o.Type, existingDb)
|
||||||
}
|
}
|
||||||
if o.Type == dbPebble || existingDb == dbPebble {
|
if o.Type == dbPebble || existingDb == dbPebble {
|
||||||
log.Info("Using pebble as the backing database")
|
if PebbleEnabled {
|
||||||
return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
|
log.Info("Using pebble as the backing database")
|
||||||
|
return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("db.engine 'pebble' not supported on this platform")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if o.Type == dbLeveldb || existingDb == dbLeveldb {
|
if o.Type == dbLeveldb || existingDb == dbLeveldb {
|
||||||
log.Info("Using leveldb as the backing database")
|
log.Info("Using leveldb as the backing database")
|
||||||
@@ -500,8 +493,10 @@ func openKeyValueDatabase(o OpenOptions) (ethdb.Database, error) {
|
|||||||
}
|
}
|
||||||
// No pre-existing database, no user-requested one either. Default to Pebble
|
// No pre-existing database, no user-requested one either. Default to Pebble
|
||||||
// on supported platforms and LevelDB on anything else.
|
// on supported platforms and LevelDB on anything else.
|
||||||
|
// if PebbleEnabled {
|
||||||
// log.Info("Defaulting to pebble as the backing database")
|
// log.Info("Defaulting to pebble as the backing database")
|
||||||
// return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
|
// return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
|
||||||
|
// }
|
||||||
log.Info("Defaulting to leveldb as the backing database")
|
log.Info("Defaulting to leveldb as the backing database")
|
||||||
return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
|
return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly)
|
||||||
}
|
}
|
||||||
|
|||||||
37
core/rawdb/databases_64bit.go
Normal file
37
core/rawdb/databases_64bit.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2023 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
//go:build (arm64 || amd64) && !openbsd
|
||||||
|
|
||||||
|
package rawdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb/pebble"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Pebble is unsuported on 32bit architecture
|
||||||
|
const PebbleEnabled = true
|
||||||
|
|
||||||
|
// NewPebbleDBDatabase creates a persistent key-value database without a freezer
|
||||||
|
// moving immutable chain segments into cold storage.
|
||||||
|
func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) {
|
||||||
|
db, err := pebble.New(file, cache, handles, namespace, readonly)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewDatabase(db), nil
|
||||||
|
}
|
||||||
34
core/rawdb/databases_non64bit.go
Normal file
34
core/rawdb/databases_non64bit.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2023 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//go:build !((arm64 || amd64) && !openbsd)
|
||||||
|
|
||||||
|
package rawdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Pebble is unsuported on 32bit architecture
|
||||||
|
const PebbleEnabled = false
|
||||||
|
|
||||||
|
// NewPebbleDBDatabase creates a persistent key-value database without a freezer
|
||||||
|
// moving immutable chain segments into cold storage.
|
||||||
|
func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) {
|
||||||
|
return nil, errors.New("pebble is not supported on this platform")
|
||||||
|
}
|
||||||
@@ -13,4 +13,10 @@ const (
|
|||||||
TokenManagerContract = "0x0000000000000000000000000000000000001008"
|
TokenManagerContract = "0x0000000000000000000000000000000000001008"
|
||||||
CrossChainContract = "0x0000000000000000000000000000000000002000"
|
CrossChainContract = "0x0000000000000000000000000000000000002000"
|
||||||
StakingContract = "0x0000000000000000000000000000000000002001"
|
StakingContract = "0x0000000000000000000000000000000000002001"
|
||||||
|
StakeHubContract = "0x0000000000000000000000000000000000002002"
|
||||||
|
StakeCreditContract = "0x0000000000000000000000000000000000002003"
|
||||||
|
GovernorContract = "0x0000000000000000000000000000000000002004"
|
||||||
|
GovTokenContract = "0x0000000000000000000000000000000000002005"
|
||||||
|
TimelockContract = "0x0000000000000000000000000000000000002006"
|
||||||
|
TokenRecoverPortalContract = "0x0000000000000000000000000000000000003000"
|
||||||
)
|
)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -26,6 +26,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
@@ -560,8 +562,7 @@ func (d *DiffLayer) DecodeRLP(s *rlp.Stream) error {
|
|||||||
if err := s.Decode(&ed); err != nil {
|
if err := s.Decode(&ed); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
d.BlockHash, d.Number, d.Codes, d.Destructs, d.Accounts, d.Storages =
|
d.BlockHash, d.Number, d.Codes, d.Destructs, d.Accounts, d.Storages = ed.BlockHash, ed.Number, ed.Codes, ed.Destructs, ed.Accounts, ed.Storages
|
||||||
ed.BlockHash, ed.Number, ed.Codes, ed.Destructs, ed.Accounts, ed.Storages
|
|
||||||
|
|
||||||
d.Receipts = make([]*Receipt, len(ed.Receipts))
|
d.Receipts = make([]*Receipt, len(ed.Receipts))
|
||||||
for i, storageReceipt := range ed.Receipts {
|
for i, storageReceipt := range ed.Receipts {
|
||||||
@@ -608,6 +609,7 @@ func (storage *DiffStorage) Swap(i, j int) {
|
|||||||
storage.Keys[i], storage.Keys[j] = storage.Keys[j], storage.Keys[i]
|
storage.Keys[i], storage.Keys[j] = storage.Keys[j], storage.Keys[i]
|
||||||
storage.Vals[i], storage.Vals[j] = storage.Vals[j], storage.Vals[i]
|
storage.Vals[i], storage.Vals[j] = storage.Vals[j], storage.Vals[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage *DiffStorage) Less(i, j int) bool {
|
func (storage *DiffStorage) Less(i, j int) bool {
|
||||||
return string(storage.Keys[i][:]) < string(storage.Keys[j][:])
|
return string(storage.Keys[i][:]) < string(storage.Keys[j][:])
|
||||||
}
|
}
|
||||||
@@ -622,3 +624,64 @@ type DiffAccountsInBlock struct {
|
|||||||
BlockHash common.Hash
|
BlockHash common.Hash
|
||||||
Transactions []DiffAccountsInTx
|
Transactions []DiffAccountsInTx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
|
||||||
|
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
|
||||||
|
)
|
||||||
|
|
||||||
|
// SealHash returns the hash of a block prior to it being sealed.
|
||||||
|
func SealHash(header *Header, chainId *big.Int) (hash common.Hash) {
|
||||||
|
hasher := sha3.NewLegacyKeccak256()
|
||||||
|
EncodeSigHeader(hasher, header, chainId)
|
||||||
|
hasher.Sum(hash[:0])
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeSigHeader(w io.Writer, header *Header, chainId *big.Int) {
|
||||||
|
err := rlp.Encode(w, []interface{}{
|
||||||
|
chainId,
|
||||||
|
header.ParentHash,
|
||||||
|
header.UncleHash,
|
||||||
|
header.Coinbase,
|
||||||
|
header.Root,
|
||||||
|
header.TxHash,
|
||||||
|
header.ReceiptHash,
|
||||||
|
header.Bloom,
|
||||||
|
header.Difficulty,
|
||||||
|
header.Number,
|
||||||
|
header.GasLimit,
|
||||||
|
header.GasUsed,
|
||||||
|
header.Time,
|
||||||
|
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
|
||||||
|
header.MixDigest,
|
||||||
|
header.Nonce,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic("can't encode: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeSigHeaderWithoutVoteAttestation(w io.Writer, header *Header, chainId *big.Int) {
|
||||||
|
err := rlp.Encode(w, []interface{}{
|
||||||
|
chainId,
|
||||||
|
header.ParentHash,
|
||||||
|
header.UncleHash,
|
||||||
|
header.Coinbase,
|
||||||
|
header.Root,
|
||||||
|
header.TxHash,
|
||||||
|
header.ReceiptHash,
|
||||||
|
header.Bloom,
|
||||||
|
header.Difficulty,
|
||||||
|
header.Number,
|
||||||
|
header.GasLimit,
|
||||||
|
header.GasUsed,
|
||||||
|
header.Time,
|
||||||
|
header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation
|
||||||
|
header.MixDigest,
|
||||||
|
header.Nonce,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic("can't encode: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,23 +17,28 @@
|
|||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
||||||
|
"golang.org/x/crypto/ripemd160"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
||||||
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
||||||
"github.com/ethereum/go-ethereum/crypto/bn256"
|
"github.com/ethereum/go-ethereum/crypto/bn256"
|
||||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/crypto/ripemd160"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrecompiledContract is the basic interface for native Go contracts. The implementation
|
// PrecompiledContract is the basic interface for native Go contracts. The implementation
|
||||||
@@ -219,6 +224,27 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{
|
|||||||
common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
|
common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrecompiledContractsFeynman contains the default set of pre-compiled Ethereum
|
||||||
|
// contracts used in the Feynman release.
|
||||||
|
var PrecompiledContractsFeynman = map[common.Address]PrecompiledContract{
|
||||||
|
common.BytesToAddress([]byte{1}): &ecrecover{},
|
||||||
|
common.BytesToAddress([]byte{2}): &sha256hash{},
|
||||||
|
common.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||||
|
common.BytesToAddress([]byte{4}): &dataCopy{},
|
||||||
|
common.BytesToAddress([]byte{5}): &bigModExp{},
|
||||||
|
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{9}): &blake2F{},
|
||||||
|
|
||||||
|
common.BytesToAddress([]byte{100}): &tmHeaderValidate{},
|
||||||
|
common.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlato{},
|
||||||
|
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
|
||||||
|
common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
|
||||||
|
common.BytesToAddress([]byte{104}): &verifyDoubleSignEvidence{},
|
||||||
|
common.BytesToAddress([]byte{105}): &secp256k1SignatureRecover{},
|
||||||
|
}
|
||||||
|
|
||||||
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
|
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
|
||||||
// contracts specified in EIP-2537. These are exported for testing purposes.
|
// contracts specified in EIP-2537. These are exported for testing purposes.
|
||||||
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
||||||
@@ -245,6 +271,7 @@ var (
|
|||||||
PrecompiledAddressesIstanbul []common.Address
|
PrecompiledAddressesIstanbul []common.Address
|
||||||
PrecompiledAddressesByzantium []common.Address
|
PrecompiledAddressesByzantium []common.Address
|
||||||
PrecompiledAddressesHomestead []common.Address
|
PrecompiledAddressesHomestead []common.Address
|
||||||
|
PrecompiledAddressesFeynman []common.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -281,11 +308,16 @@ func init() {
|
|||||||
for k := range PrecompiledContractsCancun {
|
for k := range PrecompiledContractsCancun {
|
||||||
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
|
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
|
||||||
}
|
}
|
||||||
|
for k := range PrecompiledContractsFeynman {
|
||||||
|
PrecompiledAddressesFeynman = append(PrecompiledAddressesFeynman, k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
||||||
func ActivePrecompiles(rules params.Rules) []common.Address {
|
func ActivePrecompiles(rules params.Rules) []common.Address {
|
||||||
switch {
|
switch {
|
||||||
|
case rules.IsFeynman:
|
||||||
|
return PrecompiledAddressesFeynman
|
||||||
case rules.IsCancun:
|
case rules.IsCancun:
|
||||||
return PrecompiledAddressesCancun
|
return PrecompiledAddressesCancun
|
||||||
case rules.IsHertz:
|
case rules.IsHertz:
|
||||||
@@ -561,7 +593,7 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) {
|
|||||||
// Modulo 0 is undefined, return zero
|
// Modulo 0 is undefined, return zero
|
||||||
return common.LeftPadBytes([]byte{}, int(modLen)), nil
|
return common.LeftPadBytes([]byte{}, int(modLen)), nil
|
||||||
case base.BitLen() == 1: // a bit length of 1 means it's 1 (or -1).
|
case base.BitLen() == 1: // a bit length of 1 means it's 1 (or -1).
|
||||||
//If base == 1, then we can just return base % mod (if mod >= 1, which it is)
|
// If base == 1, then we can just return base % mod (if mod >= 1, which it is)
|
||||||
v = base.Mod(base, mod).Bytes()
|
v = base.Mod(base, mod).Bytes()
|
||||||
default:
|
default:
|
||||||
v = base.Exp(base, exp, mod).Bytes()
|
v = base.Exp(base, exp, mod).Bytes()
|
||||||
@@ -1355,3 +1387,92 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
|
|||||||
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verifyDoubleSignEvidence implements bsc header verification precompile.
|
||||||
|
type verifyDoubleSignEvidence struct{}
|
||||||
|
|
||||||
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||||
|
func (c *verifyDoubleSignEvidence) RequiredGas(input []byte) uint64 {
|
||||||
|
return params.DoubleSignEvidenceVerifyGas
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
extraSeal = 65
|
||||||
|
)
|
||||||
|
|
||||||
|
type DoubleSignEvidence struct {
|
||||||
|
ChainId *big.Int
|
||||||
|
HeaderBytes1 []byte
|
||||||
|
HeaderBytes2 []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run input: rlp encoded DoubleSignEvidence
|
||||||
|
// return:
|
||||||
|
// signer address| evidence time|
|
||||||
|
// 20 bytes | 32 bytes |
|
||||||
|
func (c *verifyDoubleSignEvidence) Run(input []byte) ([]byte, error) {
|
||||||
|
evidence := &DoubleSignEvidence{}
|
||||||
|
err := rlp.DecodeBytes(input, evidence)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
header1 := &types.Header{}
|
||||||
|
err = rlp.DecodeBytes(evidence.HeaderBytes1, header1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
header2 := &types.Header{}
|
||||||
|
err = rlp.DecodeBytes(evidence.HeaderBytes2, header2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic check
|
||||||
|
if header1.Number.Uint64() != header2.Number.Uint64() {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
if header1.ParentHash != header2.ParentHash {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(header1.Extra) < extraSeal || len(header2.Extra) < extraSeal {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
sig1 := header1.Extra[len(header1.Extra)-extraSeal:]
|
||||||
|
sig2 := header2.Extra[len(header2.Extra)-extraSeal:]
|
||||||
|
if bytes.Equal(sig1, sig2) {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
evidenceTime := header1.Time
|
||||||
|
if evidenceTime < header2.Time {
|
||||||
|
evidenceTime = header2.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// check sig
|
||||||
|
msgHash1 := types.SealHash(header1, evidence.ChainId)
|
||||||
|
msgHash2 := types.SealHash(header2, evidence.ChainId)
|
||||||
|
if bytes.Equal(msgHash1.Bytes(), msgHash2.Bytes()) {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
pubkey1, err := secp256k1.RecoverPubkey(msgHash1.Bytes(), sig1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
pubkey2, err := secp256k1.RecoverPubkey(msgHash2.Bytes(), sig2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
if !bytes.Equal(pubkey1, pubkey2) {
|
||||||
|
return nil, ErrExecutionReverted
|
||||||
|
}
|
||||||
|
|
||||||
|
returnBz := make([]byte, 52) // 20 + 32
|
||||||
|
signerAddr := crypto.Keccak256(pubkey1[1:])[12:]
|
||||||
|
evidenceTimeBz := big.NewInt(int64(evidenceTime)).Bytes()
|
||||||
|
copy(returnBz[:20], signerAddr)
|
||||||
|
copy(returnBz[52-len(evidenceTimeBz):], evidenceTimeBz)
|
||||||
|
|
||||||
|
return returnBz, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import (
|
|||||||
|
|
||||||
"github.com/tendermint/iavl"
|
"github.com/tendermint/iavl"
|
||||||
"github.com/tendermint/tendermint/crypto/merkle"
|
"github.com/tendermint/tendermint/crypto/merkle"
|
||||||
|
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
|
|
||||||
|
//nolint:staticcheck
|
||||||
v1 "github.com/ethereum/go-ethereum/core/vm/lightclient/v1"
|
v1 "github.com/ethereum/go-ethereum/core/vm/lightclient/v1"
|
||||||
v2 "github.com/ethereum/go-ethereum/core/vm/lightclient/v2"
|
v2 "github.com/ethereum/go-ethereum/core/vm/lightclient/v2"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
@@ -104,7 +106,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// iavlMerkleProofValidate implemented as a native contract.
|
// iavlMerkleProofValidate implemented as a native contract.
|
||||||
type iavlMerkleProofValidate struct {
|
type iavlMerkleProofValidate struct {
|
||||||
@@ -397,3 +399,40 @@ type cometBFTLightBlockValidateHertz struct {
|
|||||||
func (c *cometBFTLightBlockValidateHertz) Run(input []byte) (result []byte, err error) {
|
func (c *cometBFTLightBlockValidateHertz) Run(input []byte) (result []byte, err error) {
|
||||||
return c.run(input, true)
|
return c.run(input, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// secp256k1SignatureRecover implemented as a native contract.
|
||||||
|
type secp256k1SignatureRecover struct{}
|
||||||
|
|
||||||
|
func (c *secp256k1SignatureRecover) RequiredGas(input []byte) uint64 {
|
||||||
|
return params.EcrecoverGas
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
tmPubKeyLength uint8 = 33
|
||||||
|
tmSignatureLength uint8 = 64
|
||||||
|
tmSignatureMsgHashLength uint8 = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
// input:
|
||||||
|
// | tmPubKey | tmSignature | tmSignatureMsgHash |
|
||||||
|
// | 33 bytes | 64 bytes | 32 bytes |
|
||||||
|
func (c *secp256k1SignatureRecover) Run(input []byte) (result []byte, err error) {
|
||||||
|
if len(input) != int(tmPubKeyLength)+int(tmSignatureLength)+int(tmSignatureMsgHashLength) {
|
||||||
|
return nil, fmt.Errorf("invalid input")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.runTMSecp256k1Signature(
|
||||||
|
input[:tmPubKeyLength],
|
||||||
|
input[tmPubKeyLength:tmPubKeyLength+tmSignatureLength],
|
||||||
|
input[tmPubKeyLength+tmSignatureLength:],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *secp256k1SignatureRecover) runTMSecp256k1Signature(pubkey, signatureStr, msgHash []byte) (result []byte, err error) {
|
||||||
|
tmPubKey := secp256k1.PubKeySecp256k1(pubkey)
|
||||||
|
ok := tmPubKey.VerifyBytesWithMsgHash(msgHash, signatureStr)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("invalid signature")
|
||||||
|
}
|
||||||
|
return tmPubKey.Address().Bytes(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -373,3 +373,42 @@ func TestCometBFTLightBlockValidateHertz(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, expectOutputStr, hex.EncodeToString(res))
|
require.Equal(t, expectOutputStr, hex.EncodeToString(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSecp256k1SignatureRecover(t *testing.T) {
|
||||||
|
// local key
|
||||||
|
{
|
||||||
|
pubKey, err := hex.DecodeString("0278caa4d6321aa856d6341dd3e8bcdfe0b55901548871c63c3f5cec43c2ae88a9")
|
||||||
|
require.NoError(t, err)
|
||||||
|
sig, err := hex.DecodeString("0cb78be0d8eaeab991907b06c61240c04f4ca83f54b7799ce77cf029b837988038c4b3b7f5df231695b0d14499b716e1fd6504860eb3c9244ecb4e569d44c062")
|
||||||
|
require.NoError(t, err)
|
||||||
|
msghash, err := hex.DecodeString("b6ac827edff4bbbf23579720782dbef40b65780af292cc66849e7e5944f1230f")
|
||||||
|
require.NoError(t, err)
|
||||||
|
expectedAddr, err := hex.DecodeString("fa3B227adFf8EA1706098928715076D76959Ae6c")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
input := append(append(pubKey, sig...), msghash...)
|
||||||
|
contract := &secp256k1SignatureRecover{}
|
||||||
|
res, err := contract.Run(input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, expectedAddr, res)
|
||||||
|
}
|
||||||
|
// ledger
|
||||||
|
{
|
||||||
|
pubKey, err := hex.DecodeString("02d63ee39adb1779353b4393dd5ea9d6d2b6df63b71d168571803cc7b9a0a20e98")
|
||||||
|
require.NoError(t, err)
|
||||||
|
sig, err := hex.DecodeString("66bdb5d381b2773c0f569858c7ee143959522d7c1f46dc656c325cb7353ec40c28ec22dff3650b34c096c5b12e702d7237d409f1ebaaa6dd1128a8f2d401fd5b")
|
||||||
|
require.NoError(t, err)
|
||||||
|
msghash, err := hex.DecodeString("c45e8f0dc7c054c31912beeffd6f10f1c585606d61e252e97968cd66661c2571")
|
||||||
|
require.NoError(t, err)
|
||||||
|
expectedAddr, err := hex.DecodeString("65a284146b84210a01add088954bb52d88b230af")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
input := append(append(pubKey, sig...), msghash...)
|
||||||
|
contract := &secp256k1SignatureRecover{}
|
||||||
|
res, err := contract.Run(input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, expectedAddr, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
|
|||||||
common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{},
|
common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{},
|
||||||
common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{},
|
common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{},
|
||||||
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
|
common.BytesToAddress([]byte{102}): &blsSignatureVerify{},
|
||||||
|
common.BytesToAddress([]byte{104}): &verifyDoubleSignEvidence{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// EIP-152 test vectors
|
// EIP-152 test vectors
|
||||||
@@ -405,3 +406,14 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
|
|||||||
}
|
}
|
||||||
benchmarkPrecompiled("0f", testcase, b)
|
benchmarkPrecompiled("0f", testcase, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDoubleSignSlash(t *testing.T) {
|
||||||
|
tc := precompiledTest{
|
||||||
|
Input: "f906278202cab9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494976ea74026e726554db657fa54763abd0c3a0aa9a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a804ae755e0fe64b59753f4db6308a1f679747bce186aa2c62b95fa6eeff3fbd08f3b0667e45428a54ade15bad19f49641c499b431b36f65803ea71b379e6b61de501a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094976ea74026e726554db657fa54763abd0c3a0aa9a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a80c0b17bfe88534296ff064cb7156548f6deba2d6310d5044ed6485f087dc6ef232e051c28e1909c2b50a3b4f29345d66681c319bef653e52e5d746480d5a3983b00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000",
|
||||||
|
Expected: "15d34aaf54267db7d7c367839aaf71a00a2c6a65000000000000000000000000000000000000000000000000000000006555fa64",
|
||||||
|
Gas: 1000,
|
||||||
|
Name: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrecompiled("68", tc, t)
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ type (
|
|||||||
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
||||||
var precompiles map[common.Address]PrecompiledContract
|
var precompiles map[common.Address]PrecompiledContract
|
||||||
switch {
|
switch {
|
||||||
|
case evm.chainRules.IsFeynman:
|
||||||
|
precompiles = PrecompiledContractsFeynman
|
||||||
case evm.chainRules.IsCancun:
|
case evm.chainRules.IsCancun:
|
||||||
precompiles = PrecompiledContractsCancun
|
precompiles = PrecompiledContractsCancun
|
||||||
case evm.chainRules.IsHertz:
|
case evm.chainRules.IsHertz:
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
const blocksNumberSinceMining = 5 // the number of blocks need to wait before voting, counting from the validator begin to mine
|
|
||||||
|
|
||||||
var votesManagerCounter = metrics.NewRegisteredCounter("votesManager/local", nil)
|
var votesManagerCounter = metrics.NewRegisteredCounter("votesManager/local", nil)
|
||||||
|
|
||||||
// Backend wraps all methods required for voting.
|
// Backend wraps all methods required for voting.
|
||||||
@@ -97,7 +95,6 @@ func (voteManager *VoteManager) loop() {
|
|||||||
dlEventCh := events.Chan()
|
dlEventCh := events.Chan()
|
||||||
|
|
||||||
startVote := true
|
startVote := true
|
||||||
blockCountSinceMining := 0
|
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -123,15 +120,9 @@ func (voteManager *VoteManager) loop() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !voteManager.eth.IsMining() {
|
if !voteManager.eth.IsMining() {
|
||||||
blockCountSinceMining = 0
|
|
||||||
log.Debug("skip voting because mining is disabled, continue")
|
log.Debug("skip voting because mining is disabled, continue")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
blockCountSinceMining++
|
|
||||||
if blockCountSinceMining <= blocksNumberSinceMining {
|
|
||||||
log.Debug("skip voting", "blockCountSinceMining", blockCountSinceMining, "blocksNumberSinceMining", blocksNumberSinceMining)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if cHead.Block == nil {
|
if cHead.Block == nil {
|
||||||
log.Debug("cHead.Block is nil, continue")
|
log.Debug("cHead.Block is nil, continue")
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ func testVotePool(t *testing.T, isValidRules bool) {
|
|||||||
if _, err := chain.InsertChain(bs); err != nil {
|
if _, err := chain.InsertChain(bs); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
for i := 0; i < 10+blocksNumberSinceMining; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil)
|
bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil)
|
||||||
if _, err := chain.InsertChain(bs); err != nil {
|
if _, err := chain.InsertChain(bs); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@@ -56,10 +56,10 @@ var LightClientGPO = gasprice.Config{
|
|||||||
IgnorePrice: gasprice.DefaultIgnorePrice,
|
IgnorePrice: gasprice.DefaultIgnorePrice,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defaults contains default settings for use on the BSC main net.
|
// Defaults contains default settings for use on the Ethereum main net.
|
||||||
var Defaults = Config{
|
var Defaults = Config{
|
||||||
SyncMode: downloader.SnapSync,
|
SyncMode: downloader.SnapSync,
|
||||||
NetworkId: 56,
|
NetworkId: 1,
|
||||||
TxLookupLimit: 2350000,
|
TxLookupLimit: 2350000,
|
||||||
TransactionHistory: 2350000,
|
TransactionHistory: 2350000,
|
||||||
StateHistory: params.FullImmutabilityThreshold,
|
StateHistory: params.FullImmutabilityThreshold,
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//go:build (arm64 || amd64) && !openbsd
|
||||||
|
|
||||||
// Package pebble implements the key-value database layer based on pebble.
|
// Package pebble implements the key-value database layer based on pebble.
|
||||||
package pebble
|
package pebble
|
||||||
|
|
||||||
@@ -139,15 +141,8 @@ func New(file string, cache int, handles int, namespace string, readonly bool) (
|
|||||||
|
|
||||||
// The max memtable size is limited by the uint32 offsets stored in
|
// The max memtable size is limited by the uint32 offsets stored in
|
||||||
// internal/arenaskl.node, DeferredBatchOp, and flushableBatchEntry.
|
// internal/arenaskl.node, DeferredBatchOp, and flushableBatchEntry.
|
||||||
//
|
// Taken from https://github.com/cockroachdb/pebble/blob/master/open.go#L38
|
||||||
// - MaxUint32 on 64-bit platforms;
|
maxMemTableSize := 4<<30 - 1 // Capped by 4 GB
|
||||||
// - MaxInt on 32-bit platforms.
|
|
||||||
//
|
|
||||||
// It is used when slices are limited to Uint32 on 64-bit platforms (the
|
|
||||||
// length limit for slices is naturally MaxInt on 32-bit platforms).
|
|
||||||
//
|
|
||||||
// Taken from https://github.com/cockroachdb/pebble/blob/master/internal/constants/constants.go
|
|
||||||
maxMemTableSize := (1<<31)<<(^uint(0)>>63) - 1
|
|
||||||
|
|
||||||
// Two memory tables is configured which is identical to leveldb,
|
// Two memory tables is configured which is identical to leveldb,
|
||||||
// including a frozen memory table and another live one.
|
// including a frozen memory table and another live one.
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//go:build (arm64 || amd64) && !openbsd
|
||||||
|
|
||||||
package pebble
|
package pebble
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -295,5 +295,5 @@ replace (
|
|||||||
github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2
|
github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1
|
github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1
|
||||||
github.com/syndtr/goleveldb v1.0.1 => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
github.com/syndtr/goleveldb v1.0.1 => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
||||||
github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15
|
github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.16
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -188,8 +188,8 @@ github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2 h1
|
|||||||
github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs=
|
github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs=
|
||||||
github.com/bnb-chain/ics23 v0.1.0 h1:DvjGOts2FBfbxB48384CYD1LbcrfjThFz8kowY/7KxU=
|
github.com/bnb-chain/ics23 v0.1.0 h1:DvjGOts2FBfbxB48384CYD1LbcrfjThFz8kowY/7KxU=
|
||||||
github.com/bnb-chain/ics23 v0.1.0/go.mod h1:cU6lTGolbbLFsGCgceNB2AzplH1xecLp6+KXvxM32nI=
|
github.com/bnb-chain/ics23 v0.1.0/go.mod h1:cU6lTGolbbLFsGCgceNB2AzplH1xecLp6+KXvxM32nI=
|
||||||
github.com/bnb-chain/tendermint v0.31.15 h1:Xyn/Hifb/7X4E1zSuMdnZdMSoM2Fx6cZuKCNnqIxbNU=
|
github.com/bnb-chain/tendermint v0.31.16 h1:rOO6WG61JDAuRCCL8TKnGhorJftQDVygq0mqR7A0ck4=
|
||||||
github.com/bnb-chain/tendermint v0.31.15/go.mod h1:cmt8HHmQUSVaWQ/hoTefRxsh5X3ERaM1zCUIR0DPbFU=
|
github.com/bnb-chain/tendermint v0.31.16/go.mod h1:cmt8HHmQUSVaWQ/hoTefRxsh5X3ERaM1zCUIR0DPbFU=
|
||||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||||
|
|||||||
@@ -17,18 +17,15 @@ type TimeTicker struct {
|
|||||||
|
|
||||||
// NewTimeTicker creates a TimeTicker that notifies based on rotateHours parameter.
|
// NewTimeTicker creates a TimeTicker that notifies based on rotateHours parameter.
|
||||||
// if rotateHours is 1 and current time is 11:32 it means that the ticker will tick at 12:00
|
// if rotateHours is 1 and current time is 11:32 it means that the ticker will tick at 12:00
|
||||||
// if rotateHours is 2 and current time is 09:12 means that the ticker will tick at 11:00
|
// if rotateHours is 5 and current time is 09:12 means that the ticker will tick at 11:00
|
||||||
// specially, if rotateHours is 0, then no rotation
|
func NewTimeTicker(rotateHours int) *TimeTicker {
|
||||||
func NewTimeTicker(rotateHours uint) *TimeTicker {
|
|
||||||
ch := make(chan time.Time)
|
ch := make(chan time.Time)
|
||||||
tt := TimeTicker{
|
tt := TimeTicker{
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
C: ch,
|
C: ch,
|
||||||
}
|
}
|
||||||
|
|
||||||
if rotateHours > 0 {
|
tt.startTicker(ch, rotateHours)
|
||||||
tt.startTicker(ch, rotateHours)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tt
|
return &tt
|
||||||
}
|
}
|
||||||
@@ -37,7 +34,7 @@ func (tt *TimeTicker) Stop() {
|
|||||||
tt.stop <- struct{}{}
|
tt.stop <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tt *TimeTicker) startTicker(ch chan time.Time, rotateHours uint) {
|
func (tt *TimeTicker) startTicker(ch chan time.Time, rotateHours int) {
|
||||||
go func() {
|
go func() {
|
||||||
nextRotationHour := getNextRotationHour(time.Now(), rotateHours)
|
nextRotationHour := getNextRotationHour(time.Now(), rotateHours)
|
||||||
ticker := time.NewTicker(time.Second)
|
ticker := time.NewTicker(time.Second)
|
||||||
@@ -56,7 +53,7 @@ func (tt *TimeTicker) startTicker(ch chan time.Time, rotateHours uint) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNextRotationHour(now time.Time, delta uint) int {
|
func getNextRotationHour(now time.Time, delta int) int {
|
||||||
return now.Add(time.Hour * time.Duration(delta)).Hour()
|
return now.Add(time.Hour * time.Duration(delta)).Hour()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +68,7 @@ type AsyncFileWriter struct {
|
|||||||
timeTicker *TimeTicker
|
timeTicker *TimeTicker
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAsyncFileWriter(filePath string, maxBytesSize int64, rotateHours uint) *AsyncFileWriter {
|
func NewAsyncFileWriter(filePath string, maxBytesSize int64, rotateHours int) *AsyncFileWriter {
|
||||||
absFilePath, err := filepath.Abs(filePath)
|
absFilePath, err := filepath.Abs(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("get file path of logger error. filePath=%s, err=%s", filePath, err))
|
panic(fmt.Sprintf("get file path of logger error. filePath=%s, err=%s", filePath, err))
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func TestWriterHourly(t *testing.T) {
|
|||||||
func TestGetNextRotationHour(t *testing.T) {
|
func TestGetNextRotationHour(t *testing.T) {
|
||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
now time.Time
|
now time.Time
|
||||||
delta uint
|
delta int
|
||||||
expectedHour int
|
expectedHour int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -54,7 +54,7 @@ func TestGetNextRotationHour(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
test := func(now time.Time, delta uint, expectedHour int) func(*testing.T) {
|
test := func(now time.Time, delta, expectedHour int) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
got := getNextRotationHour(now, delta)
|
got := getNextRotationHour(now, delta)
|
||||||
if got != expectedHour {
|
if got != expectedHour {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func FileHandler(path string, fmtr Format) (Handler, error) {
|
|||||||
// RotatingFileHandler returns a handler which writes log records to file chunks
|
// RotatingFileHandler returns a handler which writes log records to file chunks
|
||||||
// at the given path. When a file's size reaches the limit, the handler creates
|
// at the given path. When a file's size reaches the limit, the handler creates
|
||||||
// a new file named after the timestamp of the first log record it will contain.
|
// a new file named after the timestamp of the first log record it will contain.
|
||||||
func RotatingFileHandler(filePath string, limit uint, formatter Format, rotateHours uint) (Handler, error) {
|
func RotatingFileHandler(filePath string, limit uint, formatter Format, rotateHours int) (Handler, error) {
|
||||||
if _, err := os.Stat(path.Dir(filePath)); os.IsNotExist(err) {
|
if _, err := os.Stat(path.Dir(filePath)); os.IsNotExist(err) {
|
||||||
err := os.MkdirAll(path.Dir(filePath), 0755)
|
err := os.MkdirAll(path.Dir(filePath), 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ func (c Ctx) toArray() []interface{} {
|
|||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileLvlHandler(logPath string, maxBytesSize uint, level string, rotateHours uint) Handler {
|
func NewFileLvlHandler(logPath string, maxBytesSize uint, level string, rotateHours int) Handler {
|
||||||
rfh, err := RotatingFileHandler(logPath, maxBytesSize, LogfmtFormat(), rotateHours)
|
rfh, err := RotatingFileHandler(logPath, maxBytesSize, LogfmtFormat(), rotateHours)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@@ -711,11 +711,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||||||
gasLimit := env.header.GasLimit
|
gasLimit := env.header.GasLimit
|
||||||
if env.gasPool == nil {
|
if env.gasPool == nil {
|
||||||
env.gasPool = new(core.GasPool).AddGas(gasLimit)
|
env.gasPool = new(core.GasPool).AddGas(gasLimit)
|
||||||
if w.chain.Config().IsEuler(env.header.Number) {
|
env.gasPool.SubGas(params.SystemTxsGas * 5)
|
||||||
env.gasPool.SubGas(params.SystemTxsGas * 3)
|
|
||||||
} else {
|
|
||||||
env.gasPool.SubGas(params.SystemTxsGas)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var coalescedLogs []*types.Log
|
var coalescedLogs []*types.Log
|
||||||
@@ -728,7 +724,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||||||
|
|
||||||
stopPrefetchCh := make(chan struct{})
|
stopPrefetchCh := make(chan struct{})
|
||||||
defer close(stopPrefetchCh)
|
defer close(stopPrefetchCh)
|
||||||
//prefetch txs from all pending txs
|
// prefetch txs from all pending txs
|
||||||
txsPrefetch := txs.Copy()
|
txsPrefetch := txs.Copy()
|
||||||
tx := txsPrefetch.PeekWithUnwrap()
|
tx := txsPrefetch.PeekWithUnwrap()
|
||||||
if tx != nil {
|
if tx != nil {
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ type LogConfig struct {
|
|||||||
FilePath *string `toml:",omitempty"`
|
FilePath *string `toml:",omitempty"`
|
||||||
MaxBytesSize *uint `toml:",omitempty"`
|
MaxBytesSize *uint `toml:",omitempty"`
|
||||||
Level *string `toml:",omitempty"`
|
Level *string `toml:",omitempty"`
|
||||||
RotateHours *uint `toml:",omitempty"`
|
RotateHours int `toml:",omitempty"`
|
||||||
|
|
||||||
// TermTimeFormat is the time format used for console logging.
|
// TermTimeFormat is the time format used for console logging.
|
||||||
TermTimeFormat *string `toml:",omitempty"`
|
TermTimeFormat *string `toml:",omitempty"`
|
||||||
|
|||||||
16
node/node.go
16
node/node.go
@@ -109,16 +109,16 @@ func New(conf *Config) (*Node, error) {
|
|||||||
logFilePath = path.Join(*conf.LogConfig.FileRoot, *conf.LogConfig.FilePath)
|
logFilePath = path.Join(*conf.LogConfig.FileRoot, *conf.LogConfig.FilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
rotateHours := uint(1) // To maintain backwards compatibility, if RotateHours is not set, then it defaults to 1
|
if conf.LogConfig.RotateHours > 24 {
|
||||||
if conf.LogConfig.RotateHours != nil {
|
return nil, errors.New("Config.LogConfig.RotateHours cannot be greater than 24")
|
||||||
if *conf.LogConfig.RotateHours > 23 {
|
|
||||||
return nil, errors.New("Config.LogConfig.RotateHours cannot be greater than 23")
|
|
||||||
}
|
|
||||||
|
|
||||||
rotateHours = *conf.LogConfig.RotateHours
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Root().SetHandler(log.NewFileLvlHandler(logFilePath, *conf.LogConfig.MaxBytesSize, *conf.LogConfig.Level, rotateHours))
|
// To maintain backwards compatibility, if RotateHours is not set or set to a negative value, then it defaults to 1
|
||||||
|
if conf.LogConfig.RotateHours < 1 {
|
||||||
|
conf.LogConfig.RotateHours = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Root().SetHandler(log.NewFileLvlHandler(logFilePath, *conf.LogConfig.MaxBytesSize, *conf.LogConfig.Level, conf.LogConfig.RotateHours))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if conf.Logger == nil {
|
if conf.Logger == nil {
|
||||||
|
|||||||
@@ -169,6 +169,9 @@ var (
|
|||||||
ShanghaiTime: newUint64(1705996800),
|
ShanghaiTime: newUint64(1705996800),
|
||||||
KeplerTime: newUint64(1705996800),
|
KeplerTime: newUint64(1705996800),
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
FeynmanTime: nil,
|
||||||
|
|
||||||
Parlia: &ParliaConfig{
|
Parlia: &ParliaConfig{
|
||||||
Period: 3,
|
Period: 3,
|
||||||
Epoch: 200,
|
Epoch: 200,
|
||||||
@@ -205,6 +208,9 @@ var (
|
|||||||
ShanghaiTime: newUint64(1702972800),
|
ShanghaiTime: newUint64(1702972800),
|
||||||
KeplerTime: newUint64(1702972800),
|
KeplerTime: newUint64(1702972800),
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
FeynmanTime: nil,
|
||||||
|
|
||||||
Parlia: &ParliaConfig{
|
Parlia: &ParliaConfig{
|
||||||
Period: 3,
|
Period: 3,
|
||||||
Epoch: 200,
|
Epoch: 200,
|
||||||
@@ -212,7 +218,7 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
RialtoChainConfig = &ChainConfig{
|
RialtoChainConfig = &ChainConfig{
|
||||||
ChainID: big.NewInt(1417),
|
ChainID: big.NewInt(714),
|
||||||
HomesteadBlock: big.NewInt(0),
|
HomesteadBlock: big.NewInt(0),
|
||||||
EIP150Block: big.NewInt(0),
|
EIP150Block: big.NewInt(0),
|
||||||
EIP155Block: big.NewInt(0),
|
EIP155Block: big.NewInt(0),
|
||||||
@@ -222,20 +228,26 @@ var (
|
|||||||
PetersburgBlock: big.NewInt(0),
|
PetersburgBlock: big.NewInt(0),
|
||||||
IstanbulBlock: big.NewInt(0),
|
IstanbulBlock: big.NewInt(0),
|
||||||
MuirGlacierBlock: big.NewInt(0),
|
MuirGlacierBlock: big.NewInt(0),
|
||||||
RamanujanBlock: big.NewInt(400),
|
RamanujanBlock: big.NewInt(0),
|
||||||
NielsBlock: big.NewInt(0),
|
NielsBlock: big.NewInt(0),
|
||||||
MirrorSyncBlock: big.NewInt(400),
|
MirrorSyncBlock: big.NewInt(1),
|
||||||
BrunoBlock: big.NewInt(400),
|
BrunoBlock: big.NewInt(1),
|
||||||
EulerBlock: big.NewInt(400),
|
EulerBlock: big.NewInt(2),
|
||||||
GibbsBlock: big.NewInt(400),
|
GibbsBlock: big.NewInt(3),
|
||||||
NanoBlock: nil,
|
NanoBlock: nil,
|
||||||
MoranBlock: nil,
|
MoranBlock: big.NewInt(4),
|
||||||
PlanckBlock: nil,
|
PlanckBlock: big.NewInt(5),
|
||||||
LubanBlock: nil,
|
LubanBlock: big.NewInt(6),
|
||||||
PlatoBlock: nil,
|
PlatoBlock: big.NewInt(7),
|
||||||
BerlinBlock: nil,
|
BerlinBlock: _hertz_upgrade_block_,
|
||||||
HertzBlock: nil,
|
LondonBlock: _hertz_upgrade_block_,
|
||||||
HertzfixBlock: nil,
|
HertzBlock: _hertz_upgrade_block_,
|
||||||
|
HertzfixBlock: _hertz_upgrade_block_,
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
ShanghaiTime: _rialto_upgrade_height_,
|
||||||
|
KeplerTime: _rialto_upgrade_height_,
|
||||||
|
FeynmanTime: _rialto_upgrade_height_,
|
||||||
|
|
||||||
Parlia: &ParliaConfig{
|
Parlia: &ParliaConfig{
|
||||||
Period: 3,
|
Period: 3,
|
||||||
@@ -458,6 +470,7 @@ type ChainConfig struct {
|
|||||||
|
|
||||||
ShanghaiTime *uint64 `json:"shanghaiTime,omitempty" toml:",omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai)
|
ShanghaiTime *uint64 `json:"shanghaiTime,omitempty" toml:",omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai)
|
||||||
KeplerTime *uint64 `json:"keplerTime,omitempty" toml:",omitempty"` // Kepler switch time (nil = no fork, 0 = already activated)
|
KeplerTime *uint64 `json:"keplerTime,omitempty" toml:",omitempty"` // Kepler switch time (nil = no fork, 0 = already activated)
|
||||||
|
FeynmanTime *uint64 `json:"feynmanTime,omitempty" toml:",omitempty"` // Feynman switch time (nil = no fork, 0 = already activated)
|
||||||
CancunTime *uint64 `json:"cancunTime,omitempty" toml:",omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun)
|
CancunTime *uint64 `json:"cancunTime,omitempty" toml:",omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun)
|
||||||
PragueTime *uint64 `json:"pragueTime,omitempty" toml:",omitempty"` // Prague switch time (nil = no fork, 0 = already on prague)
|
PragueTime *uint64 `json:"pragueTime,omitempty" toml:",omitempty"` // Prague switch time (nil = no fork, 0 = already on prague)
|
||||||
VerkleTime *uint64 `json:"verkleTime,omitempty" toml:",omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
|
VerkleTime *uint64 `json:"verkleTime,omitempty" toml:",omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
|
||||||
@@ -550,7 +563,12 @@ func (c *ChainConfig) String() string {
|
|||||||
KeplerTime = big.NewInt(0).SetUint64(*c.KeplerTime)
|
KeplerTime = big.NewInt(0).SetUint64(*c.KeplerTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
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, Engine: %v}",
|
var FeynmanTime *big.Int
|
||||||
|
if c.FeynmanTime != nil {
|
||||||
|
FeynmanTime = big.NewInt(0).SetUint64(*c.FeynmanTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Hertzfix: %v, ShanghaiTime: %v, KeplerTime: %v, FeynmanTime: %v, Engine: %v}",
|
||||||
c.ChainID,
|
c.ChainID,
|
||||||
c.HomesteadBlock,
|
c.HomesteadBlock,
|
||||||
c.DAOForkBlock,
|
c.DAOForkBlock,
|
||||||
@@ -584,6 +602,7 @@ func (c *ChainConfig) String() string {
|
|||||||
c.HertzfixBlock,
|
c.HertzfixBlock,
|
||||||
ShanghaiTime,
|
ShanghaiTime,
|
||||||
KeplerTime,
|
KeplerTime,
|
||||||
|
FeynmanTime,
|
||||||
engine,
|
engine,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -809,6 +828,20 @@ func (c *ChainConfig) IsOnKepler(currentBlockNumber *big.Int, lastBlockTime uint
|
|||||||
return !c.IsKepler(lastBlockNumber, lastBlockTime) && c.IsKepler(currentBlockNumber, currentBlockTime)
|
return !c.IsKepler(lastBlockNumber, lastBlockTime) && c.IsKepler(currentBlockNumber, currentBlockTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsFeynman returns whether time is either equal to the Feynman fork time or greater.
|
||||||
|
func (c *ChainConfig) IsFeynman(num *big.Int, time uint64) bool {
|
||||||
|
return c.IsLondon(num) && isTimestampForked(c.FeynmanTime, time)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsOnFeynman returns whether currentBlockTime is either equal to the Feynman fork time or greater firstly.
|
||||||
|
func (c *ChainConfig) IsOnFeynman(currentBlockNumber *big.Int, lastBlockTime uint64, currentBlockTime uint64) bool {
|
||||||
|
lastBlockNumber := new(big.Int)
|
||||||
|
if currentBlockNumber.Cmp(big.NewInt(1)) >= 0 {
|
||||||
|
lastBlockNumber.Sub(currentBlockNumber, big.NewInt(1))
|
||||||
|
}
|
||||||
|
return !c.IsFeynman(lastBlockNumber, lastBlockTime) && c.IsFeynman(currentBlockNumber, currentBlockTime)
|
||||||
|
}
|
||||||
|
|
||||||
// IsCancun returns whether num is either equal to the Cancun fork time or greater.
|
// IsCancun returns whether num is either equal to the Cancun fork time or greater.
|
||||||
func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
|
func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
|
||||||
return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
|
return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
|
||||||
@@ -873,7 +906,9 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
|
|||||||
{name: "platoBlock", block: c.PlatoBlock},
|
{name: "platoBlock", block: c.PlatoBlock},
|
||||||
{name: "hertzBlock", block: c.HertzBlock},
|
{name: "hertzBlock", block: c.HertzBlock},
|
||||||
{name: "hertzfixBlock", block: c.HertzfixBlock},
|
{name: "hertzfixBlock", block: c.HertzfixBlock},
|
||||||
|
{name: "shanghaiTime", timestamp: c.ShanghaiTime},
|
||||||
{name: "keplerTime", timestamp: c.KeplerTime},
|
{name: "keplerTime", timestamp: c.KeplerTime},
|
||||||
|
{name: "feynmanTime", timestamp: c.FeynmanTime},
|
||||||
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
|
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
|
||||||
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
|
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
|
||||||
{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
|
{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
|
||||||
@@ -1013,6 +1048,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
|
|||||||
if isForkTimestampIncompatible(c.KeplerTime, newcfg.KeplerTime, headTimestamp) {
|
if isForkTimestampIncompatible(c.KeplerTime, newcfg.KeplerTime, headTimestamp) {
|
||||||
return newTimestampCompatError("Kepler fork timestamp", c.KeplerTime, newcfg.KeplerTime)
|
return newTimestampCompatError("Kepler fork timestamp", c.KeplerTime, newcfg.KeplerTime)
|
||||||
}
|
}
|
||||||
|
if isForkTimestampIncompatible(c.FeynmanTime, newcfg.FeynmanTime, headTimestamp) {
|
||||||
|
return newTimestampCompatError("Feynman fork timestamp", c.FeynmanTime, newcfg.FeynmanTime)
|
||||||
|
}
|
||||||
if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) {
|
if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) {
|
||||||
return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime)
|
return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime)
|
||||||
}
|
}
|
||||||
@@ -1174,7 +1212,7 @@ type Rules struct {
|
|||||||
IsPlato bool
|
IsPlato bool
|
||||||
IsHertz bool
|
IsHertz bool
|
||||||
IsHertzfix bool
|
IsHertzfix bool
|
||||||
IsShanghai, IsKepler, IsCancun, IsPrague bool
|
IsShanghai, IsKepler, IsFeynman, IsCancun, IsPrague bool
|
||||||
IsVerkle bool
|
IsVerkle bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1206,6 +1244,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
|
|||||||
IsHertzfix: c.IsHertzfix(num),
|
IsHertzfix: c.IsHertzfix(num),
|
||||||
IsShanghai: c.IsShanghai(num, timestamp),
|
IsShanghai: c.IsShanghai(num, timestamp),
|
||||||
IsKepler: c.IsKepler(num, timestamp),
|
IsKepler: c.IsKepler(num, timestamp),
|
||||||
|
IsFeynman: c.IsFeynman(num, timestamp),
|
||||||
IsCancun: c.IsCancun(num, timestamp),
|
IsCancun: c.IsCancun(num, timestamp),
|
||||||
IsPrague: c.IsPrague(num, timestamp),
|
IsPrague: c.IsPrague(num, timestamp),
|
||||||
IsVerkle: c.IsVerkle(num, timestamp),
|
IsVerkle: c.IsVerkle(num, timestamp),
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ const (
|
|||||||
IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation
|
IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation
|
||||||
BlsSignatureVerifyBaseGas uint64 = 1000 // base price for a BLS signature verify operation
|
BlsSignatureVerifyBaseGas uint64 = 1000 // base price for a BLS signature verify operation
|
||||||
BlsSignatureVerifyPerKeyGas uint64 = 3500 // Per-key price for a BLS signature verify operation
|
BlsSignatureVerifyPerKeyGas uint64 = 3500 // Per-key price for a BLS signature verify operation
|
||||||
|
DoubleSignEvidenceVerifyGas uint64 = 1000 // Gas for verify double sign evidence
|
||||||
|
|
||||||
Bn256AddGasByzantium uint64 = 500 // Byzantium gas needed for an elliptic curve addition
|
Bn256AddGasByzantium uint64 = 500 // Byzantium gas needed for an elliptic curve addition
|
||||||
Bn256AddGasIstanbul uint64 = 150 // Gas needed for an elliptic curve addition
|
Bn256AddGasIstanbul uint64 = 150 // Gas needed for an elliptic curve addition
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
VersionMajor = 1 // Major version component of the current release
|
VersionMajor = 1 // Major version component of the current release
|
||||||
VersionMinor = 3 // Minor version component of the current release
|
VersionMinor = 3 // Minor version component of the current release
|
||||||
VersionPatch = 6 // Patch version component of the current release
|
VersionPatch = 5 // Patch version component of the current release
|
||||||
VersionMeta = "" // Version metadata to append to the version string
|
VersionMeta = "" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ func parliaHeaderHashAndRlp(header *types.Header, chainId *big.Int) (hash, rlp [
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
rlp = parlia.ParliaRLP(header, chainId)
|
rlp = parlia.ParliaRLP(header, chainId)
|
||||||
hash = parlia.SealHash(header, chainId).Bytes()
|
hash = types.SealHash(header, chainId).Bytes()
|
||||||
return hash, rlp, err
|
return hash, rlp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user