mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Merge branch 'master' into lean_reindex
This commit is contained in:
commit
be4346a8f9
15 changed files with 205 additions and 63 deletions
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
|
@ -401,6 +402,27 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
|
|||
} else {
|
||||
hi = b.pendingBlock.GasLimit()
|
||||
}
|
||||
// Recap the highest gas allowance with account's balance.
|
||||
if call.GasPrice != nil && call.GasPrice.Uint64() != 0 {
|
||||
balance := b.pendingState.GetBalance(call.From) // from can't be nil
|
||||
available := new(big.Int).Set(balance)
|
||||
if call.Value != nil {
|
||||
if call.Value.Cmp(available) >= 0 {
|
||||
return 0, errors.New("insufficient funds for transfer")
|
||||
}
|
||||
available.Sub(available, call.Value)
|
||||
}
|
||||
allowance := new(big.Int).Div(available, call.GasPrice)
|
||||
if hi > allowance.Uint64() {
|
||||
transfer := call.Value
|
||||
if transfer == nil {
|
||||
transfer = new(big.Int)
|
||||
}
|
||||
log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance,
|
||||
"sent", transfer, "gasprice", call.GasPrice, "fundable", allowance)
|
||||
hi = allowance.Uint64()
|
||||
}
|
||||
}
|
||||
cap = hi
|
||||
|
||||
// Create a helper to check if a gas allowance results in an executable transaction
|
||||
|
|
|
|||
|
|
@ -466,6 +466,73 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) {
|
||||
key, _ := crypto.GenerateKey()
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
||||
sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000)
|
||||
defer sim.Close()
|
||||
|
||||
receipant := common.HexToAddress("deadbeef")
|
||||
var cases = []struct {
|
||||
name string
|
||||
message ethereum.CallMsg
|
||||
expect uint64
|
||||
expectError error
|
||||
}{
|
||||
{"EstimateWithoutPrice", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &receipant,
|
||||
Gas: 0,
|
||||
GasPrice: big.NewInt(0),
|
||||
Value: big.NewInt(1000),
|
||||
Data: nil,
|
||||
}, 21000, nil},
|
||||
|
||||
{"EstimateWithPrice", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &receipant,
|
||||
Gas: 0,
|
||||
GasPrice: big.NewInt(1000),
|
||||
Value: big.NewInt(1000),
|
||||
Data: nil,
|
||||
}, 21000, nil},
|
||||
|
||||
{"EstimateWithVeryHighPrice", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &receipant,
|
||||
Gas: 0,
|
||||
GasPrice: big.NewInt(1e14), // gascost = 2.1ether
|
||||
Value: big.NewInt(1e17), // the remaining balance for fee is 2.1ether
|
||||
Data: nil,
|
||||
}, 21000, nil},
|
||||
|
||||
{"EstimateWithSuperhighPrice", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &receipant,
|
||||
Gas: 0,
|
||||
GasPrice: big.NewInt(2e14), // gascost = 4.2ether
|
||||
Value: big.NewInt(1000),
|
||||
Data: nil,
|
||||
}, 21000, errors.New("gas required exceeds allowance (10999)")}, // 10999=(2.2ether-1000wei)/(2e14)
|
||||
}
|
||||
for _, c := range cases {
|
||||
got, err := sim.EstimateGas(context.Background(), c.message)
|
||||
if c.expectError != nil {
|
||||
if err == nil {
|
||||
t.Fatalf("Expect error, got nil")
|
||||
}
|
||||
if c.expectError.Error() != err.Error() {
|
||||
t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if got != c.expect {
|
||||
t.Fatalf("Gas estimation mismatch, want %d, got %d", c.expect, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimulatedBackend_HeaderByHash(t *testing.T) {
|
||||
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ Section "Geth" GETH_IDX
|
|||
|
||||
# Create start menu launcher
|
||||
createDirectory "$SMPROGRAMS\${APPNAME}"
|
||||
createShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\geth.exe" "--fast" "--cache=512"
|
||||
createShortCut "$SMPROGRAMS\${APPNAME}\Attach.lnk" "$INSTDIR\geth.exe" "attach" "" ""
|
||||
createShortCut "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "" ""
|
||||
createShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\geth.exe"
|
||||
createShortCut "$SMPROGRAMS\${APPNAME}\Attach.lnk" "$INSTDIR\geth.exe" "attach"
|
||||
createShortCut "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
||||
|
||||
# Firewall - remove rules (if exists)
|
||||
SimpleFC::AdvRemoveRule "Geth incoming peers (TCP:30303)"
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ var (
|
|||
utils.UnlockedAccountFlag,
|
||||
utils.PasswordFileFlag,
|
||||
utils.BootnodesFlag,
|
||||
utils.BootnodesV4Flag,
|
||||
utils.BootnodesV5Flag,
|
||||
utils.LegacyBootnodesV4Flag,
|
||||
utils.LegacyBootnodesV5Flag,
|
||||
utils.DataDirFlag,
|
||||
utils.AncientFlag,
|
||||
utils.KeyStoreDirFlag,
|
||||
|
|
|
|||
|
|
@ -184,8 +184,8 @@ var AppHelpFlagGroups = []flagGroup{
|
|||
Name: "NETWORKING",
|
||||
Flags: []cli.Flag{
|
||||
utils.BootnodesFlag,
|
||||
utils.BootnodesV4Flag,
|
||||
utils.BootnodesV5Flag,
|
||||
utils.LegacyBootnodesV4Flag,
|
||||
utils.LegacyBootnodesV5Flag,
|
||||
utils.DNSDiscoveryFlag,
|
||||
utils.ListenPortFlag,
|
||||
utils.MaxPeersFlag,
|
||||
|
|
|
|||
|
|
@ -600,17 +600,7 @@ var (
|
|||
}
|
||||
BootnodesFlag = cli.StringFlag{
|
||||
Name: "bootnodes",
|
||||
Usage: "Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)",
|
||||
Value: "",
|
||||
}
|
||||
BootnodesV4Flag = cli.StringFlag{
|
||||
Name: "bootnodesv4",
|
||||
Usage: "Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)",
|
||||
Value: "",
|
||||
}
|
||||
BootnodesV5Flag = cli.StringFlag{
|
||||
Name: "bootnodesv5",
|
||||
Usage: "Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)",
|
||||
Usage: "Comma separated enode URLs for P2P discovery bootstrap",
|
||||
Value: "",
|
||||
}
|
||||
NodeKeyFileFlag = cli.StringFlag{
|
||||
|
|
@ -798,9 +788,9 @@ func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) {
|
|||
func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
|
||||
urls := params.MainnetBootnodes
|
||||
switch {
|
||||
case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV4Flag.Name):
|
||||
if ctx.GlobalIsSet(BootnodesV4Flag.Name) {
|
||||
urls = splitAndTrim(ctx.GlobalString(BootnodesV4Flag.Name))
|
||||
case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(LegacyBootnodesV4Flag.Name):
|
||||
if ctx.GlobalIsSet(LegacyBootnodesV4Flag.Name) {
|
||||
urls = splitAndTrim(ctx.GlobalString(LegacyBootnodesV4Flag.Name))
|
||||
} else {
|
||||
urls = splitAndTrim(ctx.GlobalString(BootnodesFlag.Name))
|
||||
}
|
||||
|
|
@ -830,14 +820,16 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
|
|||
// setBootstrapNodesV5 creates a list of bootstrap nodes from the command line
|
||||
// flags, reverting to pre-configured ones if none have been specified.
|
||||
func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
|
||||
urls := params.DiscoveryV5Bootnodes
|
||||
urls := params.MainnetBootnodes
|
||||
switch {
|
||||
case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV5Flag.Name):
|
||||
if ctx.GlobalIsSet(BootnodesV5Flag.Name) {
|
||||
urls = splitAndTrim(ctx.GlobalString(BootnodesV5Flag.Name))
|
||||
case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(LegacyBootnodesV5Flag.Name):
|
||||
if ctx.GlobalIsSet(LegacyBootnodesV5Flag.Name) {
|
||||
urls = splitAndTrim(ctx.GlobalString(LegacyBootnodesV5Flag.Name))
|
||||
} else {
|
||||
urls = splitAndTrim(ctx.GlobalString(BootnodesFlag.Name))
|
||||
}
|
||||
case ctx.GlobalBool(RopstenFlag.Name):
|
||||
urls = params.RopstenBootnodes
|
||||
case ctx.GlobalBool(RinkebyFlag.Name):
|
||||
urls = params.RinkebyBootnodes
|
||||
case ctx.GlobalBool(GoerliFlag.Name):
|
||||
|
|
|
|||
|
|
@ -148,6 +148,16 @@ var (
|
|||
Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices (deprecated, use --gpo.percentile)",
|
||||
Value: eth.DefaultConfig.GPO.Percentile,
|
||||
}
|
||||
LegacyBootnodesV4Flag = cli.StringFlag{
|
||||
Name: "bootnodesv4",
|
||||
Usage: "Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes) (deprecated, use --bootnodes)",
|
||||
Value: "",
|
||||
}
|
||||
LegacyBootnodesV5Flag = cli.StringFlag{
|
||||
Name: "bootnodesv5",
|
||||
Usage: "Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes) (deprecated, use --bootnodes)",
|
||||
Value: "",
|
||||
}
|
||||
)
|
||||
|
||||
// showDeprecated displays deprecated flags that will be soon removed from the codebase.
|
||||
|
|
|
|||
|
|
@ -229,6 +229,9 @@ func (b *bridge) readPinAndReopenWallet(call jsre.Call) (goja.Value, error) {
|
|||
// original RPC method (saved in jeth.unlockAccount) with it to actually execute
|
||||
// the RPC call.
|
||||
func (b *bridge) UnlockAccount(call jsre.Call) (goja.Value, error) {
|
||||
if nArgs := len(call.Arguments); nArgs < 2 {
|
||||
return nil, fmt.Errorf("usage: unlockAccount(account, [ password, duration ])")
|
||||
}
|
||||
// Make sure we have an account specified to unlock.
|
||||
if call.Argument(0).ExportType().Kind() != reflect.String {
|
||||
return nil, fmt.Errorf("first argument must be the account to unlock")
|
||||
|
|
@ -272,6 +275,9 @@ func (b *bridge) UnlockAccount(call jsre.Call) (goja.Value, error) {
|
|||
// prompt to acquire the passphrase and executes the original RPC method (saved in
|
||||
// jeth.sign) with it to actually execute the RPC call.
|
||||
func (b *bridge) Sign(call jsre.Call) (goja.Value, error) {
|
||||
if nArgs := len(call.Arguments); nArgs < 2 {
|
||||
return nil, fmt.Errorf("usage: sign(message, account, [ password ])")
|
||||
}
|
||||
var (
|
||||
message = call.Argument(0)
|
||||
account = call.Argument(1)
|
||||
|
|
@ -307,6 +313,9 @@ func (b *bridge) Sign(call jsre.Call) (goja.Value, error) {
|
|||
|
||||
// Sleep will block the console for the specified number of seconds.
|
||||
func (b *bridge) Sleep(call jsre.Call) (goja.Value, error) {
|
||||
if nArgs := len(call.Arguments); nArgs < 1 {
|
||||
return nil, fmt.Errorf("usage: sleep(<number of seconds>)")
|
||||
}
|
||||
if !isNumber(call.Argument(0)) {
|
||||
return nil, fmt.Errorf("usage: sleep(<number of seconds>)")
|
||||
}
|
||||
|
|
@ -334,7 +343,7 @@ func (b *bridge) SleepBlocks(call jsre.Call) (goja.Value, error) {
|
|||
blocks = call.Argument(0).ToInteger()
|
||||
}
|
||||
if nArgs >= 2 {
|
||||
if isNumber(call.Argument(1)) {
|
||||
if !isNumber(call.Argument(1)) {
|
||||
return nil, fmt.Errorf("expected number as second argument")
|
||||
}
|
||||
sleep = call.Argument(1).ToInteger()
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@ type freezerdb struct {
|
|||
// the slow ancient tables.
|
||||
func (frdb *freezerdb) Close() error {
|
||||
var errs []error
|
||||
if err := frdb.KeyValueStore.Close(); err != nil {
|
||||
if err := frdb.AncientStore.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if err := frdb.AncientStore.Close(); err != nil {
|
||||
if err := frdb.KeyValueStore.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if len(errs) != 0 {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ type freezer struct {
|
|||
|
||||
tables map[string]*freezerTable // Data tables for storing everything
|
||||
instanceLock fileutil.Releaser // File-system lock to prevent double opens
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
// newFreezer creates a chain freezer that moves ancient chain data into
|
||||
|
|
@ -101,6 +102,7 @@ func newFreezer(datadir string, namespace string) (*freezer, error) {
|
|||
freezer := &freezer{
|
||||
tables: make(map[string]*freezerTable),
|
||||
instanceLock: lock,
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
for name, disableSnappy := range freezerNoSnappy {
|
||||
table, err := newTable(datadir, name, readMeter, writeMeter, sizeGauge, disableSnappy)
|
||||
|
|
@ -126,6 +128,7 @@ func newFreezer(datadir string, namespace string) (*freezer, error) {
|
|||
|
||||
// Close terminates the chain freezer, unmapping all the data files.
|
||||
func (f *freezer) Close() error {
|
||||
f.quit <- struct{}{}
|
||||
var errs []error
|
||||
for _, table := range f.tables {
|
||||
if err := table.Close(); err != nil {
|
||||
|
|
@ -254,35 +257,50 @@ func (f *freezer) Sync() error {
|
|||
func (f *freezer) freeze(db ethdb.KeyValueStore) {
|
||||
nfdb := &nofreezedb{KeyValueStore: db}
|
||||
|
||||
backoff := false
|
||||
for {
|
||||
select {
|
||||
case <-f.quit:
|
||||
log.Info("Freezer shutting down")
|
||||
return
|
||||
default:
|
||||
}
|
||||
if backoff {
|
||||
select {
|
||||
case <-time.NewTimer(freezerRecheckInterval).C:
|
||||
backoff = false
|
||||
case <-f.quit:
|
||||
return
|
||||
}
|
||||
}
|
||||
// Retrieve the freezing threshold.
|
||||
hash := ReadHeadBlockHash(nfdb)
|
||||
if hash == (common.Hash{}) {
|
||||
log.Debug("Current full block hash unavailable") // new chain, empty database
|
||||
time.Sleep(freezerRecheckInterval)
|
||||
backoff = true
|
||||
continue
|
||||
}
|
||||
number := ReadHeaderNumber(nfdb, hash)
|
||||
switch {
|
||||
case number == nil:
|
||||
log.Error("Current full block number unavailable", "hash", hash)
|
||||
time.Sleep(freezerRecheckInterval)
|
||||
backoff = true
|
||||
continue
|
||||
|
||||
case *number < params.ImmutabilityThreshold:
|
||||
log.Debug("Current full block not old enough", "number", *number, "hash", hash, "delay", params.ImmutabilityThreshold)
|
||||
time.Sleep(freezerRecheckInterval)
|
||||
backoff = true
|
||||
continue
|
||||
|
||||
case *number-params.ImmutabilityThreshold <= f.frozen:
|
||||
log.Debug("Ancient blocks frozen already", "number", *number, "hash", hash, "frozen", f.frozen)
|
||||
time.Sleep(freezerRecheckInterval)
|
||||
backoff = true
|
||||
continue
|
||||
}
|
||||
head := ReadHeader(nfdb, hash, *number)
|
||||
if head == nil {
|
||||
log.Error("Current full block unavailable", "number", *number, "hash", hash)
|
||||
time.Sleep(freezerRecheckInterval)
|
||||
backoff = true
|
||||
continue
|
||||
}
|
||||
// Seems we have data ready to be frozen, process in usable batches
|
||||
|
|
@ -369,7 +387,7 @@ func (f *freezer) freeze(db ethdb.KeyValueStore) {
|
|||
|
||||
// Avoid database thrashing with tiny writes
|
||||
if f.frozen-first < freezerBatchLimit {
|
||||
time.Sleep(freezerRecheckInterval)
|
||||
backoff = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -454,6 +454,23 @@ func (s *stateObject) Code(db Database) []byte {
|
|||
return code
|
||||
}
|
||||
|
||||
// CodeSize returns the size of the contract code associated with this object,
|
||||
// or zero if none. This methos is an almost mirror of Code, but uses a cache
|
||||
// inside the database to avoid loading codes seen recently.
|
||||
func (s *stateObject) CodeSize(db Database) int {
|
||||
if s.code != nil {
|
||||
return len(s.code)
|
||||
}
|
||||
if bytes.Equal(s.CodeHash(), emptyCodeHash) {
|
||||
return 0
|
||||
}
|
||||
size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))
|
||||
if err != nil {
|
||||
s.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err))
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
|
||||
prevcode := s.Code(s.db.db)
|
||||
s.db.journal.append(codeChange{
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
|
@ -289,20 +288,10 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
|
|||
|
||||
func (s *StateDB) GetCodeSize(addr common.Address) int {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return 0
|
||||
if stateObject != nil {
|
||||
return stateObject.CodeSize(s.db)
|
||||
}
|
||||
if stateObject.code != nil {
|
||||
return len(stateObject.code)
|
||||
}
|
||||
if bytes.Equal(stateObject.CodeHash(), emptyCode[:]) {
|
||||
return 0
|
||||
}
|
||||
size, err := s.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash()))
|
||||
if err != nil {
|
||||
s.setError(fmt.Errorf("GetCodeSize (%x) error: %v", addr[:], err))
|
||||
}
|
||||
return size
|
||||
return 0
|
||||
}
|
||||
|
||||
func (s *StateDB) GetCodeHash(addr common.Address) common.Hash {
|
||||
|
|
|
|||
|
|
@ -906,6 +906,11 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
|
|||
hi uint64
|
||||
cap uint64
|
||||
)
|
||||
// Use zero address if sender unspecified.
|
||||
if args.From == nil {
|
||||
args.From = new(common.Address)
|
||||
}
|
||||
// Determine the highest gas limit can be used during the estimation.
|
||||
if args.Gas != nil && uint64(*args.Gas) >= params.TxGas {
|
||||
hi = uint64(*args.Gas)
|
||||
} else {
|
||||
|
|
@ -916,16 +921,38 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
|
|||
}
|
||||
hi = block.GasLimit()
|
||||
}
|
||||
// Recap the highest gas limit with account's available balance.
|
||||
if args.GasPrice != nil && args.GasPrice.ToInt().Uint64() != 0 {
|
||||
state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
balance := state.GetBalance(*args.From) // from can't be nil
|
||||
available := new(big.Int).Set(balance)
|
||||
if args.Value != nil {
|
||||
if args.Value.ToInt().Cmp(available) >= 0 {
|
||||
return 0, errors.New("insufficient funds for transfer")
|
||||
}
|
||||
available.Sub(available, args.Value.ToInt())
|
||||
}
|
||||
allowance := new(big.Int).Div(available, args.GasPrice.ToInt())
|
||||
if hi > allowance.Uint64() {
|
||||
transfer := args.Value
|
||||
if transfer == nil {
|
||||
transfer = new(hexutil.Big)
|
||||
}
|
||||
log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance,
|
||||
"sent", transfer.ToInt(), "gasprice", args.GasPrice.ToInt(), "fundable", allowance)
|
||||
hi = allowance.Uint64()
|
||||
}
|
||||
}
|
||||
// Recap the highest gas allowance with specified gascap.
|
||||
if gasCap != nil && hi > gasCap.Uint64() {
|
||||
log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap)
|
||||
hi = gasCap.Uint64()
|
||||
}
|
||||
cap = hi
|
||||
|
||||
// Use zero address if sender unspecified.
|
||||
if args.From == nil {
|
||||
args.From = new(common.Address)
|
||||
}
|
||||
// Create a helper to check if a gas allowance results in an executable transaction
|
||||
executable := func(gas uint64) (bool, *core.ExecutionResult, error) {
|
||||
args.Gas = (*hexutil.Uint64)(&gas)
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ func GoerliGenesis() string {
|
|||
// FoundationBootnodes returns the enode URLs of the P2P bootstrap nodes operated
|
||||
// by the foundation running the V5 discovery protocol.
|
||||
func FoundationBootnodes() *Enodes {
|
||||
nodes := &Enodes{nodes: make([]*discv5.Node, len(params.DiscoveryV5Bootnodes))}
|
||||
for i, url := range params.DiscoveryV5Bootnodes {
|
||||
nodes := &Enodes{nodes: make([]*discv5.Node, len(params.MainnetBootnodes))}
|
||||
for i, url := range params.MainnetBootnodes {
|
||||
nodes.nodes[i] = discv5.MustParseNode(url)
|
||||
}
|
||||
return nodes
|
||||
|
|
|
|||
|
|
@ -63,15 +63,6 @@ var GoerliBootnodes = []string{
|
|||
"enode://a61215641fb8714a373c80edbfa0ea8878243193f57c96eeb44d0bc019ef295abd4e044fd619bfc4c59731a73fb79afe84e9ab6da0c743ceb479cbb6d263fa91@3.11.147.67: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",
|
||||
}
|
||||
|
||||
const dnsPrefix = "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@"
|
||||
|
||||
// These DNS names provide bootstrap connectivity for public testnets and the mainnet.
|
||||
|
|
|
|||
Loading…
Reference in a new issue