Compare commits
45 Commits
v1.0.0-alp
...
v1.0.1-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b652ef3a67 | ||
|
|
011f043418 | ||
|
|
d9a0607e5e | ||
|
|
f2e4ef2e6d | ||
|
|
8c8c2a7d9e | ||
|
|
4a8f63917f | ||
|
|
45f17d59a0 | ||
|
|
c399c88e08 | ||
|
|
8c1d1dbb79 | ||
|
|
4f431e0843 | ||
|
|
85ebea9e8c | ||
|
|
c4f4377cfd | ||
|
|
baae91db37 | ||
|
|
650d066757 | ||
|
|
02154bb0f0 | ||
|
|
13cca06be8 | ||
|
|
4450b337c4 | ||
|
|
3789ea31dd | ||
|
|
3f36e996df | ||
|
|
a8c9e53eb0 | ||
|
|
83d72b8e91 | ||
|
|
8124e60e9d | ||
|
|
5cc893a5e4 | ||
|
|
04287ebe50 | ||
|
|
f4816ee8b7 | ||
|
|
8d48b0deb8 | ||
|
|
1940dc887c | ||
|
|
2f2778deec | ||
|
|
6f46fc0589 | ||
|
|
6f40b0e238 | ||
|
|
ef1e8746d6 | ||
|
|
511bbf546f | ||
|
|
5e4f5785c7 | ||
|
|
11bc803884 | ||
|
|
6a19c9803c | ||
|
|
9f1aaecb29 | ||
|
|
4bd4469151 | ||
|
|
ce14f2cae5 | ||
|
|
2ff7a21d64 | ||
|
|
e83397e26a | ||
|
|
ed9b28fe7b | ||
|
|
fd8c9c0f1f | ||
|
|
b72be127cf | ||
|
|
4909842097 | ||
|
|
39c80ce175 |
31
CHANGELOG.md
Normal file
31
CHANGELOG.md
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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: ¶ms.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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
44
consensus/parlia/ramanujanfork.go
Normal file
44
consensus/parlia/ramanujanfork.go
Normal 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
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()))
|
||||
|
||||
15
core/systemcontracts/const.go
Normal file
15
core/systemcontracts/const.go
Normal 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"
|
||||
)
|
||||
273
core/systemcontracts/upgrade.go
Normal file
273
core/systemcontracts/upgrade.go
Normal file
File diff suppressed because one or more lines are too long
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
3
go.mod
@@ -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
5
go.sum
@@ -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=
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user