good morning!!!!
Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
B
bor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Harbor Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
open
bor
Commits
430f69e0
Unverified
Commit
430f69e0
authored
Mar 2, 2021
by
Péter Szilágyi
Browse files
Options
Downloads
Patches
Plain Diff
core/vm/runtime: more unshipping
parent
7834e4a2
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
core/vm/runtime/runtime_test.go
+2
-223
2 additions, 223 deletions
core/vm/runtime/runtime_test.go
with
2 additions
and
223 deletions
core/vm/runtime/runtime_test.go
+
2
−
223
View file @
430f69e0
...
...
@@ -330,14 +330,14 @@ func (s *stepCounter) CaptureStart(from common.Address, to common.Address, creat
return
nil
}
func
(
s
*
stepCounter
)
CaptureState
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
rStack
*
vm
.
ReturnStack
,
rData
[]
byte
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
func
(
s
*
stepCounter
)
CaptureState
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
rData
[]
byte
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
s
.
steps
++
// Enable this for more output
//s.inner.CaptureState(env, pc, op, gas, cost, memory, stack, rStack, contract, depth, err)
return
nil
}
func
(
s
*
stepCounter
)
CaptureFault
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
rStack
*
vm
.
ReturnStack
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
func
(
s
*
stepCounter
)
CaptureFault
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
memory
*
vm
.
Memory
,
stack
*
vm
.
Stack
,
contract
*
vm
.
Contract
,
depth
int
,
err
error
)
error
{
return
nil
}
...
...
@@ -345,227 +345,6 @@ func (s *stepCounter) CaptureEnd(output []byte, gasUsed uint64, t time.Duration,
return
nil
}
func
TestJumpSub1024Limit
(
t
*
testing
.
T
)
{
state
,
_
:=
state
.
New
(
common
.
Hash
{},
state
.
NewDatabase
(
rawdb
.
NewMemoryDatabase
()),
nil
)
address
:=
common
.
HexToAddress
(
"0x0a"
)
// Code is
// 0 beginsub
// 1 push 0
// 3 jumpsub
//
// The code recursively calls itself. It should error when the returns-stack
// grows above 1023
state
.
SetCode
(
address
,
[]
byte
{
byte
(
vm
.
PUSH1
),
3
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
PUSH1
),
3
,
byte
(
vm
.
JUMPSUB
),
})
tracer
:=
stepCounter
{
inner
:
vm
.
NewJSONLogger
(
nil
,
os
.
Stdout
)}
// Enable 2315
_
,
_
,
err
:=
Call
(
address
,
nil
,
&
Config
{
State
:
state
,
GasLimit
:
20000
,
ChainConfig
:
params
.
AllEthashProtocolChanges
,
EVMConfig
:
vm
.
Config
{
ExtraEips
:
[]
int
{
2315
},
Debug
:
true
,
//Tracer: vm.NewJSONLogger(nil, os.Stdout),
Tracer
:
&
tracer
,
}})
exp
:=
"return stack limit reached"
if
err
.
Error
()
!=
exp
{
t
.
Fatalf
(
"expected %v, got %v"
,
exp
,
err
)
}
if
exp
,
got
:=
2048
,
tracer
.
steps
;
exp
!=
got
{
t
.
Fatalf
(
"expected %d steps, got %d"
,
exp
,
got
)
}
}
func
TestReturnSubShallow
(
t
*
testing
.
T
)
{
state
,
_
:=
state
.
New
(
common
.
Hash
{},
state
.
NewDatabase
(
rawdb
.
NewMemoryDatabase
()),
nil
)
address
:=
common
.
HexToAddress
(
"0x0a"
)
// The code does returnsub without having anything on the returnstack.
// It should not panic, but just fail after one step
state
.
SetCode
(
address
,
[]
byte
{
byte
(
vm
.
PUSH1
),
5
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
PC
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
PC
),
})
tracer
:=
stepCounter
{}
// Enable 2315
_
,
_
,
err
:=
Call
(
address
,
nil
,
&
Config
{
State
:
state
,
GasLimit
:
10000
,
ChainConfig
:
params
.
AllEthashProtocolChanges
,
EVMConfig
:
vm
.
Config
{
ExtraEips
:
[]
int
{
2315
},
Debug
:
true
,
Tracer
:
&
tracer
,
}})
exp
:=
"invalid retsub"
if
err
.
Error
()
!=
exp
{
t
.
Fatalf
(
"expected %v, got %v"
,
exp
,
err
)
}
if
exp
,
got
:=
4
,
tracer
.
steps
;
exp
!=
got
{
t
.
Fatalf
(
"expected %d steps, got %d"
,
exp
,
got
)
}
}
// disabled -- only used for generating markdown
func
DisabledTestReturnCases
(
t
*
testing
.
T
)
{
cfg
:=
&
Config
{
EVMConfig
:
vm
.
Config
{
Debug
:
true
,
Tracer
:
vm
.
NewMarkdownLogger
(
nil
,
os
.
Stdout
),
ExtraEips
:
[]
int
{
2315
},
},
}
// This should fail at first opcode
Execute
([]
byte
{
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
PC
),
byte
(
vm
.
PC
),
},
nil
,
cfg
)
// Should also fail
Execute
([]
byte
{
byte
(
vm
.
PUSH1
),
5
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
PC
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
PC
),
},
nil
,
cfg
)
// This should complete
Execute
([]
byte
{
byte
(
vm
.
PUSH1
),
0x4
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
STOP
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
PUSH1
),
0x9
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
},
nil
,
cfg
)
}
// DisabledTestEipExampleCases contains various testcases that are used for the
// EIP examples
// This test is disabled, as it's only used for generating markdown
func
DisabledTestEipExampleCases
(
t
*
testing
.
T
)
{
cfg
:=
&
Config
{
EVMConfig
:
vm
.
Config
{
Debug
:
true
,
Tracer
:
vm
.
NewMarkdownLogger
(
nil
,
os
.
Stdout
),
ExtraEips
:
[]
int
{
2315
},
},
}
prettyPrint
:=
func
(
comment
string
,
code
[]
byte
)
{
instrs
:=
make
([]
string
,
0
)
it
:=
asm
.
NewInstructionIterator
(
code
)
for
it
.
Next
()
{
if
it
.
Arg
()
!=
nil
&&
0
<
len
(
it
.
Arg
())
{
instrs
=
append
(
instrs
,
fmt
.
Sprintf
(
"%v 0x%x"
,
it
.
Op
(),
it
.
Arg
()))
}
else
{
instrs
=
append
(
instrs
,
fmt
.
Sprintf
(
"%v"
,
it
.
Op
()))
}
}
ops
:=
strings
.
Join
(
instrs
,
", "
)
fmt
.
Printf
(
"%v
\n
Bytecode: `0x%x` (`%v`)
\n
"
,
comment
,
code
,
ops
)
Execute
(
code
,
nil
,
cfg
)
}
{
// First eip testcase
code
:=
[]
byte
{
byte
(
vm
.
PUSH1
),
4
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
STOP
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
}
prettyPrint
(
"This should jump into a subroutine, back out and stop."
,
code
)
}
{
code
:=
[]
byte
{
byte
(
vm
.
PUSH9
),
0x00
,
0x00
,
0x00
,
0x00
,
0x0
,
0x00
,
0x00
,
0x00
,
4
+
8
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
STOP
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
PUSH1
),
8
+
9
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
}
prettyPrint
(
"This should execute fine, going into one two depths of subroutines"
,
code
)
}
// TODO(@holiman) move this test into an actual test, which not only prints
// out the trace.
{
code
:=
[]
byte
{
byte
(
vm
.
PUSH9
),
0x01
,
0x00
,
0x00
,
0x00
,
0x0
,
0x00
,
0x00
,
0x00
,
4
+
8
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
STOP
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
PUSH1
),
8
+
9
,
byte
(
vm
.
JUMPSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
}
prettyPrint
(
"This should fail, since the given location is outside of the "
+
"code-range. The code is the same as previous example, except that the "
+
"pushed location is `0x01000000000000000c` instead of `0x0c`."
,
code
)
}
{
// This should fail at first opcode
code
:=
[]
byte
{
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
PC
),
byte
(
vm
.
PC
),
}
prettyPrint
(
"This should fail at first opcode, due to shallow `return_stack`"
,
code
)
}
{
code
:=
[]
byte
{
byte
(
vm
.
PUSH1
),
5
,
// Jump past the subroutine
byte
(
vm
.
JUMP
),
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
JUMPDEST
),
byte
(
vm
.
PUSH1
),
3
,
// Now invoke the subroutine
byte
(
vm
.
JUMPSUB
),
}
prettyPrint
(
"In this example. the JUMPSUB is on the last byte of code. When the "
+
"subroutine returns, it should hit the 'virtual stop' _after_ the bytecode, "
+
"and not exit with error"
,
code
)
}
{
code
:=
[]
byte
{
byte
(
vm
.
BEGINSUB
),
byte
(
vm
.
RETURNSUB
),
byte
(
vm
.
STOP
),
}
prettyPrint
(
"In this example, the code 'walks' into a subroutine, which is not "
+
"allowed, and causes an error"
,
code
)
}
}
// benchmarkNonModifyingCode benchmarks code, but if the code modifies the
// state, this should not be used, since it does not reset the state between runs.
func
benchmarkNonModifyingCode
(
gas
uint64
,
code
[]
byte
,
name
string
,
b
*
testing
.
B
)
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment