diff options
author | Antoine A <> | 2023-11-23 03:52:49 +0100 |
---|---|---|
committer | Antoine A <> | 2023-11-23 03:52:49 +0100 |
commit | 52e7d8b74bdf30f0b718758dc3636d0ebe17c3cf (patch) | |
tree | a1a4e104f737041bd5215483aad1c038c8b7d9e9 | |
parent | 50be772c9d85eb2c1b59cd6ed9865acf7747e254 (diff) | |
download | depolymerization-52e7d8b74bdf30f0b718758dc3636d0ebe17c3cf.tar.gz depolymerization-52e7d8b74bdf30f0b718758dc3636d0ebe17c3cf.tar.bz2 depolymerization-52e7d8b74bdf30f0b718758dc3636d0ebe17c3cf.zip |
Fix dirty fix
-rw-r--r-- | btc-wire/src/segwit.rs | 343 | ||||
-rw-r--r-- | eth-wire/src/rpc.rs | 17 | ||||
-rw-r--r-- | instrumentation/src/eth.rs | 8 | ||||
-rw-r--r-- | instrumentation/src/main.rs | 3 |
4 files changed, 181 insertions, 190 deletions
diff --git a/btc-wire/src/segwit.rs b/btc-wire/src/segwit.rs index 5b7414d..e754d71 100644 --- a/btc-wire/src/segwit.rs +++ b/btc-wire/src/segwit.rs @@ -1,171 +1,172 @@ -/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-use bech32::{u5, FromBase32, ToBase32, Variant};
-use common::{rand::rngs::OsRng, rand_slice};
-
-/// Encode metadata into a segwit address
-pub fn encode_segwit_addr(hrp: &str, metada: &[u8; 20]) -> String {
- // We use the version 0 with bech32 encoding
- let mut buf = vec![u5::try_from_u8(0).unwrap()];
- buf.extend_from_slice(&metada.to_base32());
- bech32::encode(hrp, buf, Variant::Bech32).unwrap()
-}
-
-/// Encode half of a 32B key into a segwit address
-fn encode_segwit_key_half(
- hrp: &str,
- is_first: bool,
- prefix: &[u8; 4],
- key_half: &[u8; 16],
-) -> String {
- // Combine prefix and the key half
- let mut buf = [0u8; 20];
- buf[..4].copy_from_slice(prefix);
- buf[4..].copy_from_slice(key_half);
- // Toggle first bit for ordering
- if is_first {
- buf[0] &= 0b0111_1111 // Unset first bit
- } else {
- buf[0] |= 0b1000_0000 // Set first bit
- }
- // Encode into an fake segwit address
- encode_segwit_addr(hrp, &buf)
-}
-
-/// Encode a 32B key into two segwit adresses
-pub fn encode_segwit_key(hrp: &str, msg: &[u8; 32]) -> [String; 2] {
- // Generate a random prefix
- let prefix = rand_slice();
- // Split key in half;
- let split: (&[u8; 16], &[u8; 16]) =
- (msg[..16].try_into().unwrap(), msg[16..].try_into().unwrap());
- [
- encode_segwit_key_half(hrp, true, &prefix, split.0),
- encode_segwit_key_half(hrp, false, &prefix, split.1),
- ]
-}
-
-#[derive(Debug, Clone, thiserror::Error)]
-pub enum DecodeSegWitErr {
- #[error("There is less than 2 segwit addresses")]
- MissingSegWitAddress,
- #[error("No adresses are sharing a common prefix")]
- NoPrefixMatch,
- #[error("More than two addresses are sharing a common prefix")]
- PrefixCollision,
-}
-
-/// Decode a 32B key into from adresses
-pub fn decode_segwit_msg(segwit_addrs: &[impl AsRef<str>]) -> Result<[u8; 32], DecodeSegWitErr> {
- // Extract parts from every addresses
- let decoded: Vec<(bool, [u8; 4], [u8; 16])> = segwit_addrs
- .iter()
- .filter_map(|addr| {
- bech32::decode(addr.as_ref()).ok().and_then(|(_, wp, _)| {
- // Skip version
- let pg: Vec<u8> = Vec::from_base32(&wp[1..]).unwrap();
- if pg.len() == 20 {
- let mut prefix: [u8; 4] = pg[..4].try_into().unwrap();
- let key_half: [u8; 16] = pg[4..].try_into().unwrap();
- let is_first = !pg[0] & 0b1000_0000 == 0;
- // Clear first bit
- prefix[0] &= 0b0111_1111;
- Some((is_first, prefix, key_half))
- } else {
- None
- }
- })
- })
- .collect();
-
- if decoded.len() < 2 {
- return Err(DecodeSegWitErr::MissingSegWitAddress);
- }
- // Keep only the addresses with duplicated prefix
- // TODO use sort_unstable_by and partition_dedup_by_key when stable
- let matches: Vec<&(bool, [u8; 4], [u8; 16])> = decoded
- .iter()
- .filter(|(_, prefix, _)| {
- decoded
- .iter()
- .filter(|(_, other, _)| other == prefix)
- .count()
- > 1
- })
- .collect();
-
- if matches.len() > 2 {
- return Err(DecodeSegWitErr::PrefixCollision);
- } else if matches.len() < 2 {
- return Err(DecodeSegWitErr::MissingSegWitAddress);
- }
-
- let mut key = [0; 32];
- for (is_first, _, half) in matches {
- key[*is_first as usize * 16..][..16].copy_from_slice(half);
- }
- Ok(key)
-}
-
-// TODO find a way to hide that function while using it in test and benchmark
-pub fn rand_addresses(hrp: &str, key: &[u8; 32]) -> Vec<String> {
- use common::rand::prelude::SliceRandom;
-
- let mut rng_address: Vec<String> =
- std::iter::repeat_with(|| encode_segwit_addr(hrp, &rand_slice()))
- .take(2)
- .collect();
-
- let mut addresses = encode_segwit_key(hrp, key).to_vec();
- addresses.append(&mut rng_address);
- addresses.shuffle(&mut OsRng);
- addresses
-}
-
-#[cfg(test)]
-mod test {
- use common::{
- rand::{prelude::SliceRandom, rngs::OsRng},
- rand_slice,
- };
-
- use crate::segwit::{decode_segwit_msg, encode_segwit_key, rand_addresses};
-
- #[test]
- fn test_shuffle() {
- for _ in 0..1000 {
- let key = rand_slice();
- let mut addresses = encode_segwit_key("test", &key);
- addresses.shuffle(&mut OsRng);
- let decoded =
- decode_segwit_msg(&addresses.iter().map(|s| s.as_str()).collect::<Vec<&str>>())
- .unwrap();
- assert_eq!(key, decoded);
- }
- }
-
- #[test]
- fn test_shuffle_many() {
- for _ in 0..1000 {
- let key = rand_slice();
- let addresses = rand_addresses("test", &key);
- let decoded =
- decode_segwit_msg(&addresses.iter().map(|s| s.as_str()).collect::<Vec<&str>>())
- .unwrap();
- assert_eq!(key, decoded);
- }
- }
-}
+/* + This file is part of TALER + Copyright (C) 2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +use bech32::{u5, FromBase32, ToBase32, Variant}; +use common::{rand::rngs::OsRng, rand_slice}; +use std::cmp::Ordering; + +/// Encode metadata into a segwit address +pub fn encode_segwit_addr(hrp: &str, metada: &[u8; 20]) -> String { + // We use the version 0 with bech32 encoding + let mut buf = vec![u5::try_from_u8(0).unwrap()]; + buf.extend_from_slice(&metada.to_base32()); + bech32::encode(hrp, buf, Variant::Bech32).unwrap() +} + +/// Encode half of a 32B key into a segwit address +fn encode_segwit_key_half( + hrp: &str, + is_first: bool, + prefix: &[u8; 4], + key_half: &[u8; 16], +) -> String { + // Combine prefix and the key half + let mut buf = [0u8; 20]; + buf[..4].copy_from_slice(prefix); + buf[4..].copy_from_slice(key_half); + // Toggle first bit for ordering + if is_first { + buf[0] &= 0b0111_1111 // Unset first bit + } else { + buf[0] |= 0b1000_0000 // Set first bit + } + // Encode into an fake segwit address + encode_segwit_addr(hrp, &buf) +} + +/// Encode a 32B key into two segwit adresses +pub fn encode_segwit_key(hrp: &str, msg: &[u8; 32]) -> [String; 2] { + // Generate a random prefix + let prefix = rand_slice(); + // Split key in half; + let split: (&[u8; 16], &[u8; 16]) = + (msg[..16].try_into().unwrap(), msg[16..].try_into().unwrap()); + [ + encode_segwit_key_half(hrp, true, &prefix, split.0), + encode_segwit_key_half(hrp, false, &prefix, split.1), + ] +} + +#[derive(Debug, Clone, thiserror::Error)] +pub enum DecodeSegWitErr { + #[error("There is less than 2 segwit addresses")] + MissingSegWitAddress, + #[error("No adresses are sharing a common prefix")] + NoPrefixMatch, + #[error("More than two addresses are sharing a common prefix")] + PrefixCollision, +} + +/// Decode a 32B key into from adresses +pub fn decode_segwit_msg(segwit_addrs: &[impl AsRef<str>]) -> Result<[u8; 32], DecodeSegWitErr> { + // Extract parts from every addresses + let decoded: Vec<(bool, [u8; 4], [u8; 16])> = segwit_addrs + .iter() + .filter_map(|addr| { + bech32::decode(addr.as_ref()).ok().and_then(|(_, wp, _)| { + // Skip version + let pg: Vec<u8> = Vec::from_base32(&wp[1..]).unwrap(); + if pg.len() == 20 { + let mut prefix: [u8; 4] = pg[..4].try_into().unwrap(); + let key_half: [u8; 16] = pg[4..].try_into().unwrap(); + let is_first = !pg[0] & 0b1000_0000 == 0; + // Clear first bit + prefix[0] &= 0b0111_1111; + Some((is_first, prefix, key_half)) + } else { + None + } + }) + }) + .collect(); + + if decoded.len() < 2 { + return Err(DecodeSegWitErr::MissingSegWitAddress); + } + // Keep only the addresses with duplicated prefix + // TODO use sort_unstable_by and partition_dedup_by_key when stable + let matches: Vec<&(bool, [u8; 4], [u8; 16])> = decoded + .iter() + .filter(|(_, prefix, _)| { + decoded + .iter() + .filter(|(_, other, _)| other == prefix) + .count() + > 1 + }) + .collect(); + + match matches.len().cmp(&2) { + Ordering::Equal => { + let mut key = [0; 32]; + for (is_first, _, half) in matches { + key[*is_first as usize * 16..][..16].copy_from_slice(half); + } + Ok(key) + } + Ordering::Greater => Err(DecodeSegWitErr::PrefixCollision), + Ordering::Less => Err(DecodeSegWitErr::MissingSegWitAddress), + } +} + +// TODO find a way to hide that function while using it in test and benchmark +pub fn rand_addresses(hrp: &str, key: &[u8; 32]) -> Vec<String> { + use common::rand::prelude::SliceRandom; + + let mut rng_address: Vec<String> = + std::iter::repeat_with(|| encode_segwit_addr(hrp, &rand_slice())) + .take(2) + .collect(); + + let mut addresses = encode_segwit_key(hrp, key).to_vec(); + addresses.append(&mut rng_address); + addresses.shuffle(&mut OsRng); + addresses +} + +#[cfg(test)] +mod test { + use common::{ + rand::{prelude::SliceRandom, rngs::OsRng}, + rand_slice, + }; + + use crate::segwit::{decode_segwit_msg, encode_segwit_key, rand_addresses}; + + #[test] + fn test_shuffle() { + for _ in 0..1000 { + let key = rand_slice(); + let mut addresses = encode_segwit_key("test", &key); + addresses.shuffle(&mut OsRng); + let decoded = + decode_segwit_msg(&addresses.iter().map(|s| s.as_str()).collect::<Vec<&str>>()) + .unwrap(); + assert_eq!(key, decoded); + } + } + + #[test] + fn test_shuffle_many() { + for _ in 0..1000 { + let key = rand_slice(); + let addresses = rand_addresses("test", &key); + let decoded = + decode_segwit_msg(&addresses.iter().map(|s| s.as_str()).collect::<Vec<&str>>()) + .unwrap(); + assert_eq!(key, decoded); + } + } +} diff --git a/eth-wire/src/rpc.rs b/eth-wire/src/rpc.rs index 95d3428..66b16b0 100644 --- a/eth-wire/src/rpc.rs +++ b/eth-wire/src/rpc.rs @@ -180,14 +180,7 @@ impl Rpc { } pub fn subscribe_new_head(&mut self) -> Result<RpcStream<Nothing>> { - self.send("eth_subscribe", &["newHeads"])?; - let id = loop { - match self.receive::<SubscribeDirtyFix>()? { - SubscribeDirtyFix::Fix(_) => { /* TODO debug */ } - SubscribeDirtyFix::Id(id) => break id, - } - }; - let id = self.handle_response(id)?; + let id: String = self.call("eth_subscribe", &["newHeads"])?; Ok(RpcStream::new(self, id)) } @@ -288,7 +281,6 @@ impl<N: Debug + DeserializeOwned> Drop for RpcStream<'_, N> { NotificationOrResponse::Response(_) => return, } } - println!("has unusubsriced") } } @@ -407,11 +399,8 @@ pub trait RpcClient { /* ----- Miner ----- */ - fn miner_set_etherbase(&mut self, addr: &H160) -> Result<()> { - match self.call("miner_setEtherbase", &[addr]) { - Err(Error::Null) => Ok(()), - i => i, - } + fn miner_set_etherbase(&mut self, addr: &H160) -> Result<bool> { + self.call("miner_setEtherbase", &[addr]) } /// Start mining diff --git a/instrumentation/src/eth.rs b/instrumentation/src/eth.rs index f215fd3..7d5c534 100644 --- a/instrumentation/src/eth.rs +++ b/instrumentation/src/eth.rs @@ -321,7 +321,7 @@ impl EthCtx { &unused_port().to_string(), "--port", &unused_port().to_string(), - "--rpc.enabledeprecatedpersonal" + "--rpc.enabledeprecatedpersonal", ], &ctx.log("geth"), ); @@ -330,7 +330,7 @@ impl EthCtx { // Generate wallet let out = cmd_out( - &ctx.wire_bin_path, + &ctx.wire_bin_path, &["-c", ctx.conf.to_str().unwrap(), "initwallet"], ); @@ -442,7 +442,7 @@ impl EthCtx { &unused_port().to_string(), "--port", &unused_port().to_string(), - "--rpc.enabledeprecatedpersonal" + "--rpc.enabledeprecatedpersonal", ], &self.ctx.log("geth2"), ); @@ -485,7 +485,7 @@ impl EthCtx { &unused_port().to_string(), "--port", &unused_port().to_string(), - "--rpc.enabledeprecatedpersonal" + "--rpc.enabledeprecatedpersonal", ], &self.ctx.log("geth"), ); diff --git a/instrumentation/src/main.rs b/instrumentation/src/main.rs index 12971ad..c31fb71 100644 --- a/instrumentation/src/main.rs +++ b/instrumentation/src/main.rs @@ -17,7 +17,8 @@ use std::{ panic::catch_unwind, path::PathBuf, - time::{Duration, Instant}, sync::{Arc, Mutex}, + sync::{Arc, Mutex}, + time::{Duration, Instant}, }; use clap::Parser; |