ciri 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/Gemfile.lock +6 -6
  4. data/README.md +68 -48
  5. data/Rakefile +16 -11
  6. data/ciri-crypto/lib/ciri/crypto/signature.rb +7 -5
  7. data/ciri-rlp/ciri-rlp.gemspec +1 -1
  8. data/ciri-rlp/lib/ciri/rlp.rb +1 -1
  9. data/ciri-rlp/lib/ciri/rlp/decode.rb +23 -7
  10. data/ciri-rlp/lib/ciri/rlp/encode.rb +8 -2
  11. data/ciri-rlp/lib/ciri/rlp/serializable.rb +14 -4
  12. data/ciri-rlp/lib/ciri/rlp/version.rb +1 -1
  13. data/ciri-rlp/spec/ciri/fixture_spec.rb +2 -2
  14. data/ciri-utils/Gemfile.lock +1 -1
  15. data/ciri-utils/lib/ciri/utils/version.rb +1 -1
  16. data/ciri.gemspec +4 -4
  17. data/lib/ciri/chain/header.rb +13 -11
  18. data/lib/ciri/chain/header_chain.rb +1 -10
  19. data/lib/ciri/chain/transaction.rb +5 -23
  20. data/lib/ciri/db/account_db.rb +0 -4
  21. data/lib/ciri/db/backend/errors.rb +27 -0
  22. data/lib/ciri/db/backend/memory.rb +10 -12
  23. data/lib/ciri/db/backend/rocks.rb +13 -6
  24. data/lib/ciri/db/backend/rocks_db.rb +4 -0
  25. data/lib/ciri/evm.rb +6 -1
  26. data/lib/ciri/evm/execution_context.rb +6 -2
  27. data/lib/ciri/evm/instruction.rb +0 -1
  28. data/lib/ciri/evm/op.rb +11 -5
  29. data/lib/ciri/evm/op/errors.rb +37 -0
  30. data/lib/ciri/evm/state.rb +1 -1
  31. data/lib/ciri/evm/sub_state.rb +6 -6
  32. data/lib/ciri/evm/vm.rb +53 -33
  33. data/lib/ciri/forks.rb +4 -0
  34. data/lib/ciri/forks/base.rb +28 -0
  35. data/lib/ciri/forks/byzantium.rb +45 -11
  36. data/lib/ciri/forks/byzantium/opcodes.rb +37 -0
  37. data/lib/ciri/forks/constantinople.rb +29 -0
  38. data/lib/ciri/forks/frontier.rb +49 -29
  39. data/lib/ciri/forks/frontier/cost.rb +91 -95
  40. data/lib/ciri/forks/frontier/opcodes.rb +99 -0
  41. data/lib/ciri/forks/frontier/transaction.rb +62 -0
  42. data/lib/ciri/forks/homestead.rb +31 -7
  43. data/lib/ciri/forks/homestead/opcodes.rb +37 -0
  44. data/lib/ciri/forks/homestead/transaction.rb +43 -0
  45. data/lib/ciri/forks/spurious_dragon.rb +55 -0
  46. data/lib/ciri/forks/spurious_dragon/cost.rb +91 -0
  47. data/lib/ciri/forks/spurious_dragon/transaction.rb +44 -0
  48. data/lib/ciri/forks/tangerine_whistle.rb +37 -0
  49. data/lib/ciri/forks/tangerine_whistle/cost.rb +98 -0
  50. data/lib/ciri/rlp/decode.rb +4 -4
  51. data/lib/ciri/rlp/encode.rb +2 -2
  52. data/lib/ciri/version.rb +1 -1
  53. metadata +22 -10
  54. data/lib/ciri/forks/homestead/cost.rb +0 -195
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61fa52ad5872fda629e5eb32e0d6af81626e3ba2496d63bb5bd74f33abce933f
4
- data.tar.gz: e0d6afeff09d16e2e052c7c7579c6bb969d16303d5f5fbefe5f7029c3eafde3f
3
+ metadata.gz: 20618c56ec07fac482c96e6a4bd5cdb3f3bfb45402be5548e748994283246c99
4
+ data.tar.gz: d76e2848328eb6a42b4bd0705aaf20885a44cbb0b487b1d4a485fff92f0dd42a
5
5
  SHA512:
