Skip to content

Commit

Permalink
fix(bridge): avoid problems with overloaded functions
Browse files Browse the repository at this point in the history
By ensuring that only one function exists with any given name
  • Loading branch information
tmpolaczyk committed Mar 21, 2022
1 parent b56a7d1 commit 0f46bd5
Showing 1 changed file with 45 additions and 1 deletion.
46 changes: 45 additions & 1 deletion bridges/centralized-ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,40 @@ pub fn create_wrb_contract(eth_client_url: &str, wrb_contract_addr: H160) -> Con
let web3 = web3::Web3::new(web3_http);
// Why read files at runtime when you can read files at compile time
let wrb_contract_abi_json: &[u8] = include_bytes!("../wrb_abi.json");
let wrb_contract_abi = web3::ethabi::Contract::load(wrb_contract_abi_json)
let mut wrb_contract_abi = web3::ethabi::Contract::load(wrb_contract_abi_json)
.map_err(|e| format!("Unable to load WRB contract from ABI: {:?}", e))
.unwrap();

// Fix issue #2046, manually select the desired function when multiple candidates have the same name
// https://github.com/witnet/witnet-rust/issues/2046
hack_fix_functions_with_multiple_definitions(&mut wrb_contract_abi);

Contract::new(web3.eth(), wrb_contract_addr, wrb_contract_abi)
}

// The web3 library does not properly support overloaded functions yet, so here we ensure that there
// is no ambiguity and every function has only one possible definition
fn hack_fix_functions_with_multiple_definitions(wrb_contract_abi: &mut web3::ethabi::Contract) {
let functions = wrb_contract_abi
.functions
.get_mut("reportResult")
.expect("no reportResult function in ABI");
// There are two candidate "reportResult" functions, we want to keep the one with 4 inputs
assert_eq!(functions.len(), 2);
functions.retain(|f| f.inputs.len() == 4);
assert_eq!(functions.len(), 1);

// Ensure that all functions only have one possible definition
for (function_name, definitions) in &wrb_contract_abi.functions {
assert_eq!(
definitions.len(),
1,
"function {:?} is duplicated in ABI",
function_name
);
}
}

/// Check if the witnet node is running
pub async fn check_witnet_node_running(witnet_addr: &str) -> Result<(), String> {
let (_handle, witnet_client) = TcpSocket::new(witnet_addr).unwrap();
Expand Down Expand Up @@ -136,3 +164,19 @@ pub async fn handle_receipt(receipt: &TransactionReceipt) -> Result<(), ()> {
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_hack_fix_functions_with_multiple_definitions() {
// The hack_fix_functions_with_multiple_definitions function already does some checks
// internally, so here we call it to ensure the ABI is correct.
let wrb_contract_abi_json: &[u8] = include_bytes!("../wrb_abi.json");
let mut wrb_contract_abi = web3::ethabi::Contract::load(wrb_contract_abi_json)
.map_err(|e| format!("Unable to load WRB contract from ABI: {:?}", e))
.unwrap();
hack_fix_functions_with_multiple_definitions(&mut wrb_contract_abi);
}
}

0 comments on commit 0f46bd5

Please sign in to comment.