diff --git a/BUGS.md b/BUGS.md new file mode 100644 index 0000000000..da4e0dc645 --- /dev/null +++ b/BUGS.md @@ -0,0 +1,11 @@ +# BUGS? THERE ARE NO BUGS! + +go test ./tests -count=1 -v -run "^TestBlockchain/ValidBlocks/bcValidBlockTest/SimpleTx3LowS.json$" + + +run tests under tests + +run tests under tests/block_test.go + +### Timeout happens automatically when running large block of tests, this is likely why the UI didnt run all tests, it should be configurable in vscode go config as well +go test ./tests -count=1 -timeout 600m -v 2>&1 | Tee-Object run.log \ No newline at end of file diff --git a/core/state/statedb.go b/core/state/statedb.go index 776a9760f4..6b6d6dbe70 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -763,6 +763,9 @@ func (s *StateDB) MergeParallelChildInto(child *StateDB, txHash common.Hash) { if s.accessEvents != nil && child.accessEvents != nil { s.accessEvents.Merge(child.accessEvents) } + if s.witness != nil { + s.witness.Merge(child.witness) + } for _, addr := range child.parallelMergeAddrs { if op, ok := child.mutations[addr]; ok && op.isDelete() { delete(s.stateObjects, addr) diff --git a/core/state_processor.go b/core/state_processor.go index 698248bb9a..9992a88710 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" ) // StateProcessor is a basic Processor, which takes care of transitioning @@ -114,6 +115,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } txWaveExecStart := time.Now() + for groupIdx, group := range groups { sortedIdx := append([]int(nil), group...) sort.Ints(sortedIdx) @@ -137,6 +139,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg continue } + coinbaseBase := new(uint256.Int).Set(statedb.GetBalance(header.Coinbase)) + coinbaseFinal := new(uint256.Int).Set(coinbaseBase) txForks := make([]*state.StateDB, n) var wg sync.WaitGroup var errMu sync.Mutex @@ -182,8 +186,17 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg return nil, firstErr } for _, i := range sortedIdx { + childCoinbase := txForks[i].GetBalance(header.Coinbase) + if childCoinbase.Cmp(coinbaseBase) >= 0 { + coinbaseFinal.Add(coinbaseFinal, new(uint256.Int).Sub(childCoinbase, coinbaseBase)) + } else { + coinbaseFinal.Sub(coinbaseFinal, new(uint256.Int).Sub(coinbaseBase, childCoinbase)) + } statedb.MergeParallelChildInto(txForks[i], txs[i].Hash()) } + // ponytail: Coinbase balance deltas are additive; dynamic reads + // conflicts still require observed read/write sets and speculative re-execution and are not handled. + statedb.SetBalance(header.Coinbase, coinbaseFinal, tracing.BalanceIncreaseRewardTransactionFee) if err := statedb.Error(); err != nil { return nil, err } diff --git a/core/stateless/witness.go b/core/stateless/witness.go index aecfad1d52..c4b0ca8c24 100644 --- a/core/stateless/witness.go +++ b/core/stateless/witness.go @@ -113,6 +113,22 @@ func (w *Witness) Copy() *Witness { return cpy } +// Merge adds everything collected by another witness. +// This operates under the assumption that the transactions are truly independent +func (w *Witness) Merge(other *Witness) { + if other == nil { + return + } + w.lock.Lock() + defer w.lock.Unlock() + + if len(other.Headers) > len(w.Headers) { + w.Headers = slices.Clone(other.Headers) + } + maps.Copy(w.Codes, other.Codes) + maps.Copy(w.State, other.State) +} + // Root returns the pre-state root from the first header. // // Note, this method will panic in case of a bad witness (but RLP decoding will