Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
508891e
core/vm: use pointers to operations vs. copy by value
karalabe Jul 16, 2020
722b742
params: begin v1.9.18 release cycle
karalabe Jul 20, 2020
3a52c4d
Merge pull request #21336 from karalabe/tiny-ref-optimization
karalabe Jul 21, 2020
4366c45
les: make clientPool.connectedBias configurable (#21305)
binacs Jul 21, 2020
7163a66
ethclient: serialize negative block number as "pending" (#21177)
sammy007 Jul 21, 2020
123864f
whisper/whisperv6: improve test error messages (#21348)
renaynay Jul 21, 2020
9e22e91
cmd/utils: reuse existing genesis in persistent dev mode
karalabe Jul 21, 2020
0b53e48
Merge pull request #21352 from karalabe/dev-noinit-genesis
karalabe Jul 22, 2020
4c268e6
cmd/utils: implement configurable developer (--dev) account options (…
meowsbits Jul 23, 2020
997b552
build: fix GOBIN for gomobile commands (#21361)
fjl Jul 23, 2020
3a57eec
mobile: fix build on iOS (#21362)
fjl Jul 23, 2020
1059221
eth/downloader: refactor downloader + queue (#21263)
holiman Jul 24, 2020
c374447
core: fix queued transaction eviction
villanuevawill May 23, 2020
5413df1
core: fix heartbeat in txpool
rjl493456442 Jul 8, 2020
6793ffa
Merge pull request #21300 from rjl493456442/txpool-fix-queued-evictions
karalabe Jul 24, 2020
56434bf
deps: update uint256 to v1.1.1
holiman Jul 24, 2020
e997f92
Merge pull request #21368 from holiman/update_uint256
karalabe Jul 24, 2020
b1be979
params: upgrade CHTs (#21376)
rjl493456442 Jul 27, 2020
f538259
params: release Geth v1.9.18
karalabe Jul 27, 2020
74b12e7
Merge branch 'upgrade/go-ethereum/v1.9.17-2021219105839' into upgrade…
ricardolyn Feb 24, 2021
e91a788
Merge branch 'upgrade/go-ethereum/v1.9.17-2021219105839' into upgrade…
ricardolyn Feb 24, 2021
00e1265
Merge branch 'master' into upgrade/go-ethereum/v1.9.18-2021224170947
ricardolyn Mar 1, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -888,11 +888,12 @@ func gomobileTool(subcmd string, args ...string) *exec.Cmd {
"PATH=" + GOBIN + string(os.PathListSeparator) + os.Getenv("PATH"),
}
for _, e := range os.Environ() {
if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "PATH=") {
if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "PATH=") || strings.HasPrefix(e, "GOBIN=") {
continue
}
cmd.Env = append(cmd.Env, e)
}
cmd.Env = append(cmd.Env, "GOBIN="+GOBIN)
return cmd
}

Expand Down Expand Up @@ -961,7 +962,7 @@ func doXCodeFramework(cmdline []string) {

if *local {
// If we're building locally, use the build folder and stop afterwards
bind.Dir, _ = filepath.Abs(GOBIN)
bind.Dir = GOBIN
build.MustRun(bind)
return
}
Expand Down
30 changes: 25 additions & 5 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1873,23 +1873,43 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
}
// Create new developer account or reuse existing one
var (
developer accounts.Account
err error
developer accounts.Account
passphrase string
err error
)
if accs := ks.Accounts(); len(accs) > 0 {
if list := MakePasswordList(ctx); len(list) > 0 {
// Just take the first value. Although the function returns a possible multiple values and
// some usages iterate through them as attempts, that doesn't make sense in this setting,
// when we're definitely concerned with only one account.
passphrase = list[0]
}
// setEtherbase has been called above, configuring the miner address from command line flags.
if cfg.Miner.Etherbase != (common.Address{}) {
developer = accounts.Account{Address: cfg.Miner.Etherbase}
} else if accs := ks.Accounts(); len(accs) > 0 {
developer = ks.Accounts()[0]
} else {
developer, err = ks.NewAccount("")
developer, err = ks.NewAccount(passphrase)
if err != nil {
Fatalf("Failed to create developer account: %v", err)
}
}
if err := ks.Unlock(developer, ""); err != nil {
if err := ks.Unlock(developer, passphrase); err != nil {
Fatalf("Failed to unlock developer account: %v", err)
}
log.Info("Using developer account", "address", developer.Address)

// Create a new developer genesis block or reuse existing one
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)
if ctx.GlobalIsSet(DataDirFlag.Name) {
// Check if we have an already initialized chain and fall back to
// that if so. Otherwise we need to generate a new genesis spec.
chaindb := MakeChainDatabase(ctx, stack)
if rawdb.ReadCanonicalHash(chaindb, 0) != (common.Hash{}) {
cfg.Genesis = nil // fallback to db content
}
chaindb.Close()
}
if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) && !ctx.GlobalIsSet(LegacyMinerGasPriceFlag.Name) {
cfg.Miner.GasPrice = big.NewInt(1)
}
Expand Down
23 changes: 16 additions & 7 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ var (
queuedReplaceMeter = metrics.NewRegisteredMeter("txpool/queued/replace", nil)
queuedRateLimitMeter = metrics.NewRegisteredMeter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting
queuedNofundsMeter = metrics.NewRegisteredMeter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds
queuedEvictionMeter = metrics.NewRegisteredMeter("txpool/queued/eviction", nil) // Dropped due to lifetime

// General tx metrics
knownTxMeter = metrics.NewRegisteredMeter("txpool/known", nil)
Expand Down Expand Up @@ -378,9 +379,11 @@ func (pool *TxPool) loop() {
}
// Any non-locals old enough should be removed
if time.Since(pool.beats[addr]) > pool.config.Lifetime {
for _, tx := range pool.queue[addr].Flatten() {
list := pool.queue[addr].Flatten()
for _, tx := range list {
pool.removeTx(tx.Hash(), true)
}
queuedEvictionMeter.Mark(int64(len(list)))
}
}
pool.mu.Unlock()
Expand Down Expand Up @@ -653,6 +656,9 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
pool.journalTx(from, tx)
pool.queueTxEvent(tx)
log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())

// Successful promotion, bump the heartbeat
pool.beats[from] = time.Now()
return old != nil, nil
}
// New transaction isn't replacing a pending one, push into queue
Expand Down Expand Up @@ -704,6 +710,10 @@ func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, er
pool.all.Add(tx)
pool.priced.Put(tx)
}
// If we never record the heartbeat, do it right now.
if _, exist := pool.beats[from]; !exist {
pool.beats[from] = time.Now()
}
return old != nil, nil
}

Expand Down Expand Up @@ -735,15 +745,13 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T
// An older transaction was better, discard this
pool.all.Remove(hash)
pool.priced.Removed(1)

pendingDiscardMeter.Mark(1)
return false
}
// Otherwise discard any previous transaction and mark this
if old != nil {
pool.all.Remove(old.Hash())
pool.priced.Removed(1)

pendingReplaceMeter.Mark(1)
} else {
// Nothing was replaced, bump the pending counter
Expand All @@ -755,9 +763,10 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T
pool.priced.Put(tx)
}
// Set the potentially new pending nonce and notify any subsystems of the new tx
pool.beats[addr] = time.Now()
pool.pendingNonces.set(addr, tx.Nonce()+1)

// Successful promotion, bump the heartbeat
pool.beats[addr] = time.Now()
return true
}

Expand Down Expand Up @@ -930,7 +939,6 @@ func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
// If no more pending transactions are left, remove the list
if pending.Empty() {
delete(pool.pending, addr)
delete(pool.beats, addr)
}
// Postpone any invalidated transactions
for _, tx := range invalids {
Expand All @@ -951,6 +959,7 @@ func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
}
if future.Empty() {
delete(pool.queue, addr)
delete(pool.beats, addr)
}
}
}
Expand Down Expand Up @@ -1277,6 +1286,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Trans
// Delete the entire queue entry if it became empty.
if list.Empty() {
delete(pool.queue, addr)
delete(pool.beats, addr)
}
}
return promoted
Expand Down Expand Up @@ -1458,10 +1468,9 @@ func (pool *TxPool) demoteUnexecutables() {
}
pendingGauge.Dec(int64(len(gapped)))
}
// Delete the entire queue entry if it became empty.
// Delete the entire pending entry if it became empty.
if list.Empty() {
delete(pool.pending, addr)
delete(pool.beats, addr)
}
}
}
Expand Down
85 changes: 84 additions & 1 deletion core/tx_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func validateTxPoolInternals(pool *TxPool) error {
if priced := pool.priced.items.Len() - pool.priced.stales; priced != pending+queued {
return fmt.Errorf("total priced transaction count %d != %d pending + %d queued", priced, pending, queued)
}

// Ensure the next nonce to assign is the correct one
for addr, txs := range pool.pending {
// Find the last transaction
Expand Down Expand Up @@ -982,7 +983,7 @@ func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
// Reduce the eviction interval to a testable amount
defer func(old time.Duration) { evictionInterval = old }(evictionInterval)
evictionInterval = time.Second
evictionInterval = time.Millisecond * 100

// Create the pool to test the non-expiration enforcement
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
Expand Down Expand Up @@ -1019,6 +1020,22 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
if err := validateTxPoolInternals(pool); err != nil {
t.Fatalf("pool internal state corrupted: %v", err)
}

// Allow the eviction interval to run
time.Sleep(2 * evictionInterval)

// Transactions should not be evicted from the queue yet since lifetime duration has not passed
pending, queued = pool.Stats()
if pending != 0 {
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
}
if queued != 2 {
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
}
if err := validateTxPoolInternals(pool); err != nil {
t.Fatalf("pool internal state corrupted: %v", err)
}

// Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
time.Sleep(2 * config.Lifetime)

Expand All @@ -1038,6 +1055,72 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
if err := validateTxPoolInternals(pool); err != nil {
t.Fatalf("pool internal state corrupted: %v", err)
}

// remove current transactions and increase nonce to prepare for a reset and cleanup
statedb.SetNonce(crypto.PubkeyToAddress(remote.PublicKey), 2)
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2)
<-pool.requestReset(nil, nil)

// make sure queue, pending are cleared
pending, queued = pool.Stats()
if pending != 0 {
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
}
if queued != 0 {
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
}
if err := validateTxPoolInternals(pool); err != nil {
t.Fatalf("pool internal state corrupted: %v", err)
}

// Queue gapped transactions
if err := pool.AddLocal(pricedTransaction(4, 100000, big.NewInt(1), local)); err != nil {
t.Fatalf("failed to add remote transaction: %v", err)
}
if err := pool.addRemoteSync(pricedTransaction(4, 100000, big.NewInt(1), remote)); err != nil {
t.Fatalf("failed to add remote transaction: %v", err)
}
time.Sleep(5 * evictionInterval) // A half lifetime pass

// Queue executable transactions, the life cycle should be restarted.
if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil {
t.Fatalf("failed to add remote transaction: %v", err)
}
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), remote)); err != nil {
t.Fatalf("failed to add remote transaction: %v", err)
}
time.Sleep(6 * evictionInterval)

