Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
335abdce
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
335abdce
编写于
6月 13, 2017
作者:
P
Péter Szilágyi
提交者:
GitHub
6月 13, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #14581 from holiman/byte_opt
core/vm: improve opByte
上级
73227309
ac986579
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
174 addition
and
8 deletion
+174
-8
common/math/big.go
common/math/big.go
+28
-0
common/math/big_test.go
common/math/big_test.go
+98
-1
core/vm/instructions.go
core/vm/instructions.go
+6
-7
core/vm/instructions_test.go
core/vm/instructions_test.go
+42
-0
未找到文件。
common/math/big.go
浏览文件 @
335abdce
...
...
@@ -130,6 +130,34 @@ func PaddedBigBytes(bigint *big.Int, n int) []byte {
return
ret
}
// bigEndianByteAt returns the byte at position n,
// in Big-Endian encoding
// So n==0 returns the least significant byte
func
bigEndianByteAt
(
bigint
*
big
.
Int
,
n
int
)
byte
{
words
:=
bigint
.
Bits
()
// Check word-bucket the byte will reside in
i
:=
n
/
wordBytes
if
i
>=
len
(
words
)
{
return
byte
(
0
)
}
word
:=
words
[
i
]
// Offset of the byte
shift
:=
8
*
uint
(
n
%
wordBytes
)
return
byte
(
word
>>
shift
)
}
// Byte returns the byte at position n,
// with the supplied padlength in Little-Endian encoding.
// n==0 returns the MSB
// Example: bigint '5', padlength 32, n=31 => 5
func
Byte
(
bigint
*
big
.
Int
,
padlength
,
n
int
)
byte
{
if
n
>=
padlength
{
return
byte
(
0
)
}
return
bigEndianByteAt
(
bigint
,
padlength
-
1
-
n
)
}
// ReadBits encodes the absolute value of bigint as big-endian bytes. Callers must ensure
// that buf has enough space. If buf is too short the result will be incomplete.
func
ReadBits
(
bigint
*
big
.
Int
,
buf
[]
byte
)
{
...
...
common/math/big_test.go
浏览文件 @
335abdce
...
...
@@ -21,6 +21,8 @@ import (
"encoding/hex"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
)
func
TestHexOrDecimal256
(
t
*
testing
.
T
)
{
...
...
@@ -133,8 +135,44 @@ func TestPaddedBigBytes(t *testing.T) {
}
}
func
BenchmarkPaddedBigBytes
(
b
*
testing
.
B
)
{
func
BenchmarkPaddedBigBytes
LargePadding
(
b
*
testing
.
B
)
{
bigint
:=
MustParseBig256
(
"123456789123456789123456789123456789"
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
PaddedBigBytes
(
bigint
,
200
)
}
}
func
BenchmarkPaddedBigBytesSmallPadding
(
b
*
testing
.
B
)
{
bigint
:=
MustParseBig256
(
"0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC"
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
PaddedBigBytes
(
bigint
,
5
)
}
}
func
BenchmarkPaddedBigBytesSmallOnePadding
(
b
*
testing
.
B
)
{
bigint
:=
MustParseBig256
(
"0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC"
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
PaddedBigBytes
(
bigint
,
32
)
}
}
func
BenchmarkByteAtBrandNew
(
b
*
testing
.
B
)
{
bigint
:=
MustParseBig256
(
"0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC"
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
bigEndianByteAt
(
bigint
,
15
)
}
}
func
BenchmarkByteAt
(
b
*
testing
.
B
)
{
bigint
:=
MustParseBig256
(
"0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC"
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
bigEndianByteAt
(
bigint
,
15
)
}
}
func
BenchmarkByteAtOld
(
b
*
testing
.
B
)
{
bigint
:=
MustParseBig256
(
"0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC"
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
PaddedBigBytes
(
bigint
,
32
)
}
...
...
@@ -174,6 +212,65 @@ func TestU256(t *testing.T) {
}
}
func
TestBigEndianByteAt
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
x
string
y
int
exp
byte
}{
{
"00"
,
0
,
0x00
},
{
"01"
,
1
,
0x00
},
{
"00"
,
1
,
0x00
},
{
"01"
,
0
,
0x01
},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
0
,
0x30
},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
1
,
0x20
},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
31
,
0xAB
},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
32
,
0x00
},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
500
,
0x00
},
}
for
_
,
test
:=
range
tests
{
v
:=
new
(
big
.
Int
)
.
SetBytes
(
common
.
Hex2Bytes
(
test
.
x
))
actual
:=
bigEndianByteAt
(
v
,
test
.
y
)
if
actual
!=
test
.
exp
{
t
.
Fatalf
(
"Expected [%v] %v:th byte to be %v, was %v."
,
test
.
x
,
test
.
y
,
test
.
exp
,
actual
)
}
}
}
func
TestLittleEndianByteAt
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
x
string
y
int
exp
byte
}{
{
"00"
,
0
,
0x00
},
{
"01"
,
1
,
0x00
},
{
"00"
,
1
,
0x00
},
{
"01"
,
0
,
0x00
},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
0
,
0x00
},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
1
,
0x00
},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
31
,
0x00
},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
32
,
0x00
},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
0
,
0xAB
},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
1
,
0xCD
},
{
"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
,
0
,
0x00
},
{
"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
,
1
,
0xCD
},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
31
,
0x30
},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
30
,
0x20
},
{
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
,
32
,
0x0
},
{
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
,
31
,
0xFF
},
{
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
,
0xFFFF
,
0x0
},
}
for
_
,
test
:=
range
tests
{
v
:=
new
(
big
.
Int
)
.
SetBytes
(
common
.
Hex2Bytes
(
test
.
x
))
actual
:=
Byte
(
v
,
32
,
test
.
y
)
if
actual
!=
test
.
exp
{
t
.
Fatalf
(
"Expected [%v] %v:th byte to be %v, was %v."
,
test
.
x
,
test
.
y
,
test
.
exp
,
actual
)
}
}
}
func
TestS256
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
x
,
y
*
big
.
Int
}{
{
x
:
big
.
NewInt
(
0
),
y
:
big
.
NewInt
(
0
)},
...
...
core/vm/instructions.go
浏览文件 @
335abdce
...
...
@@ -256,15 +256,14 @@ func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
}
func
opByte
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
th
,
val
:=
stack
.
pop
(),
stack
.
p
op
()
if
th
.
Cmp
(
big
.
NewInt
(
32
)
)
<
0
{
b
yte
:=
evm
.
interpreter
.
intPool
.
get
()
.
SetInt64
(
int64
(
math
.
PaddedBigBytes
(
val
,
32
)[
th
.
Int64
()]
))
stack
.
push
(
byte
)
th
,
val
:=
stack
.
pop
(),
stack
.
p
eek
()
if
th
.
Cmp
(
common
.
Big32
)
<
0
{
b
:=
math
.
Byte
(
val
,
32
,
int
(
th
.
Int64
()
))
val
.
SetUint64
(
uint64
(
b
)
)
}
else
{
stack
.
push
(
new
(
big
.
Int
)
)
val
.
SetUint64
(
0
)
}
evm
.
interpreter
.
intPool
.
put
(
th
,
val
)
evm
.
interpreter
.
intPool
.
put
(
th
)
return
nil
,
nil
}
func
opAddmod
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
...
...
core/vm/instructions_test.go
0 → 100644
浏览文件 @
335abdce
package
vm
import
(
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
)
func
TestByteOp
(
t
*
testing
.
T
)
{
var
(
env
=
NewEVM
(
Context
{},
nil
,
params
.
TestChainConfig
,
Config
{
EnableJit
:
false
,
ForceJit
:
false
})
stack
=
newstack
()
)
tests
:=
[]
struct
{
v
string
th
uint64
expected
*
big
.
Int
}{
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
0
,
big
.
NewInt
(
0xAB
)},
{
"ABCDEF0908070605040302010000000000000000000000000000000000000000"
,
1
,
big
.
NewInt
(
0xCD
)},
{
"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
,
0
,
big
.
NewInt
(
0x00
)},
{
"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff"
,
1
,
big
.
NewInt
(
0xCD
)},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
31
,
big
.
NewInt
(
0x30
)},
{
"0000000000000000000000000000000000000000000000000000000000102030"
,
30
,
big
.
NewInt
(
0x20
)},
{
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
,
32
,
big
.
NewInt
(
0x0
)},
{
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
,
0xFFFFFFFFFFFFFFFF
,
big
.
NewInt
(
0x0
)},
}
pc
:=
uint64
(
0
)
for
_
,
test
:=
range
tests
{
val
:=
new
(
big
.
Int
)
.
SetBytes
(
common
.
Hex2Bytes
(
test
.
v
))
th
:=
new
(
big
.
Int
)
.
SetUint64
(
test
.
th
)
stack
.
push
(
val
)
stack
.
push
(
th
)
opByte
(
&
pc
,
env
,
nil
,
nil
,
stack
)
actual
:=
stack
.
pop
()
if
actual
.
Cmp
(
test
.
expected
)
!=
0
{
t
.
Fatalf
(
"Expected [%v] %v:th byte to be %v, was %v."
,
test
.
v
,
test
.
th
,
test
.
expected
,
actual
)
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录