6
- metadata.gz: 50bf9082352959c511d99d67556a33d700ba7e241e4302a46f75be1017d23340ac09bf0f77c4479f9fee8ab418da89ee5893a6349a9f2baa82b56a6755b71517
7
- data.tar.gz: 1f2a10fcccbe305d97233bf5270bbc20a63206e57facd77fb415eb29e5aff0450f34826821797aacfe076f0888af0c7152329d7f06c7cc2b56474d2abda0e717
6
+ metadata.gz: 665f5f8f3d6437c24993c4e2f573b805886906a70f9a0fec5610eec0a5c870ce5d8d8b72558212b5600ba3c9f23f9a29287d2d53bdc85c91623caf8cc487dbc5
7
+ data.tar.gz: b16a58be1b92f544c2670a2c6956b2943d14f5f5cc1ffc05a3be3f148578049754a2bfc146372f20e493fb127bda8668c2e2174d304a82bb42cd27d26dc7b1e4
@@ -5,8 +5,8 @@ services:
5
5
  - docker
6
6
 
7
7
  before_install:
8
- - docker pull ciriethereum/base:latest
8
+ - docker pull ciriethereum/ciri:latest
9
9
  - gem install rake
10
10
 
11
11
  script:
12
- - rake docker:test
12
+ - rake docker:quick
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ciri (0.0.3)
4
+ ciri (0.0.4)
5
5
  bitcoin-secp256k1 (~> 0.4.0)
6
6
  ciri-crypto (~> 0.1.1)
7
- ciri-rlp (~> 0.1.1)
8
- ciri-utils (~> 0.2.0)
7
+ ciri-rlp (~> 0.2.1)
8
+ ciri-utils (~> 0.2.1)
9
9
  concurrent-ruby (~> 1.0.5)
10
10
  ffi (~> 1.9.23)
11
11
  lru_redux (~> 1.1.0)
@@ -13,9 +13,9 @@ PATH
13
13
  ciri-crypto (0.1.1)
14
14
  bitcoin-secp256k1 (~> 0.4.0)
15
15
  ciri-utils (~> 0.2.0)
16
- ciri-rlp (0.1.1)
17
- ciri-utils (~> 0.2.0)
18
- ciri-utils (0.2.0)
16
+ ciri-rlp (0.2.1)
17
+ ciri-utils (~> 0.2.1)
18
+ ciri-utils (0.2.1)
19
19
  digest-sha3 (~> 1.1.0)
20
20
 
21
21
  GEM
