Compare commits

...

45 Commits

Author SHA1 Message Date
zjubfd
b652ef3a67 Merge pull request #27 from binance-chain/1.0.1.beta.2
[R4R]add niels fork
2020-08-13 21:03:21 +08:00
fudongbai
011f043418 add niels fork 2020-08-13 21:00:57 +08:00
zjubfd
d9a0607e5e Merge pull request #24 from binance-chain/develop
[R4R] prepare for release 1.0.1-beta
2020-08-11 18:03:51 +08:00
fudongbai
f2e4ef2e6d prepare for release 1.0.1-beta 2020-08-11 17:07:20 +08:00
zjubfd
8c8c2a7d9e Merge pull request #16 from binance-chain/system-contract-upgrade
R4R: system contract upgrade framework and upgrade tokenhub
2020-08-11 16:58:57 +08:00
zjubfd
4a8f63917f Merge pull request #26 from binance-chain/chapelupgrade
[R4R]update chapel ramanujan fork
2020-08-11 16:57:50 +08:00
fudongbai
45f17d59a0 update chapel ramanujan fork 2020-08-11 16:55:11 +08:00
fudongbai
c399c88e08 fix not return error when blockTimeVerifyForRamanujanFork failed 2020-08-11 15:13:10 +08:00
zjubfd
8c1d1dbb79 Merge pull request #25 from binance-chain/fixdelayLogic
[R4R] minor fix for ramanujan upgrade
2020-08-10 13:58:01 +08:00
fudongbai
4f431e0843 fix index out of range 2020-08-10 11:27:36 +08:00
fudongbai
85ebea9e8c fix hex code of new smart contract 2020-08-09 18:09:43 +08:00
fudongbai
c4f4377cfd fix deplay check 2020-08-09 12:38:02 +08:00
fudongbai
baae91db37 add upgrade height for rialto 2020-08-07 17:29:22 +08:00
HaoyangLiu
650d066757 resolve comment 2020-08-07 17:16:39 +08:00
HaoyangLiu
02154bb0f0 add multiple upgrade config 2020-08-07 17:15:09 +08:00
HaoyangLiu
13cca06be8 add beforeUpgrade and afterUpgrade 2020-08-07 17:15:09 +08:00
HaoyangLiu
4450b337c4 refactor upgrade config 2020-08-07 17:15:09 +08:00
HaoyangLiu
3789ea31dd improve upgrade config 2020-08-07 17:15:09 +08:00
HaoyangLiu
3f36e996df framework for upgrade system contract 2020-08-07 17:15:09 +08:00
zjubfd
a8c9e53eb0 enforce backoff time for out-turn validator (#23) 2020-08-07 17:06:29 +08:00
yutianwu
83d72b8e91 Merge pull request #22 from binance-chain/resolve-best-pratices
[R4R]: resolve best practice advice
2020-08-05 10:54:38 +08:00
HaoyangLiu
8124e60e9d resolve best practice advice 2020-08-04 13:56:13 +08:00
zjubfd
5cc893a5e4 prepare for 1.0.0-beta.1 (#20) 2020-07-28 18:12:34 +08:00
zjubfd
04287ebe50 reestimate the gas consumption for system tx when there is 41 validators (#19) 2020-07-28 10:25:46 +08:00
zjubfd
f4816ee8b7 add chain id into sign bytes to avoid replay attack (#18) 2020-07-09 15:46:37 +08:00
yutianwu
8d48b0deb8 Merge pull request #17 from binance-chain/develop
[R4R] Prepare for release v1.0.0-beta.0
2020-07-03 17:59:01 +08:00
fudongbai
1940dc887c add changelog for v1.0.0-beta.0 2020-07-03 17:56:34 +08:00
fudongbai
2f2778deec update metaversion to beta.0 2020-07-03 16:07:04 +08:00
zjubfd
6f46fc0589 allow slash failed (#15) 2020-06-30 20:22:57 +08:00
HaoyangLiu
6f40b0e238 Merge pull request #14 from binance-chain/crossContract
[R4R]add cross chain contract to system contract
2020-06-30 16:39:53 +08:00
fudongbai
ef1e8746d6 add cross chain contract to system contract 2020-06-30 08:38:15 +00:00
zjubfd
511bbf546f add bep2p tokens for faucet (#5) 2020-06-30 16:16:26 +08:00
zjubfd
5e4f5785c7 fix debug_traceTransaction crashed issue (#13) 2020-06-30 16:15:12 +08:00
zjubfd
11bc803884 Merge pull request #11 from guagualvcha/gas_limit
[R4R]remove redundant gaslimit check
2020-06-24 16:22:21 +08:00
fudongbai
6a19c9803c remove redundant gaslimit check 2020-06-24 16:17:22 +08:00
yutianwu
9f1aaecb29 Merge pull request #10 from guagualvcha/gas_limit
[R4R]add gas limit check in parlia implement
2020-06-18 10:19:27 +08:00
fudongbai
4bd4469151 add gas limit check in parlia implement 2020-06-18 00:26:27 +08:00
zjubfd
ce14f2cae5 Merge pull request #6 from guagualvcha/stale_depth
[R4R] modify params for Parlia consensus with 21 validators
2020-06-17 12:10:21 +08:00
fudongbai
2ff7a21d64 update stale depth 2020-06-15 17:31:40 +08:00
zjubfd
e83397e26a Merge pull request #4 from binance-chain/issue3
[R4R]fix validator failed to sync a block produced by itself,  resolve #3
2020-06-15 17:16:35 +08:00
fudongbai
ed9b28fe7b fix validator failed to sync a block produced by itself 2020-06-02 16:41:48 +08:00
zjubfd
fd8c9c0f1f Merge pull request #1 from binance-chain/gov
[R4R]add gov/tokenHub/RelayerIncentivize contracts to the init list and apply  strict condition for system transaction
2020-06-01 15:51:58 +08:00
zjubfd
b72be127cf update 'running a node' part of readme (#2) 2020-05-25 17:41:47 +08:00
fudongbai
4909842097 add gov init transaction 2020-05-22 10:38:14 +08:00
fudongbai
39c80ce175 more strick condition for system transaction 2020-05-22 10:21:57 +08:00
28 changed files with 779 additions and 182 deletions

31
CHANGELOG.md Normal file
View File

@@ -0,0 +1,31 @@
# Changelog
## v1.0.1-beta
IMPROVEMENT
* [\#22](https://github.com/binance-chain/bsc/pull/22) resolve best practice advice
FEATURES
* [\#23](https://github.com/binance-chain/bsc/pull/23) enforce backoff time for out-turn validator
BUGFIX
* [\#25](https://github.com/binance-chain/bsc/pull/25) minor fix for ramanujan upgrade
UPGRADE
* [\#26](https://github.com/binance-chain/bsc/pull/26) update chapel network config for ramanujan fork
## v1.0.0-beta.0
FEATURES
* [\#5](https://github.com/binance-chain/bsc/pull/5) enable bep2e tokens for faucet
* [\#14](https://github.com/binance-chain/bsc/pull/14) add cross chain contract to system contract
* [\#15](https://github.com/binance-chain/bsc/pull/15) Allow liveness slash fail
IMPROVEMENT
* [\#11](https://github.com/binance-chain/bsc/pull/11) remove redundant gaslimit check
BUGFIX
* [\#4](https://github.com/binance-chain/bsc/pull/4) fix validator failed to sync a block produced by itself
* [\#6](https://github.com/binance-chain/bsc/pull/6) modify params for Parlia consensus with 21 validators
* [\#10](https://github.com/binance-chain/bsc/pull/10) add gas limit check in parlia implement
* [\#13](https://github.com/binance-chain/bsc/pull/13) fix debug_traceTransaction crashed issue

View File

@@ -104,14 +104,14 @@ The hardware must meet certain requirements to run a full node.
Steps:
1. Download the config and genesis files. You need to have [genesis.json](https://github.com/binance-chain/smart-chain-binary/blob/pre-release/bsc/fullnode/config/genesis.json) and [config.toml](https://github.com/binance-chain/smart-chain-binary/blob/pre-release/bsc/fullnode/config/config.toml)
1. Download the binary, config and genesis files from [release](https://github.com/binance-chain/bsc/releases/download/v1.0.0-alpha.0/binary.zip), or compile the binary by `make geth`.
2. Init genesis state: `./geth --datadir node init genesis.json`.
3. Start your fullnode: `./geth --config ./config.toml --datadir ./node`.
4. Or start a validator node: `./geth --config ./config.toml --datadir ./node -unlock ${validatorAddr} --mine --allow-insecure-unlock`. The ${validatorAddr} is the wallet account address of your running validator node.
*Note: The default p2p port is 30311 and the RPC port is 8575 which is different from Ethereum.*
More details about [running a node](https://github.com/binance-chain/docs-site/blob/add-bsc/docs/smart-chain/developer/fullnode.md) and [becoming a validator](https://github.com/binance-chain/docs-site/blob/add-bsc/docs/guides/concepts/bc-staking.md).
More details about [running a node](https://docs.binance.org/smart-chain/developer/fullnode.html) and [becoming a validator](https://docs.binance.org/smart-chain/validator/candidate.html).
*Note: Although there are some internal protective measures to prevent transactions from
crossing over between the main network and test network, you should make sure to always

View File

@@ -42,6 +42,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
@@ -83,11 +84,15 @@ var (
noauthFlag = flag.Bool("noauth", false, "Enables funding requests without authentication")
logFlag = flag.Int("loglevel", 3, "Log level to use for Ethereum and the faucet")
fixGasPrice = flag.Int64("faucet.fixedprice", 0, "Will use fixed gas price if specified")
bep2eContracts = flag.String("bep2eContracts", "", "the list of bep2p contracts")
bep2eSymbols = flag.String("bep2eSymbols", "", "the symbol of bep2p tokens")
bep2eAmounts = flag.String("bep2eAmounts", "", "the amount of bep2p tokens")
fixGasPrice = flag.Int64("faucet.fixedprice", 0, "Will use fixed gas price if specified")
)
var (
ether = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)
ether = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)
bep2eAbiJson = `[ { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "symbol", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getOwner", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "_owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" } ]`
)
var (
@@ -110,7 +115,39 @@ func main() {
amounts[i] = strings.TrimSuffix(amounts[i], "s")
}
}
bep2eNumAmounts := make([]string, 0)
if bep2eAmounts != nil && len(*bep2eAmounts) > 0 {
bep2eNumAmounts = strings.Split(*bep2eAmounts, ",")
}
symbols := make([]string, 0)
if bep2eSymbols != nil && len(*bep2eSymbols) > 0 {
symbols = strings.Split(*bep2eSymbols, ",")
}
contracts := make([]string, 0)
if bep2eContracts != nil && len(*bep2eContracts) > 0 {
contracts = strings.Split(*bep2eContracts, ",")
}
if len(bep2eNumAmounts) != len(symbols) || len(symbols) != len(contracts) {
log.Crit("Length of bep2eContracts, bep2eSymbols, bep2eAmounts mismatch")
}
bep2eInfos := make(map[string]bep2eInfo, 0)
for idx, s := range symbols {
n, ok := big.NewInt(0).SetString(bep2eNumAmounts[idx], 10)
if !ok {
log.Crit("failed to parse bep2eAmounts")
}
amountStr := big.NewFloat(0).Quo(big.NewFloat(0).SetInt(n), big.NewFloat(0).SetInt64(params.Ether)).String()
bep2eInfos[s] = bep2eInfo{
Contract: common.HexToAddress(contracts[idx]),
Amount: *n,
AmountStr: amountStr,
}
}
// Load up and render the faucet website
tmpl, err := Asset("faucet.html")
if err != nil {
@@ -118,10 +155,11 @@ func main() {
}
website := new(bytes.Buffer)
err = template.Must(template.New("").Parse(string(tmpl))).Execute(website, map[string]interface{}{
"Network": *netnameFlag,
"Amounts": amounts,
"Recaptcha": *captchaToken,
"NoAuth": *noauthFlag,
"Network": *netnameFlag,
"Amounts": amounts,
"Recaptcha": *captchaToken,
"NoAuth": *noauthFlag,
"Bep2eInfos": bep2eInfos,
})
if err != nil {
log.Crit("Failed to render the faucet template", "err", err)
@@ -162,7 +200,7 @@ func main() {
ks.Unlock(acc, pass)
// Assemble and start the faucet light service
faucet, err := newFaucet(genesis, *ethPortFlag, enodes, *netFlag, *statsFlag, ks, website.Bytes())
faucet, err := newFaucet(genesis, *ethPortFlag, enodes, *netFlag, *statsFlag, ks, website.Bytes(), bep2eInfos)
if err != nil {
log.Crit("Failed to start faucet", "err", err)
}
@@ -181,6 +219,12 @@ type request struct {
Tx *types.Transaction `json:"tx"` // Transaction funding the account
}
type bep2eInfo struct {
Contract common.Address
Amount big.Int
AmountStr string
}
// faucet represents a crypto faucet backed by an Ethereum light client.
type faucet struct {
config *params.ChainConfig // Chain configurations for signing
@@ -201,9 +245,12 @@ type faucet struct {
update chan struct{} // Channel to signal request updates
lock sync.RWMutex // Lock protecting the faucet's internals
bep2eInfos map[string]bep2eInfo
bep2eAbi abi.ABI
}
func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network uint64, stats string, ks *keystore.KeyStore, index []byte) (*faucet, error) {
func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network uint64, stats string, ks *keystore.KeyStore, index []byte, bep2eInfos map[string]bep2eInfo) (*faucet, error) {
// Assemble the raw devp2p protocol stack
stack, err := node.New(&node.Config{
Name: "geth",
@@ -222,6 +269,10 @@ func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network u
if err != nil {
return nil, err
}
bep2eAbi, err := abi.JSON(strings.NewReader(bep2eAbiJson))
if err != nil {
return nil, err
}
// Assemble the Ethereum light client protocol
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
cfg := eth.DefaultConfig
@@ -261,14 +312,16 @@ func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network u
client := ethclient.NewClient(api)
return &faucet{
config: genesis.Config,
stack: stack,
client: client,
index: index,
keystore: ks,
account: ks.Accounts()[0],
timeouts: make(map[string]time.Time),
update: make(chan struct{}, 1),
config: genesis.Config,
stack: stack,
client: client,
index: index,
keystore: ks,
account: ks.Accounts()[0],
timeouts: make(map[string]time.Time),
update: make(chan struct{}, 1),
bep2eInfos: bep2eInfos,
bep2eAbi: bep2eAbi,
}, nil
}
@@ -371,6 +424,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {
URL string `json:"url"`
Tier uint `json:"tier"`
Captcha string `json:"captcha"`
Symbol string `json:"symbol"`
}
if err = conn.ReadJSON(&msg); err != nil {
return
@@ -475,13 +529,31 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {
fund bool
timeout time.Time
)
if timeout = f.timeouts[username]; time.Now().After(timeout) {
// User wasn't funded recently, create the funding transaction
amount := new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether)
amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil))
amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil))
tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil)
if timeout = f.timeouts[username]; time.Now().After(timeout) {
var tx *types.Transaction
if msg.Symbol == "BNB" {
// User wasn't funded recently, create the funding transaction
amount := new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether)
amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil))
amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil))
tx = types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil)
} else {
tokenInfo, ok := f.bep2eInfos[msg.Symbol]
if !ok {
f.lock.Unlock()
log.Warn("Failed to find symbol", "symbol", msg.Symbol)
continue
}
input, err := f.bep2eAbi.Pack("transfer", address, &tokenInfo.Amount)
if err != nil {
f.lock.Unlock()
log.Warn("Failed to pack transfer transaction", "err", err)
continue
}
tx = types.NewTransaction(f.nonce+uint64(len(f.reqs)), tokenInfo.Contract, nil, 420000, f.price, input)
}
signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID)
if err != nil {
f.lock.Unlock()

View File

@@ -53,7 +53,13 @@
<span class="input-group-btn">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Give me BNB <i class="fa fa-caret-down" aria-hidden="true"></i></button>
<ul class="dropdown-menu dropdown-menu-right">{{range $idx, $amount := .Amounts}}
<li><a style="text-align: center;" onclick="tier={{$idx}}; {{if $.Recaptcha}}grecaptcha.execute(){{else}}submit({{$idx}}){{end}}">{{$amount}}</a></li>{{end}}
<li><a style="text-align: center;" onclick="tier={{$idx}};symbol='BNB'; {{if $.Recaptcha}}grecaptcha.execute(){{else}}submit({{$idx}}){{end}}">{{$amount}}</a></li>{{end}}
</ul>
</span>
<span class="input-group-btn">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Peggy tokens<i class="fa fa-caret-down" aria-hidden="true"></i></button>
<ul class="dropdown-menu dropdown-menu-right"> {{range $symbol, $bep2eInfo := .Bep2eInfos}}
<li><a style="text-align: center;" onclick="symbol={{$symbol}}; {{if $.Recaptcha}}grecaptcha.execute(){{else}}submitBep2e({{$symbol}}){{end}}">{{$bep2eInfo.AmountStr}} {{$symbol}}</a></li>{{end}}
</ul>
</span>
</div>{{if .Recaptcha}}
@@ -85,6 +91,7 @@
var attempt = 0;
var server;
var tier = 0;
var symbol="";
var requests = [];
// Define a function that creates closures to drop old requests
@@ -100,7 +107,7 @@
};
// Define the function that submits a gist url to the server
var submit = function({{if .Recaptcha}}captcha{{end}}) {
server.send(JSON.stringify({url: $("#url")[0].value, tier: tier{{if .Recaptcha}}, captcha: captcha{{end}}}));{{if .Recaptcha}}
server.send(JSON.stringify({url: $("#url")[0].value, symbol: symbol, tier: tier{{if .Recaptcha}}, captcha: captcha{{end}}}));{{if .Recaptcha}}
grecaptcha.reset();{{end}}
};
// Define a method to reconnect upon server loss

File diff suppressed because one or more lines are too long

View File

@@ -36,6 +36,7 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
@@ -133,6 +134,7 @@ type CParamsParams struct {
ConstantinopleForkBlock *math.HexOrDecimal64 `json:"constantinopleForkBlock"`
ConstantinopleFixForkBlock *math.HexOrDecimal64 `json:"constantinopleFixForkBlock"`
IstanbulBlock *math.HexOrDecimal64 `json:"istanbulForkBlock"`
RamanujanForkBlock *math.HexOrDecimal64 `json:"ramanujanForkBlock"`
ChainID *math.HexOrDecimal256 `json:"chainID"`
MaximumExtraDataSize math.HexOrDecimal64 `json:"maximumExtraDataSize"`
TieBreakingGas bool `json:"tieBreakingGas"`
@@ -322,6 +324,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
constantinopleBlock *big.Int
petersburgBlock *big.Int
istanbulBlock *big.Int
ramanujanBlock *big.Int
)
if chainParams.Params.HomesteadForkBlock != nil {
homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock))
@@ -351,6 +354,9 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
if chainParams.Params.IstanbulBlock != nil {
istanbulBlock = big.NewInt(int64(*chainParams.Params.IstanbulBlock))
}
if chainParams.Params.RamanujanForkBlock != nil {
ramanujanBlock = big.NewInt(int64(*chainParams.Params.RamanujanForkBlock))
}
genesis := &core.Genesis{
Config: &params.ChainConfig{
@@ -365,6 +371,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
ConstantinopleBlock: constantinopleBlock,
PetersburgBlock: petersburgBlock,
IstanbulBlock: istanbulBlock,
RamanujanBlock: ramanujanBlock,
},
Nonce: uint64(chainParams.Genesis.Nonce),
Timestamp: uint64(chainParams.Genesis.Timestamp),
@@ -501,6 +508,7 @@ func (api *RetestethAPI) mineBlock() error {
if api.chainConfig.DAOForkSupport && api.chainConfig.DAOForkBlock != nil && api.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(statedb)
}
systemcontracts.UpgradeBuildInSystemContract(api.chainConfig, header.Number, statedb)
gasPool := new(core.GasPool).AddGas(header.GasLimit)
txCount := 0
var txs []*types.Transaction

View File

@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc"
"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/core/vm"
"github.com/ethereum/go-ethereum/crypto"
@@ -48,17 +49,11 @@ const (
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
validatorBytesLength = common.AddressLength
wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
fixedBackOffTime = 200 * time.Millisecond
wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers
initialBackOffTime = uint64(1) // second
systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system
// genesis contracts
ValidatorContract = "0x0000000000000000000000000000000000001000"
SlashContract = "0x0000000000000000000000000000000000001001"
SystemRewardContract = "0x0000000000000000000000000000000000001002"
LightClientContract = "0x0000000000000000000000000000000000001003"
RelayerHubContract = "0x0000000000000000000000000000000000001006"
)
var (
@@ -69,11 +64,15 @@ var (
maxSystemBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(params.Ether))
systemContracts = map[common.Address]bool{
common.HexToAddress(ValidatorContract): true,
common.HexToAddress(SlashContract): true,
common.HexToAddress(SystemRewardContract): true,
common.HexToAddress(LightClientContract): true,
common.HexToAddress(RelayerHubContract): true,
common.HexToAddress(systemcontracts.ValidatorContract): true,
common.HexToAddress(systemcontracts.SlashContract): true,
common.HexToAddress(systemcontracts.SystemRewardContract): true,
common.HexToAddress(systemcontracts.LightClientContract): true,
common.HexToAddress(systemcontracts.RelayerHubContract): true,
common.HexToAddress(systemcontracts.GovHubContract): true,
common.HexToAddress(systemcontracts.TokenHubContract): true,
common.HexToAddress(systemcontracts.RelayerIncentivizeContract): true,
common.HexToAddress(systemcontracts.CrossChainContract): true,
}
)
@@ -148,7 +147,7 @@ func isToSystemContract(to common.Address) bool {
}
// ecrecover extracts the Ethereum account address from a signed header.
func ecrecover(header *types.Header, sigCache *lru.ARCCache) (common.Address, error) {
func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (common.Address, error) {
// If the signature's already cached, return that
hash := header.Hash()
if address, known := sigCache.Get(hash); known {
@@ -161,7 +160,7 @@ func ecrecover(header *types.Header, sigCache *lru.ARCCache) (common.Address, er
signature := header.Extra[len(header.Extra)-extraSeal:]
// Recover the public key and the Ethereum address
pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature)
pubkey, err := crypto.Ecrecover(SealHash(header, chainId).Bytes(), signature)
if err != nil {
return common.Address{}, err
}
@@ -179,9 +178,9 @@ func ecrecover(header *types.Header, sigCache *lru.ARCCache) (common.Address, er
// Note, the method requires the extra data to be at least 65 bytes, otherwise it
// panics. This is done to avoid accidentally using both forms (signature present
// or not), which could be abused to produce different hashes for the same header.
func ParliaRLP(header *types.Header) []byte {
func ParliaRLP(header *types.Header, chainId *big.Int) []byte {
b := new(bytes.Buffer)
encodeSigHeader(b, header)
encodeSigHeader(b, header, chainId)
return b.Bytes()
}
@@ -265,7 +264,7 @@ func (p *Parlia) IsSystemTransaction(tx *types.Transaction, header *types.Header
if err != nil {
return false, errors.New("UnAuthorized transaction")
}
if sender == header.Coinbase && isToSystemContract(*tx.To()) {
if sender == header.Coinbase && isToSystemContract(*tx.To()) && tx.GasPrice().Cmp(big.NewInt(0)) == 0 {
return true, nil
}
return false, nil
@@ -330,7 +329,6 @@ func (p *Parlia) verifyHeader(chain consensus.ChainReader, header *types.Header,
if len(header.Extra) < extraVanity+extraSeal {
return errMissingSignature
}
// check extra data
isEpoch := number%p.config.Epoch == 0
@@ -388,10 +386,20 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainReader, header *type
return consensus.ErrUnknownAncestor
}
snap, err := p.snapshot(chain, number-1, header.ParentHash, parents)
if err != nil {
return err
}
err = p.blockTimeVerifyForRamanujanFork(snap, header, parent)
if err != nil {
return err
}
// Verify that the gas limit is <= 2^63-1
cap := uint64(0x7fffffffffffffff)
if header.GasLimit > cap {
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
capacity := uint64(0x7fffffffffffffff)
if header.GasLimit > capacity {
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, capacity)
}
// Verify that the gasUsed is <= gasLimit
if header.GasUsed > header.GasLimit {
@@ -491,7 +499,7 @@ func (p *Parlia) snapshot(chain consensus.ChainReader, number uint64, hash commo
headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
}
snap, err := snap.apply(headers, chain, parents)
snap, err := snap.apply(headers, chain, parents, p.chainConfig.ChainID)
if err != nil {
return nil, err
}
@@ -539,7 +547,7 @@ func (p *Parlia) verifySeal(chain consensus.ChainReader, header *types.Header, p
}
// Resolve the authorization key and check against validators
signer, err := ecrecover(header, p.signatures)
signer, err := ecrecover(header, p.signatures, p.chainConfig.ChainID)
if err != nil {
return err
}
@@ -563,7 +571,7 @@ func (p *Parlia) verifySeal(chain consensus.ChainReader, header *types.Header, p
// Ensure that the difficulty corresponds to the turn-ness of the signer
if !p.fakeDiff {
inturn := snap.inturn(header.Number.Uint64(), signer)
inturn := snap.inturn(signer)
if inturn && header.Difficulty.Cmp(diffInTurn) != 0 {
return errWrongDifficulty
}
@@ -619,8 +627,7 @@ func (p *Parlia) Prepare(chain consensus.ChainReader, header *types.Header) erro
if parent == nil {
return consensus.ErrUnknownAncestor
}
header.Time = parent.Time + p.config.Period
header.Time = p.blockTimeForRamanujanFork(snap, header, parent)
if header.Time < uint64(time.Now().Unix()) {
header.Time = uint64(time.Now().Unix())
}
@@ -653,7 +660,7 @@ func (p *Parlia) Finalize(chain consensus.ChainReader, header *types.Header, sta
// No block rewards in PoA, so the state remains as is and uncles are dropped
cx := chainContext{Chain: chain, parlia: p}
if header.Number.Cmp(common.Big1) == 0 {
err := p.initContract(state, header, cx, txs, receipts, systemTxs, usedGas)
err := p.initContract(state, header, cx, txs, receipts, systemTxs, usedGas, false)
if err != nil {
log.Error("init contract failed")
}
@@ -674,14 +681,15 @@ func (p *Parlia) Finalize(chain consensus.ChainReader, header *types.Header, sta
}
if !signedRecently {
log.Info("slash validator", "block hash", header.Hash(), "address", spoiledVal)
err = p.slash(spoiledVal, state, header, cx, txs, receipts, systemTxs, usedGas)
err = p.slash(spoiledVal, state, header, cx, txs, receipts, systemTxs, usedGas, false)
if err != nil {
panic(err)
// it is possible that slash validator failed because of the slash channel is disabled.
log.Error("slash validator failed", "block hash", header.Hash(), "address", spoiledVal)
}
}
}
val := header.Coinbase
err := p.distributeIncoming(val, state, header, cx, txs, receipts, systemTxs, usedGas)
err := p.distributeIncoming(val, state, header, cx, txs, receipts, systemTxs, usedGas, false)
if err != nil {
panic(err)
}
@@ -706,7 +714,7 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainReader, header *types.
receipts = make([]*types.Receipt, 0)
}
if header.Number.Cmp(common.Big1) == 0 {
err := p.initContract(state, header, cx, &txs, &receipts, nil, &header.GasUsed)
err := p.initContract(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
if err != nil {
log.Error("init contract failed")
}
@@ -726,16 +734,21 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainReader, header *types.
}
}
if !signedRecently {
err = p.slash(spoiledVal, state, header, cx, &txs, &receipts, nil, &header.GasUsed)
err = p.slash(spoiledVal, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
if err != nil {
panic(err)
// it is possible that slash validator failed because of the slash channel is disabled.
log.Error("slash validator failed", "block hash", header.Hash(), "address", spoiledVal)
}
}
}
err := p.distributeIncoming(p.val, state, header, cx, &txs, &receipts, nil, &header.GasUsed)
err := p.distributeIncoming(p.val, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
if err != nil {
panic(err)
}
// should not happen. Once happen, stop the node is better than broadcast the block
if header.GasLimit < header.GasUsed {
panic("Gas consumption of system txs exceed the gas limit")
}
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil)
@@ -796,19 +809,12 @@ func (p *Parlia) Seal(chain consensus.ChainReader, block *types.Block, results c
}
// Sweet, the protocol permits us to sign the block, wait for our time
delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple
if header.Difficulty.Cmp(diffNoTurn) == 0 {
// It's not our turn explicitly to sign, delay it a bit
wiggle := time.Duration(len(snap.Validators)/2+1) * wiggleTime
delay += time.Duration(fixedBackOffTime) + time.Duration(rand.Int63n(int64(wiggle)))
log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
}
delay := p.delayForRamanujanFork(snap, header)
log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex())
// Sign all the things!
sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header))
sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID))
if err != nil {
return err
}
@@ -826,7 +832,7 @@ func (p *Parlia) Seal(chain consensus.ChainReader, block *types.Block, results c
select {
case results <- block.WithSeal(header):
default:
log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header))
log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header, p.chainConfig.ChainID))
}
}()
@@ -848,7 +854,7 @@ func (p *Parlia) CalcDifficulty(chain consensus.ChainReader, time uint64, parent
// that a new block should have based on the previous blocks in the chain and the
// current signer.
func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
if snap.inturn(snap.Number+1, signer) {
if snap.inturn(signer) {
return new(big.Int).Set(diffInTurn)
}
return new(big.Int).Set(diffNoTurn)
@@ -856,7 +862,7 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
// SealHash returns the hash of a block prior to it being sealed.
func (p *Parlia) SealHash(header *types.Header) common.Hash {
return SealHash(header)
return SealHash(header, p.chainConfig.ChainID)
}
// APIs implements consensus.Engine, returning the user facing RPC API to query snapshot.
@@ -894,7 +900,7 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address,
}
// call
msgData := (hexutil.Bytes)(data)
toAddress := common.HexToAddress(ValidatorContract)
toAddress := common.HexToAddress(systemcontracts.ValidatorContract)
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
result, err := p.ethAPI.Call(ctx, ethapi.CallArgs{
Gas: &gas,
@@ -923,7 +929,7 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address,
// slash spoiled validators
func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, header *types.Header, chain core.ChainContext,
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64) error {
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
coinbase := header.Coinbase
balance := state.GetBalance(consensus.SystemAddress)
if balance.Cmp(common.Big0) <= 0 {
@@ -932,12 +938,12 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he
state.SetBalance(consensus.SystemAddress, big.NewInt(0))
state.AddBalance(coinbase, balance)
doDistributeSysReward := state.GetBalance(common.HexToAddress(SystemRewardContract)).Cmp(maxSystemBalance) < 0
doDistributeSysReward := state.GetBalance(common.HexToAddress(systemcontracts.SystemRewardContract)).Cmp(maxSystemBalance) < 0
if doDistributeSysReward {
var rewards = new(big.Int)
rewards = rewards.Rsh(balance, systemRewardPercent)
if rewards.Cmp(common.Big0) > 0 {
err := p.distributeToSystem(rewards, state, header, chain, txs, receipts, receivedTxs, usedGas)
err := p.distributeToSystem(rewards, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
if err != nil {
return err
}
@@ -946,12 +952,12 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he
}
}
log.Info("distribute to validator contract", "block hash", header.Hash(), "amount", balance)
return p.distributeToValidator(balance, val, state, header, chain, txs, receipts, receivedTxs, usedGas)
return p.distributeToValidator(balance, val, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
}
// slash spoiled validators
func (p *Parlia) slash(spoiledVal common.Address, state *state.StateDB, header *types.Header, chain core.ChainContext,
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64) error {
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
// method
method := "slash"
@@ -964,18 +970,26 @@ func (p *Parlia) slash(spoiledVal common.Address, state *state.StateDB, header *
return err
}
// get system message
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(SlashContract), data, common.Big0)
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.SlashContract), data, common.Big0)
// apply message
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas)
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
}
// init contract
func (p *Parlia) initContract(state *state.StateDB, header *types.Header, chain core.ChainContext,
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64) error {
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
// method
method := "init"
// contracts
contracts := []string{ValidatorContract, SlashContract, LightClientContract, RelayerHubContract}
contracts := []string{
systemcontracts.ValidatorContract,
systemcontracts.SlashContract,
systemcontracts.LightClientContract,
systemcontracts.RelayerHubContract,
systemcontracts.TokenHubContract,
systemcontracts.RelayerIncentivizeContract,
systemcontracts.CrossChainContract,
}
// get packed data
data, err := p.validatorSetABI.Pack(method)
if err != nil {
@@ -986,7 +1000,7 @@ func (p *Parlia) initContract(state *state.StateDB, header *types.Header, chain
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(c), data, common.Big0)
// apply message
log.Info("init contract", "block hash", header.Hash(), "contract", c)
err = p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas)
err = p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
if err != nil {
return err
}
@@ -995,17 +1009,17 @@ func (p *Parlia) initContract(state *state.StateDB, header *types.Header, chain
}
func (p *Parlia) distributeToSystem(amount *big.Int, state *state.StateDB, header *types.Header, chain core.ChainContext,
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64) error {
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
// get system message
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(SystemRewardContract), nil, amount)
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.SystemRewardContract), nil, amount)
// apply message
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas)
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
}
// slash spoiled validators
func (p *Parlia) distributeToValidator(amount *big.Int, validator common.Address,
state *state.StateDB, header *types.Header, chain core.ChainContext,
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64) error {
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
// method
method := "deposit"
@@ -1018,9 +1032,9 @@ func (p *Parlia) distributeToValidator(amount *big.Int, validator common.Address
return err
}
// get system message
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(ValidatorContract), data, amount)
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, amount)
// apply message
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas)
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
}
// get system message
@@ -1043,13 +1057,13 @@ func (p *Parlia) applyTransaction(
header *types.Header,
chainContext core.ChainContext,
txs *[]*types.Transaction, receipts *[]*types.Receipt,
receivedTxs *[]*types.Transaction, usedGas *uint64,
receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool,
) (err error) {
nonce := state.GetNonce(msg.From())
expectedTx := types.NewTransaction(nonce, *msg.To(), msg.Value(), msg.Gas(), msg.GasPrice(), msg.Data())
expectedHash := p.signer.Hash(expectedTx)
if msg.From() == p.val {
if msg.From() == p.val && mining {
expectedTx, err = p.signTxFn(accounts.Account{Address: msg.From()}, expectedTx, p.chainConfig.ChainID)
if err != nil {
return err
@@ -1059,8 +1073,8 @@ func (p *Parlia) applyTransaction(
return errors.New("supposed to get a actual transaction, but get none")
}
actualTx := (*receivedTxs)[0]
if bytes.Compare(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) != 0 {
return errors.New(fmt.Sprintf("expected tx hash %v, get %v", expectedHash.String(), actualTx.Hash().String()))
if !bytes.Equal(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) {
return fmt.Errorf("expected tx hash %v, get %v", expectedHash.String(), actualTx.Hash().String())
}
expectedTx = actualTx
// move to next
@@ -1096,15 +1110,16 @@ func (p *Parlia) applyTransaction(
// =========================== utility function ==========================
// SealHash returns the hash of a block prior to it being sealed.
func SealHash(header *types.Header) (hash common.Hash) {
func SealHash(header *types.Header, chainId *big.Int) (hash common.Hash) {
hasher := sha3.NewLegacyKeccak256()
encodeSigHeader(hasher, header)
encodeSigHeader(hasher, header, chainId)
hasher.Sum(hash[:0])
return hash
}
func encodeSigHeader(w io.Writer, header *types.Header) {
func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) {
err := rlp.Encode(w, []interface{}{
chainId,
header.ParentHash,
header.UncleHash,
header.Coinbase,
@@ -1126,6 +1141,30 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
}
}
func backOffTime(snap *Snapshot, val common.Address) uint64 {
if snap.inturn(val) {
return 0
} else {
idx := snap.indexOfVal(val)
if idx < 0 {
// The backOffTime does not matter when a validator is not authorized.
return 0
}
s := rand.NewSource(int64(snap.Number))
r := rand.New(s)
n := len(snap.Validators)
backOffSteps := make([]uint64, 0, n)
for idx := uint64(0); idx < uint64(n); idx++ {
backOffSteps = append(backOffSteps, idx)
}
r.Shuffle(n, func(i, j int) {
backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i]
})
delay := initialBackOffTime + backOffSteps[idx]*wiggleTime
return delay
}
}
// chain context
type chainContext struct {
Chain consensus.ChainReader

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"math/rand"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
)
@@ -57,7 +56,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
return validators[idx]
}
downDelay := time.Duration(0)
downDelay := uint64(0)
for h := 1; h <= downBlocks; h++ {
if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit {
delete(recents, uint64(h)-limit)
@@ -73,7 +72,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
if len(candidates) == 0 {
panic("can not test such case")
}
idx, delay := producerBlockDelay(candidates, totalValidators)
idx, delay := producerBlockDelay(candidates, h, totalValidators)
downDelay = downDelay + delay
recents[uint64(h)] = idx
} else {
@@ -81,13 +80,13 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
}
}
fmt.Printf("average delay is %v when there is %d validators and %d is down \n",
downDelay/time.Duration(downBlocks), totalValidators, downValidators)
downDelay/uint64(downBlocks), totalValidators, downValidators)
for i := 0; i < downValidators; i++ {
validators[down[i]] = true
}
recoverDelay := time.Duration(0)
recoverDelay := uint64(0)
lastseen := downBlocks
for h := downBlocks + 1; h <= downBlocks+recoverBlocks; h++ {
if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit {
@@ -105,7 +104,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
if len(candidates) == 0 {
panic("can not test such case")
}
idx, delay := producerBlockDelay(candidates, totalValidators)
idx, delay := producerBlockDelay(candidates, h, totalValidators)
recoverDelay = recoverDelay + delay
recents[uint64(h)] = idx
} else {
@@ -116,18 +115,28 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
recoverDelay, downValidators, lastseen)
}
func producerBlockDelay(candidates map[int]bool, numOfValidators int) (int, time.Duration) {
minDur := time.Duration(0)
minIdx := 0
wiggle := time.Duration(numOfValidators/2+1) * wiggleTime
for idx := range candidates {
sleepTime := rand.Int63n(int64(wiggle))
if int64(minDur) < sleepTime {
minDur = time.Duration(rand.Int63n(int64(wiggle)))
minIdx = idx
func producerBlockDelay(candidates map[int]bool, height, numOfValidators int) (int, uint64) {
s := rand.NewSource(int64(height))
r := rand.New(s)
n := numOfValidators
backOffSteps := make([]int, 0, n)
for idx := 0; idx < n; idx++ {
backOffSteps = append(backOffSteps, idx)
}
r.Shuffle(n, func(i, j int) {
backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i]
})
minDelay := numOfValidators
minCandidate := 0
for c := range candidates {
if minDelay > backOffSteps[c] {
minDelay = backOffSteps[c]
minCandidate = c
}
}
return minIdx, minDur
delay := initialBackOffTime + uint64(minDelay)*wiggleTime
return minCandidate, delay
}
func randomAddress() common.Address {

View File

@@ -0,0 +1,44 @@
package parlia
import (
"math/rand"
"time"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/types"
)
const (
wiggleTimeBeforeFork = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
fixedBackOffTimeBeforeFork = 200 * time.Millisecond
)
func (p *Parlia) delayForRamanujanFork(snap *Snapshot, header *types.Header) time.Duration {
delay := time.Until(time.Unix(int64(header.Time), 0)) // nolint: gosimple
if p.chainConfig.IsRamanujan(header.Number) {
return delay
}
if header.Difficulty.Cmp(diffNoTurn) == 0 {
// It's not our turn explicitly to sign, delay it a bit
wiggle := time.Duration(len(snap.Validators)/2+1) * wiggleTimeBeforeFork
delay += time.Duration(fixedBackOffTimeBeforeFork) + time.Duration(rand.Int63n(int64(wiggle)))
}
return delay
}
func (p *Parlia) blockTimeForRamanujanFork(snap *Snapshot, header, parent *types.Header) uint64 {
blockTime := parent.Time + p.config.Period
if p.chainConfig.IsRamanujan(header.Number) {
blockTime = blockTime + backOffTime(snap, p.val)
}
return blockTime
}
func (p *Parlia) blockTimeVerifyForRamanujanFork(snap *Snapshot, header, parent *types.Header) error {
if p.chainConfig.IsRamanujan(header.Number) {
if header.Time < parent.Time+p.config.Period+backOffTime(snap, header.Coinbase) {
return consensus.ErrFutureBlock
}
}
return nil
}

View File

@@ -20,6 +20,7 @@ import (
"bytes"
"encoding/json"
"errors"
"math/big"
"sort"
"github.com/ethereum/go-ethereum/common"
@@ -123,7 +124,7 @@ func (s *Snapshot) copy() *Snapshot {
return cpy
}
func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainReader, parents []*types.Header) (*Snapshot, error) {
func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainReader, parents []*types.Header, chainId *big.Int) (*Snapshot, error) {
// Allow passing in no headers for cleaner code
if len(headers) == 0 {
return s, nil
@@ -153,7 +154,7 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainReader, p
delete(snap.Recents, number-limit)
}
// Resolve the authorization key and check against signers
validator, err := ecrecover(header, s.sigCache)
validator, err := ecrecover(header, s.sigCache, chainId)
if err != nil {
return nil, err
}
@@ -209,12 +210,22 @@ func (s *Snapshot) validators() []common.Address {
}
// inturn returns if a validator at a given block height is in-turn or not.
func (s *Snapshot) inturn(number uint64, validator common.Address) bool {
func (s *Snapshot) inturn(validator common.Address) bool {
validators := s.validators()
offset := number % uint64(len(validators))
offset := (s.Number + 1) % uint64(len(validators))
return validators[offset] == validator
}
func (s *Snapshot) indexOfVal(validator common.Address) int {
validators := s.validators()
for idx, val := range validators {
if val == validator {
return idx
}
}
return -1
}
func (s *Snapshot) supposeValidator() common.Address {
validators := s.validators()
index := (s.Number + 1) % uint64(len(validators))

View File

@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
"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/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
@@ -207,6 +208,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
misc.ApplyDAOHardFork(statedb)
}
systemcontracts.UpgradeBuildInSystemContract(config, b.header.Number, statedb)
// Execute any user modifications to the block
if gen != nil {
gen(i, b)

View File

@@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/rawdb"
"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/crypto"
"github.com/ethereum/go-ethereum/ethdb"
@@ -161,6 +162,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
}
// Just commit the new block if there is no stored genesis block.
stored := rawdb.ReadCanonicalHash(db, 0)
systemcontracts.GenesisHash = stored
if (stored == common.Hash{}) {
if genesis == nil {
log.Info("Writing default main-net genesis block")
@@ -222,7 +224,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
// Special case: don't change the existing config of a non-mainnet chain if no new
// config is supplied. These chains would get AllProtocolChanges (and a compat error)
// if we just continued here.
if genesis == nil && stored != params.MainnetGenesisHash {
// The full node of two BSC testnets may run without genesis file after been inited.
if genesis == nil && stored != params.MainnetGenesisHash &&
stored != params.ChapelGenesisHash && stored != params.RialtoGenesisHash {
return storedcfg, stored, nil
}
@@ -252,6 +256,10 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
return params.RinkebyChainConfig
case ghash == params.GoerliGenesisHash:
return params.GoerliChainConfig
case ghash == params.ChapelGenesisHash:
return params.ChapelChainConfig
case ghash == params.RialtoGenesisHash:
return params.RialtoChainConfig
default:
return params.AllEthashProtocolChanges
}

View File

@@ -21,6 +21,7 @@ import (
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
"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/core/vm"
"github.com/ethereum/go-ethereum/crypto"
@@ -65,6 +66,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
}
// Handle upgrade build-in system contract code
systemcontracts.UpgradeBuildInSystemContract(p.config, block.Number(), statedb)
// Iterate over and process the individual transactions
posa, isPoSA := p.engine.(consensus.PoSA)
commonTxs := make([]*types.Transaction, 0, len(block.Transactions()))

View File

@@ -0,0 +1,15 @@
package systemcontracts
const (
// genesis contracts
ValidatorContract = "0x0000000000000000000000000000000000001000"
SlashContract = "0x0000000000000000000000000000000000001001"
SystemRewardContract = "0x0000000000000000000000000000000000001002"
LightClientContract = "0x0000000000000000000000000000000000001003"
TokenHubContract = "0x0000000000000000000000000000000000001004"
RelayerIncentivizeContract = "0x0000000000000000000000000000000000001005"
RelayerHubContract = "0x0000000000000000000000000000000000001006"
GovHubContract = "0x0000000000000000000000000000000000001007"
TokenManagerContract = "0x0000000000000000000000000000000000001008"
CrossChainContract = "0x0000000000000000000000000000000000002000"
)

File diff suppressed because one or more lines are too long

View File

@@ -9,6 +9,7 @@ import (
)
const (
uint64TypeLength uint64 = 8
precompileContractInputMetaDataLength uint64 = 32
consensusStateLengthBytesLength uint64 = 32
@@ -20,7 +21,7 @@ const (
// consensus state length | consensus state | tendermint header |
// 32 bytes | | |
func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.ConsensusState, *lightclient.Header, error) {
csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-8 : consensusStateLengthBytesLength])
csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength])
if uint64(len(input)) <= consensusStateLengthBytesLength+csLen {
return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input))
}
@@ -55,7 +56,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
return nil, fmt.Errorf("invalid input")
}
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-8 : precompileContractInputMetaDataLength])
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : precompileContractInputMetaDataLength])
if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength {
return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input))
}
@@ -83,7 +84,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
copy(lengthBytes[:1], []byte{0x01})
}
consensusStateBytesLength := uint64(len(consensusStateBytes))
binary.BigEndian.PutUint64(lengthBytes[tmHeaderValidateResultMetaDataLength-8:], consensusStateBytesLength)
binary.BigEndian.PutUint64(lengthBytes[tmHeaderValidateResultMetaDataLength-uint64TypeLength:], consensusStateBytesLength)
result = append(lengthBytes, consensusStateBytes...)
@@ -113,7 +114,7 @@ func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
return nil, fmt.Errorf("invalid input: input should include %d bytes payload length and payload", precompileContractInputMetaDataLength)
}
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-8 : precompileContractInputMetaDataLength])
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : precompileContractInputMetaDataLength])
if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength {
return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input))
}
@@ -129,6 +130,6 @@ func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
}
result = make([]byte, merkleProofValidateResultLength)
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-8:], 0x01)
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01)
return result, nil
}

View File

@@ -24,6 +24,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) {
"cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc000000174876e80049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb7" +
"87a5b314a298e000000174876e80004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b6000000174876e8004034b37ce" +
"da8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800")
require.NoError(t, err)
cs, err := lightclient.DecodeConsensusState(consensusStateBytes)
require.NoError(t, err)

