contracts_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package vm
  17. import (
  18. "bytes"
  19. "encoding/json"
  20. "fmt"
  21. "io/ioutil"
  22. "math/big"
  23. "testing"
  24. "github.com/ethereum/go-ethereum/common"
  25. )
  26. // precompiledTest defines the input/output pairs for precompiled contract tests.
  27. type precompiledTest struct {
  28. Input, Expected string
  29. Name string
  30. NoBenchmark bool // Benchmark primarily the worst-cases
  31. }
  32. // precompiledFailureTest defines the input/error pairs for precompiled
  33. // contract failure tests.
  34. type precompiledFailureTest struct {
  35. Input string
  36. ExpectedError string
  37. Name string
  38. }
  39. var allPrecompiles = PrecompiledContractsYoloV1
  40. // EIP-152 test vectors
  41. var blake2FMalformedInputTests = []precompiledFailureTest{
  42. {
  43. Input: "",
  44. ExpectedError: errBlake2FInvalidInputLength.Error(),
  45. Name: "vector 0: empty input",
  46. },
  47. {
  48. Input: "00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
  49. ExpectedError: errBlake2FInvalidInputLength.Error(),
  50. Name: "vector 1: less than 213 bytes input",
  51. },
  52. {
  53. Input: "000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
  54. ExpectedError: errBlake2FInvalidInputLength.Error(),
  55. Name: "vector 2: more than 213 bytes input",
  56. },
  57. {
  58. Input: "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002",
  59. ExpectedError: errBlake2FInvalidFinalFlag.Error(),
  60. Name: "vector 3: malformed final block indicator flag",
  61. },
  62. }
  63. func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
  64. p := allPrecompiles[common.HexToAddress(addr)]
  65. in := common.Hex2Bytes(test.Input)
  66. contract := NewContract(AccountRef(common.HexToAddress("1337")),
  67. nil, new(big.Int), p.RequiredGas(in))
  68. t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, contract.Gas), func(t *testing.T) {
  69. if res, err := RunPrecompiledContract(p, in, contract); err != nil {
  70. t.Error(err)
  71. } else if common.Bytes2Hex(res) != test.Expected {
  72. t.Errorf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res))
  73. }
  74. // Verify that the precompile did not touch the input buffer
  75. exp := common.Hex2Bytes(test.Input)
  76. if !bytes.Equal(in, exp) {
  77. t.Errorf("Precompiled %v modified input data", addr)
  78. }
  79. })
  80. }
  81. func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
  82. p := allPrecompiles[common.HexToAddress(addr)]
  83. in := common.Hex2Bytes(test.Input)
  84. contract := NewContract(AccountRef(common.HexToAddress("1337")),
  85. nil, new(big.Int), p.RequiredGas(in)-1)
  86. t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, contract.Gas), func(t *testing.T) {
  87. _, err := RunPrecompiledContract(p, in, contract)
  88. if err.Error() != "out of gas" {
  89. t.Errorf("Expected error [out of gas], got [%v]", err)
  90. }
  91. // Verify that the precompile did not touch the input buffer
  92. exp := common.Hex2Bytes(test.Input)
  93. if !bytes.Equal(in, exp) {
  94. t.Errorf("Precompiled %v modified input data", addr)
  95. }
  96. })
  97. }
  98. func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing.T) {
  99. p := allPrecompiles[common.HexToAddress(addr)]
  100. in := common.Hex2Bytes(test.Input)
  101. contract := NewContract(AccountRef(common.HexToAddress("31337")),
  102. nil, new(big.Int), p.RequiredGas(in))
  103. t.Run(test.Name, func(t *testing.T) {
  104. _, err := RunPrecompiledContract(p, in, contract)
  105. if err.Error() != test.ExpectedError {
  106. t.Errorf("Expected error [%v], got [%v]", test.ExpectedError, err)
  107. }
  108. // Verify that the precompile did not touch the input buffer
  109. exp := common.Hex2Bytes(test.Input)
  110. if !bytes.Equal(in, exp) {
  111. t.Errorf("Precompiled %v modified input data", addr)
  112. }
  113. })
  114. }
  115. func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
  116. if test.NoBenchmark {
  117. return
  118. }
  119. p := allPrecompiles[common.HexToAddress(addr)]
  120. in := common.Hex2Bytes(test.Input)
  121. reqGas := p.RequiredGas(in)
  122. contract := NewContract(AccountRef(common.HexToAddress("1337")),
  123. nil, new(big.Int), reqGas)
  124. var (
  125. res []byte
  126. err error
  127. data = make([]byte, len(in))
  128. )
  129. bench.Run(fmt.Sprintf("%s-Gas=%d", test.Name, contract.Gas), func(bench *testing.B) {
  130. bench.ReportAllocs()
  131. bench.ResetTimer()
  132. for i := 0; i < bench.N; i++ {
  133. contract.Gas = reqGas
  134. copy(data, in)
  135. res, err = RunPrecompiledContract(p, data, contract)
  136. }
  137. bench.StopTimer()
  138. bench.ReportMetric(float64(reqGas), "gas/op")
  139. //Check if it is correct
  140. if err != nil {
  141. bench.Error(err)
  142. return
  143. }
  144. if common.Bytes2Hex(res) != test.Expected {
  145. bench.Error(fmt.Sprintf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res)))
  146. return
  147. }
  148. })
  149. }
  150. // Benchmarks the sample inputs from the ECRECOVER precompile.
  151. func BenchmarkPrecompiledEcrecover(bench *testing.B) {
  152. t := precompiledTest{
  153. Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
  154. Expected: "000000000000000000000000ceaccac640adf55b2028469bd36ba501f28b699d",
  155. Name: "",
  156. }
  157. benchmarkPrecompiled("01", t, bench)
  158. }
  159. // Benchmarks the sample inputs from the SHA256 precompile.
  160. func BenchmarkPrecompiledSha256(bench *testing.B) {
  161. t := precompiledTest{
  162. Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
  163. Expected: "811c7003375852fabd0d362e40e68607a12bdabae61a7d068fe5fdd1dbbf2a5d",
  164. Name: "128",
  165. }
  166. benchmarkPrecompiled("02", t, bench)
  167. }
  168. // Benchmarks the sample inputs from the RIPEMD precompile.
  169. func BenchmarkPrecompiledRipeMD(bench *testing.B) {
  170. t := precompiledTest{
  171. Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
  172. Expected: "0000000000000000000000009215b8d9882ff46f0dfde6684d78e831467f65e6",
  173. Name: "128",
  174. }
  175. benchmarkPrecompiled("03", t, bench)
  176. }
  177. // Benchmarks the sample inputs from the identiy precompile.
  178. func BenchmarkPrecompiledIdentity(bench *testing.B) {
  179. t := precompiledTest{
  180. Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
  181. Expected: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02",
  182. Name: "128",
  183. }
  184. benchmarkPrecompiled("04", t, bench)
  185. }
  186. // Tests the sample inputs from the ModExp EIP 198.
  187. func TestPrecompiledModExp(t *testing.T) { testJson("modexp", "05", t) }
  188. func BenchmarkPrecompiledModExp(b *testing.B) { benchJson("modexp", "05", b) }
  189. // Tests the sample inputs from the elliptic curve addition EIP 213.
  190. func TestPrecompiledBn256Add(t *testing.T) { testJson("bn256Add", "06", t) }
  191. func BenchmarkPrecompiledBn256Add(b *testing.B) { benchJson("bn256Add", "06", b) }
  192. // Tests OOG
  193. func TestPrecompiledModExpOOG(t *testing.T) {
  194. modexpTests, err := loadJson("modexp")
  195. if err != nil {
  196. t.Fatal(err)
  197. }
  198. for _, test := range modexpTests {
  199. testPrecompiledOOG("05", test, t)
  200. }
  201. }
  202. // Tests the sample inputs from the elliptic curve scalar multiplication EIP 213.
  203. func TestPrecompiledBn256ScalarMul(t *testing.T) { testJson("bn256ScalarMul", "07", t) }
  204. func BenchmarkPrecompiledBn256ScalarMul(b *testing.B) { benchJson("bn256ScalarMul", "07", b) }
  205. // Tests the sample inputs from the elliptic curve pairing check EIP 197.
  206. func TestPrecompiledBn256Pairing(t *testing.T) { testJson("bn256Pairing", "08", t) }
  207. func BenchmarkPrecompiledBn256Pairing(b *testing.B) { benchJson("bn256Pairing", "08", b) }
  208. func TestPrecompiledBlake2F(t *testing.T) { testJson("blake2F", "09", t) }
  209. func BenchmarkPrecompiledBlake2F(b *testing.B) { benchJson("blake2F", "09", b) }
  210. func TestPrecompileBlake2FMalformedInput(t *testing.T) {
  211. for _, test := range blake2FMalformedInputTests {
  212. testPrecompiledFailure("09", test, t)
  213. }
  214. }
  215. func TestPrecompiledEcrecover(t *testing.T) { testJson("ecRecover", "01", t) }
  216. func testJson(name, addr string, t *testing.T) {
  217. tests, err := loadJson(name)
  218. if err != nil {
  219. t.Fatal(err)
  220. }
  221. for _, test := range tests {
  222. testPrecompiled(addr, test, t)
  223. }
  224. }
  225. func testJsonFail(name, addr string, t *testing.T) {
  226. tests, err := loadJsonFail(name)
  227. if err != nil {
  228. t.Fatal(err)
  229. }
  230. for _, test := range tests {
  231. testPrecompiledFailure(addr, test, t)
  232. }
  233. }
  234. func benchJson(name, addr string, b *testing.B) {
  235. tests, err := loadJson(name)
  236. if err != nil {
  237. b.Fatal(err)
  238. }
  239. for _, test := range tests {
  240. benchmarkPrecompiled(addr, test, b)
  241. }
  242. }
  243. func TestPrecompiledBLS12381G1Add(t *testing.T) { testJson("blsG1Add", "0a", t) }
  244. func TestPrecompiledBLS12381G1Mul(t *testing.T) { testJson("blsG1Mul", "0b", t) }
  245. func TestPrecompiledBLS12381G1MultiExp(t *testing.T) { testJson("blsG1MultiExp", "0c", t) }
  246. func TestPrecompiledBLS12381G2Add(t *testing.T) { testJson("blsG2Add", "0d", t) }
  247. func TestPrecompiledBLS12381G2Mul(t *testing.T) { testJson("blsG2Mul", "0e", t) }
  248. func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp", "0f", t) }
  249. func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "10", t) }
  250. func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "11", t) }
  251. func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "12", t) }
  252. func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "0a", b) }
  253. func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "0b", b) }
  254. func BenchmarkPrecompiledBLS12381G1MultiExp(b *testing.B) { benchJson("blsG1MultiExp", "0c", b) }
  255. func BenchmarkPrecompiledBLS12381G2Add(b *testing.B) { benchJson("blsG2Add", "0d", b) }
  256. func BenchmarkPrecompiledBLS12381G2Mul(b *testing.B) { benchJson("blsG2Mul", "0e", b) }
  257. func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2MultiExp", "0f", b) }
  258. func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "10", b) }
  259. func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "11", b) }
  260. func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "12", b) }
  261. // Failure tests
  262. func TestPrecompiledBLS12381G1AddFail(t *testing.T) { testJsonFail("blsG1Add", "0a", t) }
  263. func TestPrecompiledBLS12381G1MulFail(t *testing.T) { testJsonFail("blsG1Mul", "0b", t) }
  264. func TestPrecompiledBLS12381G1MultiExpFail(t *testing.T) { testJsonFail("blsG1MultiExp", "0c", t) }
  265. func TestPrecompiledBLS12381G2AddFail(t *testing.T) { testJsonFail("blsG2Add", "0d", t) }
  266. func TestPrecompiledBLS12381G2MulFail(t *testing.T) { testJsonFail("blsG2Mul", "0e", t) }
  267. func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2MultiExp", "0f", t) }
  268. func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "10", t) }
  269. func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "11", t) }
  270. func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "12", t) }
  271. func loadJson(name string) ([]precompiledTest, error) {
  272. data, err := ioutil.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name))
  273. if err != nil {
  274. return nil, err
  275. }
  276. var testcases []precompiledTest
  277. err = json.Unmarshal(data, &testcases)
  278. return testcases, err
  279. }
  280. func loadJsonFail(name string) ([]precompiledFailureTest, error) {
  281. data, err := ioutil.ReadFile(fmt.Sprintf("testdata/precompiles/fail-%v.json", name))
  282. if err != nil {
  283. return nil, err
  284. }
  285. var testcases []precompiledFailureTest
  286. err = json.Unmarshal(data, &testcases)
  287. return testcases, err
  288. }