Skip to content

Commit 63d2422

Browse files
committed
core/vm: speed up push and interpreter loop
1 parent f8f5609 commit 63d2422

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

core/vm/instructions.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -984,13 +984,13 @@ func makePush(size uint64, pushByteSize int) executionFunc {
984984
start = min(codeLen, int(*pc+1))
985985
end = min(codeLen, start+pushByteSize)
986986
)
987-
scope.Stack.push(new(uint256.Int).SetBytes(
988-
common.RightPadBytes(
989-
scope.Contract.Code[start:end],
990-
pushByteSize,
991-
)),
992-
)
987+
a := new(uint256.Int).SetBytes(scope.Contract.Code[start:end])
993988

989+
// Missing bytes: pushByteSize - len(pushData)
990+
if missing := pushByteSize - (end - start); missing > 0 {
991+
a.Lsh(a, uint(8*missing))
992+
}
993+
scope.Stack.push(a)
994994
*pc += size
995995
return nil, nil
996996
}

core/vm/instructions_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,3 +927,74 @@ func TestOpMCopy(t *testing.T) {
927927
}
928928
}
929929
}
930+
931+
func TestPush(t *testing.T) {
932+
933+
code := common.FromHex("0011223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121")
934+
935+
push32 := makePush(32, 32)
936+
937+
scope := &ScopeContext{
938+
Memory: nil,
939+
Stack: newstack(),
940+
Contract: &Contract{
941+
Code: code,
942+
},
943+
}
944+
for i, want := range []string{
945+
"0x11223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1",
946+
"0x223344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1",
947+
"0x3344556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1",
948+
"0x44556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1",
949+
"0x556677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1",
950+
"0x6677889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1",
951+
"0x77889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191",
952+
"0x889900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181",
953+
"0x9900aabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171",
954+
"0xaabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161",
955+
"0xaabbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151",
956+
"0xbbccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141",
957+
"0xccddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131",
958+
"0xddeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121",
959+
"0xeeff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100",
960+
"0xff0102030405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000",
961+
"0x102030405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000",
962+
"0x2030405060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000",
963+
"0x30405060708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000",
964+
"0x405060708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000",
965+
"0x5060708090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000",
966+
"0x60708090a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000000000",
967+
"0x708090a0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000000000",
968+
"0x8090a0b0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000000000",
969+
"0x90a0b0c0d0e0ff1e1d1c1b1a191817161514131210000000000000000000000",
970+
"0xa0b0c0d0e0ff1e1d1c1b1a19181716151413121000000000000000000000000",
971+
"0xb0c0d0e0ff1e1d1c1b1a1918171615141312100000000000000000000000000",
972+
"0xc0d0e0ff1e1d1c1b1a191817161514131210000000000000000000000000000",
973+
"0xd0e0ff1e1d1c1b1a19181716151413121000000000000000000000000000000",
974+
"0xe0ff1e1d1c1b1a1918171615141312100000000000000000000000000000000",
975+
"0xff1e1d1c1b1a191817161514131210000000000000000000000000000000000",
976+
"0xf1e1d1c1b1a19181716151413121000000000000000000000000000000000000",
977+
"0xe1d1c1b1a1918171615141312100000000000000000000000000000000000000",
978+
"0xd1c1b1a191817161514131210000000000000000000000000000000000000000",
979+
"0xc1b1a19181716151413121000000000000000000000000000000000000000000",
980+
"0xb1a1918171615141312100000000000000000000000000000000000000000000",
981+
"0xa191817161514131210000000000000000000000000000000000000000000000",
982+
"0x9181716151413121000000000000000000000000000000000000000000000000",
983+
"0x8171615141312100000000000000000000000000000000000000000000000000",
984+
"0x7161514131210000000000000000000000000000000000000000000000000000",
985+
"0x6151413121000000000000000000000000000000000000000000000000000000",
986+
"0x5141312100000000000000000000000000000000000000000000000000000000",
987+
"0x4131210000000000000000000000000000000000000000000000000000000000",
988+
"0x3121000000000000000000000000000000000000000000000000000000000000",
989+
"0x2100000000000000000000000000000000000000000000000000000000000000",
990+
"0x0",
991+
} {
992+
pc := new(uint64)
993+
*pc = uint64(i)
994+
push32(pc, nil, scope)
995+
res := scope.Stack.pop()
996+
if have := res.Hex(); have != want {
997+
t.Fatalf("case %d, have %v want %v", i, have, want)
998+
}
999+
}
1000+
}

core/vm/interpreter.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,11 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
249249
} else if sLen > operation.maxStack {
250250
return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack}
251251
}
252-
if !contract.UseGas(cost, in.evm.Config.Tracer, tracing.GasChangeIgnored) {
252+
// for tracing: this gas consumption is ignored, so can be done in-line
253+
if contract.Gas < cost {
253254
return nil, ErrOutOfGas
255+
} else {
256+
contract.Gas -= cost
254257
}
255258

256259
if operation.dynamicGas != nil {
@@ -279,8 +282,11 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
279282
if err != nil {
280283
return nil, fmt.Errorf("%w: %v", ErrOutOfGas, err)
281284
}
282-
if !contract.UseGas(dynamicCost, in.evm.Config.Tracer, tracing.GasChangeIgnored) {
285+
// for tracing: this gas consumption is ignored, so can be done in-line
286+
if contract.Gas < dynamicCost {
283287
return nil, ErrOutOfGas
288+
} else {
289+
contract.Gas -= dynamicCost
284290
}
285291

286292
// Do tracing before memory expansion

0 commit comments

Comments
 (0)