View File

@@ -162,10 +162,11 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// as every returning call will return new data anyway.
in.returnData = nil
// TODO temporary fix for issue
// Don't bother with the execution if there's no code.
if len(contract.Code) == 0 {
return nil, nil
}
//if len(contract.Code) == 0 {
// return nil, nil
//}
var (
op OpCode // current opcode

View File

@@ -226,17 +226,11 @@ func (kvmp *KeyValueMerkleProof) Validate() bool {
if len(kvmp.Value) == 0 {
err := prt.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String())
if err != nil {
return false
}
return true
return err == nil
}
err := prt.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value)
if err != nil {
return false
}
return true
return err == nil
}
// input:

View File

@@ -502,12 +502,13 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
// Generate the next state snapshot fast without tracing
msg, _ := tx.AsMessage(signer)
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
if posa, ok := api.eth.engine.(consensus.PoSA); ok && msg.From() == block.Header().Coinbase &&
posa.IsSystemContract(msg.To()) {
balance := statedb.GetBalance(consensus.SystemAddress)
if balance.Cmp(common.Big0) > 0 {
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0))
statedb.AddBalance(block.Header().Coinbase, balance)
if posa, ok := api.eth.engine.(consensus.PoSA); ok {
if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem {
balance := statedb.GetBalance(consensus.SystemAddress)
if balance.Cmp(common.Big0) > 0 {
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0))
statedb.AddBalance(block.Header().Coinbase, balance)
}
}
}
vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vm.Config{})
@@ -767,7 +768,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
// Run the transaction with tracing enabled.
vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vm.Config{Debug: true, Tracer: tracer})
if posa, ok := api.eth.engine.(consensus.PoSA); ok && message.From() == vmctx.Coinbase &&
posa.IsSystemContract(message.To()) {
posa.IsSystemContract(message.To()) && message.GasPrice().Cmp(big.NewInt(0)) == 0 {
balance := statedb.GetBalance(consensus.SystemAddress)
if balance.Cmp(common.Big0) > 0 {
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0))
@@ -822,12 +823,13 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
for idx, tx := range block.Transactions() {
// Assemble the transaction call message and return if the requested offset
msg, _ := tx.AsMessage(signer)
if posa, ok := api.eth.engine.(consensus.PoSA); ok && msg.From() == block.Header().Coinbase &&
posa.IsSystemContract(msg.To()) {
balance := statedb.GetBalance(consensus.SystemAddress)
if balance.Cmp(common.Big0) > 0 {
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0))
statedb.AddBalance(block.Header().Coinbase, balance)
if posa, ok := api.eth.engine.(consensus.PoSA); ok {
if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem {
balance := statedb.GetBalance(consensus.SystemAddress)
if balance.Cmp(common.Big0) > 0 {
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0))
statedb.AddBalance(block.Header().Coinbase, balance)
}
}
}
context := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)

