core: add blockchain test too for revert cornercase
This commit is contained in:
parent
223b950944
commit
f49d6e5ec0
@ -2287,3 +2287,78 @@ func TestSideImportPrunedBlocks(t *testing.T) {
|
|||||||
t.Errorf("Got error, %v", err)
|
t.Errorf("Got error, %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestDeleteCreateRevert tests a weird state transition corner case that we hit
|
||||||
|
// while changing the internals of statedb. The workflow is that a contract is
|
||||||
|
// self destructed, then in a followup transaction (but same block) it's created
|
||||||
|
// again and the transaction reverted.
|
||||||
|
//
|
||||||
|
// The original statedb implementation flushed dirty objects to the tries after
|
||||||
|
// each transaction, so this works ok. The rework accumulated writes in memory
|
||||||
|
// first, but the journal wiped the entire state object on create-revert.
|
||||||
|
func TestDeleteCreateRevert(t *testing.T) {
|
||||||
|
var (
|
||||||
|
aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
|
||||||
|
bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
|
||||||
|
// Generate a canonical chain to act as the main dataset
|
||||||
|
engine = ethash.NewFaker()
|
||||||
|
db = rawdb.NewMemoryDatabase()
|
||||||
|
|
||||||
|
// A sender who makes transactions, has some funds
|
||||||
|
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
funds = big.NewInt(1000000000)
|
||||||
|
gspec = &Genesis{
|
||||||
|
Config: params.TestChainConfig,
|
||||||
|
Alloc: GenesisAlloc{
|
||||||
|
address: {Balance: funds},
|
||||||
|
// The address 0xAAAAA selfdestructs if called
|
||||||
|
aa: {
|
||||||
|
// Code needs to just selfdestruct
|
||||||
|
Code: []byte{byte(vm.PC), 0xFF},
|
||||||
|
Nonce: 1,
|
||||||
|
Balance: big.NewInt(0),
|
||||||
|
},
|
||||||
|
// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
|
||||||
|
bb: {
|
||||||
|
Code: []byte{
|
||||||
|
byte(vm.PC), // [0]
|
||||||
|
byte(vm.DUP1), // [0,0]
|
||||||
|
byte(vm.DUP1), // [0,0,0]
|
||||||
|
byte(vm.DUP1), // [0,0,0,0]
|
||||||
|
byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
|
||||||
|
byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
|
||||||
|
byte(vm.GAS),
|
||||||
|
byte(vm.CALL),
|
||||||
|
byte(vm.REVERT),
|
||||||
|
},
|
||||||
|
Balance: big.NewInt(1),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
genesis = gspec.MustCommit(db)
|
||||||
|
)
|
||||||
|
|
||||||
|
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
|
||||||
|
b.SetCoinbase(common.Address{1})
|
||||||
|
// One transaction to AAAA
|
||||||
|
tx, _ := types.SignTx(types.NewTransaction(0, aa,
|
||||||
|
big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
|
||||||
|
b.AddTx(tx)
|
||||||
|
// One transaction to BBBB
|
||||||
|
tx, _ = types.SignTx(types.NewTransaction(1, bb,
|
||||||
|
big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
|
||||||
|
b.AddTx(tx)
|
||||||
|
})
|
||||||
|
// Import the canonical chain
|
||||||
|
diskdb := rawdb.NewMemoryDatabase()
|
||||||
|
gspec.MustCommit(diskdb)
|
||||||
|
|
||||||
|
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
|
}
|
||||||
|
if n, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user