-
Notifications
You must be signed in to change notification settings - Fork 80
fix #112 - users were able to burn value during withdraw #114
Conversation
more explicit, easier to test in isolation
remove ignoring of messages with insufficient value because no longer needed. use user specified gas price on withdraw.
…by something easily modifiable (json, ethabi use)
|
||
/// an ECDSA signature consisting of `v`, `r` and `s` | ||
#[derive(PartialEq, Debug)] | ||
pub struct Signature { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hah... something like this should be migrated to ethereum-types
at some point ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
definitely : )
bridge/src/bridge/withdraw_relay.rs
Outdated
let payload: Bytes = app.home_bridge.functions().withdraw().input( | ||
signatures.iter().map(|x| Signature::v_from_bytes(x.0.as_slice())), | ||
signatures.iter().map(|x| Signature::r_from_bytes(x.0.as_slice()).0), | ||
signatures.iter().map(|x| Signature::s_from_bytes(x.0.as_slice()).0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v_from_bytes
, r_from_bytes
and s_from_bytes
panic if bytes is not long enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, you don't have to call as_slice
. &
is shorter and commonly used ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'll take more care here to handle the possible failures and either use Result
or a panic with a proof (q.e.d.
) it can't happen!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as_slice(x) == &x[..]
, as_slice(x) != &x
, right?
https://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_slice
usually i prefer &x[..]
as well.
i prefer .as_slice(x)
when it's part of a .
chain since it's only requires a suffix and not also a prefix.
bridge/src/bridge/withdraw_relay.rs
Outdated
signatures.iter().map(|x| Signature::s_from_bytes(x.0.as_slice()).0), | ||
message.clone().0).into(); | ||
let request = TransactionRequest { | ||
from: app.config.home.account.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need to clone()
it. It implements Copy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pub fn from_bytes(bytes: &[u8]) -> Self { | ||
assert_eq!(bytes.len(), MESSAGE_LENGTH); | ||
|
||
Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol, this is new. It wasn't available in old versions of rust
:)
bridge/src/message_to_mainnet.rs
Outdated
let hash = web3_log.transaction_hash | ||
.ok_or(Error::from_kind(ErrorKind::Msg("`log` must be mined and contain `transaction_hash`".into())))?; | ||
Ok(Self { | ||
recipient: withdraw_log.recipient.0.into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this conversion is probably redundant since web3
and ethabi
are using the same version of ethereum-types
crate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
bridge/src/message_to_mainnet.rs
Outdated
recipient: withdraw_log.recipient.0.into(), | ||
value: U256(withdraw_log.value.0), | ||
sidenet_transaction_hash: hash.to_vec().as_slice().into(), | ||
mainnet_gas_price: U256(withdraw_log.home_gas_price.0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all other coversion here as well
mainnet_gas_price_raw: u64 | ||
) -> TestResult { | ||
if recipient_raw.len() != 20 || sidenet_transaction_hash_raw.len() != 32 { | ||
return TestResult::discard(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it possible to specify the length of these vectors? If not, the chance that both of them will have desired len is pretty low...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's possible but more work. one would have to create a new type that implements quickchecks Arbitrary
and only generates vectors of a specific size.
quickcheck by default will fail if it doesn't generate at least 100 tests.
so we're guaranteed that it generates at least 100 vectors of the desired lengths.
this is not perfect but good enough in my opinion.
N.B. Since discarding a test means it neither passes nor fails, quickcheck will try to replace the discarded test with a fresh one. However, if your condition is seldom met, it's possible that quickcheck will have to settle for running fewer tests than usual. By default, if quickcheck can't find 100 valid tests after trying 10,000 times, then it will give up.
https://github.com/BurntSushi/quickcheck#discarding-test-results-or-properties-are-polymorphic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting. let's leave it as it is for now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now i remember the full context. this is just a workaround. the best solution would be to implement quickcheck::Arbitrary
for the types in ethereum-types! ethereum-types could benefit from some quickchecking itself as well. i'll give it a shot next week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. and let's hide it behind feature gate :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added paritytech/primitives#21
|
||
quickcheck! { | ||
fn quickcheck_signature_roundtrips(v: u8, r_raw: Vec<u8>, s_raw: Vec<u8>) -> TestResult { | ||
if r_raw.len() != 32 || s_raw.len() != 32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question. How are these lengths defined?
"eth_getLogs" => | ||
req => r#"[{"address":["0x0000000000000000000000000000000000000000"],"fromBlock":"0x1","limit":null,"toBlock":"0x1005","topics":[["0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"],null,null,null]}]"#, | ||
res => r#"[]"#; | ||
req => json!([{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 👍 👍
resolves grumbles: #114 (comment) #114 (comment)
resolves grumble: #114 (comment)
bridge/src/message_to_mainnet.rs
Outdated
@@ -41,10 +41,10 @@ impl MessageToMainnet { | |||
let hash = web3_log.transaction_hash | |||
.ok_or(Error::from_kind(ErrorKind::Msg("`log` must be mined and contain `transaction_hash`".into())))?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be also shortened to:
let hash = web3_log.transaction_hash.ok_or_else(|| "`log` must be mined and contain `transaction_hash`")?;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@debris all grumbles addressed |
Cargo.lock
Outdated
@@ -1026,6 +1051,7 @@ dependencies = [ | |||
"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a" | |||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" | |||
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" | |||
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one more thing. Can you bump env_logger
in cli/Cargo.toml:17:env_logger = "0.3"
to 0.4
? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the library is not duplicated :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
seen in many other solidity projects with high code quality
resolves grumble: paritytech/parity-bridge#114 (comment)
resolve grumble: paritytech/parity-bridge#114 (comment)
fixes #112 through solution laid out in issue
fix broke a lot of existing tests.
tests used a lot of raw data hex strings (#79) which were hard to adapt to changes.
therefore includes a pretty big refactoring to make it easy to adapt tests to changes like this.
still todo after opening PR:
tests
so they can be modified easiermessage
modulesignature
moduleHelpers.verifySignatures
Message.getHomeGasPrice