Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
bc5d742c
Unverified
Commit
bc5d742c
authored
Mar 04, 2020
by
Martin Holst Swende
Committed by
GitHub
Mar 04, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: more blockchain tests
parent
eff7cfbb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
201 additions
and
6 deletions
+201
-6
blockchain_test.go
core/blockchain_test.go
+201
-6
No files found.
core/blockchain_test.go
View file @
bc5d742c
...
...
@@ -2376,11 +2376,9 @@ func TestDeleteRecreateSlots(t *testing.T) {
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
)
aa
=
common
.
HexToAddress
(
"0x7217d81b76bdd8707601e959454e3d776aee5f43"
)
key
,
_
=
crypto
.
HexToECDSA
(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
)
address
=
crypto
.
PubkeyToAddress
(
key
.
PublicKey
)
funds
=
big
.
NewInt
(
1000000000
)
bb
=
common
.
HexToAddress
(
"0x000000000000000000000000000000000000bbbb"
)
aaStorage
=
make
(
map
[
common
.
Hash
]
common
.
Hash
)
// Initial storage in AA
aaCode
=
[]
byte
{
byte
(
vm
.
PC
),
byte
(
vm
.
SELFDESTRUCT
)}
// Code for AA (simple selfdestruct)
...
...
@@ -2403,7 +2401,7 @@ func TestDeleteRecreateSlots(t *testing.T) {
byte
(
vm
.
PUSH1
),
0x4
,
// location
byte
(
vm
.
SSTORE
),
// Set slot[4] = 1
// Slots are set, now return the code
byte
(
vm
.
PUSH2
),
0x88
,
0xff
,
// Push code on stack
byte
(
vm
.
PUSH2
),
byte
(
vm
.
PC
),
byte
(
vm
.
SELFDESTRUCT
)
,
// Push code on stack
byte
(
vm
.
PUSH1
),
0x0
,
// memory start on stack
byte
(
vm
.
MSTORE
),
// Code is now in memory.
...
...
@@ -2428,6 +2426,10 @@ func TestDeleteRecreateSlots(t *testing.T) {
byte
(
vm
.
CREATE2
),
}
...
)
initHash
:=
crypto
.
Keccak256Hash
(
initCode
)
aa
:=
crypto
.
CreateAddress2
(
bb
,
[
32
]
byte
{},
initHash
[
:
])
t
.
Logf
(
"Destination address: %x
\n
"
,
aa
)
gspec
:=
&
Genesis
{
Config
:
params
.
TestChainConfig
,
Alloc
:
GenesisAlloc
{
...
...
@@ -2563,3 +2565,196 @@ func TestDeleteRecreateAccount(t *testing.T) {
t
.
Errorf
(
"got %x exp %x"
,
got
,
exp
)
}
}
// TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
// and recreation of contract state.
// Contract A exists, has slots 1 and 2 set
// Tx 1: Selfdestruct A
// Tx 2: Re-create A, set slots 3 and 4
// Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
// and then the new slots exist
func
TestDeleteRecreateSlotsAcrossManyBlocks
(
t
*
testing
.
T
)
{
var
(
// 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
)
bb
=
common
.
HexToAddress
(
"0x000000000000000000000000000000000000bbbb"
)
aaStorage
=
make
(
map
[
common
.
Hash
]
common
.
Hash
)
// Initial storage in AA
aaCode
=
[]
byte
{
byte
(
vm
.
PC
),
byte
(
vm
.
SELFDESTRUCT
)}
// Code for AA (simple selfdestruct)
)
// Populate two slots
aaStorage
[
common
.
HexToHash
(
"01"
)]
=
common
.
HexToHash
(
"01"
)
aaStorage
[
common
.
HexToHash
(
"02"
)]
=
common
.
HexToHash
(
"02"
)
// The bb-code needs to CREATE2 the aa contract. It consists of
// both initcode and deployment code
// initcode:
// 1. Set slots 3=blocknum+1, 4=4,
// 2. Return aaCode
initCode
:=
[]
byte
{
byte
(
vm
.
PUSH1
),
0x1
,
//
byte
(
vm
.
NUMBER
),
// value = number + 1
byte
(
vm
.
ADD
),
//
byte
(
vm
.
PUSH1
),
0x3
,
// location
byte
(
vm
.
SSTORE
),
// Set slot[3] = number + 1
byte
(
vm
.
PUSH1
),
0x4
,
// value
byte
(
vm
.
PUSH1
),
0x4
,
// location
byte
(
vm
.
SSTORE
),
// Set slot[4] = 4
// Slots are set, now return the code
byte
(
vm
.
PUSH2
),
byte
(
vm
.
PC
),
byte
(
vm
.
SELFDESTRUCT
),
// Push code on stack
byte
(
vm
.
PUSH1
),
0x0
,
// memory start on stack
byte
(
vm
.
MSTORE
),
// Code is now in memory.
byte
(
vm
.
PUSH1
),
0x2
,
// size
byte
(
vm
.
PUSH1
),
byte
(
32
-
2
),
// offset
byte
(
vm
.
RETURN
),
}
if
l
:=
len
(
initCode
);
l
>
32
{
t
.
Fatalf
(
"init code is too long for a pushx, need a more elaborate deployer"
)
}
bbCode
:=
[]
byte
{
// Push initcode onto stack
byte
(
vm
.
PUSH1
)
+
byte
(
len
(
initCode
)
-
1
)}
bbCode
=
append
(
bbCode
,
initCode
...
)
bbCode
=
append
(
bbCode
,
[]
byte
{
byte
(
vm
.
PUSH1
),
0x0
,
// memory start on stack
byte
(
vm
.
MSTORE
),
byte
(
vm
.
PUSH1
),
0x00
,
// salt
byte
(
vm
.
PUSH1
),
byte
(
len
(
initCode
)),
// size
byte
(
vm
.
PUSH1
),
byte
(
32
-
len
(
initCode
)),
// offset
byte
(
vm
.
PUSH1
),
0x00
,
// endowment
byte
(
vm
.
CREATE2
),
}
...
)
initHash
:=
crypto
.
Keccak256Hash
(
initCode
)
aa
:=
crypto
.
CreateAddress2
(
bb
,
[
32
]
byte
{},
initHash
[
:
])
t
.
Logf
(
"Destination address: %x
\n
"
,
aa
)
gspec
:=
&
Genesis
{
Config
:
params
.
TestChainConfig
,
Alloc
:
GenesisAlloc
{
address
:
{
Balance
:
funds
},
// The address 0xAAAAA selfdestructs if called
aa
:
{
// Code needs to just selfdestruct
Code
:
aaCode
,
Nonce
:
1
,
Balance
:
big
.
NewInt
(
0
),
Storage
:
aaStorage
,
},
// The contract BB recreates AA
bb
:
{
Code
:
bbCode
,
Balance
:
big
.
NewInt
(
1
),
},
},
}
genesis
:=
gspec
.
MustCommit
(
db
)
var
nonce
uint64
type
expectation
struct
{
exist
bool
blocknum
int
values
map
[
int
]
int
}
var
current
=
&
expectation
{
exist
:
true
,
// exists in genesis
blocknum
:
0
,
values
:
map
[
int
]
int
{
1
:
1
,
2
:
2
},
}
var
expectations
[]
*
expectation
var
newDestruct
=
func
(
e
*
expectation
)
*
types
.
Transaction
{
tx
,
_
:=
types
.
SignTx
(
types
.
NewTransaction
(
nonce
,
aa
,
big
.
NewInt
(
0
),
50000
,
big
.
NewInt
(
1
),
nil
),
types
.
HomesteadSigner
{},
key
)
nonce
++
if
e
.
exist
{
e
.
exist
=
false
e
.
values
=
nil
}
t
.
Logf
(
"block %d; adding destruct
\n
"
,
e
.
blocknum
)
return
tx
}
var
newResurrect
=
func
(
e
*
expectation
)
*
types
.
Transaction
{
tx
,
_
:=
types
.
SignTx
(
types
.
NewTransaction
(
nonce
,
bb
,
big
.
NewInt
(
0
),
100000
,
big
.
NewInt
(
1
),
nil
),
types
.
HomesteadSigner
{},
key
)
nonce
++
if
!
e
.
exist
{
e
.
exist
=
true
e
.
values
=
map
[
int
]
int
{
3
:
e
.
blocknum
+
1
,
4
:
4
}
}
t
.
Logf
(
"block %d; adding resurrect
\n
"
,
e
.
blocknum
)
return
tx
}
blocks
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
genesis
,
engine
,
db
,
150
,
func
(
i
int
,
b
*
BlockGen
)
{
var
exp
=
new
(
expectation
)
exp
.
blocknum
=
i
+
1
exp
.
values
=
make
(
map
[
int
]
int
)
for
k
,
v
:=
range
current
.
values
{
exp
.
values
[
k
]
=
v
}
exp
.
exist
=
current
.
exist
b
.
SetCoinbase
(
common
.
Address
{
1
})
if
i
%
2
==
0
{
b
.
AddTx
(
newDestruct
(
exp
))
}
if
i
%
3
==
0
{
b
.
AddTx
(
newResurrect
(
exp
))
}
if
i
%
5
==
0
{
b
.
AddTx
(
newDestruct
(
exp
))
}
if
i
%
7
==
0
{
b
.
AddTx
(
newResurrect
(
exp
))
}
expectations
=
append
(
expectations
,
exp
)
current
=
exp
})
// Import the canonical chain
diskdb
:=
rawdb
.
NewMemoryDatabase
()
gspec
.
MustCommit
(
diskdb
)
chain
,
err
:=
NewBlockChain
(
diskdb
,
nil
,
params
.
TestChainConfig
,
engine
,
vm
.
Config
{
//Debug: true,
//Tracer: vm.NewJSONLogger(nil, os.Stdout),
},
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create tester chain: %v"
,
err
)
}
var
asHash
=
func
(
num
int
)
common
.
Hash
{
return
common
.
BytesToHash
([]
byte
{
byte
(
num
)})
}
for
i
,
block
:=
range
blocks
{
blockNum
:=
i
+
1
if
n
,
err
:=
chain
.
InsertChain
([]
*
types
.
Block
{
block
});
err
!=
nil
{
t
.
Fatalf
(
"block %d: failed to insert into chain: %v"
,
n
,
err
)
}
statedb
,
_
:=
chain
.
State
()
// If all is correct, then slot 1 and 2 are zero
if
got
,
exp
:=
statedb
.
GetState
(
aa
,
common
.
HexToHash
(
"01"
)),
(
common
.
Hash
{});
got
!=
exp
{
t
.
Errorf
(
"block %d, got %x exp %x"
,
blockNum
,
got
,
exp
)
}
if
got
,
exp
:=
statedb
.
GetState
(
aa
,
common
.
HexToHash
(
"02"
)),
(
common
.
Hash
{});
got
!=
exp
{
t
.
Errorf
(
"block %d, got %x exp %x"
,
blockNum
,
got
,
exp
)
}
exp
:=
expectations
[
i
]
if
exp
.
exist
{
if
!
statedb
.
Exist
(
aa
)
{
t
.
Fatalf
(
"block %d, expected %v to exist, it did not"
,
blockNum
,
aa
)
}
for
slot
,
val
:=
range
exp
.
values
{
if
gotValue
,
expValue
:=
statedb
.
GetState
(
aa
,
asHash
(
slot
)),
asHash
(
val
);
gotValue
!=
expValue
{
t
.
Fatalf
(
"block %d, slot %d, got %x exp %x"
,
blockNum
,
slot
,
gotValue
,
expValue
)
}
}
}
else
{
if
statedb
.
Exist
(
aa
)
{
t
.
Fatalf
(
"block %d, expected %v to not exist, it did"
,
blockNum
,
aa
)
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment