parent
e176a5a9cc
commit
08e7375610
@ -1,505 +0,0 @@ |
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package backends |
||||
|
||||
import ( |
||||
"context" |
||||
"errors" |
||||
"fmt" |
||||
"math/big" |
||||
"sync" |
||||
"time" |
||||
|
||||
ethereum "github.com/ethereum/go-ethereum" |
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind" |
||||
"github.com/ethereum/go-ethereum/common" |
||||
"github.com/ethereum/go-ethereum/common/math" |
||||
"github.com/ethereum/go-ethereum/consensus/ethash" |
||||
"github.com/ethereum/go-ethereum/core" |
||||
"github.com/ethereum/go-ethereum/core/bloombits" |
||||
"github.com/ethereum/go-ethereum/core/rawdb" |
||||
"github.com/ethereum/go-ethereum/core/state" |
||||
"github.com/ethereum/go-ethereum/core/types" |
||||
"github.com/ethereum/go-ethereum/core/vm" |
||||
"github.com/ethereum/go-ethereum/eth/filters" |
||||
"github.com/ethereum/go-ethereum/ethdb" |
||||
"github.com/ethereum/go-ethereum/event" |
||||
"github.com/ethereum/go-ethereum/params" |
||||
"github.com/ethereum/go-ethereum/rpc" |
||||
) |
||||
|
||||
// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend.
|
||||
var _ bind.ContractBackend = (*SimulatedBackend)(nil) |
||||
|
||||
var errBlockNumberUnsupported = errors.New("SimulatedBackend cannot access blocks other than the latest block") |
||||
var errGasEstimationFailed = errors.New("gas required exceeds allowance or always failing transaction") |
||||
|
||||
// SimulatedBackend implements bind.ContractBackend, simulating a blockchain in
|
||||
// the background. Its main purpose is to allow easily testing contract bindings.
|
||||
type SimulatedBackend struct { |
||||
database ethdb.Database // In memory database to store our testing data
|
||||
blockchain *core.BlockChain // Ethereum blockchain to handle the consensus
|
||||
|
||||
mu sync.Mutex |
||||
pendingBlock *types.Block // Currently pending block that will be imported on request
|
||||
pendingState *state.StateDB // Currently pending state that will be the active on on request
|
||||
|
||||
events *filters.EventSystem // Event system for filtering log events live
|
||||
|
||||
config *params.ChainConfig |
||||
} |
||||
|
||||
// NewSimulatedBackend creates a new binding backend using a simulated blockchain
|
||||
// for testing purposes.
|
||||
func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { |
||||
database := ethdb.NewMemDatabase() |
||||
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc} |
||||
genesis.MustCommit(database) |
||||
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil) |
||||
|
||||
backend := &SimulatedBackend{ |
||||
database: database, |
||||
blockchain: blockchain, |
||||
config: genesis.Config, |
||||
events: filters.NewEventSystem(new(event.TypeMux), &filterBackend{database, blockchain}, false), |
||||
} |
||||
backend.rollback() |
||||
return backend |
||||
} |
||||
|
||||
// Commit imports all the pending transactions as a single block and starts a
|
||||
// fresh new state.
|
||||
func (b *SimulatedBackend) Commit() { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil { |
||||
panic(err) // This cannot happen unless the simulator is wrong, fail in that case
|
||||
} |
||||
b.rollback() |
||||
} |
||||
|
||||
// Rollback aborts all pending transactions, reverting to the last committed state.
|
||||
func (b *SimulatedBackend) Rollback() { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
b.rollback() |
||||
} |
||||
|
||||
func (b *SimulatedBackend) rollback() { |
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {}) |
||||
statedb, _ := b.blockchain.State() |
||||
|
||||
b.pendingBlock = blocks[0] |
||||
b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) |
||||
} |
||||
|
||||
// CodeAt returns the code associated with a certain account in the blockchain.
|
||||
func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { |
||||
return nil, errBlockNumberUnsupported |
||||
} |
||||
statedb, _ := b.blockchain.State() |
||||
return statedb.GetCode(contract), nil |
||||
} |
||||
|
||||
// BalanceAt returns the wei balance of a certain account in the blockchain.
|
||||
func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (*big.Int, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { |
||||
return nil, errBlockNumberUnsupported |
||||
} |
||||
statedb, _ := b.blockchain.State() |
||||
return statedb.GetBalance(contract), nil |
||||
} |
||||
|
||||
// NonceAt returns the nonce of a certain account in the blockchain.
|
||||
func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (uint64, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { |
||||
return 0, errBlockNumberUnsupported |
||||
} |
||||
statedb, _ := b.blockchain.State() |
||||
return statedb.GetNonce(contract), nil |
||||
} |
||||
|
||||
// StorageAt returns the value of key in the storage of an account in the blockchain.
|
||||
func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { |
||||
return nil, errBlockNumberUnsupported |
||||
} |
||||
statedb, _ := b.blockchain.State() |
||||
val := statedb.GetState(contract, key) |
||||
return val[:], nil |
||||
} |
||||
|
||||
// TransactionReceipt returns the receipt of a transaction.
|
||||
func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { |
||||
receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash) |
||||
return receipt, nil |
||||
} |
||||
|
||||
// TransactionByHash checks the pool of pending transactions in addition to the
|
||||
// blockchain. The isPending return value indicates whether the transaction has been
|
||||
// mined yet. Note that the transaction may not be part of the canonical chain even if
|
||||
// it's not pending.
|
||||
func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
tx := b.pendingBlock.Transaction(txHash) |
||||
if tx != nil { |
||||
return tx, true, nil |
||||
} |
||||
tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash) |
||||
if tx != nil { |
||||
return tx, false, nil |
||||
} |
||||
return nil, false, ethereum.NotFound |
||||
} |
||||
|
||||
// PendingCodeAt returns the code associated with an account in the pending state.
|
||||
func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
return b.pendingState.GetCode(contract), nil |
||||
} |
||||
|
||||
// CallContract executes a contract call.
|
||||
func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { |
||||
return nil, errBlockNumberUnsupported |
||||
} |
||||
state, err := b.blockchain.State() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
rval, _, _, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), state) |
||||
return rval, err |
||||
} |
||||
|
||||
// PendingCallContract executes a contract call on the pending state.
|
||||
func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot()) |
||||
|
||||
rval, _, _, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) |
||||
return rval, err |
||||
} |
||||
|
||||
// PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving
|
||||
// the nonce currently pending for the account.
|
||||
func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
return b.pendingState.GetOrNewStateObject(account).Nonce(), nil |
||||
} |
||||
|
||||
// SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated
|
||||
// chain doesn't have miners, we just return a gas price of 1 for any call.
|
||||
func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { |
||||
return big.NewInt(1), nil |
||||
} |
||||
|
||||
// EstimateGas executes the requested code against the currently pending block/state and
|
||||
// returns the used amount of gas.
|
||||
func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
// Determine the lowest and highest possible gas limits to binary search in between
|
||||
var ( |
||||
lo = params.TxGas - 1 |
||||
hi uint64 |
||||
cap uint64 |
||||
) |
||||
if call.Gas >= params.TxGas { |
||||
hi = call.Gas |
||||
} else { |
||||
hi = b.pendingBlock.GasLimit() |
||||
} |
||||
cap = hi |
||||
|
||||
// Create a helper to check if a gas allowance results in an executable transaction
|
||||
executable := func(gas uint64) bool { |
||||
call.Gas = gas |
||||
|
||||
snapshot := b.pendingState.Snapshot() |
||||
_, _, failed, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) |
||||
b.pendingState.RevertToSnapshot(snapshot) |
||||
|
||||
if err != nil || failed { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
// Execute the binary search and hone in on an executable gas limit
|
||||
for lo+1 < hi { |
||||
mid := (hi + lo) / 2 |
||||
if !executable(mid) { |
||||
lo = mid |
||||
} else { |
||||
hi = mid |
||||
} |
||||
} |
||||
// Reject the transaction as invalid if it still fails at the highest allowance
|
||||
if hi == cap { |
||||
if !executable(hi) { |
||||
return 0, errGasEstimationFailed |
||||
} |
||||
} |
||||
return hi, nil |
||||
} |
||||
|
||||
// callContract implements common code between normal and pending contract calls.
|
||||
// state is modified during execution, make sure to copy it if necessary.
|
||||
func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, uint64, bool, error) { |
||||
// Ensure message is initialized properly.
|
||||
if call.GasPrice == nil { |
||||
call.GasPrice = big.NewInt(1) |
||||
} |
||||
if call.Gas == 0 { |
||||
call.Gas = 50000000 |
||||
} |
||||
if call.Value == nil { |
||||
call.Value = new(big.Int) |
||||
} |
||||
// Set infinite balance to the fake caller account.
|
||||
from := statedb.GetOrNewStateObject(call.From) |
||||
from.SetBalance(math.MaxBig256) |
||||
// Execute the call.
|
||||
msg := callmsg{call} |
||||
|
||||
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil) |
||||
// Create a new environment which holds all relevant information
|
||||
// about the transaction and calling mechanisms.
|
||||
vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{}) |
||||
gaspool := new(core.GasPool).AddGas(math.MaxUint64) |
||||
|
||||
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() |
||||
} |
||||
|
||||
// SendTransaction updates the pending block to include the given transaction.
|
||||
// It panics if the transaction is invalid.
|
||||
func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
|
||||
sender, err := types.Sender(types.HomesteadSigner{}, tx) |
||||
if err != nil { |
||||
panic(fmt.Errorf("invalid transaction: %v", err)) |
||||
} |
||||
nonce := b.pendingState.GetNonce(sender) |
||||
if tx.Nonce() != nonce { |
||||
panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce)) |
||||
} |
||||
|
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { |
||||
for _, tx := range b.pendingBlock.Transactions() { |
||||
block.AddTxWithChain(b.blockchain, tx) |
||||
} |
||||
block.AddTxWithChain(b.blockchain, tx) |
||||
}) |
||||
statedb, _ := b.blockchain.State() |
||||
|
||||
b.pendingBlock = blocks[0] |
||||
b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) |
||||
return nil |
||||
} |
||||
|
||||
// FilterLogs executes a log filter operation, blocking during execution and
|
||||
// returning all the results in one batch.
|
||||
//
|
||||
// TODO(karalabe): Deprecate when the subscription one can return past data too.
|
||||
func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { |
||||
var filter *filters.Filter |
||||
if query.BlockHash != nil { |
||||
// Block filter requested, construct a single-shot filter
|
||||
filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics) |
||||
} else { |
||||
// Initialize unset filter boundaried to run from genesis to chain head
|
||||
from := int64(0) |
||||
if query.FromBlock != nil { |
||||
from = query.FromBlock.Int64() |
||||
} |
||||
to := int64(-1) |
||||
if query.ToBlock != nil { |
||||
to = query.ToBlock.Int64() |
||||
} |
||||
// Construct the range filter
|
||||
filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) |
||||
} |
||||
// Run the filter and return all the logs
|
||||
logs, err := filter.Logs(ctx) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
res := make([]types.Log, len(logs)) |
||||
for i, log := range logs { |
||||
res[i] = *log |
||||
} |
||||
return res, nil |
||||
} |
||||
|
||||
// SubscribeFilterLogs creates a background log filtering operation, returning a
|
||||
// subscription immediately, which can be used to stream the found events.
|
||||
func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { |
||||
// Subscribe to contract events
|
||||
sink := make(chan []*types.Log) |
||||
|
||||
sub, err := b.events.SubscribeLogs(query, sink) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
// Since we're getting logs in batches, we need to flatten them into a plain stream
|
||||
return event.NewSubscription(func(quit <-chan struct{}) error { |
||||
defer sub.Unsubscribe() |
||||
for { |
||||
select { |
||||
case logs := <-sink: |
||||
for _, log := range logs { |
||||
select { |
||||
case ch <- *log: |
||||
case err := <-sub.Err(): |
||||
return err |
||||
case <-quit: |
||||
return nil |
||||
} |
||||
} |
||||
case err := <-sub.Err(): |
||||
return err |
||||
case <-quit: |
||||
return nil |
||||
} |
||||
} |
||||
}), nil |
||||
} |
||||
|
||||
// AdjustTime adds a time shift to the simulated clock.
|
||||
func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { |
||||
b.mu.Lock() |
||||
defer b.mu.Unlock() |
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { |
||||
for _, tx := range b.pendingBlock.Transactions() { |
||||
block.AddTx(tx) |
||||
} |
||||
block.OffsetTime(int64(adjustment.Seconds())) |
||||
}) |
||||
statedb, _ := b.blockchain.State() |
||||
|
||||
b.pendingBlock = blocks[0] |
||||
b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) |
||||
|
||||
return nil |
||||
} |
||||
|
||||
// callmsg implements core.Message to allow passing it as a transaction simulator.
|
||||
type callmsg struct { |
||||
ethereum.CallMsg |
||||
} |
||||
|
||||
func (m callmsg) From() common.Address { return m.CallMsg.From } |
||||
func (m callmsg) Nonce() uint64 { return 0 } |
||||
func (m callmsg) CheckNonce() bool { return false } |
||||
func (m callmsg) To() *common.Address { return m.CallMsg.To } |
||||
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } |
||||
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas } |
||||
func (m callmsg) Value() *big.Int { return m.CallMsg.Value } |
||||
func (m callmsg) Data() []byte { return m.CallMsg.Data } |
||||
|
||||
// filterBackend implements filters.Backend to support filtering for logs without
|
||||
// taking bloom-bits acceleration structures into account.
|
||||
type filterBackend struct { |
||||
db ethdb.Database |
||||
bc *core.BlockChain |
||||
} |
||||
|
||||
func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } |
||||
func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } |
||||
|
||||
func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { |
||||
if block == rpc.LatestBlockNumber { |
||||
return fb.bc.CurrentHeader(), nil |
||||
} |
||||
return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil |
||||
} |
||||
|
||||
func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { |
||||
return fb.bc.GetHeaderByHash(hash), nil |
||||
} |
||||
|
||||
func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { |
||||
number := rawdb.ReadHeaderNumber(fb.db, hash) |
||||
if number == nil { |
||||
return nil, nil |
||||
} |
||||
return rawdb.ReadReceipts(fb.db, hash, *number), nil |
||||
} |
||||
|
||||
func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { |
||||
number := rawdb.ReadHeaderNumber(fb.db, hash) |
||||
if number == nil { |
||||
return nil, nil |
||||
} |
||||
receipts := rawdb.ReadReceipts(fb.db, hash, *number) |
||||
if receipts == nil { |
||||
return nil, nil |
||||
} |
||||
logs := make([][]*types.Log, len(receipts)) |
||||
for i, receipt := range receipts { |
||||
logs[i] = receipt.Logs |
||||
} |
||||
return logs, nil |
||||
} |
||||
|
||||
func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { |
||||
return event.NewSubscription(func(quit <-chan struct{}) error { |
||||
<-quit |
||||
return nil |
||||
}) |
||||
} |
||||
func (fb *filterBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { |
||||
return fb.bc.SubscribeChainEvent(ch) |
||||
} |
||||
func (fb *filterBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { |
||||
return fb.bc.SubscribeRemovedLogsEvent(ch) |
||||
} |
||||
func (fb *filterBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { |
||||
return fb.bc.SubscribeLogsEvent(ch) |
||||
} |
||||
|
||||
func (fb *filterBackend) BloomStatus() (uint64, uint64) { return 4096, 0 } |
||||
func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.MatcherSession) { |
||||
panic("not supported") |
||||
} |
@ -0,0 +1,71 @@ |
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
// MainnetBootnodes are the enode URLs of the P2P bootstrap nodes running on
|
||||
// the main Ethereum network.
|
||||
var MainnetBootnodes = []string{ |
||||
// Ethereum Foundation Go Bootnodes
|
||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", // IE
|
||||
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303", // US-WEST
|
||||
"enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303", // BR
|
||||
"enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303", // AU
|
||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303", // SG
|
||||
|
||||
// Ethereum Foundation C++ Bootnodes
|
||||
"enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303", // DE
|
||||
} |
||||
|
||||
// TestnetBootnodes are the enode URLs of the P2P bootstrap nodes running on the
|
||||
// Ropsten test network.
|
||||
var TestnetBootnodes = []string{ |
||||
"enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303", // US-Azure geth
|
||||
"enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303", // US-Azure parity
|
||||
"enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303", // Parity
|
||||
"enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303", // @gpip
|
||||
} |
||||
|
||||
// RinkebyBootnodes are the enode URLs of the P2P bootstrap nodes running on the
|
||||
// Rinkeby test network.
|
||||
var RinkebyBootnodes = []string{ |
||||
"enode://a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45cb4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf@52.169.42.101:30303", // IE
|
||||
"enode://343149e4feefa15d882d9fe4ac7d88f885bd05ebb735e547f12e12080a9fa07c8014ca6fd7f373123488102fe5e34111f8509cf0b7de3f5b44339c9f25e87cb8@52.3.158.184:30303", // INFURA
|
||||
"enode://b6b28890b006743680c52e64e0d16db57f28124885595fa03a562be1d2bf0f3a1da297d56b13da25fb992888fd556d4c1a27b1f39d531bde7de1921c90061cc6@159.89.28.211:30303", // AKASHA
|
||||
} |
||||
|
||||
// GoerliBootnodes are the enode URLs of the P2P bootstrap nodes running on the
|
||||
// Görli test network.
|
||||
var GoerliBootnodes = []string{ |
||||
// Upstrem bootnodes
|
||||
"enode://011f758e6552d105183b1761c5e2dea0111bc20fd5f6422bc7f91e0fabbec9a6595caf6239b37feb773dddd3f87240d99d859431891e4a642cf2a0a9e6cbb98a@51.141.78.53:30303", |
||||
"enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303", |
||||
"enode://46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291@94.237.54.114:30313", |
||||
"enode://c1f8b7c2ac4453271fa07d8e9ecf9a2e8285aa0bd0c07df0131f47153306b0736fd3db8924e7a9bf0bed6b1d8d4f87362a71b033dc7c64547728d953e43e59b2@52.64.155.147:30303", |
||||
"enode://f4a9c6ee28586009fb5a96c8af13a58ed6d8315a9eee4772212c1d4d9cebe5a8b8a78ea4434f318726317d04a3f531a1ef0420cf9752605a562cfe858c46e263@213.186.16.82:30303", |
||||
|
||||
// Ethereum Foundation bootnode
|
||||
"enode://573b6607cd59f241e30e4c4943fd50e99e2b6f42f9bd5ca111659d309c06741247f4f1e93843ad3e8c8c18b6e2d94c161b7ef67479b3938780a97134b618b5ce@52.56.136.200:30303", |
||||
} |
||||
|
||||
// DiscoveryV5Bootnodes are the enode URLs of the P2P bootstrap nodes for the
|
||||
// experimental RLPx v5 topic-discovery network.
|
||||
var DiscoveryV5Bootnodes = []string{ |
||||
"enode://06051a5573c81934c9554ef2898eb13b33a34b94cf36b202b69fde139ca17a85051979867720d4bdae4323d4943ddf9aeeb6643633aa656e0be843659795007a@35.177.226.168:30303", |
||||
"enode://0cc5f5ffb5d9098c8b8c62325f3797f56509bff942704687b6530992ac706e2cb946b90a34f1f19548cd3c7baccbcaea354531e5983c7d1bc0dee16ce4b6440b@40.118.3.223:30304", |
||||
"enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30306", |
||||
"enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30307", |
||||
} |
@ -0,0 +1,459 @@ |
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
import ( |
||||
"fmt" |
||||
"math/big" |
||||
|
||||
"github.com/ethereum/go-ethereum/common" |
||||
) |
||||
|
||||
// Genesis hashes to enforce below configs on.
|
||||
var ( |
||||
MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") |
||||
TestnetGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") |
||||
RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") |
||||
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") |
||||
) |
||||
|
||||
// TrustedCheckpoints associates each known checkpoint with the genesis hash of
|
||||
// the chain it belongs to.
|
||||
var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{ |
||||
MainnetGenesisHash: MainnetTrustedCheckpoint, |
||||
TestnetGenesisHash: TestnetTrustedCheckpoint, |
||||
RinkebyGenesisHash: RinkebyTrustedCheckpoint, |
||||
GoerliGenesisHash: GoerliTrustedCheckpoint, |
||||
} |
||||
|
||||
var ( |
||||
// MainnetChainConfig is the chain parameters to run a node on the main network.
|
||||
MainnetChainConfig = &ChainConfig{ |
||||
ChainID: big.NewInt(1), |
||||
HomesteadBlock: big.NewInt(1150000), |
||||
DAOForkBlock: big.NewInt(1920000), |
||||
DAOForkSupport: true, |
||||
EIP150Block: big.NewInt(2463000), |
||||
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), |
||||
EIP155Block: big.NewInt(2675000), |
||||
EIP158Block: big.NewInt(2675000), |
||||
ByzantiumBlock: big.NewInt(4370000), |
||||
ConstantinopleBlock: big.NewInt(7280000), |
||||
PetersburgBlock: big.NewInt(7280000), |
||||
Ethash: new(EthashConfig), |
||||
} |
||||
|
||||
// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
|
||||
MainnetTrustedCheckpoint = &TrustedCheckpoint{ |
||||
Name: "mainnet", |
||||
SectionIndex: 227, |
||||
SectionHead: common.HexToHash("0xa2e0b25d72c2fc6e35a7f853cdacb193b4b4f95c606accf7f8fa8415283582c7"), |
||||
CHTRoot: common.HexToHash("0xf69bdd4053b95b61a27b106a0e86103d791edd8574950dc96aa351ab9b9f1aa0"), |
||||
BloomRoot: common.HexToHash("0xec1b454d4c6322c78ccedf76ac922a8698c3cac4d98748a84af4995b7bd3d744"), |
||||
} |
||||
|
||||
// TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network.
|
||||
TestnetChainConfig = &ChainConfig{ |
||||
ChainID: big.NewInt(3), |
||||
HomesteadBlock: big.NewInt(0), |
||||
DAOForkBlock: nil, |
||||
DAOForkSupport: true, |
||||
EIP150Block: big.NewInt(0), |
||||
EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), |
||||
EIP155Block: big.NewInt(10), |
||||
EIP158Block: big.NewInt(10), |
||||
ByzantiumBlock: big.NewInt(1700000), |
||||
ConstantinopleBlock: big.NewInt(4230000), |
||||
PetersburgBlock: big.NewInt(4939394), |
||||
Ethash: new(EthashConfig), |
||||
} |
||||
|
||||
// TestnetTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
|
||||
TestnetTrustedCheckpoint = &TrustedCheckpoint{ |
||||
Name: "testnet", |
||||
SectionIndex: 161, |
||||
SectionHead: common.HexToHash("0x5378afa734e1feafb34bcca1534c4d96952b754579b96a4afb23d5301ecececc"), |
||||
CHTRoot: common.HexToHash("0x1cf2b071e7443a62914362486b613ff30f60cea0d9c268ed8c545f876a3ee60c"), |
||||
BloomRoot: common.HexToHash("0x5ac25c84bd18a9cbe878d4609a80220f57f85037a112644532412ba0d498a31b"), |
||||
} |
||||
|
||||
// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
|
||||
RinkebyChainConfig = &ChainConfig{ |
||||
ChainID: big.NewInt(4), |
||||
HomesteadBlock: big.NewInt(1), |
||||
DAOForkBlock: nil, |
||||
DAOForkSupport: true, |
||||
EIP150Block: big.NewInt(2), |
||||
EIP150Hash: common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"), |
||||
EIP155Block: big.NewInt(3), |
||||
EIP158Block: big.NewInt(3), |
||||
ByzantiumBlock: big.NewInt(1035301), |
||||
ConstantinopleBlock: big.NewInt(3660663), |
||||
PetersburgBlock: big.NewInt(4321234), |
||||
Clique: &CliqueConfig{ |
||||
Period: 15, |
||||
Epoch: 30000, |
||||
}, |
||||
} |
||||
|
||||
// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
|
||||
RinkebyTrustedCheckpoint = &TrustedCheckpoint{ |
||||
Name: "rinkeby", |
||||
SectionIndex: 125, |
||||
SectionHead: common.HexToHash("0x8a738386f6bb34add15846f8f49c4c519a2f32519096e792b9f43bcb407c831c"), |
||||
CHTRoot: common.HexToHash("0xa1e5720a9bad4dce794f129e4ac6744398197b652868011486a6f89c8ec84a75"), |
||||
BloomRoot: common.HexToHash("0xa3048fe8b7e30f77f11bc755a88478363d7d3e71c2bdfe4e8ab9e269cd804ba2"), |
||||
} |
||||
|
||||
// GoerliChainConfig contains the chain parameters to run a node on the Görli test network.
|
||||
GoerliChainConfig = &ChainConfig{ |
||||
ChainID: big.NewInt(5), |
||||
HomesteadBlock: big.NewInt(0), |
||||
DAOForkBlock: nil, |
||||
DAOForkSupport: true, |
||||
EIP150Block: big.NewInt(0), |
||||
EIP155Block: big.NewInt(0), |
||||
EIP158Block: big.NewInt(0), |
||||
ByzantiumBlock: big.NewInt(0), |
||||
ConstantinopleBlock: big.NewInt(0), |
||||
PetersburgBlock: big.NewInt(0), |
||||
Clique: &CliqueConfig{ |
||||
Period: 15, |
||||
Epoch: 30000, |
||||
}, |
||||
} |
||||
|
||||
// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
|
||||
GoerliTrustedCheckpoint = &TrustedCheckpoint{ |
||||
Name: "goerli", |
||||
SectionIndex: 9, |
||||
SectionHead: common.HexToHash("0x8e223d827391eee53b07cb8ee057dbfa11c93e0b45352188c783affd7840a921"), |
||||
CHTRoot: common.HexToHash("0xe0a817ac69b36c1e437c5b0cff9e764853f5115702b5f66d451b665d6afb7e78"), |
||||
BloomRoot: common.HexToHash("0x50d672aeb655b723284969c7c1201fb6ca003c23ed144bcb9f2d1b30e2971c1b"), |
||||
} |
||||
|
||||
// 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), nil, new(EthashConfig), 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), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} |
||||
|
||||
// TestChainConfig ...
|
||||
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), nil, new(EthashConfig), nil} |
||||
// TestRules ...
|
||||
TestRules = TestChainConfig.Rules(new(big.Int)) |
||||
) |
||||
|
||||
// TrustedCheckpoint represents a set of post-processed trie roots (CHT and
|
||||
// BloomTrie) associated with the appropriate section index and head hash. It is
|
||||
// used to start light syncing from this checkpoint and avoid downloading the
|
||||
// entire header chain while still being able to securely access old headers/logs.
|
||||
type TrustedCheckpoint struct { |
||||
Name string `json:"-"` |
||||
SectionIndex uint64 `json:"sectionIndex"` |
||||
SectionHead common.Hash `json:"sectionHead"` |
||||
CHTRoot common.Hash `json:"chtRoot"` |
||||
BloomRoot common.Hash `json:"bloomRoot"` |
||||
} |
||||
|
||||
// ChainConfig is the core config which determines the blockchain settings.
|
||||
//
|
||||
// ChainConfig is stored in the database on a per block basis. This means
|
||||
// that any network, identified by its genesis block, can have its own
|
||||
// set of configuration options.
|
||||
type ChainConfig struct { |
||||
ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
|
||||
|
||||
HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
|
||||
|
||||
DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork)
|
||||
DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
|
||||
|
||||
// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
|
||||
EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
|
||||
EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed)
|
||||
|
||||
EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
|
||||
EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
|
||||
|
||||
ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium)
|
||||
ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
|
||||
PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople)
|
||||
EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated)
|
||||
|
||||
// Various consensus engines
|
||||
Ethash *EthashConfig `json:"ethash,omitempty"` |
||||
Clique *CliqueConfig `json:"clique,omitempty"` |
||||
} |
||||
|
||||
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
||||
type EthashConfig struct{} |
||||
|
||||
// String implements the stringer interface, returning the consensus engine details.
|
||||
func (c *EthashConfig) String() string { |
||||
return "ethash" |
||||
} |
||||
|
||||
// CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
|
||||
type CliqueConfig struct { |
||||
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
|
||||
Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint
|
||||
} |
||||
|
||||
// String implements the stringer interface, returning the consensus engine details.
|
||||
func (c *CliqueConfig) String() string { |
||||
return "clique" |
||||
} |
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (c *ChainConfig) String() string { |
||||
var engine interface{} |
||||
switch { |
||||
case c.Ethash != nil: |
||||
engine = c.Ethash |
||||
case c.Clique != nil: |
||||
engine = c.Clique |
||||
default: |
||||
engine = "unknown" |
||||
} |
||||
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v ConstantinopleFix: %v Engine: %v}", |
||||
c.ChainID, |
||||
c.HomesteadBlock, |
||||
c.DAOForkBlock, |
||||
c.DAOForkSupport, |
||||
c.EIP150Block, |
||||
c.EIP155Block, |
||||
c.EIP158Block, |
||||
c.ByzantiumBlock, |
||||
c.ConstantinopleBlock, |
||||
c.PetersburgBlock, |
||||
engine, |
||||
) |
||||
} |
||||
|
||||
// IsHomestead returns whether num is either equal to the homestead block or greater.
|
||||
func (c *ChainConfig) IsHomestead(num *big.Int) bool { |
||||
return isForked(c.HomesteadBlock, num) |
||||
} |
||||
|
||||
// IsDAOFork returns whether num is either equal to the DAO fork block or greater.
|
||||
func (c *ChainConfig) IsDAOFork(num *big.Int) bool { |
||||
return isForked(c.DAOForkBlock, num) |
||||
} |
||||
|
||||
// IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
|
||||
func (c *ChainConfig) IsEIP150(num *big.Int) bool { |
||||
return isForked(c.EIP150Block, num) |
||||
} |
||||
|
||||
// IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
|
||||
func (c *ChainConfig) IsEIP155(num *big.Int) bool { |
||||
return isForked(c.EIP155Block, num) |
||||
} |
||||
|
||||
// IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
|
||||
func (c *ChainConfig) IsEIP158(num *big.Int) bool { |
||||
return isForked(c.EIP158Block, num) |
||||
} |
||||
|
||||
// IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
|
||||
func (c *ChainConfig) IsByzantium(num *big.Int) bool { |
||||
return isForked(c.ByzantiumBlock, num) |
||||
} |
||||
|
||||
// IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
|
||||
func (c *ChainConfig) IsConstantinople(num *big.Int) bool { |
||||
return isForked(c.ConstantinopleBlock, num) |
||||
} |
||||
|
||||
// IsPetersburg returns whether num is either
|
||||
// - equal to or greater than the PetersburgBlock fork block,
|
||||
// - OR is nil, and Constantinople is active
|
||||
func (c *ChainConfig) IsPetersburg(num *big.Int) bool { |
||||
return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num) |
||||
} |
||||
|
||||
// IsEWASM returns whether num represents a block number after the EWASM fork
|
||||
func (c *ChainConfig) IsEWASM(num *big.Int) bool { |
||||
return isForked(c.EWASMBlock, num) |
||||
} |
||||
|
||||
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
|
||||
//
|
||||
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
|
||||
func (c *ChainConfig) GasTable(num *big.Int) GasTable { |
||||
if num == nil { |
||||
return GasTableHomestead |
||||
} |
||||
switch { |
||||
case c.IsConstantinople(num): |
||||
return GasTableConstantinople |
||||
case c.IsEIP158(num): |
||||
return GasTableEIP158 |
||||
case c.IsEIP150(num): |
||||
return GasTableEIP150 |
||||
default: |
||||
return GasTableHomestead |
||||
} |
||||
} |
||||
|
||||
// CheckCompatible checks whether scheduled fork transitions have been imported
|
||||
// with a mismatching chain configuration.
|
||||
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { |
||||
bhead := new(big.Int).SetUint64(height) |
||||
|
||||
// Iterate checkCompatible to find the lowest conflict.
|
||||
var lasterr *ConfigCompatError |
||||
for { |
||||
err := c.checkCompatible(newcfg, bhead) |
||||
if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { |
||||
break |
||||
} |
||||
lasterr = err |
||||
bhead.SetUint64(err.RewindTo) |
||||
} |
||||
return lasterr |
||||
} |
||||
|
||||
func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { |
||||
if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { |
||||
return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) |
||||
} |
||||
if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { |
||||
return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) |
||||
} |
||||
if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { |
||||
return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) |
||||
} |
||||
if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { |
||||
return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) |
||||
} |
||||
if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { |
||||
return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) |
||||
} |
||||
if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { |
||||
return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) |
||||
} |
||||
if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) { |
||||
return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) |
||||
} |
||||
if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { |
||||
return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) |
||||
} |
||||
if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { |
||||
return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) |
||||
} |
||||
if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) { |
||||
return newCompatError("ConstantinopleFix fork block", c.PetersburgBlock, newcfg.PetersburgBlock) |
||||
} |
||||
if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) { |
||||
return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
|
||||
// block s2 because head is already past the fork.
|
||||
func isForkIncompatible(s1, s2, head *big.Int) bool { |
||||
return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) |
||||
} |
||||
|
||||
// isForked returns whether a fork scheduled at block s is active at the given head block.
|
||||
func isForked(s, head *big.Int) bool { |
||||
if s == nil || head == nil { |
||||
return false |
||||
} |
||||
return s.Cmp(head) <= 0 |
||||
} |
||||
|
||||
func configNumEqual(x, y *big.Int) bool { |
||||
if x == nil { |
||||
return y == nil |
||||
} |
||||
if y == nil { |
||||
return x == nil |
||||
} |
||||
return x.Cmp(y) == 0 |
||||
} |
||||
|
||||
// ConfigCompatError is raised if the locally-stored blockchain is initialised with a
|
||||
// ChainConfig that would alter the past.
|
||||
type ConfigCompatError struct { |
||||
What string |
||||
// block numbers of the stored and new configurations
|
||||
StoredConfig, NewConfig *big.Int |
||||
// the block number to which the local chain must be rewound to correct the error
|
||||
RewindTo uint64 |
||||
} |
||||
|
||||
func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { |
||||
var rew *big.Int |
||||
switch { |
||||
case storedblock == nil: |
||||
rew = newblock |
||||
case newblock == nil || storedblock.Cmp(newblock) < 0: |
||||
rew = storedblock |
||||
default: |
||||
rew = newblock |
||||
} |
||||
err := &ConfigCompatError{what, storedblock, newblock, 0} |
||||
if rew != nil && rew.Sign() > 0 { |
||||
err.RewindTo = rew.Uint64() - 1 |
||||
} |
||||
return err |
||||
} |
||||
|
||||
func (err *ConfigCompatError) Error() string { |
||||
return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) |
||||
} |
||||
|
||||
// Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
|
||||
// that do not have or require information about the block.
|
||||
//
|
||||
// Rules is a one time interface meaning that it shouldn't be used in between transition
|
||||
// phases.
|
||||
type Rules struct { |
||||
ChainID *big.Int |
||||
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool |
||||
IsByzantium, IsConstantinople, IsPetersburg bool |
||||
} |
||||
|
||||
// Rules ensures c's ChainID is not nil.
|
||||
func (c *ChainConfig) Rules(num *big.Int) Rules { |
||||
chainID := c.ChainID |
||||
if chainID == nil { |
||||
chainID = new(big.Int) |
||||
} |
||||
return Rules{ |
||||
ChainID: new(big.Int).Set(chainID), |
||||
IsHomestead: c.IsHomestead(num), |
||||
IsEIP150: c.IsEIP150(num), |
||||
IsEIP155: c.IsEIP155(num), |
||||
IsEIP158: c.IsEIP158(num), |
||||
IsByzantium: c.IsByzantium(num), |
||||
IsConstantinople: c.IsConstantinople(num), |
||||
IsPetersburg: c.IsPetersburg(num), |
||||
} |
||||
} |
@ -0,0 +1,81 @@ |
||||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
import ( |
||||
"math/big" |
||||
"reflect" |
||||
"testing" |
||||
) |
||||
|
||||
func TestCheckCompatible(t *testing.T) { |
||||
type test struct { |
||||
stored, new *ChainConfig |
||||
head uint64 |
||||
wantErr *ConfigCompatError |
||||
} |
||||
tests := []test{ |
||||
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 0, wantErr: nil}, |
||||
{stored: AllEthashProtocolChanges, new: AllEthashProtocolChanges, head: 100, wantErr: nil}, |
||||
{ |
||||
stored: &ChainConfig{EIP150Block: big.NewInt(10)}, |
||||
new: &ChainConfig{EIP150Block: big.NewInt(20)}, |
||||
head: 9, |
||||
wantErr: nil, |
||||
}, |
||||
{ |
||||
stored: AllEthashProtocolChanges, |
||||
new: &ChainConfig{HomesteadBlock: nil}, |
||||
head: 3, |
||||
wantErr: &ConfigCompatError{ |
||||
What: "Homestead fork block", |
||||
StoredConfig: big.NewInt(0), |
||||
NewConfig: nil, |
||||
RewindTo: 0, |
||||
}, |
||||
}, |
||||
{ |
||||
stored: AllEthashProtocolChanges, |
||||
new: &ChainConfig{HomesteadBlock: big.NewInt(1)}, |
||||
head: 3, |
||||
wantErr: &ConfigCompatError{ |
||||
What: "Homestead fork block", |
||||
StoredConfig: big.NewInt(0), |
||||
NewConfig: big.NewInt(1), |
||||
RewindTo: 0, |
||||
}, |
||||
}, |
||||
{ |
||||
stored: &ChainConfig{HomesteadBlock: big.NewInt(30), EIP150Block: big.NewInt(10)}, |
||||
new: &ChainConfig{HomesteadBlock: big.NewInt(25), EIP150Block: big.NewInt(20)}, |
||||
head: 25, |
||||
wantErr: &ConfigCompatError{ |
||||
What: "EIP150 fork block", |
||||
StoredConfig: big.NewInt(10), |
||||
NewConfig: big.NewInt(20), |
||||
RewindTo: 9, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
for _, test := range tests { |
||||
err := test.stored.CheckCompatible(test.new, test.head) |
||||
if !reflect.DeepEqual(err, test.wantErr) { |
||||
t.Errorf("error mismatch:\nstored: %v\nnew: %v\nhead: %v\nerr: %v\nwant: %v", test.stored, test.new, test.head, err, test.wantErr) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,158 @@ |
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
import ( |
||||
"math/big" |
||||
|
||||
"github.com/ethereum/go-ethereum/common" |
||||
) |
||||
|
||||
// DAOForkBlockExtra is the block header extra-data field to set for the DAO fork
|
||||
// point and a number of consecutive blocks to allow fast/light syncers to correctly
|
||||
// pick the side they want ("dao-hard-fork").
|
||||
var DAOForkBlockExtra = common.FromHex("0x64616f2d686172642d666f726b") |
||||
|
||||
// DAOForkExtraRange is the number of consecutive blocks from the DAO fork point
|
||||
// to override the extra-data in to prevent no-fork attacks.
|
||||
var DAOForkExtraRange = big.NewInt(10) |
||||
|
||||
// DAORefundContract is the address of the refund contract to send DAO balances to.
|
||||
var DAORefundContract = common.HexToAddress("0xbf4ed7b27f1d666546e30d74d50d173d20bca754") |
||||
|
||||
// DAODrainList is the list of accounts whose full balances will be moved into a
|
||||
// refund contract at the beginning of the dao-fork block.
|
||||
func DAODrainList() []common.Address { |
||||
return []common.Address{ |
||||
common.HexToAddress("0xd4fe7bc31cedb7bfb8a345f31e668033056b2728"), |
||||
common.HexToAddress("0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425"), |
||||
common.HexToAddress("0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f"), |
||||
common.HexToAddress("0xecd135fa4f61a655311e86238c92adcd779555d2"), |
||||
common.HexToAddress("0x1975bd06d486162d5dc297798dfc41edd5d160a7"), |
||||
common.HexToAddress("0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6"), |
||||
common.HexToAddress("0x319f70bab6845585f412ec7724b744fec6095c85"), |
||||
common.HexToAddress("0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936"), |
||||
common.HexToAddress("0x5c8536898fbb74fc7445814902fd08422eac56d0"), |
||||
common.HexToAddress("0x6966ab0d485353095148a2155858910e0965b6f9"), |
||||
common.HexToAddress("0x779543a0491a837ca36ce8c635d6154e3c4911a6"), |
||||
common.HexToAddress("0x2a5ed960395e2a49b1c758cef4aa15213cfd874c"), |
||||
common.HexToAddress("0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5"), |
||||
common.HexToAddress("0x9c50426be05db97f5d64fc54bf89eff947f0a321"), |
||||
common.HexToAddress("0x200450f06520bdd6c527622a273333384d870efb"), |
||||
common.HexToAddress("0xbe8539bfe837b67d1282b2b1d61c3f723966f049"), |
||||
common.HexToAddress("0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb"), |
||||
common.HexToAddress("0xf1385fb24aad0cd7432824085e42aff90886fef5"), |
||||
common.HexToAddress("0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091"), |
||||
common.HexToAddress("0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd"), |
||||
common.HexToAddress("0x51e0ddd9998364a2eb38588679f0d2c42653e4a6"), |
||||
common.HexToAddress("0x627a0a960c079c21c34f7612d5d230e01b4ad4c7"), |
||||
common.HexToAddress("0xf0b1aa0eb660754448a7937c022e30aa692fe0c5"), |
||||
common.HexToAddress("0x24c4d950dfd4dd1902bbed3508144a54542bba94"), |
||||
common.HexToAddress("0x9f27daea7aca0aa0446220b98d028715e3bc803d"), |
||||
common.HexToAddress("0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90"), |
||||
common.HexToAddress("0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b"), |
||||
common.HexToAddress("0x63ed5a272de2f6d968408b4acb9024f4cc208ebf"), |
||||
common.HexToAddress("0x6f6704e5a10332af6672e50b3d9754dc460dfa4d"), |
||||
common.HexToAddress("0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6"), |
||||
common.HexToAddress("0x492ea3bb0f3315521c31f273e565b868fc090f17"), |
||||
common.HexToAddress("0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00"), |
||||
common.HexToAddress("0x9ea779f907f0b315b364b0cfc39a0fde5b02a416"), |
||||
common.HexToAddress("0xceaeb481747ca6c540a000c1f3641f8cef161fa7"), |
||||
common.HexToAddress("0xcc34673c6c40e791051898567a1222daf90be287"), |
||||
common.HexToAddress("0x579a80d909f346fbfb1189493f521d7f48d52238"), |
||||
common.HexToAddress("0xe308bd1ac5fda103967359b2712dd89deffb7973"), |
||||
common.HexToAddress("0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c"), |
||||
common.HexToAddress("0xac1ecab32727358dba8962a0f3b261731aad9723"), |
||||
common.HexToAddress("0x4fd6ace747f06ece9c49699c7cabc62d02211f75"), |
||||
common.HexToAddress("0x440c59b325d2997a134c2c7c60a8c61611212bad"), |
||||
common.HexToAddress("0x4486a3d68fac6967006d7a517b889fd3f98c102b"), |
||||
common.HexToAddress("0x9c15b54878ba618f494b38f0ae7443db6af648ba"), |
||||
common.HexToAddress("0x27b137a85656544b1ccb5a0f2e561a5703c6a68f"), |
||||
common.HexToAddress("0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241"), |
||||
common.HexToAddress("0x23b75c2f6791eef49c69684db4c6c1f93bf49a50"), |
||||
common.HexToAddress("0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b"), |
||||
common.HexToAddress("0xb9637156d330c0d605a791f1c31ba5890582fe1c"), |
||||
common.HexToAddress("0x6131c42fa982e56929107413a9d526fd99405560"), |
||||
common.HexToAddress("0x1591fc0f688c81fbeb17f5426a162a7024d430c2"), |
||||
common.HexToAddress("0x542a9515200d14b68e934e9830d91645a980dd7a"), |
||||
common.HexToAddress("0xc4bbd073882dd2add2424cf47d35213405b01324"), |
||||
common.HexToAddress("0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4"), |
||||
common.HexToAddress("0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb"), |
||||
common.HexToAddress("0x3ba4d81db016dc2890c81f3acec2454bff5aada5"), |
||||
common.HexToAddress("0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab"), |
||||
common.HexToAddress("0xe4ae1efdfc53b73893af49113d8694a057b9c0d1"), |
||||
common.HexToAddress("0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5"), |
||||
common.HexToAddress("0x0737a6b837f97f46ebade41b9bc3e1c509c85c53"), |
||||
common.HexToAddress("0x97f43a37f595ab5dd318fb46e7a155eae057317a"), |
||||
common.HexToAddress("0x52c5317c848ba20c7504cb2c8052abd1fde29d03"), |
||||
common.HexToAddress("0x4863226780fe7c0356454236d3b1c8792785748d"), |
||||
common.HexToAddress("0x5d2b2e6fcbe3b11d26b525e085ff818dae332479"), |
||||
common.HexToAddress("0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c"), |
||||
common.HexToAddress("0x057b56736d32b86616a10f619859c6cd6f59092a"), |
||||
common.HexToAddress("0x9aa008f65de0b923a2a4f02012ad034a5e2e2192"), |
||||
common.HexToAddress("0x304a554a310c7e546dfe434669c62820b7d83490"), |
||||
common.HexToAddress("0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79"), |
||||
common.HexToAddress("0x4deb0033bb26bc534b197e61d19e0733e5679784"), |
||||
common.HexToAddress("0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a"), |
||||
common.HexToAddress("0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b"), |
||||
common.HexToAddress("0x4fa802324e929786dbda3b8820dc7834e9134a2a"), |
||||
common.HexToAddress("0x9da397b9e80755301a3b32173283a91c0ef6c87e"), |
||||
common.HexToAddress("0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6"), |
||||
common.HexToAddress("0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9"), |
||||
common.HexToAddress("0x5dc28b15dffed94048d73806ce4b7a4612a1d48f"), |
||||
common.HexToAddress("0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76"), |
||||
common.HexToAddress("0x12e626b0eebfe86a56d633b9864e389b45dcb260"), |
||||
common.HexToAddress("0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7"), |
||||
common.HexToAddress("0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5"), |
||||
common.HexToAddress("0xd164b088bd9108b60d0ca3751da4bceb207b0782"), |
||||
common.HexToAddress("0x6231b6d0d5e77fe001c2a460bd9584fee60d409b"), |
||||
common.HexToAddress("0x1cba23d343a983e9b5cfd19496b9a9701ada385f"), |
||||
common.HexToAddress("0xa82f360a8d3455c5c41366975bde739c37bfeb8a"), |
||||
common.HexToAddress("0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339"), |
||||
common.HexToAddress("0x005f5cee7a43331d5a3d3eec71305925a62f34b6"), |
||||
common.HexToAddress("0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d"), |
||||
common.HexToAddress("0xd131637d5275fd1a68a3200f4ad25c71a2a9522e"), |
||||
common.HexToAddress("0xbc07118b9ac290e4622f5e77a0853539789effbe"), |
||||
common.HexToAddress("0x47e7aa56d6bdf3f36be34619660de61275420af8"), |
||||
common.HexToAddress("0xacd87e28b0c9d1254e868b81cba4cc20d9a32225"), |
||||
common.HexToAddress("0xadf80daec7ba8dcf15392f1ac611fff65d94f880"), |
||||
common.HexToAddress("0x5524c55fb03cf21f549444ccbecb664d0acad706"), |
||||
common.HexToAddress("0x40b803a9abce16f50f36a77ba41180eb90023925"), |
||||
common.HexToAddress("0xfe24cdd8648121a43a7c86d289be4dd2951ed49f"), |
||||
common.HexToAddress("0x17802f43a0137c506ba92291391a8a8f207f487d"), |
||||
common.HexToAddress("0x253488078a4edf4d6f42f113d1e62836a942cf1a"), |
||||
common.HexToAddress("0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915"), |
||||
common.HexToAddress("0xb136707642a4ea12fb4bae820f03d2562ebff487"), |
||||
common.HexToAddress("0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940"), |
||||
common.HexToAddress("0xf14c14075d6c4ed84b86798af0956deef67365b5"), |
||||
common.HexToAddress("0xca544e5c4687d109611d0f8f928b53a25af72448"), |
||||
common.HexToAddress("0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c"), |
||||
common.HexToAddress("0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7"), |
||||
common.HexToAddress("0x6d87578288b6cb5549d5076a207456a1f6a63dc0"), |
||||
common.HexToAddress("0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e"), |
||||
common.HexToAddress("0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6"), |
||||
common.HexToAddress("0x2b3455ec7fedf16e646268bf88846bd7a2319bb2"), |
||||
common.HexToAddress("0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a"), |
||||
common.HexToAddress("0xd343b217de44030afaa275f54d31a9317c7f441e"), |
||||
common.HexToAddress("0x84ef4b2357079cd7a7c69fd7a37cd0609a679106"), |
||||
common.HexToAddress("0xda2fef9e4a3230988ff17df2165440f37e8b1708"), |
||||
common.HexToAddress("0xf4c64518ea10f995918a454158c6b61407ea345c"), |
||||
common.HexToAddress("0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97"), |
||||
common.HexToAddress("0xbb9bc244d798123fde783fcc1c72d3bb8c189413"), |
||||
common.HexToAddress("0x807640a13483f8ac783c557fcdf27be11ea4ac7a"), |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
// These are the multipliers for ether denominations.
|
||||
// Example: To get the wei value of an amount in 'gwei', use
|
||||
//
|
||||
// new(big.Int).Mul(value, big.NewInt(params.GWei))
|
||||
//
|
||||
const ( |
||||
Wei = 1 |
||||
GWei = 1e9 |
||||
Ether = 1e18 |
||||
) |
@ -0,0 +1,93 @@ |
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
// GasTable organizes gas prices for different ethereum phases.
|
||||
type GasTable struct { |
||||
ExtcodeSize uint64 |
||||
ExtcodeCopy uint64 |
||||
ExtcodeHash uint64 |
||||
Balance uint64 |
||||
SLoad uint64 |
||||
Calls uint64 |
||||
Suicide uint64 |
||||
|
||||
ExpByte uint64 |
||||
|
||||
// CreateBySuicide occurs when the
|
||||
// refunded account is one that does
|
||||
// not exist. This logic is similar
|
||||
// to call. May be left nil. Nil means
|
||||
// not charged.
|
||||
CreateBySuicide uint64 |
||||
} |
||||
|
||||
// Variables containing gas prices for different ethereum phases.
|
||||
var ( |
||||
// GasTableHomestead contain the gas prices for
|
||||
// the homestead phase.
|
||||
GasTableHomestead = GasTable{ |
||||
ExtcodeSize: 20, |
||||
ExtcodeCopy: 20, |
||||
Balance: 20, |
||||
SLoad: 50, |
||||
Calls: 40, |
||||
Suicide: 0, |
||||
ExpByte: 10, |
||||
} |
||||
|
||||
// GasTableEIP150 contain the gas re-prices for
|
||||
// the EIP150 phase.
|
||||
GasTableEIP150 = GasTable{ |
||||
ExtcodeSize: 700, |
||||
ExtcodeCopy: 700, |
||||
Balance: 400, |
||||
SLoad: 200, |
||||
Calls: 700, |
||||
Suicide: 5000, |
||||
ExpByte: 10, |
||||
|
||||
CreateBySuicide: 25000, |
||||
} |
||||
// GasTableEIP158 contain the gas re-prices for
|
||||
// the EIP155/EIP158 phase.
|
||||
GasTableEIP158 = GasTable{ |
||||
ExtcodeSize: 700, |
||||
ExtcodeCopy: 700, |
||||
Balance: 400, |
||||
SLoad: 200, |
||||
Calls: 700, |
||||
Suicide: 5000, |
||||
ExpByte: 50, |
||||
|
||||
CreateBySuicide: 25000, |
||||
} |
||||
// GasTableConstantinople contain the gas re-prices for
|
||||
// the constantinople phase.
|
||||
GasTableConstantinople = GasTable{ |
||||
ExtcodeSize: 700, |
||||
ExtcodeCopy: 700, |
||||
ExtcodeHash: 400, |
||||
Balance: 400, |
||||
SLoad: 200, |
||||
Calls: 700, |
||||
Suicide: 5000, |
||||
ExpByte: 50, |
||||
|
||||
CreateBySuicide: 25000, |
||||
} |
||||
) |
@ -0,0 +1,54 @@ |
||||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
// These are network parameters that need to be constant between clients, but
|
||||
// aren't necessarily consensus related.
|
||||
|
||||
const ( |
||||
// BloomBitsBlocks is the number of blocks a single bloom bit section vector
|
||||
// contains on the server side.
|
||||
BloomBitsBlocks uint64 = 4096 |
||||
|
||||
// BloomBitsBlocksClient is the number of blocks a single bloom bit section vector
|
||||
// contains on the light client side
|
||||
BloomBitsBlocksClient uint64 = 32768 |
||||
|
||||
// BloomConfirms is the number of confirmation blocks before a bloom section is
|
||||
// considered probably final and its rotated bits are calculated.
|
||||
BloomConfirms = 256 |
||||
|
||||
// CHTFrequencyClient is the block frequency for creating CHTs on the client side.
|
||||
CHTFrequencyClient = 32768 |
||||
|
||||
// CHTFrequencyServer is the block frequency for creating CHTs on the server side.
|
||||
// Eventually this can be merged back with the client version, but that requires a
|
||||
// full database upgrade, so that should be left for a suitable moment.
|
||||
CHTFrequencyServer = 4096 |
||||
|
||||
// BloomTrieFrequency is the block frequency for creating BloomTrie on both
|
||||
// server/client sides.
|
||||
BloomTrieFrequency = 32768 |
||||
|
||||
// HelperTrieConfirmations is the number of confirmations before a client is expected
|
||||
// to have the given HelperTrie available.
|
||||
HelperTrieConfirmations = 2048 |
||||
|
||||
// HelperTrieProcessConfirmations is the number of confirmations before a HelperTrie
|
||||
// is generated
|
||||
HelperTrieProcessConfirmations = 256 |
||||
) |
@ -0,0 +1,155 @@ |
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
import "math/big" |
||||
|
||||
const ( |
||||
// GasLimitBoundDivisor ...
|
||||
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
|
||||
// MinGasLimit ...
|
||||
MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be.
|
||||
// GenesisGasLimit ...
|
||||
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
|
||||
|
||||
// MaximumExtraDataSize ...
|
||||
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
|
||||
// ExpByteGas ...
|
||||
ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction.
|
||||
// SloadGas ...
|
||||
SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
|
||||
// CallValueTransferGas ...
|
||||
CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero.
|
||||
// CallNewAccountGas ...
|
||||
CallNewAccountGas uint64 = 25000 // Paid for CALL when the destination address didn't exist prior.
|
||||
// TxGas ...
|
||||
TxGas uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions.
|
||||
// TxGasContractCreation ...
|
||||
TxGasContractCreation uint64 = 53000 // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions.
|
||||
// TxDataZeroGas ...
|
||||
TxDataZeroGas uint64 = 4 // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
|
||||
// QuadCoeffDiv ...
|
||||
QuadCoeffDiv uint64 = 512 // Divisor for the quadratic particle of the memory cost equation.
|
||||
// LogDataGas ...
|
||||
LogDataGas uint64 = 8 // Per byte in a LOG* operation's data.
|
||||
// CallStipend ...
|
||||
CallStipend uint64 = 2300 // Free gas given at beginning of call.
|
||||
|
||||
// Sha3Gas ...
|
||||
Sha3Gas uint64 = 30 // Once per SHA3 operation.
|
||||
// Sha3WordGas ...
|
||||
Sha3WordGas uint64 = 6 // Once per word of the SHA3 operation's data.
|
||||
|
||||
// SstoreSetGas ...
|
||||
SstoreSetGas uint64 = 20000 // Once per SLOAD operation.
|
||||
// SstoreResetGas ...
|
||||
SstoreResetGas uint64 = 5000 // Once per SSTORE operation if the zeroness changes from zero.
|
||||
// SstoreClearGas ...
|
||||
SstoreClearGas uint64 = 5000 // Once per SSTORE operation if the zeroness doesn't change.
|
||||
// SstoreRefundGas ...
|
||||
SstoreRefundGas uint64 = 15000 // Once per SSTORE operation if the zeroness changes to zero.
|
||||
|
||||
// NetSstoreNoopGas ...
|
||||
NetSstoreNoopGas uint64 = 200 // Once per SSTORE operation if the value doesn't change.
|
||||
// NetSstoreInitGas ...
|
||||
NetSstoreInitGas uint64 = 20000 // Once per SSTORE operation from clean zero.
|
||||
// NetSstoreCleanGas ...
|
||||
NetSstoreCleanGas uint64 = 5000 // Once per SSTORE operation from clean non-zero.
|
||||
// NetSstoreDirtyGas ...
|
||||
NetSstoreDirtyGas uint64 = 200 // Once per SSTORE operation from dirty.
|
||||
|
||||
// NetSstoreClearRefund ...
|
||||
NetSstoreClearRefund uint64 = 15000 // Once per SSTORE operation for clearing an originally existing storage slot
|
||||
// NetSstoreResetRefund ...
|
||||
NetSstoreResetRefund uint64 = 4800 // Once per SSTORE operation for resetting to the original non-zero value
|
||||
// NetSstoreResetClearRefund ...
|
||||
NetSstoreResetClearRefund uint64 = 19800 // Once per SSTORE operation for resetting to the original zero value
|
||||
|
||||
// JumpdestGas ...
|
||||
JumpdestGas uint64 = 1 // Refunded gas, once per SSTORE operation if the zeroness changes to zero.
|
||||
// EpochDuration ...
|
||||
EpochDuration uint64 = 30000 // Duration between proof-of-work epochs.
|
||||
// CallGas ...
|
||||
CallGas uint64 = 40 // Once per CALL operation & message call transaction.
|
||||
// CreateDataGas ...
|
||||
CreateDataGas uint64 = 200 //
|
||||
// CallCreateDepth ...
|
||||
CallCreateDepth uint64 = 1024 // Maximum depth of call/create stack.
|
||||
// ExpGas ...
|
||||
ExpGas uint64 = 10 // Once per EXP instruction
|
||||
// LogGas ...
|
||||
LogGas uint64 = 375 // Per LOG* operation.
|
||||
// CopyGas ...
|
||||
CopyGas uint64 = 3 //
|
||||
// StackLimit ...
|
||||
StackLimit uint64 = 1024 // Maximum size of VM stack allowed.
|
||||
// TierStepGas ...
|
||||
TierStepGas uint64 = 0 // Once per operation, for a selection of them.
|
||||
// LogTopicGas ...
|
||||
LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
|
||||
// CreateGas ...
|
||||
CreateGas uint64 = 32000 // Once per CREATE operation & contract-creation transaction.
|
||||
// Create2Gas ...
|
||||
Create2Gas uint64 = 32000 // Once per CREATE2 operation
|
||||
// SuicideRefundGas ...
|
||||
SuicideRefundGas uint64 = 24000 // Refunded following a suicide operation.
|
||||
// MemoryGas ...
|
||||
MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
|
||||
// TxDataNonZeroGas ...
|
||||
TxDataNonZeroGas uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
|
||||
|
||||
// MaxCodeSize ...
|
||||
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
|
||||
|
||||
// Precompiled contract gas prices
|
||||
|
||||
// EcrecoverGas ...
|
||||
EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price
|
||||
// Sha256BaseGas ...
|
||||
Sha256BaseGas uint64 = 60 // Base price for a SHA256 operation
|
||||
// Sha256PerWordGas ...
|
||||
Sha256PerWordGas uint64 = 12 // Per-word price for a SHA256 operation
|
||||
// Ripemd160BaseGas ...
|
||||
Ripemd160BaseGas uint64 = 600 // Base price for a RIPEMD160 operation
|
||||
// Ripemd160PerWordGas ...
|
||||
Ripemd160PerWordGas uint64 = 120 // Per-word price for a RIPEMD160 operation
|
||||
// IdentityBaseGas ...
|
||||
IdentityBaseGas uint64 = 15 // Base price for a data copy operation
|
||||
// IdentityPerWordGas ...
|
||||
IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation
|
||||
// ModExpQuadCoeffDiv ...
|
||||
ModExpQuadCoeffDiv uint64 = 20 // Divisor for the quadratic particle of the big int modular exponentiation
|
||||
// Bn256AddGas ...
|
||||
Bn256AddGas uint64 = 500 // Gas needed for an elliptic curve addition
|
||||
// Bn256ScalarMulGas ...
|
||||
Bn256ScalarMulGas uint64 = 40000 // Gas needed for an elliptic curve scalar multiplication
|
||||
// Bn256PairingBaseGas ...
|
||||
Bn256PairingBaseGas uint64 = 100000 // Base price for an elliptic curve pairing check
|
||||
// Bn256PairingPerPointGas ...
|
||||
Bn256PairingPerPointGas uint64 = 80000 // Per-point price for an elliptic curve pairing check
|
||||
) |
||||
|
||||
var ( |
||||
// DifficultyBoundDivisor ...
|
||||
DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations.
|
||||
// GenesisDifficulty ...
|
||||
GenesisDifficulty = big.NewInt(131072) // Difficulty of the Genesis block.
|
||||
// MinimumDifficulty ...
|
||||
MinimumDifficulty = big.NewInt(131072) // The minimum that the difficulty may ever be.
|
||||
// DurationLimit ...
|
||||
DurationLimit = big.NewInt(13) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
|
||||
) |
@ -0,0 +1,69 @@ |
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package params |
||||
|
||||
import ( |
||||
"fmt" |
||||
) |
||||
|
||||
const ( |
||||
// VersionMajor ...
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
// VersionMinor ...
|
||||
VersionMinor = 8 // Minor version component of the current release
|
||||
// VersionPatch ...
|
||||
VersionPatch = 27 // Patch version component of the current release
|
||||
// VersionMeta ...
|
||||
VersionMeta = "stable" // Version metadata to append to the version string
|
||||
) |
||||
|
||||
// Version holds the textual version string.
|
||||
var Version = func() string { |
||||
return fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionPatch) |
||||
}() |
||||
|
||||
// VersionWithMeta holds the textual version string including the metadata.
|
||||
var VersionWithMeta = func() string { |
||||
v := Version |
||||
if VersionMeta != "" { |
||||
v += "-" + VersionMeta |
||||
} |
||||
return v |
||||
}() |
||||
|
||||
// ArchiveVersion holds the textual version string used for Geth archives.
|
||||
// e.g. "1.8.11-dea1ce05" for stable releases, or
|
||||
// "1.8.13-unstable-21c059b6" for unstable releases
|
||||
func ArchiveVersion(gitCommit string) string { |
||||
vsn := Version |
||||
if VersionMeta != "stable" { |
||||
vsn += "-" + VersionMeta |
||||
} |
||||
if len(gitCommit) >= 8 { |
||||
vsn += "-" + gitCommit[:8] |
||||
} |
||||
return vsn |
||||
} |
||||
|
||||
// VersionWithCommit ...
|
||||
func VersionWithCommit(gitCommit string) string { |
||||
vsn := VersionWithMeta |
||||
if len(gitCommit) >= 8 { |
||||
vsn += "-" + gitCommit[:8] |
||||
} |
||||
return vsn |
||||
} |
Loading…
Reference in new issue