// All gapped transactions shouldn't be kicked out
pending, queued = pool.Stats()
if pending != 2 {
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
}
if queued != 2 {
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3)
}
if err := validateTxPoolInternals(pool); err != nil {
t.Fatalf("pool internal state corrupted: %v", err)
}

// The whole life time pass after last promotion, kick out stale transactions
time.Sleep(2 * config.Lifetime)
pending, queued = pool.Stats()
if pending != 2 {
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
}
if nolocals {
if queued != 0 {
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
}
} else {
if queued != 1 {
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
}
}
if err := validateTxPoolInternals(pool); err != nil {
t.Fatalf("pool internal state corrupted: %v", err)
}
}

// Tests that even if the transaction count belonging to a single account goes
Expand Down
11 changes: 11 additions & 0 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ func rlpHash(x interface{}) (h common.Hash) {
return h
}

// EmptyBody returns true if there is no additional 'body' to complete the header
// that is: no transactions and no uncles.
func (h *Header) EmptyBody() bool {
return h.TxHash == EmptyRootHash && h.UncleHash == EmptyUncleHash
}

// EmptyReceipts returns true if there are no receipts for this header/block.
func (h *Header) EmptyReceipts() bool {
return h.ReceiptHash == EmptyRootHash
}

// Body is a simple (mutable, non-safe) data container for storing and moving
// a block's data contents (transactions and uncles) together.
type Body struct {
Expand Down
18 changes: 8 additions & 10 deletions core/types/gen_log_json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions core/types/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ type Log struct {
// hash of the transaction
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
// index of the transaction in the block
TxIndex uint `json:"transactionIndex" gencodec:"required"`
TxIndex uint `json:"transactionIndex"`
// hash of the block in which the transaction was included
BlockHash common.Hash `json:"blockHash"`
// index of the log in the block
Index uint `json:"logIndex" gencodec:"required"`
Index uint `json:"logIndex"`

// The Removed field is true if this log was reverted due to a chain reorganisation.
// You must pay attention to this field if you receive logs through a filter query.
Expand Down
Loading