Merge branch 'master' into badger2

This commit is contained in:
andrew 2019-11-07 15:55:57 +01:00
commit 93ff66f900
16 changed files with 196 additions and 117 deletions

View File

@ -25,8 +25,8 @@ import (
"time"
"github.com/docker/docker/pkg/reexec"
"github.com/ledgerwatch/turbo-geth/rpc"
"github.com/ledgerwatch/turbo-geth/internal/cmdtest"
"github.com/ledgerwatch/turbo-geth/rpc"
)
func tmpdir(t *testing.T) string {

View File

@ -5,6 +5,11 @@ import (
"context"
"encoding/binary"
"fmt"
"math/big"
"os"
"os/exec"
"sort"
"github.com/ledgerwatch/bolt"
"github.com/ledgerwatch/turbo-geth/accounts/abi/bind"
"github.com/ledgerwatch/turbo-geth/accounts/abi/bind/backends"
@ -21,10 +26,6 @@ import (
"github.com/ledgerwatch/turbo-geth/params"
"github.com/ledgerwatch/turbo-geth/trie"
"github.com/ledgerwatch/turbo-geth/visual"
"math/big"
"os"
"os/exec"
"sort"
)
func constructCodeMap(tds *state.TrieDbState) (map[common.Hash][]byte, error) {
@ -108,6 +109,92 @@ func keyTape(t *trie.Trie, number int) error {
return nil
}
func stateDatabaseComparison(first *bolt.DB, second *bolt.DB, number int) error {
filename := fmt.Sprintf("changes_%d.dot", number)
f, err := os.Create(filename)
if err != nil {
return err
}
i := 0
visual.StartGraph(f, true)
m := make(map[string]string)
if err := first.View(func(readTx *bolt.Tx) error {
return readTx.ForEach(func(name []byte, b *bolt.Bucket) error {
return b.ForEach(func(k, v []byte) error {
m[fmt.Sprintf("%x_%x", name, k)] = string(v)
return nil
})
})
}); err != nil {
panic(err)
}
if err := second.View(func(readTx *bolt.Tx) error {
return readTx.ForEach(func(name []byte, b *bolt.Bucket) error {
visual.StartCluster(f, i, string(name))
if err := b.ForEach(func(k, v []byte) error {
keyKeyBytes := &trie.Keybytes{
Data: k,
Odd: false,
Terminating: false,
}
valKeyBytes := &trie.Keybytes{
Data: v,
Odd: false,
Terminating: false,
}
val := valKeyBytes.ToHex()
key := keyKeyBytes.ToHex()
if m[fmt.Sprintf("%x_%x", name, k)] != string(v) {
fmt.Fprintf(f, `k_%d -> v_%d`, i, i)
visual.Horizontal(f, key, 0, fmt.Sprintf("k_%d", i), visual.HexIndexColors, visual.HexFontColors, 110)
if len(val) > 0 {
if len(val) > 32 {
shortenedVal := val[:32]
visual.Horizontal(f, shortenedVal, 99999, fmt.Sprintf("v_%d", i), visual.HexIndexColors, visual.HexFontColors, 100)
} else {
visual.Horizontal(f, val, 99999, fmt.Sprintf("v_%d", i), visual.HexIndexColors, visual.HexFontColors, 110)
}
} else {
visual.Circle(f, fmt.Sprintf("v_%d", i), "...", false)
}
} else {
fmt.Fprintf(f, `k_%d -> v_%d`, i, i)
visual.Horizontal(f, key, 0, fmt.Sprintf("k_%d", i), visual.HexIndexColors, visual.HexFontColors, 110)
if len(val) > 0 {
if len(val) > 32 {
shortenedVal := val[:32]
visual.Horizontal(f, shortenedVal, 0, fmt.Sprintf("v_%d", i), visual.HexIndexColors, visual.HexFontColors, 100)
} else {
visual.Horizontal(f, val, 0, fmt.Sprintf("v_%d", i), visual.HexIndexColors, visual.HexFontColors, 110)
}
} else {
visual.Circle(f, fmt.Sprintf("v_%d", i), "...", false)
}
}
i++
return nil
}); err != nil {
return err
}
visual.EndCluster(f)
return nil
})
}); err != nil {
return err
}
visual.EndGraph(f)
if err := f.Close(); err != nil {
return err
}
cmd := exec.Command("dot", "-Tpng:gd", "-O", filename)
if output, err := cmd.CombinedOutput(); err != nil {
fmt.Printf("error: %v, output: %s\n", err, output)
}
return nil
}
func stateDatabaseMap(db *bolt.DB, number int) error {
filename := fmt.Sprintf("state_%d.dot", number)
f, err := os.Create(filename)
@ -214,6 +301,7 @@ func initialState1() error {
return err
}
t := tds.Trie()
snapshotDb := db.MemCopy().DB()
var codeMap map[common.Hash][]byte
if codeMap, err = constructCodeMap(tds); err != nil {
return err
@ -224,6 +312,9 @@ func initialState1() error {
if _, err = statePicture(t, codeMap, 1, 48, false, false, false, false, nil); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 0); err != nil {
return err
}
contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
transactOpts := bind.NewKeyedTransactor(key)
@ -334,34 +425,49 @@ func initialState1() error {
})
// BLOCK 1
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 1); err != nil {
return err
}
if _, err = statePicture(t, codeMap, 2, 48, false, false, false, false, nil); err != nil {
return err
}
// BLOCK 2
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 2); err != nil {
return err
}
if _, err = statePicture(t, codeMap, 3, 48, false, false, false, false, nil); err != nil {
return err
}
// BLOCK 3
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 3); err != nil {
return err
}
if _, err = statePicture(t, codeMap, 4, 48, false, false, false, false, nil); err != nil {
return err
}
@ -373,9 +479,14 @@ func initialState1() error {
}
// BLOCK 4
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[3]}); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 4); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}
@ -384,9 +495,14 @@ func initialState1() error {
}
// BLOCK 5
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[4]}); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 5); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}
@ -395,9 +511,14 @@ func initialState1() error {
}
// BLOCK 6
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[5]}); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 5); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}
@ -409,9 +530,14 @@ func initialState1() error {
}
// BLOCK 7
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[6]}); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 7); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}
@ -422,9 +548,14 @@ func initialState1() error {
tds.SetResolveReads(true)
// BLOCK 8
snapshotDb = db.MemCopy().DB()
if _, err = blockchain.InsertChain(types.Blocks{blocks[7]}); err != nil {
return err
}
if err = stateDatabaseComparison(snapshotDb, dbBolt, 8); err != nil {
return err
}
if codeMap, err = constructCodeMap(tds); err != nil {
return err
}

View File

@ -318,7 +318,7 @@ func compareStorageRanges(sm, smg map[common.Hash]storageEntry) bool {
}
}
}
for k, _ := range smg {
for k := range smg {
if _, ok := sm[k]; !ok {
fmt.Printf("%x not present in sm\n", k)
return false
@ -654,7 +654,7 @@ func bench1() {
}
req_id++
template = `{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock": "0x%x", "toBlock": "0x%x", "address": "0x%x"}],"id":%d}`
for account, _ := range accountSet {
for account := range accountSet {
var logs EthLogs
if err := post(client, turbogeth_url, fmt.Sprintf(template, prevBn, bn, account, req_id), &logs); err != nil {
fmt.Printf("Could not get logs for account %x: %v\n", account, err)

View File

@ -80,12 +80,12 @@ func (dt *DepTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos
func (dt *DepTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error {
if err == nil {
// Merge frame writes with the tx writes
for addr, _ := range dt.accountsWriteSetFrame {
for addr := range dt.accountsWriteSetFrame {
dt.accountsWriteSet[addr] = struct{}{}
}
for addr, smap := range dt.storageWriteSetFrame {
if smap_dest, ok := dt.storageWriteSet[addr]; ok {
for loc, _ := range smap {
for loc := range smap {
smap_dest[loc] = struct{}{}
}
} else {

View File

@ -64,7 +64,7 @@ func feemarket() {
if minFee.Cmp(minimum) < 0 {
minFee.Set(minimum)
}
for _, _ = range block.Transactions() {
for range block.Transactions() {
txCount++
}
fmt.Fprintf(w, "%d,%d\n", blockNum, minFee)

View File

@ -53,6 +53,7 @@ var chaindata = flag.String("chaindata", "chaindata", "path to the chaindata fil
var statefile = flag.String("statefile", "state", "path to the file where the state will be periodically written during the analysis")
var start = flag.Int("start", 0, "number of data points to skip when making a chart")
var window = flag.Int("window", 1024, "size of the window for moving average")
var triesize = flag.Int("triesize", 1024*1024, "maximum number of nodes in the state trie")
func check(e error) {
if e != nil {
@ -1681,7 +1682,7 @@ func main() {
//nakedAccountChart()
//specExecChart1()
if *action == "stateless" {
stateless(*chaindata, *statefile)
stateless(*chaindata, *statefile, *triesize)
}
if *action == "stateless_chart" {
stateless_chart_key_values("/Users/alexeyakhunov/mygit/go-ethereum/st_1/stateless.csv", []int{21, 20, 19, 18}, "breakdown.png", 2800000, 1)

View File

@ -106,8 +106,8 @@ func writeStats(w io.Writer, blockNum uint64, blockProof trie.BlockProof) {
}
*/
func stateless(chaindata string, statefile string) {
//state.MaxTrieCacheGen = 64*1024
func stateless(chaindata string, statefile string, triesize int) {
state.MaxTrieCacheGen = uint32(triesize)
startTime := time.Now()
sigs := make(chan os.Signal, 1)
interruptCh := make(chan bool, 1)
@ -152,6 +152,11 @@ func stateless(chaindata string, statefile string) {
checkRoots(stateDb, db, preRoot, blockNum-1)
}
batch := stateDb.NewBatch()
defer func() {
if _, err = batch.Commit(); err != nil {
fmt.Printf("Failed to commit batch: %v\n", err)
}
}()
tds, err := state.NewTrieDbState(preRoot, batch, blockNum-1)
check(err)
if blockNum > 1 {
@ -288,10 +293,6 @@ func stateless(chaindata string, statefile string) {
default:
}
}
if _, err := batch.Commit(); err != nil {
fmt.Printf("Failed to commit batch: %v\n", err)
return
}
stateDb.Close()
fmt.Printf("Processed %d blocks\n", blockNum)
fmt.Printf("Next time specify -block %d\n", blockNum)

View File

@ -550,10 +550,6 @@ func (tds *TrieDbState) updateTrieRoots(forward bool) ([]common.Hash, error) {
}
for addressHash, m := range b.storageUpdates {
addrHash := addressHash.Hash()
if _, ok := b.deletedHashes[addressHash.Hash()]; ok {
// Deleted contracts will be dealth with later, in the next loop
continue
}
for keyHash, v := range m {
cKey := dbutils.GenerateCompositeTrieKey(addressHash.Hash(), keyHash)
@ -592,6 +588,7 @@ func (tds *TrieDbState) updateTrieRoots(forward bool) ([]common.Hash, error) {
ok, root := tds.t.DeepHash(addrHash[:])
if ok {
account.Root = root
//fmt.Printf("(b)Set %x root for addrHash %x\n", root, addrHash)
} else {
//fmt.Printf("(b)Set empty root for addrHash %x\n", addrHash)
account.Root = trie.EmptyRoot
@ -601,6 +598,7 @@ func (tds *TrieDbState) updateTrieRoots(forward bool) ([]common.Hash, error) {
ok, root := tds.t.DeepHash(addrHash[:])
if ok {
account.Root = root
//fmt.Printf("Set %x root for addrHash %x\n", root, addrHash)
} else {
//fmt.Printf("Set empty root for addrHash %x\n", addrHash)
account.Root = trie.EmptyRoot
@ -632,14 +630,27 @@ func (tds *TrieDbState) updateTrieRoots(forward bool) ([]common.Hash, error) {
}
// For the contracts that got deleted
for address := range b.deleted {
if _, ok := b.created[address]; ok {
// In some rather artificial circumstances, an account can be recreated after having been self-destructed
// in the same block. It can only happen when contract is introduced in the genesis state with nonce 0
// rather than created by a transaction (in that case, its starting nonce is 1). The self-destructed
// contract actually gets removed from the state only at the end of the block, so if its nonce is not 0,
// it will prevent any re-creation within the same block. However, if the contract is introduced in
// the genesis state, its nonce is 0, and that means it can be self-destructed, and then re-created,
// all in the same block. In such cases, we must preserve storage modifications happening after the
// self-destruction
continue
}
addrHash, err := tds.HashAddress(address, false /*save*/)
if err != nil {
return nil, err
}
if account, ok := b.accountUpdates[addrHash]; ok && account != nil {
//fmt.Printf("(b)Set empty root for addrHash %x due to deleted\n", addrHash)
account.Root = trie.EmptyRoot
}
if account, ok := accountUpdates[addrHash]; ok && account != nil {
//fmt.Printf("Set empty root for addrHash %x due to deleted\n", addrHash)
account.Root = trie.EmptyRoot
}
tds.t.DeleteSubtree(addrHash[:], tds.blockNr)
@ -1052,12 +1063,6 @@ func (tsw *TrieStateWriter) UpdateAccountData(_ context.Context, address common.
}
tsw.tds.currentBuffer.accountUpdates[addrHash] = account
// TODO [Alexey] Are these lines below still required?
addrHashWithInc := newAddressHashWithIncarnation(addrHash, account.GetIncarnation())
if _, ok := tsw.tds.currentBuffer.storageUpdates[addrHashWithInc]; !ok && account.GetIncarnation() > 0 {
tsw.tds.currentBuffer.storageUpdates[addrHashWithInc] = map[common.Hash][]byte{}
}
return nil
}
@ -1097,6 +1102,7 @@ func (tsw *TrieStateWriter) DeleteAccount(_ context.Context, address common.Addr
return err
}
tsw.tds.currentBuffer.accountUpdates[addrHash] = nil
delete(tsw.tds.currentBuffer.storageUpdates, newAddressHashWithIncarnation(addrHash, original.GetIncarnation()))
tsw.tds.currentBuffer.deleted[address] = struct{}{}
return nil
}

View File

@ -676,55 +676,6 @@ func (sdb *IntraBlockState) CreateAccount(addr common.Address, checkPrev bool) {
newObj.created = true
}
// Copy creates a deep, independent copy of the state.
// Snapshots of the copied state cannot be applied to the copy.
func (sdb *IntraBlockState) Copy() *IntraBlockState {
// Copy all the basic fields, initialize the memory ones
state := &IntraBlockState{
stateReader: sdb.stateReader,
stateObjects: make(map[common.Address]*stateObject, len(sdb.journal.dirties)),
stateObjectsDirty: make(map[common.Address]struct{}, len(sdb.journal.dirties)),
nilAccounts: make(map[common.Address]struct{}),
refund: sdb.refund,
logs: make(map[common.Hash][]*types.Log, len(sdb.logs)),
logSize: sdb.logSize,
preimages: make(map[common.Hash][]byte, len(sdb.preimages)),
journal: newJournal(),
}
// Copy the dirty states, logs, and preimages
for addr := range sdb.journal.dirties {
// As documented [here](https://github.com/ledgerwatch/turbo-geth/pull/16485#issuecomment-380438527),
// and in the FinalizeTx method, there is a case where an object is in the journal but not
// in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for
// nil
if object, exist := sdb.stateObjects[addr]; exist {
state.stateObjects[addr] = object.deepCopy(state)
state.stateObjectsDirty[addr] = struct{}{}
}
}
// Above, we don't copy the actual journal. This means that if the copy is copied, the
// loop above will be a no-op, since the copy's journal is empty.
// Thus, here we iterate over stateObjects, to enable copies of copies
for addr := range sdb.stateObjectsDirty {
if _, exist := state.stateObjects[addr]; !exist {
state.stateObjects[addr] = sdb.stateObjects[addr].deepCopy(state)
state.stateObjectsDirty[addr] = struct{}{}
}
}
for hash, logs := range sdb.logs {
cpy := make([]*types.Log, len(logs))
for i, l := range logs {
cpy[i] = new(types.Log)
*cpy[i] = *l
}
state.logs[hash] = cpy
}
for hash, preimage := range sdb.preimages {
state.preimages[hash] = preimage
}
return state
}
// Snapshot returns an identifier for the current revision of the state.
func (sdb *IntraBlockState) Snapshot() int {
id := sdb.nextRevisionID

View File

@ -476,24 +476,6 @@ func (s *StateSuite) TestTouchDelete(c *check.C) {
}
}
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
// See https://github.com/ledgerwatch/turbo-geth/pull/15225#issuecomment-380191512
func TestCopyOfCopy(t *testing.T) {
db := ethdb.NewMemDatabase()
sdbTds, _ := NewTrieDbState(common.Hash{}, db, 0)
sdb := New(sdbTds)
sdbTds.StartNewBuffer()
addr := common.HexToAddress("aaaa")
sdb.SetBalance(addr, big.NewInt(42))
if got := sdb.Copy().GetBalance(addr).Uint64(); got != 42 {
t.Fatalf("1st copy fail, expected 42, got %v", got)
}
if got := sdb.Copy().Copy().GetBalance(addr).Uint64(); got != 42 {
t.Fatalf("2nd copy fail, expected 42, got %v", got)
}
}
func TestIntraBlockStateNewEmptyAccount(t *testing.T) {
db := ethdb.NewMemDatabase()
tds, _ := NewTrieDbState(common.Hash{}, db, 0)

View File

@ -33,9 +33,9 @@ type txNoncer struct {
}
// newTxNoncer creates a new virtual state database to track the pool nonces.
func newTxNoncer(statedb *state.IntraBlockState) *txNoncer {
func newTxNoncer(fallback *state.IntraBlockState) *txNoncer {
return &txNoncer{
fallback: statedb.Copy(),
fallback: fallback,
nonces: make(map[common.Address]uint64),
}
}

View File

@ -80,10 +80,9 @@ type txTraceResult struct {
// being traced.
type blockTraceTask struct {
tds *state.TrieDbState
statedb *state.IntraBlockState // Intermediate state prepped for tracing
block *types.Block // Block to trace the transactions from
rootref common.Hash // Trie root reference held for this task
results []*txTraceResult // Trace results procudes by the task
block *types.Block // Block to trace the transactions from
rootref common.Hash // Trie root reference held for this task
results []*txTraceResult // Trace results procudes by the task
}
// blockTraceResult represets the results of tracing a single block when an entire
@ -210,14 +209,16 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
msg, _ := tx.AsMessage(signer)
vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain, nil)
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
statedb := state.New(task.tds)
res, err := api.traceTx(ctx, msg, vmctx, statedb, config)
if err != nil {
task.results[i] = &txTraceResult{Error: err.Error()}
log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err)
break
}
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
_ = task.statedb.FinalizeTx(api.eth.blockchain.Config().WithEIPsFlags(context.Background(), task.block.Number()), task.tds.TrieStateWriter())
_ = statedb.FinalizeTx(api.eth.blockchain.Config().WithEIPsFlags(context.Background(), task.block.Number()), task.tds.TrieStateWriter())
task.results[i] = &txTraceResult{Result: res}
}
// Stream the result back to the user or abort on teardown
@ -283,7 +284,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
txs := block.Transactions()
select {
case tasks <- &blockTraceTask{statedb: statedb.Copy(), tds: tds.Copy(), block: block, rootref: proot, results: make([]*txTraceResult, len(txs))}:
case tasks <- &blockTraceTask{tds: tds.Copy(), block: block, rootref: proot, results: make([]*txTraceResult, len(txs))}:
case <-notifier.Closed():
return
}
@ -475,7 +476,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
var failed error
for i, tx := range txs {
// Send the trace task over for execution
jobs <- &txTraceTask{statedb: statedb.Copy(), index: i}
jobs <- &txTraceTask{statedb: state.New(dbstate), index: i}
// Generate the next state snapshot fast without tracing
msg, _ := tx.AsMessage(signer)

View File

@ -18,6 +18,8 @@ package ethdb
// IdealBatchSize defines the size of the data batches should ideally add in one
// write.
import "github.com/ledgerwatch/bolt"
const IdealBatchSize = 100 * 1024
// Putter wraps the database write operations.
@ -70,6 +72,7 @@ type Database interface {
Size() int
Keys() ([][]byte, error)
MemCopy() Database
DB() *bolt.DB
// [TURBO-GETH] Freezer support (minimum amount that is actually used)
// FIXME: implement support if needed
Ancients() (uint64, error)

View File

@ -3,12 +3,12 @@ package ethdb
import (
"bytes"
"errors"
"sync"
"github.com/ledgerwatch/bolt"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/common/dbutils"
"github.com/ledgerwatch/turbo-geth/log"
"github.com/petar/GoLLRB/llrb"
"sync"
)
type PutItem struct {
@ -461,3 +461,8 @@ func (m *mutation) Ancients() (uint64, error) {
func (m *mutation) TruncateAncients(items uint64) error {
return errNotSupported
}
// Get bolt database instance
func (m *mutation) DB() *bolt.DB {
return m.db.DB()
}

View File

@ -255,7 +255,9 @@ func (w *worker) pending() (*types.Block, *state.IntraBlockState, *state.TrieDbS
if w.snapshotState == nil {
return nil, nil, nil
}
return w.snapshotBlock, w.snapshotState.Copy(), w.snapshotTds.Copy()
// FIXME: fix miner code
// https://github.com/ledgerwatch/turbo-geth/issues/131
return w.snapshotBlock, w.snapshotState, w.snapshotTds.Copy()
}
// pendingBlock returns pending block.
@ -703,7 +705,9 @@ func (w *worker) updateSnapshot() {
w.current.receipts,
)
w.snapshotState = w.current.state.Copy()
// FIXME: fix miner code
// https://github.com/ledgerwatch/turbo-geth/issues/131
w.snapshotState = w.current.state
}
func (w *worker) commitTransaction(tx *types.Transaction, coinbase common.Address) ([]*types.Log, error) {
@ -973,7 +977,9 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
receipts[i] = new(types.Receipt)
*receipts[i] = *l
}
s := w.current.state.Copy()
// FIXME: fix miner code
// https://github.com/ledgerwatch/turbo-geth/issues/131
s := w.current.state
tds := w.current.tds.Copy()
block, err := w.engine.FinalizeAndAssemble(w.chainConfig, w.current.header, s, w.current.txs, uncles, w.current.receipts)
if err != nil {

View File

@ -44,14 +44,6 @@ func TestBlockchain(t *testing.T) {
// using 4.6 TGas
bt.skipLoad(`.*randomStatetest94.json.*`)
bt.fails(`^TestBlockchain/ValidBlocks/bcStateTests/suicideStorageCheckVCreate2.json/suicideStorageCheckVCreate2_Constantinople`, "not fixed yet")
bt.fails(`^TestBlockchain/ValidBlocks/bcStateTests/suicideStorageCheckVCreate2.json/suicideStorageCheckVCreate2_ConstantinopleFix`, "not fixed yet")
bt.fails(`^TestBlockchain/ValidBlocks/bcStateTests/suicideStorageCheckVCreate2.json/suicideStorageCheckVCreate2_Istanbul`, "not fixed yet")
bt.fails(`^TestBlockchain/ValidBlocks/bcStateTests/suicideStorageCheckVCreate.json.*`, "not fixed yet")
bt.fails(`^TestBlockchain/ValidBlocks/bcStateTests/suicideStorageCheck.json.*`, "not fixed yet")
bt.fails(`(?m)^TestBlockchain/TransitionTests/bcFrontierToHomestead/blockChainFrontierWithLargerTDvsHomesteadBlockchain2.json`, "Work in progress")
bt.fails(`(?m)^TestBlockchain/TransitionTests/bcFrontierToHomestead/blockChainFrontierWithLargerTDvsHomesteadBlockchain.json`, "Work in progress")