data/README.md CHANGED
@@ -3,32 +3,79 @@ Ciri
3
3
  [![Build Status](https://travis-ci.org/ciri-ethereum/ciri.svg?branch=master)](https://travis-ci.org/ciri-ethereum/ciri)
4
4
  [![Gitter](https://badges.gitter.im/join.svg)](https://gitter.im/ciri-ethereum/Lobby)
5
5
 
6
- Ciri ethereum is intended to build as a full feature set ethereum implementation.
6
+ Ciri is an ongoing Ethereum implementation.
7
7
 
8
- It aims to be a feature complete, long maintained and stable ethereum implementation.
9
- As you see it'is still under development.
8
+ It aims to be a feature complete Ethereum implementation and expects to achieve both research-friendly and high-performance.
9
+ As you see, it's still under development.
10
10
 
11
- Talk to me on [gitter](https://gitter.im/ciri-ethereum/Lobby) if you interesting in this project or want to contributing. See [How to learn Ethereum and contibute to Ciri](https://github.com/ciri-ethereum/ciri/wiki#how-to-learn-ethereum-and-contribute-to-ciri).
11
+ See [How to learn Ethereum and contribute to Ciri](https://github.com/ciri-ethereum/ciri/wiki#how-to-learn-ethereum-and-contribute-to-ciri).
12
12
 
13
13
  See [projects](https://github.com/ciri-ethereum/ciri/projects) and [milestones](https://github.com/ciri-ethereum/ciri/milestones) for current development status.
14
14
 
15
15
  Roadmap
16
16
  ---------------
17
17
 
18
- See [Wiki Roadmap](https://github.com/ciri-ethereum/ciri/wiki)
19
-
20
- Documentation
21
- ---------------
22
-
23
- [YARD documentation](https://www.rubydoc.info/github/ciri-ethereum/ciri/master)
18
+ See [Roadmap](https://github.com/ciri-ethereum/ciri/wiki) on Wiki
24
19
 
25
20
  Development
26
21
  ---------------
27
22
 
28
23
  Ciri depends on [rocksdb](https://github.com/facebook/rocksdb), [secp256k1](https://github.com/bitcoin-core/secp256k1), [ethash](https://github.com/ethereum/ethash) and [snappy](https://github.com/google/snappy).
29
24
 
30
- It's recommendation to [setup with docker](#setup-with-docker), it will save lots of time.
25
+ It's a recommendation to [setup with docker](#setup-with-docker), it will help to save lots of time.
26
+
27
+ ### Setup with docker
28
+
29
+ Use docker command to pull image:
30
+
31
+ ``` bash
32
+ docker pull ciriethereum/ciri
33
+ ```
34
+
35
+ Or you can use our prepared rake tasks if you're not familiar with docker:
36
+
37
+ clone repo and submodules
38
+
39
+ ``` bash
40
+ git clone --recursive https://github.com/ciri-ethereum/ciri.git
41
+ cd ciri
42
+ ```
43
+
44
+ make sure we have installed docker, ruby and rake
45
+ ``` bash
46
+ # make sure we have installed docker, ruby and rake
47
+ docker -v
48
+ gem install rake
49
+ ```
50
+
51
+ #### Pull docker image
52
+
53
+ ``` bash
54
+ # pull Ciri docker image
55
+ rake docker:pull
56
+ ```
57
+
58
+ #### Build docker image
59
+ (it will take a few minutes)
60
+ ``` bash
61
+ # build Ciri docker image
62
+ rake docker:build
63
+ ```
64
+
65
+ #### Run tests in docker
66
+ ``` bash
67
+ # run tests
68
+ rake docker:quick
69
+ ```
70
+
71
+ #### Other usages
72
+ ``` bash
73
+ # open a shell for developing
74
+ rake docker:shell
31
75
 
76
+ # type 'rake -T' see other supported tasks
77
+ rake -T
78
+ ```
32
79
 
33
80
  ### Manually Setup
34
81
 
@@ -40,7 +87,7 @@ git clone --recursive https://github.com/ciri-ethereum/ciri.git
40
87
 
41
88
  #### Install dependencies
42
89
 
43
- On mac you can install `rocksdb` and `snappy` with homebrew
90
+ On a mac you can install `rocksdb` and `snappy` with homebrew
44
91
 
45
92
  ``` bash
46
93
  brew install rocksdb snappy
@@ -58,7 +105,7 @@ secp256k1
58
105
  cd secp256k1 && ./autogen.sh && ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh && make && make install
59
106
  ```
60
107
 
61
- For linux user, remember check [Dockerfile](/docker) instructions for hint.
108
+ For linux users, remember to check [Dockerfile](/docker) instructions for hint.
62
109
 
63
110
  then run:
64
111
  ``` bash
@@ -67,49 +114,22 @@ bundle install
67
114
 
68
115
  run tests:
69
116
  ``` bash
70
- RUBY_THREAD_VM_STACK_SIZE=52428800 bundle exec rake test
117
+ RUBY_THREAD_VM_STACK_SIZE=52428800 bundle exec rake quick
71
118
  ```
72
119
 
120
+ Why Ruby?
121
+ ---------------
73
122
 
74
- ### Setup with docker
123
+ > Because Ruby has built-in block support!
75
124
 
76
- It's recommendation to use docker to handle dependencies:
125
+ Seriously,
77
126
 
78
- make sure we have installed docker, ruby and rake
79
- ``` bash
80
- # make sure we have installed docker, ruby and rake
81
- docker -v
82
- gem install rake
83
- ```
127
+ Ruby is a scripting language which makes it easy to write prototype or research code (like the official python Ethereum implementation intended).
84
128
 
85
- #### Pull docker image
86
- pull latest released Ciri docker image
87
- ``` bash
88
- # pull Ciri docker image
89
- rake docker:pull
90
- ```
91
-
92
- #### Build docker image
93
- build local docker image (it will take few minutes)
94
- ``` bash
95
- # build Ciri docker image
96
- rake docker:build
97
- ```
129
+ According to the several performance research projects in Ruby community (JIT, JRuby, TruffleRuby), we are highly looking forward to seeing improvement of this language performance in the future.
98
130
 
99
- #### Run tests in docker
100
- ``` bash
101
- # run tests
102
- rake docker:test
103
- ```
131
+ Due to Ruby, we could expect to achieve both research-friendly and high-performance in our implementation.
104
132
 
105
- #### Other usage
106
- ``` bash
107
- # open a shell for develop
108
- rake docker:shell
109
-
110
- # cool, type 'rake -T' see other supported tasks
111
- rake -T
112
- ```
113
133
 
114
134
  Contributors
115
135
  ---------------
data/Rakefile CHANGED
@@ -14,8 +14,8 @@ end
14
14
 
15
15
  SUB_COMPONENTS = %w{ciri-utils ciri-rlp ciri-crypto}
16
16
 
17
- desc 'run tests'
18
- task :test do
17
+ desc 'run quick spec'
18
+ task :quick do
19
19
  exit(1) unless check_env
20
20
  run("rspec -t ~slow_tests")
21
21
  SUB_COMPONENTS.each do |dir|
@@ -23,8 +23,8 @@ task :test do
23
23
  end
24
24
  end
25
25
 
26
- desc 'run all tests, include extreme slow tests'
27
- task :"test:all" do
26
+ desc 'run all specs, include extreme slow tests'
27
+ task :"spec:all" do
28
28
  exit(1) unless check_env
29
29
  run("rspec")
30
30
  SUB_COMPONENTS.each do |dir|
@@ -33,7 +33,7 @@ task :"test:all" do
33
33
  end
34
34
 
35
35
  namespace :docker do
36
- base_image = 'ciriethereum/base'
36
+ base_image = 'ciriethereum/ciri'
37
37
 
38
38
  desc 'pull docker image'
39
39
  task :pull do
@@ -46,6 +46,11 @@ namespace :docker do
46
46
  run("docker build . -f docker/Dockerfile -t #{base_image}:latest")
47
47
  end
48
48
 
49
+ desc 'push docker image'
50
+ task :push do
51
+ run("docker push #{base_image}:latest")
52
+ end
53
+
49
54
  desc 'open Ciri develop container shell'
50
55
  task :shell do
51
56
  container_name = 'ciri-develop'
@@ -57,14 +62,14 @@ namespace :docker do
57
62
  end
58
63
  end
59
64
 
60
- desc 'run tests in docker'
61
- task :test do
62
- run("docker run -v `pwd`:/app --rm #{base_image}:latest rake test")
65
+ desc 'run quick specs in docker'
66
+ task :quick do
67
+ run("docker run -v `pwd`:/app --rm #{base_image}:latest rake quick")
63
68
  end
64
69
 
65
- desc 'run all tests(include slow tests) in docker'
66
- task :"test:all" do
67
- run("docker run -v `pwd`:/app --rm #{base_image}:latest rake test:all")
70
+ desc 'run all specs(include slow tests) in docker'
71
+ task :"spec:all" do
72
+ run("docker run -v `pwd`:/app --rm #{base_image}:latest rake spec:all")
68
73
  end
69
74
 
70
75
  private
@@ -50,20 +50,22 @@ module Ciri
50
50
 
51
51
  def signature
52
52
  @signature ||= Utils.big_endian_encode(@r, "\x00".b, size: 32) +
53
- Utils.big_endian_encode(@s, "\x00".b, size: 32) +
54
- Utils.big_endian_encode(@v, "\x00".b)
53
+ Utils.big_endian_encode(@s, "\x00".b, size: 32) +
54
+ Utils.big_endian_encode(@v, "\x00".b)
55
55
  end
56
56
 
57
57
  alias to_s signature
58
58
 
59
59
  def valid?
60
60
  v <= 1 &&
61
- r < SECP256K1N && r >= 1 &&
62
- s < SECP256K1N && s >= 1
61
+ r < SECP256K1N && r >= 1 &&
62
+ s < SECP256K1N && s >= 1
63
63
  end
64
64
 
65
+ # high s value is invalid after Homestead fork
66
+ # see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md#specification
65
67
  def low_s?
66
- s < (SECP256K1N / 2)
68
+ s <= (SECP256K1N / 2)
67
69
  end
68
70
  end
69
71
 
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_dependency "ciri-utils", "~> 0.2.0"
24
+ spec.add_dependency "ciri-utils", "~> 0.2.1"
25
25
  spec.add_development_dependency "bundler", "~> 1.16"
26
26
  spec.add_development_dependency "rake", "~> 12.0"
27
27
  spec.add_development_dependency "rspec", "~> 3.0"
@@ -22,7 +22,7 @@ require_relative 'rlp/serializable'
22
22
  module Ciri
23
23
  module RLP
24
24
 
25
- class InvalidValueError < StandardError
25
+ class InvalidError < StandardError
26
26
  end
27
27
 
28
28
  extend Encode
@@ -44,7 +44,7 @@ module Ciri
44
44
  if type == Integer
45
45
  item = s.read(1)
46
46
  if item.nil?
47
- raise InvalidValueError.new "invalid bool value nil"
47
+ raise InvalidError.new "invalid bool value nil"
48
48
  elsif item == "\x80".b || item.empty?
49
49
  0
50
50
  elsif item.ord < 0x80
@@ -60,7 +60,7 @@ module Ciri
60
60
  elsif item == Bool::ENCODED_FALSE
61
61
  false
62
62
  else
63
- raise InvalidValueError.new "invalid bool value #{item}"
63
+ raise InvalidError.new "invalid bool value #{item}"
64
64
  end
65
65
  elsif type.is_a?(Class) && type.respond_to?(:rlp_decode)
66
66
  type.rlp_decode(s)
@@ -73,10 +73,18 @@ module Ciri
73
73
  i += 1
74
74
  end
75
75
  end
76
+ elsif type == RawString
77
+ str = decode_stream(s)
78
+ raise RLP::InvalidError.new "decode #{str.class} from RawString" unless str.is_a?(String)
79
+ str
80
+ elsif type == RawList
81
+ list = decode_stream(s)
82
+ raise RLP::InvalidError.new "decode #{list.class} from RawList" unless list.is_a?(Array)
83
+ list
76
84
  elsif type == Raw
77
85
  decode_stream(s)
78
86
  else
79
- raise RLP::InvalidValueError.new "unknown type #{type}"
87
+ raise RLP::InvalidError.new "unknown type #{type}"
80
88
  end
81
89
  rescue
82
90
  STDERR.puts "when decoding #{s} into #{type}"
@@ -89,7 +97,6 @@ module Ciri
89
97
  s = StringIO.new(s) if s.is_a?(String)
90
98
  c = first_char || s.read(1)
91
99
  list = []
92
-
93
100
  sub_s = case c.ord
94
101
  when 0xc0..0xf7
95
102
  length = c.ord - 0xc0
@@ -97,11 +104,13 @@ module Ciri
97
104
  when 0xf8..0xff
98
105
  length_binary = s.read(c.ord - 0xf7)
99
106
  length = int_from_binary(length_binary)
100
- s.read(length)
107
+ check_range_and_read(s, length)
101
108
  else
102
- raise InvalidValueError.new("invalid char #{c}")
109
+ raise InvalidError.new("invalid char #{c}")
103
110
  end
104
111
 
112
+ raise InvalidError.new("stream EOF when encode_list") unless sub_s
113
+
105
114
  decoder.call(list, StringIO.new(sub_s))
106
115
  list
107
116
  end
@@ -110,6 +119,7 @@ module Ciri
110
119
 
111
120
  def decode_stream(s)
112
121
  c = s.read(1)
122
+ raise InvalidError.new("read none char from stream") unless c
113
123
  case c.ord
114
124
  when 0x00..0x7f
115
125
  c
@@ -119,7 +129,7 @@ module Ciri
119
129
  when 0xb8..0xbf
120
130
  length_binary = s.read(c.ord - 0xb7)
121
131
  length = int_from_binary(length_binary)
122
- s.read(length)
132
+ check_range_and_read(s, length)
123
133
  else
124
134
  decode_list(s, c) do |list, s2|
125
135
  until s2.eof?
@@ -129,6 +139,12 @@ module Ciri
129
139
  end
130
140
  end
131
141
 
142
+ def check_range_and_read(s, length)
143
+ s.read(length)
144
+ rescue RangeError
145
+ raise InvalidError.new("length too long: #{length}")
146
+ end
147
+
132
148
  def int_from_binary(input)
133
149
  Ciri::Utils.big_endian_decode(input)
134
150
  end
@@ -70,12 +70,18 @@ module Ciri
70
70
  if type.size == 1 # array type
71
71
  encode_list(item) {|i| encode_with_type(i, type[0])}
72
72
  else # unknown
73
- raise RLP::InvalidValueError.new "type size should be 1, got #{type}"
73
+ raise RLP::InvalidError.new "type size should be 1, got #{type}"
74
74
  end
75
75
  elsif type == Raw
76
76
  encode_raw(item)
77
+ elsif type == RawString
78
+ raise RLP::InvalidError.new "expect String, got #{item.class}" unless item.is_a?(String)
79
+ encode_raw(item)
80
+ elsif type == RawList
81
+ raise RLP::InvalidError.new "expect Array, got #{item.class}" unless item.is_a?(Array)
82
+ encode_raw(item)
77
83
  else
78
- raise RLP::InvalidValueError.new "unknown type #{type}"
84
+ raise RLP::InvalidError.new "unknown type #{type}"
79
85
  end
80
86
  rescue
81
87
  STDERR.puts "when encoding #{Utils.to_hex item.to_s} into #{type}"
@@ -30,6 +30,12 @@ module Ciri
30
30
  class Raw
31
31
  end
32
32
 
33
+ class RawString
34
+ end
35
+
36
+ class RawList
37
+ end
38
+
33
39
  # Serializable module allow ruby objects serialize/deserialize to or from RLP encoding.
34
40
  # See Ciri::RLP::Serializable::TYPES for supported type.
35
41
  #
@@ -69,7 +75,7 @@ module Ciri
69
75
  #
70
76
  module Serializable
71
77
  # nil represent RLP raw value(string or array of string)
72
- TYPES = [Raw, Integer, Bool].map {|key| [key, true]}.to_h.freeze
78
+ TYPES = [Raw, RawString, RawList, Integer, Bool].map {|key| [key, true]}.to_h.freeze
73
79
 
74
80
  # Schema specific columns types of classes, normally you should not use Serializable::Schema directly
75
81
  #
@@ -176,9 +182,13 @@ module Ciri
176
182
  end
177
183
 
178
184
  def schema(data_schema = nil)
179
- @data_schema ||= Schema.new(data_schema).tap do |schema|
180
- # define attributes methods
181
- define_attributes(schema)
185
+ if data_schema
186
+ @data_schema = Schema.new(data_schema).tap do |schema|
187
+ # define attributes methods
188
+ define_attributes(schema)
189
+ end
190
+ else
191
+ @data_schema ||= superclass.schema
182
192
  end
183
193
  end
184
194