Test the DUP1-DUP16 opcodes.
note: Test case ported from:
- [ethereum/tests/GeneralStateTests/VMTests/vmTests/dup.json](https://github.com/ethereum/tests/blob/develop/GeneralStateTests/VMTests/vmTests/dup.json)
by Ori Pomerantz.
Source code in tests/frontier/opcodes/test_dup.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 | def test_dup(state_test: StateTestFiller, fork: str):
"""
Test the DUP1-DUP16 opcodes.
note: Test case ported from:
- [ethereum/tests/GeneralStateTests/VMTests/vmTests/dup.json](https://github.com/ethereum/tests/blob/develop/GeneralStateTests/VMTests/vmTests/dup.json)
by Ori Pomerantz.
""" # noqa: E501
env = Environment()
pre = {"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": Account(balance=1000000000000000000000)}
txs = []
post = {}
"""
We are setting up 16 accounts, ranging from 0x100 to 0x10f.
They push values into the stack from 0-16, but each contract uses a
different DUP opcode, and depending on the opcode used, the item copied
into the storage changes.
"""
for i in range(0, 16):
"""
Account 0x100 uses DUP1,
Account 0x10f uses DUP16.
"""
account = to_address(0x100 + i)
dup_opcode = 0x80 + i
pre[account] = Account(
code=(
# Push 0 - 16 onto the stack
"""0x6000 6001 6002 6003 6004 6005 6006 6007 6008 6009
600A 600B 600C 600D 600E 600F 6010"""
+
# Use the DUP opcode for this account
hex(dup_opcode)[2:]
+
# Save each stack value into different keys in storage
"""6000 55 6001 55 6002 55 6003 55 6004 55 6005 55
6006 55 6007 55 6008 55 6009 55 600A 55 600B 55
600C 55 600D 55 600E 55 600F 55 6010 55"""
)
)
"""
Also we are sending one transaction to each account.
The storage of each will only change by one item: storage[0]
The value depends on the DUP opcode used.
"""
tx = Transaction(
ty=0x0,
nonce=i,
to=account,
gas_limit=500000,
gas_price=10,
protected=False if fork in [Frontier, Homestead] else True,
data="",
)
txs.append(tx)
"""
Storage will be structured as follows:
0x00: 0x10-0x01 (Depending on DUP opcode)
0x01: 0x10
0x02: 0x0F
0x03: 0x0E
0x04: 0x0D
0x05: 0x0C
0x06: 0x0B
0x07: 0x0A
0x08: 0x09
0x09: 0x08
0x0A: 0x07
0x0B: 0x06
0x0C: 0x05
0x0D: 0x04
0x0E: 0x03
0x0F: 0x02
0x10: 0x01
DUP1 copies the first element of the stack (0x10).
DUP16 copies the 16th element of the stack (0x01).
"""
s: Storage.StorageDictType = dict(zip(range(1, 17), range(16, 0, -1)))
s[0] = 16 - i
post[account] = Account(storage=s)
state_test(env=env, pre=pre, post=post, txs=txs)
|