View File

@@ -37,7 +37,7 @@ const (
)
const (
maxUncleDist = 7 // Maximum allowed backward distance from the chain head
maxUncleDist = 11 // Maximum allowed backward distance from the chain head
maxQueueDist = 32 // Maximum allowed distance from the chain head to queue
hashLimit = 256 // Maximum number of unique blocks a peer may have announced
blockLimit = 64 // Maximum number of unique blocks a peer may have delivered
@@ -681,11 +681,12 @@ func (f *BlockFetcher) insert(peer string, block *types.Block) {
go f.broadcastBlock(block, true)
case consensus.ErrFutureBlock:
// Weird future block, don't fail, but neither propagate
log.Error("Received future block", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
f.dropPeer(peer)
default:
// Something went very wrong, drop the peer
log.Debug("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
log.Error("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
f.dropPeer(peer)
return
}

3
go.mod
View File

@@ -72,17 +72,14 @@ require (
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect
golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
golang.org/x/text v0.3.2
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 // indirect
google.golang.org/grpc v1.27.1 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9
gopkg.in/urfave/cli.v1 v1.20.0
gotest.tools v2.2.0+incompatible // indirect
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect
)

5
go.sum
View File

@@ -28,6 +28,7 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 h1:rtI0fD4oG/8eVokGVPYJEW1F88p1ZNgXiEIs9thEE4A=
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/aws/aws-sdk-go v1.25.48 h1:J82DYDGZHOKHdhx6hD24Tm30c2C3GchYGfN0mf9iKUk=
github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
@@ -50,6 +51,7 @@ github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9 h1:J82+/8rub3qSy0HxEnoYD8cs+HDlHWYrqYXe2Vqxluk=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -69,6 +71,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmakYiSlqu2425CHyFXLZZnvm7PDpU8M=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87 h1:OMbqMXf9OAXzH1dDH82mQMrddBE8LIIwDtxeK4wE1/A=
github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
@@ -136,11 +139,13 @@ github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZ
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA=
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM52clh5rGzTKpVctGT1lH4Dc8Jw=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=

View File

@@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/parlia"
"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/event"
"github.com/ethereum/go-ethereum/log"
@@ -56,7 +57,7 @@ const (
resubmitAdjustChanSize = 10
// miningLogAtDepth is the number of confirmations before logging successful mining.
miningLogAtDepth = 15
miningLogAtDepth = 11
// minRecommitInterval is the minimal time interval to recreate the mining block with
// any newly arrived transactions.
@@ -75,7 +76,7 @@ const (
intervalAdjustBias = 200 * 1000.0 * 1000.0
// staleThreshold is the maximum depth of the acceptable stale block.
staleThreshold = 7
staleThreshold = 11
)
var (
@@ -356,7 +357,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
commit(false, commitInterruptNewHead)
case head := <-w.chainHeadCh:
if !w.isRunning(){
if !w.isRunning() {
continue
}
clearPending(head.Block.NumberU64())
@@ -732,6 +733,7 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
if w.current.gasPool == nil {
w.current.gasPool = new(core.GasPool).AddGas(w.current.header.GasLimit)
w.current.gasPool.SubGas(params.SystemTxsGas)
}
var coalescedLogs []*types.Log
@@ -899,6 +901,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
if w.chainConfig.DAOForkSupport && w.chainConfig.DAOForkBlock != nil && w.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(env.state)
}
systemcontracts.UpgradeBuildInSystemContract(w.chainConfig, header.Number, env.state)
// Accumulate the uncles for the current block
uncles := make([]*types.Header, 0, 2)
commitUncles := func(blocks map[common.Hash]*types.Block) {

View File

@@ -31,6 +31,9 @@ var (
RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
ChapelGenesisHash = common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34")
RialtoGenesisHash = common.HexToHash("0xaa1c1e0af675e846942719466ab72822eff51ebf8462ead0897ae1240e3c0da1")
)
// TrustedCheckpoints associates each known checkpoint with the genesis hash of
@@ -210,21 +213,59 @@ var (
Threshold: 2,
}
ChapelChainConfig = &ChainConfig{
ChainID: big.NewInt(97),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
RamanujanBlock: big.NewInt(1010000),
NielsBlock: big.NewInt(1014369),
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
},
}
RialtoChainConfig = &ChainConfig{
ChainID: big.NewInt(1417),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
RamanujanBlock: big.NewInt(400),
NielsBlock: big.NewInt(0),
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
},
}
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Ethash consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, new(EthashConfig), nil, nil}
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, new(EthashConfig), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int))
)
@@ -296,6 +337,8 @@ type ChainConfig struct {
IstanbulBlock *big.Int `json:"istanbulBlock,omitempty" toml:",omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul)
MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty" toml:",omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
EWASMBlock *big.Int `json:"ewasmBlock,omitempty" toml:",omitempty"` // EWASM switch block (nil = no fork, 0 = already activated)
RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated)
NielsBlock *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"` // nielsBlock switch block (nil = no fork, 0 = already activated)
// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
@@ -346,7 +389,7 @@ func (c *ChainConfig) String() string {
default:
engine = "unknown"
}
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Engine: %v}",
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, Engine: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
@@ -359,6 +402,8 @@ func (c *ChainConfig) String() string {
c.PetersburgBlock,
c.IstanbulBlock,
c.MuirGlacierBlock,
c.RamanujanBlock,
c.NielsBlock,
engine,
)
}
@@ -398,6 +443,26 @@ func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
return isForked(c.ConstantinopleBlock, num)
}
// IsRamanujan returns whether num is either equal to the IsRamanujan fork block or greater.
func (c *ChainConfig) IsRamanujan(num *big.Int) bool {
return isForked(c.RamanujanBlock, num)
}
// IsOnRamanujan returns whether num is equal to the Ramanujan fork block
func (c *ChainConfig) IsOnRamanujan(num *big.Int) bool {
return configNumEqual(c.RamanujanBlock, num)
}
// IsNiels returns whether num is either equal to the Niels fork block or greater.
func (c *ChainConfig) IsNiels(num *big.Int) bool {
return isForked(c.NielsBlock, num)
}
// IsOnNiels returns whether num is equal to the IsNiels fork block
func (c *ChainConfig) IsOnNiels(num *big.Int) bool {
return configNumEqual(c.NielsBlock, num)
}
// IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
return isForked(c.MuirGlacierBlock, num)
@@ -456,6 +521,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{"petersburgBlock", c.PetersburgBlock},
{"istanbulBlock", c.IstanbulBlock},
{"muirGlacierBlock", c.MuirGlacierBlock},
{"ramanujanBlock", c.RamanujanBlock},
} {
if lastFork.name != "" {
// Next one must be higher number
@@ -515,6 +581,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
}
if isForkIncompatible(c.RamanujanBlock, newcfg.RamanujanBlock, head) {
return newCompatError("ramanujan fork block", c.RamanujanBlock, newcfg.RamanujanBlock)
}
return nil
}

