From 696fcbe07ac7926b2ba12d50e55b6c7dd66979dc Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 26 Dec 2018 18:05:41 -0500 Subject: [PATCH] Enable overflow checking on the release build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is probably best for smart contracts, where math errors are likely to be security vulnerabilities, and so overflow should be caught at run-time. Ideally, this could be done without enabling all debug assertions, but Rust doesn’t provide for this. The fold in src/bridge.rs has had overflow checking added explicitly. --- Cargo.toml | 3 +++ src/bridge.rs | 8 +++++++- src/lib.rs | 13 ++++--------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 646a0e9..e33eb21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,3 +43,6 @@ std = [ "srml-timestamp/std", "srml-democracy/std", ] + +[profile.release] +debug-assertions = true diff --git a/src/bridge.rs b/src/bridge.rs index 5ccb128..3f377b8 100644 --- a/src/bridge.rs +++ b/src/bridge.rs @@ -114,7 +114,13 @@ decl_module! { // TODO: Ensure that checking balances is sufficient vs. finding explicit stake amounts let stake_sum = new_signers.iter() .map(|s| >::total_balance(s)) - .fold(Zero::zero(), |a, b| a + b); + .fold(Zero::zero(), |a, b| { + let res = a + b; + if res < a || res < b || res - b != a { + panic!("Integer overflow in balance calculation") + } + res + }); // Check if we approve the proposal, if so, mark approved let total_issuance = >::total_issuance(); diff --git a/src/lib.rs b/src/lib.rs index 6e7cd47..bc926be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,11 +47,6 @@ extern crate srml_timestamp as timestamp; extern crate srml_democracy as democracy; extern crate srml_consensus as consensus; -// use council::{voting, motions, seats}; - -use runtime_support::dispatch::Result; -// use primitives::ed25519; - pub mod bridge; pub use bridge::{Module, Trait, RawEvent, Event}; @@ -154,19 +149,19 @@ mod tests { t.into() } - fn deposit(who: u64, target: u64, transaction_hash: H256, quantity: u64) -> super::Result { + fn deposit(who: u64, target: u64, transaction_hash: H256, quantity: u64) -> runtime_support::dispatch::Result { Bridge::deposit(Origin::signed(who), target, transaction_hash, quantity) } - fn sign_deposit(who: u64, target: u64, transaction_hash: H256, quantity: u64) -> super::Result { + fn sign_deposit(who: u64, target: u64, transaction_hash: H256, quantity: u64) -> runtime_support::dispatch::Result { Bridge::sign_deposit(Origin::signed(who), target, transaction_hash, quantity) } - fn withdraw(who: u64, quantity: u64, signed_cross_chain_tx: &[u8]) -> super::Result { + fn withdraw(who: u64, quantity: u64, signed_cross_chain_tx: &[u8]) -> runtime_support::dispatch::Result { Bridge::withdraw(Origin::signed(who), quantity, signed_cross_chain_tx.to_vec()) } - fn sign_withdraw(who: u64, target: u64, record_hash: H256, quantity: u64, signed_cross_chain_tx: &[u8]) -> super::Result { + fn sign_withdraw(who: u64, target: u64, record_hash: H256, quantity: u64, signed_cross_chain_tx: &[u8]) -> runtime_support::dispatch::Result { Bridge::sign_withdraw(Origin::signed(who), target, record_hash, quantity, signed_cross_chain_tx.to_vec()) }