Skip to content

Commit

Permalink
vm interpreter and instruction fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ucwong committed Oct 30, 2024
1 parent e6e8e3e commit 90d780a
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 9 deletions.
13 changes: 7 additions & 6 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1223,12 +1223,13 @@ func makePush(size uint64, pushByteSize int) executionFunc {
start = min(codeLen, int(*pc+1))
end = min(codeLen, start+pushByteSize)
)
scope.Stack.push(new(uint256.Int).SetBytes(
common.RightPadBytes(
scope.Contract.Code[start:end],
pushByteSize,
)),
)
a := new(uint256.Int).SetBytes(scope.Contract.Code[start:end])

// Missing bytes: pushByteSize - len(pushData)
if missing := pushByteSize - (end - start); missing > 0 {
a.Lsh(a, uint(8*missing))
}
scope.Stack.push(a)
*pc += size
return nil, nil
}
Expand Down
72 changes: 72 additions & 0 deletions core/vm/instructions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,3 +649,75 @@ func TestCreate2Addreses(t *testing.T) {
}
}
}

// TestPush sanity-checks how code with immediates are handled when the code size is
// smaller than the size of the immediate.
func TestPush(t *testing.T) {
code := common.FromHex("0011223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121")

push32 := makePush(32, 32)

scope := &ScopeContext{
Memory: nil,
Stack: newstack(),
Contract: &Contract{
Code: code,
},
}
for i, want := range []string{
"0x11223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1",
"0x223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1",
"0x3344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1",
"0x44556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1",
"0x556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1",
"0x6677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1",
"0x77889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191",
"0x889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181",
"0x9900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171",
"0xaabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161",
"0xaabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151",
"0xbbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141",
"0xccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131",
"0xddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121",
"0xeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100",
"0xff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000",
"0x102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000",
"0x2030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000",
"0x30405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000",
"0x405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000",
"0x5060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000",
"0x60708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000000000",
"0x708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000000000",
"0x8090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000000000",
"0x90a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000000000000000",
"0xa0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000000000000000",
"0xb0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000000000000000",
"0xc0d0e0ff1e1d1c1b1a191817161514131210000000000000000000000000000",
"0xd0e0ff1e1d1c1b1a19181716151413121000000000000000000000000000000",
"0xe0ff1e1d1c1b1a1918171615141312100000000000000000000000000000000",
"0xff1e1d1c1b1a191817161514131210000000000000000000000000000000000",
"0xf1e1d1c1b1a19181716151413121000000000000000000000000000000000000",
"0xe1d1c1b1a1918171615141312100000000000000000000000000000000000000",
"0xd1c1b1a191817161514131210000000000000000000000000000000000000000",
"0xc1b1a19181716151413121000000000000000000000000000000000000000000",
"0xb1a1918171615141312100000000000000000000000000000000000000000000",
"0xa191817161514131210000000000000000000000000000000000000000000000",
"0x9181716151413121000000000000000000000000000000000000000000000000",
"0x8171615141312100000000000000000000000000000000000000000000000000",
"0x7161514131210000000000000000000000000000000000000000000000000000",
"0x6151413121000000000000000000000000000000000000000000000000000000",
"0x5141312100000000000000000000000000000000000000000000000000000000",
"0x4131210000000000000000000000000000000000000000000000000000000000",
"0x3121000000000000000000000000000000000000000000000000000000000000",
"0x2100000000000000000000000000000000000000000000000000000000000000",
"0x0",
} {
pc := new(uint64)
*pc = uint64(i)
push32(pc, nil, scope)
res := scope.Stack.pop()
if have := res.Hex(); have != want {
t.Fatalf("case %d, have %v want %v", i, have, want)
}
}
}
10 changes: 8 additions & 2 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,17 @@ func (in *CVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}
}

if err != nil || !contract.UseGas(cost) {
log.Debug("Interpreter", "cost", cost, "err", err, "cgas", cgas)
if err != nil {
return nil, ErrOutOfGas
}

// for tracing: this gas consumption event is emitted below in the debug section.
if contract.Gas < cost {
return nil, ErrOutOfGas
} else {
contract.Gas -= cost
}

if memorySize > 0 {
mem.Resize(memorySize)
}
Expand Down
2 changes: 1 addition & 1 deletion core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func validate(jt JumpTable) JumpTable {

func newMergeInstructionSet() JumpTable {
instructionSet := newNeoInstructionSet()
instructionSet[RANDOM] = &operation{
instructionSet[PREVRANDAO] = &operation{
execute: opRandom,
gasCost: constGasFunc(GasQuickStep),
validateStack: makeStackFunc(0, 1),
Expand Down
12 changes: 12 additions & 0 deletions core/vm/runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,17 @@ func BenchmarkSimpleLoop(b *testing.B) {
byte(vm.JUMP),
}

loopingCode2 := []byte{
byte(vm.JUMPDEST), // [ count ]
// push args for the call
byte(vm.PUSH4), 1, 2, 3, 4,
byte(vm.PUSH5), 1, 2, 3, 4, 5,

byte(vm.POP), byte(vm.POP),
byte(vm.PUSH6), 0, 0, 0, 0, 0, 0, // jumpdestination
byte(vm.JUMP),
}

calllRevertingContractWithInput := []byte{
byte(vm.JUMPDEST), //
// push args for the call
Expand All @@ -500,6 +511,7 @@ func BenchmarkSimpleLoop(b *testing.B) {
benchmarkNonModifyingCode(100000000, staticCallIdentity, "staticcall-identity-100M", b)
benchmarkNonModifyingCode(100000000, callIdentity, "call-identity-100M", b)
benchmarkNonModifyingCode(100000000, loopingCode, "loop-100M", b)
benchmarkNonModifyingCode(100000000, loopingCode2, "loop2-100M", b)
benchmarkNonModifyingCode(100000000, callInexistant, "call-nonexist-100M", b)
benchmarkNonModifyingCode(100000000, callEOA, "call-EOA-100M", b)
benchmarkNonModifyingCode(100000000, calllRevertingContractWithInput, "call-reverting-100M", b)
Expand Down

0 comments on commit 90d780a

Please sign in to comment.