View File

@@ -19,21 +19,22 @@ package params
import "math/big"
const (
GasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations.
GasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations.
MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be.
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction.
SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero.
CallNewAccountGas uint64 = 25000 // Paid for CALL when the destination address didn't exist prior.
TxGas uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions.
TxGasContractCreation uint64 = 53000 // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions.
TxDataZeroGas uint64 = 4 // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
QuadCoeffDiv uint64 = 512 // Divisor for the quadratic particle of the memory cost equation.
LogDataGas uint64 = 8 // Per byte in a LOG* operation's data.
CallStipend uint64 = 2300 // Free gas given at beginning of call.
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction.
SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero.
CallNewAccountGas uint64 = 25000 // Paid for CALL when the destination address didn't exist prior.
TxGas uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions.
SystemTxsGas uint64 = 500000 // The gas reserved for system txs; only for parlia consensus
TxGasContractCreation uint64 = 53000 // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions.
TxDataZeroGas uint64 = 4 // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
QuadCoeffDiv uint64 = 512 // Divisor for the quadratic particle of the memory cost equation.
LogDataGas uint64 = 8 // Per byte in a LOG* operation's data.
CallStipend uint64 = 2300 // Free gas given at beginning of call.
Sha3Gas uint64 = 30 // Once per SHA3 operation.
Sha3WordGas uint64 = 6 // Once per word of the SHA3 operation's data.

View File

@@ -23,8 +23,8 @@ import (
const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 0 // Minor version component of the current release
VersionPatch = 0 // Patch version component of the current release
VersionMeta = "alpha.0" // Version metadata to append to the version string
VersionPatch = 1 // Patch version component of the current release
VersionMeta = "beta.2" // Version metadata to append to the version string
)
// Version holds the textual version string.

View File

@@ -285,7 +285,7 @@ func (api *SignerAPI) determineSignatureFormat(ctx context.Context, contentType
header.Extra = newExtra
}
// Get back the rlp data, encoded by us
sighash, parliaRlp, err := parliaHeaderHashAndRlp(header)
sighash, parliaRlp, err := parliaHeaderHashAndRlp(header, api.chainID)
if err != nil {
return nil, useEthereumV, err
}
@@ -351,13 +351,13 @@ func cliqueHeaderHashAndRlp(header *types.Header) (hash, rlp []byte, err error)
return hash, rlp, err
}
func parliaHeaderHashAndRlp(header *types.Header) (hash, rlp []byte, err error) {
func parliaHeaderHashAndRlp(header *types.Header, chainId *big.Int) (hash, rlp []byte, err error) {
if len(header.Extra) < 65 {
err = fmt.Errorf("clique header extradata too short, %d < 65", len(header.Extra))
return
}
rlp = parlia.ParliaRLP(header)
hash = parlia.SealHash(header).Bytes()
rlp = parlia.ParliaRLP(header, chainId)
hash = parlia.SealHash(header, chainId).Bytes()
return hash, rlp, err
}