ciri 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitmodules +14 -0
- data/.rspec +2 -1
- data/.travis.yml +11 -4
- data/Gemfile.lock +3 -0
- data/README.md +44 -34
- data/Rakefile +47 -4
- data/ciri.gemspec +13 -12
- data/docker/Base +34 -0
- data/lib/ciri/actor.rb +223 -0
- data/lib/ciri/chain.rb +293 -0
- data/lib/ciri/chain/block.rb +47 -0
- data/lib/ciri/chain/header.rb +62 -0
- data/lib/ciri/chain/transaction.rb +145 -0
- data/lib/ciri/crypto.rb +58 -5
- data/lib/ciri/db/backend/memory.rb +68 -0
- data/lib/ciri/db/backend/rocks.rb +104 -0
- data/lib/ciri/db/backend/rocks_db.rb +278 -0
- data/lib/ciri/devp2p/peer.rb +10 -2
- data/lib/ciri/devp2p/protocol.rb +11 -3
- data/lib/ciri/devp2p/protocol_io.rb +6 -3
- data/lib/ciri/devp2p/rlpx.rb +1 -0
- data/lib/ciri/devp2p/rlpx/encryption_handshake.rb +1 -1
- data/lib/ciri/devp2p/rlpx/frame_io.rb +1 -1
- data/lib/ciri/devp2p/rlpx/message.rb +4 -4
- data/lib/ciri/devp2p/server.rb +14 -13
- data/lib/ciri/eth.rb +33 -0
- data/lib/ciri/eth/peer.rb +64 -0
- data/lib/ciri/eth/protocol_manage.rb +122 -0
- data/lib/ciri/eth/protocol_messages.rb +158 -0
- data/lib/ciri/eth/synchronizer.rb +188 -0
- data/lib/ciri/ethash.rb +123 -0
- data/lib/ciri/evm.rb +140 -0
- data/lib/ciri/evm/account.rb +50 -0
- data/lib/ciri/evm/block_info.rb +31 -0
- data/lib/ciri/evm/forks/frontier.rb +183 -0
- data/lib/ciri/evm/instruction.rb +92 -0
- data/lib/ciri/evm/machine_state.rb +81 -0
- data/lib/ciri/evm/op.rb +536 -0
- data/lib/ciri/evm/serialize.rb +60 -0
- data/lib/ciri/evm/sub_state.rb +64 -0
- data/lib/ciri/evm/vm.rb +379 -0
- data/lib/ciri/forks.rb +38 -0
- data/lib/ciri/forks/frontier.rb +43 -0
- data/lib/ciri/key.rb +7 -1
- data/lib/ciri/pow.rb +95 -0
- data/lib/ciri/rlp.rb +3 -53
- data/lib/ciri/rlp/decode.rb +100 -40
- data/lib/ciri/rlp/encode.rb +95 -34
- data/lib/ciri/rlp/serializable.rb +61 -91
- data/lib/ciri/types/address.rb +70 -0
- data/lib/ciri/types/errors.rb +36 -0
- data/lib/ciri/utils.rb +45 -13
- data/lib/ciri/utils/lib_c.rb +46 -0
- data/lib/ciri/utils/logger.rb +99 -0
- data/lib/ciri/utils/number.rb +67 -0
- data/lib/ciri/version.rb +1 -1
- metadata +67 -7
- data/lib/ciri/devp2p/actor.rb +0 -224
data/lib/ciri/devp2p/peer.rb
CHANGED
@@ -22,8 +22,9 @@
|
|
22
22
|
# THE SOFTWARE.
|
23
23
|
|
24
24
|
|
25
|
+
require 'ciri/actor'
|
26
|
+
require 'ciri/utils'
|
25
27
|
require_relative 'rlpx'
|
26
|
-
require_relative 'actor'
|
27
28
|
require_relative 'protocol_io'
|
28
29
|
|
29
30
|
module Ciri
|
@@ -49,6 +50,12 @@ module Ciri
|
|
49
50
|
super()
|
50
51
|
end
|
51
52
|
|
53
|
+
def to_s
|
54
|
+
@display_name ||= begin
|
55
|
+
Utils.data_to_hex(node_id.id)[0..8]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
52
59
|
def node_id
|
53
60
|
@node_id ||= RLPX::NodeID.from_raw_id(@handshake.id)
|
54
61
|
end
|
@@ -74,7 +81,7 @@ module Ciri
|
|
74
81
|
|
75
82
|
def start_protocols
|
76
83
|
@protocols.each do |protocol|
|
77
|
-
protocol.start
|
84
|
+
protocol.start(self, @protocol_io_hash[protocol.name])
|
78
85
|
end
|
79
86
|
end
|
80
87
|
|
@@ -94,6 +101,7 @@ module Ciri
|
|
94
101
|
end
|
95
102
|
|
96
103
|
private
|
104
|
+
|
97
105
|
def find_protocol_io_by_msg_code(code)
|
98
106
|
@protocol_io_hash.values.find do |protocol_io|
|
99
107
|
offset = protocol_io.offset
|
data/lib/ciri/devp2p/protocol.rb
CHANGED
@@ -22,8 +22,6 @@
|
|
22
22
|
# THE SOFTWARE.
|
23
23
|
|
24
24
|
|
25
|
-
require_relative 'actor'
|
26
|
-
|
27
25
|
module Ciri
|
28
26
|
module DevP2P
|
29
27
|
|
@@ -31,12 +29,22 @@ module Ciri
|
|
31
29
|
class Protocol
|
32
30
|
|
33
31
|
attr_reader :name, :version, :length
|
34
|
-
attr_accessor :node_info, :peer_info
|
32
|
+
attr_accessor :node_info, :peer_info
|
35
33
|
|
36
34
|
def initialize(name:, version:, length:)
|
37
35
|
@name = name
|
38
36
|
@version = version
|
39
37
|
@length = length
|
38
|
+
@start = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def start=(start_proc)
|
42
|
+
@start = start_proc
|
43
|
+
end
|
44
|
+
|
45
|
+
def start(peer, io)
|
46
|
+
raise NotImplementedError.new('not set protocol start proc') unless @start
|
47
|
+
@start.call(peer, io)
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
@@ -21,7 +21,7 @@
|
|
21
21
|
# THE SOFTWARE.
|
22
22
|
|
23
23
|
|
24
|
-
|
24
|
+
require 'ciri/actor'
|
25
25
|
require_relative 'rlpx/message'
|
26
26
|
|
27
27
|
module Ciri
|
@@ -42,11 +42,14 @@ module Ciri
|
|
42
42
|
@offset = offset
|
43
43
|
@frame_io = frame_io
|
44
44
|
@msg_queue = Queue.new
|
45
|
+
@mutex = Mutex.new
|
45
46
|
end
|
46
47
|
|
47
48
|
def send_data(code, data)
|
48
|
-
|
49
|
-
|
49
|
+
@mutex.synchronize do
|
50
|
+
msg = RLPX::Message.new(code: code, size: data.size, payload: data)
|
51
|
+
write_msg(msg)
|
52
|
+
end
|
50
53
|
end
|
51
54
|
|
52
55
|
def write_msg(msg)
|
data/lib/ciri/devp2p/rlpx.rb
CHANGED
@@ -69,7 +69,7 @@ module Ciri
|
|
69
69
|
# xor
|
70
70
|
signed = xor(token, nonce)
|
71
71
|
|
72
|
-
signature = random_key.ecdsa_signature(signed)
|
72
|
+
signature = random_key.ecdsa_signature(signed).signature
|
73
73
|
initiator_pubkey = private_key.raw_public_key[1..-1]
|
74
74
|
AuthMsgV4.new(signature: signature, initiator_pubkey: initiator_pubkey, nonce: nonce, version: 4)
|
75
75
|
end
|
@@ -21,7 +21,7 @@
|
|
21
21
|
# THE SOFTWARE.
|
22
22
|
|
23
23
|
|
24
|
-
require 'ciri/rlp
|
24
|
+
require 'ciri/rlp'
|
25
25
|
|
26
26
|
module Ciri
|
27
27
|
module DevP2P
|
@@ -31,13 +31,13 @@ module Ciri
|
|
31
31
|
class Message
|
32
32
|
include Ciri::RLP::Serializable
|
33
33
|
|
34
|
+
attr_accessor :received_at
|
35
|
+
|
34
36
|
schema [
|
35
37
|
{code: Integer},
|
36
38
|
{size: Integer},
|
37
|
-
:payload
|
38
|
-
:received_at
|
39
|
+
:payload
|
39
40
|
]
|
40
|
-
default_data(received_at: nil)
|
41
41
|
end
|
42
42
|
|
43
43
|
end
|
data/lib/ciri/devp2p/server.rb
CHANGED
@@ -24,10 +24,11 @@
|
|
24
24
|
|
25
25
|
require 'concurrent'
|
26
26
|
require 'forwardable'
|
27
|
+
require 'ciri/actor'
|
28
|
+
require 'ciri/utils/logger'
|
27
29
|
require_relative 'rlpx/connection'
|
28
30
|
require_relative 'rlpx/protocol_handshake'
|
29
31
|
require_relative 'peer'
|
30
|
-
require_relative 'actor'
|
31
32
|
|
32
33
|
module Ciri
|
33
34
|
module DevP2P
|
@@ -35,6 +36,7 @@ module Ciri
|
|
35
36
|
# DevP2P Server
|
36
37
|
# maintain connection, node discovery, rlpx handshake and protocols
|
37
38
|
class Server
|
39
|
+
include Utils::Logger
|
38
40
|
include RLPX
|
39
41
|
|
40
42
|
MAX_ACTIVE_DIAL_TASKS = 16
|
@@ -47,12 +49,12 @@ module Ciri
|
|
47
49
|
end
|
48
50
|
|
49
51
|
attr_reader :handshake, :dial, :scheduler, :protocol_manage, :protocols
|
50
|
-
attr_accessor :
|
52
|
+
attr_accessor :bootstrap_nodes
|
51
53
|
|
52
|
-
def initialize(private_key:, protocol_manage
|
54
|
+
def initialize(private_key:, protocol_manage:)
|
53
55
|
@private_key = private_key
|
54
56
|
@name = 'ciri'
|
55
|
-
@scheduler = Scheduler.new(self
|
57
|
+
@scheduler = Scheduler.new(self)
|
56
58
|
@protocol_manage = protocol_manage
|
57
59
|
@protocols = protocol_manage.protocols
|
58
60
|
end
|
@@ -66,7 +68,6 @@ module Ciri
|
|
66
68
|
@handshake = ProtocolHandshake.new(version: BASE_PROTOCOL_VERSION, name: @name, id: server_node_id.id, caps: caps)
|
67
69
|
# start listen tcp
|
68
70
|
@dial = Dial.new(self)
|
69
|
-
@protocol_manage.executor ||= @scheduler.executor
|
70
71
|
@protocol_manage.start
|
71
72
|
@scheduler.start
|
72
73
|
end
|
@@ -124,19 +125,20 @@ module Ciri
|
|
124
125
|
|
125
126
|
class Scheduler
|
126
127
|
include Actor
|
128
|
+
include Utils::Logger
|
127
129
|
|
128
130
|
extend Forwardable
|
129
131
|
|
130
132
|
attr_reader :server
|
131
|
-
def_delegators :server
|
133
|
+
def_delegators :server
|
132
134
|
|
133
|
-
def initialize(server
|
135
|
+
def initialize(server)
|
134
136
|
@server = server
|
135
137
|
@queued_tasks = []
|
136
138
|
@running_tasks = []
|
137
139
|
@peers = {}
|
138
140
|
# init actor
|
139
|
-
super(
|
141
|
+
super()
|
140
142
|
end
|
141
143
|
|
142
144
|
# called by actor loop
|
@@ -168,11 +170,10 @@ module Ciri
|
|
168
170
|
end
|
169
171
|
|
170
172
|
private
|
173
|
+
|
171
174
|
def add_peer(connection, handshake)
|
172
175
|
server.protocol_handshake_checks(handshake)
|
173
176
|
peer = Peer.new(connection, handshake, server.protocols)
|
174
|
-
# set actor executor
|
175
|
-
peer.executor = executor
|
176
177
|
@peers[peer.node_id] = peer
|
177
178
|
# run peer logic
|
178
179
|
# do sub protocol handshake...
|
@@ -188,16 +189,16 @@ module Ciri
|
|
188
189
|
# remove peer
|
189
190
|
self << [:remove_peer, peer, exit_error]
|
190
191
|
}
|
191
|
-
|
192
|
+
debug("add peer: #{peer}")
|
192
193
|
end
|
193
194
|
|
194
195
|
def remove_peer(peer, *args)
|
195
196
|
error, * = args
|
196
|
-
|
197
|
+
debug("remove peer: #{peer}, error: #{error}")
|
197
198
|
end
|
198
199
|
|
199
200
|
def task_done(task, *args)
|
200
|
-
|
201
|
+
debug("task done: #{task.name}")
|
201
202
|
end
|
202
203
|
|
203
204
|
end
|
data/lib/ciri/eth.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018, by Jiang Jinyang. <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
require_relative 'actor'
|
25
|
+
require_relative 'eth/protocol_messages'
|
26
|
+
require_relative 'eth/protocol_manage'
|
27
|
+
|
28
|
+
module Ciri
|
29
|
+
# implement Ethereum Wire Protocol
|
30
|
+
# https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol
|
31
|
+
module Eth
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018, by Jiang Jinyang. <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
require 'ciri/chain'
|
25
|
+
require 'forwardable'
|
26
|
+
require_relative 'protocol_messages'
|
27
|
+
|
28
|
+
module Ciri
|
29
|
+
module Eth
|
30
|
+
|
31
|
+
# eth protocol peer
|
32
|
+
class Peer
|
33
|
+
attr_reader :io, :total_difficulty, :status
|
34
|
+
|
35
|
+
extend Forwardable
|
36
|
+
|
37
|
+
def_delegators :@peer, :to_s
|
38
|
+
|
39
|
+
def initialize(protocol_manage:, peer:, io:)
|
40
|
+
@protocol_manage = protocol_manage
|
41
|
+
@io = io
|
42
|
+
@total_difficulty = nil
|
43
|
+
@peer = peer
|
44
|
+
end
|
45
|
+
|
46
|
+
# do eth protocol handshake and return status
|
47
|
+
def handshake(network_id, total_difficulty, head_hash, genesis_hash)
|
48
|
+
status = Status.new(protocol_version: 63, network_id: network_id,
|
49
|
+
total_difficulty: total_difficulty, current_block: head_hash, genesis_block: genesis_hash)
|
50
|
+
io.send_data(Status::CODE, status.rlp_encode!)
|
51
|
+
msg = io.read_msg
|
52
|
+
@status = Status.rlp_decode!(msg.payload)
|
53
|
+
@total_difficulty = @status.total_difficulty
|
54
|
+
@status
|
55
|
+
end
|
56
|
+
|
57
|
+
def send_msg(msg_class, **data)
|
58
|
+
msg = msg_class.new(data)
|
59
|
+
io.send_data(msg_class::CODE, msg.rlp_encode!)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018, by Jiang Jinyang. <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
require 'ciri/actor'
|
25
|
+
require 'ciri/chain'
|
26
|
+
require_relative 'peer'
|
27
|
+
require_relative 'synchronizer'
|
28
|
+
|
29
|
+
module Ciri
|
30
|
+
module Eth
|
31
|
+
|
32
|
+
# ProtocolManage
|
33
|
+
class ProtocolManage
|
34
|
+
|
35
|
+
MAX_RESPONSE_HEADERS = 10
|
36
|
+
|
37
|
+
include Ciri::Actor
|
38
|
+
|
39
|
+
attr_reader :protocols, :synchronizer, :chain
|
40
|
+
|
41
|
+
def initialize(protocols:, chain:)
|
42
|
+
@protocols = protocols
|
43
|
+
@peers = {}
|
44
|
+
@chain = chain
|
45
|
+
|
46
|
+
@synchronizer = Synchronizer.new(chain: chain)
|
47
|
+
super()
|
48
|
+
end
|
49
|
+
|
50
|
+
def protocols
|
51
|
+
@protocols.each {|p| p.start = proc {|peer, io| self << [:new_peer, peer, io]}}
|
52
|
+
@protocols
|
53
|
+
end
|
54
|
+
|
55
|
+
def start
|
56
|
+
# start syncing
|
57
|
+
synchronizer.start
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
# new peer come in
|
62
|
+
def new_peer(peer, io)
|
63
|
+
peer = Peer.new(protocol_manage: self, peer: peer, io: io)
|
64
|
+
peer.handshake(1, chain.total_difficulty, chain.head.get_hash, chain.genesis_hash)
|
65
|
+
@peers[peer] = true
|
66
|
+
|
67
|
+
# register peer to synchronizer
|
68
|
+
synchronizer << [:register_peer, peer]
|
69
|
+
# start handle peer messages
|
70
|
+
executor.post {handle_peer(peer)}
|
71
|
+
end
|
72
|
+
|
73
|
+
def handle_peer(peer)
|
74
|
+
handle_msg(peer, peer.io.read_msg) while true
|
75
|
+
end
|
76
|
+
|
77
|
+
def handle_msg(peer, msg)
|
78
|
+
case msg.code
|
79
|
+
when GetBlockHeaders::CODE
|
80
|
+
get_header_msg = GetBlockHeaders.rlp_decode(msg.payload)
|
81
|
+
hash_or_number = get_header_msg.hash_or_number
|
82
|
+
|
83
|
+
header = if hash_or_number.is_a?(Integer)
|
84
|
+
chain.get_header_by_number hash_or_number
|
85
|
+
else
|
86
|
+
chain.get_header hash_or_number
|
87
|
+
end
|
88
|
+
headers = []
|
89
|
+
|
90
|
+
if header
|
91
|
+
amount = [MAX_RESPONSE_HEADERS, get_header_msg.amount].min
|
92
|
+
# skip
|
93
|
+
get_header_msg.skip.times do
|
94
|
+
next_header = chain.get_header_by_number header.number + 1
|
95
|
+
break if next_header.nil? || next_header.parent_hash != header.get_hash
|
96
|
+
header = next_header
|
97
|
+
end
|
98
|
+
amount.times do
|
99
|
+
headers << header
|
100
|
+
next_header = chain.get_header_by_number header.number + 1
|
101
|
+
break if next_header.nil? || next_header.parent_hash != header.get_hash
|
102
|
+
header = next_header
|
103
|
+
end
|
104
|
+
header.reverse! if get_header_msg.reverse
|
105
|
+
end
|
106
|
+
|
107
|
+
headers_msg = BlockHeaders.new(headers: headers).rlp_encode!
|
108
|
+
peer.io.send_data(BlockHeaders::CODE, headers_msg)
|
109
|
+
when BlockHeaders::CODE
|
110
|
+
headers = BlockHeaders.rlp_decode!(msg.payload).headers
|
111
|
+
synchronizer << [:receive_headers, peer, headers] unless headers.empty?
|
112
|
+
when BlockBodies::CODE
|
113
|
+
bodies = BlockBodies.rlp_decode!(msg.payload).bodies
|
114
|
+
synchronizer << [:receive_bodies, peer, bodies] unless bodies.empty?
|
115
|
+
else
|
116
|
+
raise StandardError, "unknown code #{msg.code}, #{msg}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|