Skip to content
GitLab
Explore
Sign in
parity
parity-bitcoin
Compare revisions
master to zcash_init
Hide whitespace changes
Inline
Side-by-side
p2p/src/io/read_any_message.rs
View file @
c56e399d
...
...
@@ -8,9 +8,9 @@ use message::{Error, MessageHeader, MessageResult, Command};
use
bytes
::
Bytes
;
use
io
::{
read_header
,
ReadHeader
};
pub
fn
read_any_message
<
A
>
(
a
:
A
,
magic
:
Magic
)
->
ReadAnyMessage
<
A
>
where
A
:
AsyncRead
{
pub
fn
read_any_message
<
A
>
(
a
:
A
,
flags
:
u32
,
magic
:
Magic
)
->
ReadAnyMessage
<
A
>
where
A
:
AsyncRead
{
ReadAnyMessage
{
state
:
ReadAnyMessageState
::
ReadHeader
(
read_header
(
a
,
magic
)),
state
:
ReadAnyMessageState
::
ReadHeader
(
read_header
(
a
,
flags
,
magic
)),
}
}
...
...
@@ -74,20 +74,20 @@ mod tests {
let
nonce
=
"5845303b6da97786"
.into
();
let
expected
=
(
name
,
nonce
);
assert_eq!
(
read_any_message
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
(),
Ok
(
expected
));
assert_eq!
(
read_any_message
(
raw
.as_ref
(),
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
(),
Err
(
Error
::
InvalidMagic
));
assert_eq!
(
read_any_message
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
(),
Ok
(
expected
));
assert_eq!
(
read_any_message
(
raw
.as_ref
(),
0
,
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
(),
Err
(
Error
::
InvalidMagic
));
}
#[test]
fn
test_read_too_short_any_message
()
{
let
raw
:
Bytes
=
"f9beb4d970696e6700000000000000000800000083c00c765845303b6da977"
.into
();
assert!
(
read_any_message
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.is_err
());
assert!
(
read_any_message
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.is_err
());
}
#[test]
fn
test_read_any_message_with_invalid_checksum
()
{
let
raw
:
Bytes
=
"f9beb4d970696e6700000000000000000800000083c01c765845303b6da97786"
.into
();
assert_eq!
(
read_any_message
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
(),
Err
(
Error
::
InvalidChecksum
));
assert_eq!
(
read_any_message
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
(),
Err
(
Error
::
InvalidChecksum
));
}
}
p2p/src/io/read_header.rs
View file @
c56e399d
...
...
@@ -5,15 +5,17 @@ use tokio_io::io::{ReadExact, read_exact};
use
message
::{
MessageHeader
,
MessageResult
};
use
network
::
Magic
;
pub
fn
read_header
<
A
>
(
a
:
A
,
magic
:
Magic
)
->
ReadHeader
<
A
>
where
A
:
AsyncRead
{
pub
fn
read_header
<
A
>
(
a
:
A
,
flags
:
u32
,
magic
:
Magic
)
->
ReadHeader
<
A
>
where
A
:
AsyncRead
{
ReadHeader
{
reader
:
read_exact
(
a
,
[
0u8
;
24
]),
magic
:
magic
,
flags
:
flags
,
}
}
pub
struct
ReadHeader
<
A
>
{
reader
:
ReadExact
<
A
,
[
u8
;
24
]
>
,
flags
:
u32
,
magic
:
Magic
,
}
...
...
@@ -23,7 +25,7 @@ impl<A> Future for ReadHeader<A> where A: AsyncRead {
fn
poll
(
&
mut
self
)
->
Poll
<
Self
::
Item
,
Self
::
Error
>
{
let
(
read
,
data
)
=
try_ready!
(
self
.reader
.poll
());
let
header
=
MessageHeader
::
deserialize
(
&
data
,
self
.magic
);
let
header
=
MessageHeader
::
deserialize
(
&
data
,
self
.flags
,
self
.magic
);
Ok
(
Async
::
Ready
((
read
,
header
)))
}
}
...
...
@@ -46,19 +48,19 @@ mod tests {
checksum
:
"ed52399b"
.into
(),
};
assert_eq!
(
read_header
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
()
.1
,
Ok
(
expected
));
assert_eq!
(
read_header
(
raw
.as_ref
(),
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidMagic
));
assert_eq!
(
read_header
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
()
.1
,
Ok
(
expected
));
assert_eq!
(
read_header
(
raw
.as_ref
(),
0
,
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidMagic
));
}
#[test]
fn
test_read_header_with_invalid_magic
()
{
let
raw
:
Bytes
=
"f9beb4d86164647200000000000000001f000000ed52399b"
.into
();
assert_eq!
(
read_header
(
raw
.as_ref
(),
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidMagic
));
assert_eq!
(
read_header
(
raw
.as_ref
(),
0
,
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidMagic
));
}
#[test]
fn
test_read_too_short_header
()
{
let
raw
:
Bytes
=
"f9beb4d96164647200000000000000001f000000ed5239"
.into
();
assert!
(
read_header
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.is_err
());
assert!
(
read_header
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
))
.wait
()
.is_err
());
}
}
p2p/src/io/read_message.rs
View file @
c56e399d
...
...
@@ -6,14 +6,15 @@ use network::Magic;
use
message
::{
MessageResult
,
Error
,
Payload
};
use
io
::{
read_header
,
ReadHeader
,
read_payload
,
ReadPayload
};
pub
fn
read_message
<
M
,
A
>
(
a
:
A
,
magic
:
Magic
,
version
:
u32
)
->
ReadMessage
<
M
,
A
>
pub
fn
read_message
<
M
,
A
>
(
a
:
A
,
flags
:
u32
,
magic
:
Magic
,
version
:
u32
)
->
ReadMessage
<
M
,
A
>
where
A
:
AsyncRead
,
M
:
Payload
{
ReadMessage
{
state
:
ReadMessageState
::
ReadHeader
{
version
:
version
,
future
:
read_header
(
a
,
magic
),
future
:
read_header
(
a
,
flags
,
magic
),
},
message_type
:
PhantomData
flags
:
flags
,
message_type
:
PhantomData
,
}
}
...
...
@@ -29,6 +30,7 @@ enum ReadMessageState<M, A> {
pub
struct
ReadMessage
<
M
,
A
>
{
state
:
ReadMessageState
<
M
,
A
>
,
flags
:
u32
,
message_type
:
PhantomData
<
M
>
,
}
...
...
@@ -45,11 +47,12 @@ impl<M, A> Future for ReadMessage<M, A> where A: AsyncRead, M: Payload {
Ok
(
header
)
=>
header
,
Err
(
err
)
=>
return
Ok
((
read
,
Err
(
err
))
.into
()),
};
if
header
.command
!=
M
::
command
()
{
return
Ok
((
read
,
Err
(
Error
::
InvalidCommand
))
.into
());
}
let
future
=
read_payload
(
read
,
version
,
header
.len
as
usize
,
header
.checksum
,
read
,
version
,
self
.flags
,
header
.len
as
usize
,
header
.checksum
,
);
ReadMessageState
::
ReadPayload
{
future
:
future
,
...
...
@@ -78,21 +81,21 @@ mod tests {
fn
test_read_message
()
{
let
raw
:
Bytes
=
"f9beb4d970696e6700000000000000000800000083c00c765845303b6da97786"
.into
();
let
ping
=
Ping
::
new
(
u64
::
from_str_radix
(
"8677a96d3b304558"
,
16
)
.unwrap
());
assert_eq!
(
read_message
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Ok
(
ping
));
assert_eq!
(
read_message
::
<
Ping
,
_
>
(
raw
.as_ref
(),
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidMagic
));
assert_eq!
(
read_message
::
<
Pong
,
_
>
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidCommand
));
assert_eq!
(
read_message
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Ok
(
ping
));
assert_eq!
(
read_message
::
<
Ping
,
_
>
(
raw
.as_ref
(),
0
,
Network
::
Testnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidMagic
));
assert_eq!
(
read_message
::
<
Pong
,
_
>
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidCommand
));
}
#[test]
fn
test_read_too_short_message
()
{
let
raw
:
Bytes
=
"f9beb4d970696e6700000000000000000800000083c00c765845303b6da977"
.into
();
assert!
(
read_message
::
<
Ping
,
_
>
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.is_err
());
assert!
(
read_message
::
<
Ping
,
_
>
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.is_err
());
}
#[test]
fn
test_read_message_with_invalid_checksum
()
{
let
raw
:
Bytes
=
"f9beb4d970696e6700000000000000000800000083c01c765845303b6da97786"
.into
();
assert_eq!
(
read_message
::
<
Ping
,
_
>
(
raw
.as_ref
(),
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidChecksum
));
assert_eq!
(
read_message
::
<
Ping
,
_
>
(
raw
.as_ref
(),
0
,
Network
::
Mainnet
.magic
(
&
ConsensusFork
::
BitcoinCore
),
0
)
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidChecksum
));
}
}
p2p/src/io/read_payload.rs
View file @
c56e399d
...
...
@@ -8,11 +8,12 @@ use hash::H32;
use
crypto
::
checksum
;
use
message
::{
Error
,
MessageResult
,
Payload
,
deserialize_payload
};
pub
fn
read_payload
<
M
,
A
>
(
a
:
A
,
version
:
u32
,
len
:
usize
,
checksum
:
H32
)
->
ReadPayload
<
M
,
A
>
pub
fn
read_payload
<
M
,
A
>
(
a
:
A
,
version
:
u32
,
flags
:
u32
,
len
:
usize
,
checksum
:
H32
)
->
ReadPayload
<
M
,
A
>
where
A
:
AsyncRead
,
M
:
Payload
{
ReadPayload
{
reader
:
read_exact
(
a
,
Bytes
::
new_with_len
(
len
)),
version
:
version
,
flags
:
flags
,
checksum
:
checksum
,
payload_type
:
PhantomData
,
}
...
...
@@ -21,6 +22,7 @@ pub fn read_payload<M, A>(a: A, version: u32, len: usize, checksum: H32) -> Read
pub
struct
ReadPayload
<
M
,
A
>
{
reader
:
ReadExact
<
A
,
Bytes
>
,
version
:
u32
,
flags
:
u32
,
checksum
:
H32
,
payload_type
:
PhantomData
<
M
>
,
}
...
...
@@ -34,7 +36,7 @@ impl<M, A> Future for ReadPayload<M, A> where A: AsyncRead, M: Payload {
if
checksum
(
&
data
)
!=
self
.checksum
{
return
Ok
((
read
,
Err
(
Error
::
InvalidChecksum
))
.into
());
}
let
payload
=
deserialize_payload
(
&
data
,
self
.version
);
let
payload
=
deserialize_payload
(
&
data
,
self
.version
,
self
.flags
);
Ok
((
read
,
payload
)
.into
())
}
}
...
...
@@ -51,18 +53,18 @@ mod tests {
fn
test_read_payload
()
{
let
raw
:
Bytes
=
"5845303b6da97786"
.into
();
let
ping
=
Ping
::
new
(
u64
::
from_str_radix
(
"8677a96d3b304558"
,
16
)
.unwrap
());
assert_eq!
(
read_payload
(
raw
.as_ref
(),
0
,
8
,
"83c00c76"
.into
())
.wait
()
.unwrap
()
.1
,
Ok
(
ping
));
assert_eq!
(
read_payload
(
raw
.as_ref
(),
0
,
0
,
8
,
"83c00c76"
.into
())
.wait
()
.unwrap
()
.1
,
Ok
(
ping
));
}
#[test]
fn
test_read_payload_with_invalid_checksum
()
{
let
raw
:
Bytes
=
"5845303b6da97786"
.into
();
assert_eq!
(
read_payload
::
<
Ping
,
_
>
(
raw
.as_ref
(),
0
,
8
,
"83c00c75"
.into
())
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidChecksum
));
assert_eq!
(
read_payload
::
<
Ping
,
_
>
(
raw
.as_ref
(),
0
,
0
,
8
,
"83c00c75"
.into
())
.wait
()
.unwrap
()
.1
,
Err
(
Error
::
InvalidChecksum
));
}
#[test]
fn
test_read_too_short_payload
()
{
let
raw
:
Bytes
=
"5845303b6da977"
.into
();
assert!
(
read_payload
::
<
Ping
,
_
>
(
raw
.as_ref
(),
0
,
8
,
"83c00c76"
.into
())
.wait
()
.is_err
());
assert!
(
read_payload
::
<
Ping
,
_
>
(
raw
.as_ref
(),
0
,
0
,
8
,
"83c00c76"
.into
())
.wait
()
.is_err
());
}
}
p2p/src/net/accept_connection.rs
View file @
c56e399d
...
...
@@ -10,7 +10,7 @@ use net::{Config, Connection};
pub
fn
accept_connection
(
stream
:
TcpStream
,
handle
:
&
Handle
,
config
:
&
Config
,
address
:
net
::
SocketAddr
)
->
Deadline
<
AcceptConnection
>
{
let
accept
=
AcceptConnection
{
handshake
:
accept_handshake
(
stream
,
config
.magic
,
config
.version
(
&
address
),
config
.protocol_minimum
),
handshake
:
accept_handshake
(
stream
,
config
.serialization_flags
,
config
.magic
,
config
.version
(
&
address
),
config
.protocol_minimum
),
magic
:
config
.magic
,
address
:
address
,
};
...
...
p2p/src/net/channel.rs
View file @
c56e399d
...
...
@@ -23,7 +23,7 @@ impl Channel {
}
pub
fn
read_message
(
&
self
)
->
ReadAnyMessage
<
SharedTcpStream
>
{
read_any_message
(
self
.stream
.clone
(),
self
.peer_info.magic
)
read_any_message
(
self
.stream
.clone
(),
self
.peer_info.flags
,
self
.peer_info.magic
)
}
pub
fn
shutdown
(
&
self
)
{
...
...
p2p/src/net/config.rs
View file @
c56e399d
...
...
@@ -15,6 +15,7 @@ pub struct Config {
pub
user_agent
:
String
,
pub
start_height
:
i32
,
pub
relay
:
bool
,
pub
serialization_flags
:
u32
,
}
impl
Config
{
...
...
p2p/src/net/connect.rs
View file @
c56e399d
...
...
@@ -19,6 +19,7 @@ pub fn connect(address: &SocketAddr, handle: &Handle, config: &Config) -> Deadli
magic
:
config
.magic
,
address
:
*
address
,
protocol_minimum
:
config
.protocol_minimum
,
flags
:
config
.serialization_flags
,
};
deadline
(
Duration
::
new
(
5
,
0
),
handle
,
connect
)
.expect
(
"Failed to create timeout"
)
...
...
@@ -38,6 +39,7 @@ pub struct Connect {
magic
:
Magic
,
address
:
SocketAddr
,
protocol_minimum
:
u32
,
flags
:
u32
,
}
impl
Future
for
Connect
{
...
...
@@ -49,7 +51,7 @@ impl Future for Connect {
ConnectState
::
TcpConnect
{
ref
mut
future
,
ref
mut
version
}
=>
{
let
stream
=
try_ready!
(
future
.poll
());
let
version
=
version
.take
()
.expect
(
"state TcpConnect must have version"
);
let
handshake
=
handshake
(
stream
,
self
.magic
,
version
,
self
.protocol_minimum
);
let
handshake
=
handshake
(
stream
,
self
.flags
,
self
.magic
,
version
,
self
.protocol_minimum
);
(
ConnectState
::
Handshake
(
handshake
),
Async
::
NotReady
)
},
ConnectState
::
Handshake
(
ref
mut
future
)
=>
{
...
...
p2p/src/net/connections.rs
View file @
c56e399d
...
...
@@ -58,6 +58,7 @@ impl Connections {
version
:
connection
.version
,
version_message
:
connection
.version_message
,
magic
:
connection
.magic
,
flags
:
context
.serialization_flags
(),
};
let
session
=
T
::
new_session
(
context
,
peer_info
.clone
(),
SYNCHRONOUS_RESPONSES
);
...
...
p2p/src/p2p.rs
View file @
c56e399d
...
...
@@ -167,9 +167,9 @@ impl Context {
channel
.session
()
.initialize
();
Context
::
on_message
(
context
,
channel
)
},
Ok
(
DeadlineStatus
::
Meet
(
Err
(
_
)))
=>
{
Ok
(
DeadlineStatus
::
Meet
(
Err
(
err
)))
=>
{
// protocol error
trace!
(
"Handshake with {} failed"
,
socket
);
trace!
(
"Handshake with {} failed
with: {}
"
,
socket
,
err
);
// TODO: close socket
context
.node_table
.write
()
.note_failure
(
&
socket
);
context
.connection_counter
.note_close_outbound_connection
();
...
...
@@ -402,6 +402,10 @@ impl Context {
pub
fn
nodes
(
&
self
)
->
Vec
<
Node
>
{
self
.node_table
.read
()
.nodes
()
}
pub
fn
serialization_flags
(
&
self
)
->
u32
{
self
.config.serialization_flags
}
}
pub
struct
P2P
{
...
...
p2p/src/protocol/addr.rs
View file @
c56e399d
...
...
@@ -34,12 +34,12 @@ impl Protocol for AddrProtocol {
// normal nodes send addr message only after they receive getaddr message
// meanwhile seednodes, surprisingly, send addr message even before they are asked for it
if
command
==
&
GetAddr
::
command
()
{
let
_
:
GetAddr
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
));
let
_
:
GetAddr
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
,
self
.context
.info
()
.flags
));
let
entries
=
self
.context
.global
()
.node_table_entries
()
.into_iter
()
.map
(
Into
::
into
)
.collect
();
let
addr
=
Addr
::
new
(
entries
);
self
.context
.send_response_inline
(
&
addr
);
}
else
if
command
==
&
Addr
::
command
()
{
let
addr
:
Addr
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
));
let
addr
:
Addr
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
,
self
.context
.info
()
.flags
));
match
addr
{
Addr
::
V0
(
_
)
=>
{
unreachable!
(
"This version of protocol is not supported!"
);
...
...
p2p/src/protocol/ping.rs
View file @
c56e399d
...
...
@@ -78,11 +78,11 @@ impl Protocol for PingProtocol {
self
.state
=
State
::
WaitingTimeout
(
time
::
precise_time_s
());
if
command
==
&
Ping
::
command
()
{
let
ping
:
Ping
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
));
let
ping
:
Ping
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
,
self
.context
.info
()
.flags
));
let
pong
=
Pong
::
new
(
ping
.nonce
);
self
.context
.send_response_inline
(
&
pong
);
}
else
if
command
==
&
Pong
::
command
()
{
let
pong
:
Pong
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
));
let
pong
:
Pong
=
try
!
(
deserialize_payload
(
payload
,
self
.context
.info
()
.version
,
self
.context
.info
()
.flags
));
if
Some
(
pong
.nonce
)
!=
self
.last_ping_nonce
.take
()
{
return
Err
(
Error
::
InvalidCommand
)
}
...
...
p2p/src/protocol/sync.rs
View file @
c56e399d
...
...
@@ -202,82 +202,83 @@ impl Protocol for SyncProtocol {
fn
on_message
(
&
mut
self
,
command
:
&
Command
,
payload
:
&
Bytes
)
->
Result
<
(),
Error
>
{
let
version
=
self
.context
.info
()
.version
;
let
flags
=
self
.context
.info
()
.flags
;
if
command
==
&
types
::
Inv
::
command
()
{
let
message
:
types
::
Inv
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
Inv
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_inventory
(
message
);
}
else
if
command
==
&
types
::
GetData
::
command
()
{
let
message
:
types
::
GetData
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
GetData
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_getdata
(
message
);
}
else
if
command
==
&
types
::
GetBlocks
::
command
()
{
let
message
:
types
::
GetBlocks
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
GetBlocks
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_getblocks
(
message
);
}
else
if
command
==
&
types
::
GetHeaders
::
command
()
{
let
message
:
types
::
GetHeaders
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
GetHeaders
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
let
id
=
self
.context
.declare_response
();
trace!
(
"declared response {} for request: {}"
,
id
,
types
::
GetHeaders
::
command
());
self
.inbound_connection
.on_getheaders
(
message
,
id
);
}
else
if
command
==
&
types
::
Tx
::
command
()
{
let
message
:
types
::
Tx
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
Tx
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_transaction
(
message
);
}
else
if
command
==
&
types
::
Block
::
command
()
{
let
message
:
types
::
Block
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
Block
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_block
(
message
);
}
else
if
command
==
&
types
::
MemPool
::
command
()
{
let
message
:
types
::
MemPool
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
MemPool
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_mempool
(
message
);
}
else
if
command
==
&
types
::
Headers
::
command
()
{
let
message
:
types
::
Headers
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
Headers
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_headers
(
message
);
}
else
if
command
==
&
types
::
FilterLoad
::
command
()
{
let
message
:
types
::
FilterLoad
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
FilterLoad
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_filterload
(
message
);
}
else
if
command
==
&
types
::
FilterAdd
::
command
()
{
let
message
:
types
::
FilterAdd
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
FilterAdd
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_filteradd
(
message
);
}
else
if
command
==
&
types
::
FilterClear
::
command
()
{
let
message
:
types
::
FilterClear
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
FilterClear
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_filterclear
(
message
);
}
else
if
command
==
&
types
::
MerkleBlock
::
command
()
{
let
message
:
types
::
MerkleBlock
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
MerkleBlock
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_merkleblock
(
message
);
}
else
if
command
==
&
types
::
SendHeaders
::
command
()
{
let
message
:
types
::
SendHeaders
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
SendHeaders
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_sendheaders
(
message
);
}
else
if
command
==
&
types
::
FeeFilter
::
command
()
{
let
message
:
types
::
FeeFilter
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
FeeFilter
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_feefilter
(
message
);
}
else
if
command
==
&
types
::
SendCompact
::
command
()
{
let
message
:
types
::
SendCompact
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
SendCompact
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_send_compact
(
message
);
}
else
if
command
==
&
types
::
CompactBlock
::
command
()
{
let
message
:
types
::
CompactBlock
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
CompactBlock
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_compact_block
(
message
);
}
else
if
command
==
&
types
::
GetBlockTxn
::
command
()
{
let
message
:
types
::
GetBlockTxn
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
GetBlockTxn
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_get_block_txn
(
message
);
}
else
if
command
==
&
types
::
BlockTxn
::
command
()
{
let
message
:
types
::
BlockTxn
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
BlockTxn
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_block_txn
(
message
);
}
else
if
command
==
&
types
::
NotFound
::
command
()
{
let
message
:
types
::
NotFound
=
try
!
(
deserialize_payload
(
payload
,
version
));
let
message
:
types
::
NotFound
=
try
!
(
deserialize_payload
(
payload
,
version
,
flags
));
self
.inbound_connection
.on_notfound
(
message
);
}
Ok
(())
...
...
p2p/src/util/peer.rs
View file @
c56e399d
...
...
@@ -19,5 +19,6 @@ pub struct PeerInfo {
pub
version
:
u32
,
pub
version_message
:
types
::
Version
,
pub
magic
:
Magic
,
pub
flags
:
u32
,
}
pbtc/cli.yml
View file @
c56e399d
...
...
@@ -15,6 +15,9 @@ args:
-
bch
:
long
:
bch
help
:
Use Bitcoin Cash verification rules (BCH).
-
zcash
:
long
:
zcash
help
:
Use ZCash verification rules (ZCH).
-
connect
:
short
:
c
long
:
connect
...
...
pbtc/commands/rollback.rs
View file @
c56e399d
...
...
@@ -18,7 +18,7 @@ pub fn rollback(cfg: Config, matches: &ArgMatches) -> Result<(), String> {
};
let
required_block_hash
=
cfg
.db
.block_header
(
block_ref
.clone
())
.ok_or
(
format!
(
"Block {:?} is unknown"
,
block_ref
))
?
.hash
();
let
genesis_hash
=
cfg
.network
.genesis_block
()
.hash
();
let
genesis_hash
=
cfg
.network
.genesis_block
(
&
cfg
.consensus.fork
)
.hash
();
let
mut
best_block_hash
=
cfg
.db
.best_block
()
.hash
;
debug_assert!
(
best_block_hash
!=
H256
::
default
());
// genesis inserted in init_db
...
...
pbtc/commands/start.rs
View file @
c56e399d
...
...
@@ -4,9 +4,10 @@ use std::sync::Arc;
use
std
::
sync
::
mpsc
::{
channel
,
Sender
,
Receiver
};
use
std
::
sync
::
atomic
::{
AtomicBool
,
Ordering
};
use
sync
::{
create_sync_peers
,
create_local_sync_node
,
create_sync_connection_factory
,
SyncListener
};
use
network
::
ConsensusFork
;
use
primitives
::
hash
::
H256
;
use
util
::{
init_db
,
node_table_path
};
use
{
config
,
p2p
,
PROTOCOL_VERSION
,
PROTOCOL_MINIMUM
};
use
{
config
,
p2p
,
PROTOCOL_VERSION
,
PROTOCOL_MINIMUM
,
ZCASH_PROTOCOL_VERSION
,
ZCASH_
PROTOCOL_MINIMUM
};
use
super
::
super
::
rpc
;
enum
BlockNotifierTask
{
...
...
@@ -88,25 +89,39 @@ pub fn start(cfg: config::Config) -> Result<(), String> {
let
nodes_path
=
node_table_path
(
&
cfg
);
let
SERIALIZE_ZCASH
=
0x80000000
;
// TODO
let
serialization_flags
=
match
cfg
.consensus.fork
{
ConsensusFork
::
ZCash
(
_
)
=>
SERIALIZE_ZCASH
,
_
=>
0
,
};
let
p2p_cfg
=
p2p
::
Config
{
threads
:
cfg
.p2p_threads
,
inbound_connections
:
cfg
.inbound_connections
,
outbound_connections
:
cfg
.outbound_connections
,
connection
:
p2p
::
NetConfig
{
protocol_version
:
PROTOCOL_VERSION
,
protocol_minimum
:
PROTOCOL_MINIMUM
,
protocol_version
:
match
&
cfg
.consensus.fork
{
&
ConsensusFork
::
ZCash
(
_
)
=>
ZCASH_PROTOCOL_VERSION
,
_
=>
PROTOCOL_VERSION
,
},
protocol_minimum
:
match
&
cfg
.consensus.fork
{
&
ConsensusFork
::
ZCash
(
_
)
=>
ZCASH_PROTOCOL_MINIMUM
,
_
=>
PROTOCOL_MINIMUM
,
},
magic
:
cfg
.consensus
.magic
(),
local_address
:
SocketAddr
::
new
(
cfg
.host
,
cfg
.port
),
services
:
cfg
.services
,
user_agent
:
cfg
.user_agent
,
start_height
:
0
,
relay
:
true
,
serialization_flags
:
serialization_flags
,
},
peers
:
cfg
.connect
.map_or_else
(||
vec!
[],
|
x
|
vec!
[
x
]),
seeds
:
cfg
.seednodes
,
node_table_path
:
nodes_path
,
preferable_services
:
cfg
.services
,
internet_protocol
:
cfg
.internet_protocol
,
serialization_flags
:
serialization_flags
,
};
let
sync_peers
=
create_sync_peers
();
...
...
pbtc/config.rs
View file @
c56e399d
...
...
@@ -2,12 +2,14 @@ use std::net;
use
clap
;
use
storage
;
use
message
::
Services
;
use
network
::{
Network
,
ConsensusParams
,
ConsensusFork
,
BitcoinCashConsensusParams
};
use
network
::{
Network
,
ConsensusParams
,
ConsensusFork
,
BitcoinCashConsensusParams
,
ZCashConsensusParams
};
use
p2p
::
InternetProtocol
;
use
seednodes
::{
mainnet_seednodes
,
testnet_seednodes
,
bitcoin_cash_seednodes
,
bitcoin_cash_testnet_seednodes
};
use
seednodes
::{
mainnet_seednodes
,
testnet_seednodes
,
bitcoin_cash_seednodes
,
bitcoin_cash_testnet_seednodes
,
zcash_seednodes
};
use
rpc_apis
::
ApiSet
;
use
{
USER_AGENT
,
REGTEST_USER_AGENT
};
use
primitives
::
hash
::
H256
;
use
ser
;
use
rpc
::
HttpConfiguration
as
RpcHttpConfig
;
use
verification
::
VerificationLevel
;
use
sync
::
VerificationParameters
;
...
...
@@ -61,6 +63,11 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
let
consensus_fork
=
parse_consensus_fork
(
network
,
&
db
,
&
matches
)
?
;
let
consensus
=
ConsensusParams
::
new
(
network
,
consensus_fork
);
match
consensus
.fork
{
ConsensusFork
::
ZCash
(
_
)
=>
ser
::
set_default_flags
(
ser
::
SERIALIZE_ZCASH
),
_
=>
(),
};
let
(
in_connections
,
out_connections
)
=
match
network
{
Network
::
Testnet
|
Network
::
Mainnet
|
Network
::
Other
(
_
)
=>
(
10
,
10
),
Network
::
Regtest
|
Network
::
Unitest
=>
(
1
,
0
),
...
...
@@ -75,6 +82,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
let
user_agent_suffix
=
match
consensus
.fork
{
ConsensusFork
::
BitcoinCore
=>
""
,
ConsensusFork
::
BitcoinCash
(
_
)
=>
"/UAHF"
,
ConsensusFork
::
ZCash
(
_
)
=>
""
,
};
let
user_agent
=
match
network
{
Network
::
Testnet
|
Network
::
Mainnet
|
Network
::
Unitest
|
Network
::
Other
(
_
)
=>
format!
(
"{}{}"
,
USER_AGENT
,
user_agent_suffix
),
...
...
@@ -83,13 +91,13 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
let
port
=
match
matches
.value_of
(
"port"
)
{
Some
(
port
)
=>
port
.parse
()
.map_err
(|
_
|
"Invalid port"
.to_owned
())
?
,
None
=>
network
.port
(),
None
=>
network
.port
(
&
consensus
.fork
),
};
let
connect
=
match
matches
.value_of
(
"connect"
)
{
Some
(
s
)
=>
Some
(
match
s
.parse
::
<
net
::
SocketAddr
>
()
{
Err
(
_
)
=>
s
.parse
::
<
net
::
IpAddr
>
()
.map
(|
ip
|
net
::
SocketAddr
::
new
(
ip
,
network
.port
()))
.map
(|
ip
|
net
::
SocketAddr
::
new
(
ip
,
network
.port
(
&
consensus
.fork
)))
.map_err
(|
_
|
"Invalid connect"
.to_owned
()),
Ok
(
a
)
=>
Ok
(
a
),
}
?
),
...
...
@@ -99,6 +107,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
let
seednodes
:
Vec
<
String
>
=
match
matches
.value_of
(
"seednode"
)
{
Some
(
s
)
=>
vec!
[
s
.parse
()
.map_err
(|
_
|
"Invalid seednode"
.to_owned
())
?
],
None
=>
match
(
network
,
&
consensus
.fork
)
{
(
Network
::
Mainnet
,
&
ConsensusFork
::
ZCash
(
_
))
=>
zcash_seednodes
()
.into_iter
()
.map
(
Into
::
into
)
.collect
(),
(
Network
::
Mainnet
,
&
ConsensusFork
::
BitcoinCash
(
_
))
=>
bitcoin_cash_seednodes
()
.into_iter
()
.map
(
Into
::
into
)
.collect
(),
(
Network
::
Testnet
,
&
ConsensusFork
::
BitcoinCash
(
_
))
=>
bitcoin_cash_testnet_seednodes
()
.into_iter
()
.map
(
Into
::
into
)
.collect
(),
(
Network
::
Mainnet
,
_
)
=>
mainnet_seednodes
()
.into_iter
()
.map
(
Into
::
into
)
.collect
(),
...
...
@@ -131,6 +140,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
let
services
=
match
&
consensus
.fork
{
&
ConsensusFork
::
BitcoinCash
(
_
)
=>
services
.with_bitcoin_cash
(
true
),
&
ConsensusFork
::
BitcoinCore
=>
services
.with_witness
(
true
),
&
ConsensusFork
::
ZCash
(
_
)
=>
services
,
};
let
verification_level
=
match
matches
.value_of
(
"verification-level"
)
{
...
...
@@ -146,7 +156,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
let
edge
:
H256
=
s
.parse
()
.map_err
(|
_
|
"Invalid verification edge"
.to_owned
())
?
;
edge
.reversed
()
},
_
=>
network
.default_verification_edge
(),
_
=>
network
.default_verification_edge
(
&
consensus
.fork
),
};
let
config
=
Config
{
...
...
@@ -179,14 +189,15 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
fn
parse_consensus_fork
(
network
:
Network
,
db
:
&
storage
::
SharedStore
,
matches
:
&
clap
::
ArgMatches
)
->
Result
<
ConsensusFork
,
String
>
{
let
old_consensus_fork
=
db
.consensus_fork
()
?
;
let
new_consensus_fork
=
match
(
matches
.is_present
(
"btc"
),
matches
.is_present
(
"bch"
))
{
(
false
,
false
)
=>
match
&
old_consensus_fork
{
let
new_consensus_fork
=
match
(
matches
.is_present
(
"btc"
),
matches
.is_present
(
"bch"
)
,
matches
.is_present
(
"zcash"
)
)
{
(
false
,
false
,
false
)
=>
match
&
old_consensus_fork
{
&
Some
(
ref
old_consensus_fork
)
=>
old_consensus_fork
,
&
None
=>
return
Err
(
"You must select fork on first run: --btc, --bch"
.into
()),
&
None
=>
return
Err
(
"You must select fork on first run: --btc, --bch
or --zcash
"
.into
()),
},
(
true
,
false
)
=>
"btc"
,
(
false
,
true
)
=>
"bch"
,
_
=>
return
Err
(
"You can only pass single fork argument: --btc, --bch"
.into
()),
(
true
,
false
,
false
)
=>
"btc"
,
(
false
,
true
,
false
)
=>
"bch"
,
(
false
,
false
,
true
)
=>
"zcash"
,
_
=>
return
Err
(
"You can only pass single fork argument: --btc, --bch or --zcash"
.into
()),
};
match
&
old_consensus_fork
{
...
...
@@ -196,11 +207,12 @@ fn parse_consensus_fork(network: Network, db: &storage::SharedStore, matches: &c
return
Err
(
format!
(
"Cannot select '{}' fork with non-empty database of '{}' fork"
,
new_consensus_fork
,
old_consensus_fork
)),
}
return
match
new_consensus_fork
{
match
new_consensus_fork
{
"btc"
=>
Ok
(
ConsensusFork
::
BitcoinCore
),
"bch"
=>
Ok
(
ConsensusFork
::
BitcoinCash
(
BitcoinCashConsensusParams
::
new
(
network
))),
"zcash"
=>
Ok
(
ConsensusFork
::
ZCash
(
ZCashConsensusParams
::
new
(
network
))),
_
=>
Err
(
String
::
from
(
"Fork mandatory"
)),
}
;
}
}
fn
parse_rpc_config
(
network
:
Network
,
matches
:
&
clap
::
ArgMatches
)
->
Result
<
RpcHttpConfig
,
String
>
{
...
...
pbtc/main.rs
View file @
c56e399d
...
...
@@ -22,6 +22,7 @@ extern crate import;
extern
crate
rpc
as
ethcore_rpc
;
extern
crate
primitives
;
extern
crate
verification
;
extern
crate
serialization
as
ser
;
mod
commands
;
mod
config
;
...
...
@@ -35,7 +36,9 @@ use app_dirs::AppInfo;
pub
const
APP_INFO
:
AppInfo
=
AppInfo
{
name
:
"pbtc"
,
author
:
"Parity"
};
pub
const
PROTOCOL_VERSION
:
u32
=
70_014
;
pub
const
PROTOCOL_MINIMUM
:
u32
=
70_001
;
pub
const
USER_AGENT
:
&
'static
str
=
"pbtc"
;
pub
const
ZCASH_PROTOCOL_VERSION
:
u32
=
170_007
;
pub
const
ZCASH_PROTOCOL_MINIMUM
:
u32
=
170_007
;
pub
const
USER_AGENT
:
&
'static
str
=
"bcore"
;
pub
const
REGTEST_USER_AGENT
:
&
'static
str
=
"/Satoshi:0.12.1/"
;
pub
const
LOG_INFO
:
&
'static
str
=
"sync=info"
;
...
...
pbtc/seednodes.rs
View file @
c56e399d
...
...
@@ -47,3 +47,11 @@ pub fn bitcoin_cash_testnet_seednodes() -> Vec<&'static str> {
"testnet-seeder.criptolayer.net:18333"
]
}
pub
fn
zcash_seednodes
()
->
Vec
<&
'static
str
>
{
vec!
[
"dnsseed.z.cash:8233"
,
"dnsseed.str4d.xyz:8233"
,
"dnsseed.znodes.org:8233"
,
]
}
Prev
1
2
3
4
Next