Skip to content

Commit

Permalink
add radix-connector
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukasz2891 committed Aug 19, 2024
1 parent 2ed3cb0 commit 3ef52b5
Show file tree
Hide file tree
Showing 20 changed files with 316 additions and 48 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ network = []
# An extension for casper network
network_casper = ["casper-contract/wee_alloc", "casper-types", "network"]

# An extension for radix network
network_radix = ["radix-common", "scrypto", "network"]

# An extension for debug-printing of messages in the Casper extension. Not supported by Casper Contracts deployed to the network.
print_debug = ["casper-contract/test-support"]

Expand All @@ -32,6 +35,8 @@ helpers = ["hex/serde", "hex/alloc", "network"]
[dependencies]
casper-contract = { version = "^4.0.0", default-features = false, features = [], optional = true }
casper-types = { version = "^4.0.1", default-features = false, features = [], optional = true }
radix-common = { version = "1.2.0", default-features = false, features = [], optional = true }
scrypto = { version = "1.2.0", optional = true }
sha3 = { version = "^0.10.8", default-features = false, features = [], optional = true }
k256 = { version = "^0.13.3", default-features = false, features = [], optional = true }
secp256k1 = { version = "^0.29.0", default-features = false, features = [], optional = true }
Expand Down
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
CLIPPY=cargo clippy --release --fix --allow-dirty --allow-staged
DOC=cargo doc --no-deps --document-private-items
TEST=RUST_BACKTRACE=full cargo test --features="helpers"
FEATURE_SETS="crypto_k256" "crypto_k256,network_casper" "crypto_secp256k1" "crypto_secp256k1,network_casper"

FEATURE_SETS="crypto_k256" "crypto_k256,network_casper" "crypto_secp256k1" "crypto_secp256k1,network_casper" "crypto_k256,network_radix" "crypto_secp256k1" "crypto_secp256k1,network_radix"

prepare:
@rustup target add wasm32-unknown-unknown
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports_granularity = "Crate"
3 changes: 1 addition & 2 deletions src/crypto/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
pub(crate) mod recover;

pub(crate)mod recover;
mod keccak256;
10 changes: 5 additions & 5 deletions src/crypto/recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn recover_address(message: Vec<u8>, signature: Vec<u8>) -> Vec<u8> {
}

#[cfg(feature = "crypto_secp256k1")]
pub mod crypto256 {
pub(crate) mod crypto256 {
use crate::network::{assert::Unwrap, error::Error};
use secp256k1::{ecdsa::RecoverableSignature, Message, Secp256k1 as Secp256k1Curve};

Expand All @@ -40,11 +40,11 @@ pub mod crypto256 {
}

#[cfg(feature = "crypto_k256")]
pub mod crypto256 {
pub(crate) mod crypto256 {
use crate::network::{assert::Unwrap, error::Error};
use k256::ecdsa::{RecoveryId, Signature, VerifyingKey};

pub fn recover_public_key(
pub(crate) fn recover_public_key(
message_hash: Box<[u8]>,
signature_bytes: &[u8],
recovery_byte: u8,
Expand All @@ -64,8 +64,8 @@ pub mod crypto256 {
}

#[cfg(all(not(feature = "crypto_k256"), not(feature = "crypto_secp256k1")))]
pub mod crypto256 {
pub fn recover_public_key(
pub(crate) mod crypto256 {
pub(crate) fn recover_public_key(
_message_hash: Box<[u8]>,
_signature_bytes: &[u8],
_recovery_byte: u8,
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/hex.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::network::specific::{Bytes, FromBytesRepr, U256};
use crate::network::specific::{Bytes, U256};
use hex::{decode, encode};
use std::{fs::File, io::Read};
use crate::network::from_bytes_repr::FromBytesRepr;

pub fn hex_to_bytes(hex_str: String) -> Vec<u8> {
let trimmed_hex = hex_str.trim_start_matches("0x");
Expand Down
40 changes: 40 additions & 0 deletions src/network/as_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub trait AsHexStr {
}

impl AsHexStr for &[u8] {
#[allow(clippy::format_collect)]
fn as_hex_str(&self) -> String {
self.iter().map(|byte| format!("{:02x}", byte)).collect()
}
Expand All @@ -20,12 +21,27 @@ impl AsHexStr for casper_types::bytesrepr::Bytes {
}
}

#[cfg(not(feature = "network_radix"))]
impl AsHexStr for U256 {
fn as_hex_str(&self) -> String {
format!("{:X}", self)
}
}

#[cfg(feature = "network_radix")]
impl AsHexStr for U256 {
fn as_hex_str(&self) -> String {
let digits = self.to_digits();
let mut result = String::new();
for &part in &digits {
if result.is_empty() || part != 0u64 {
result.push_str(&format!("{:02X}", part));
}
}
result
}
}

impl AsHexStr for Vec<u8> {
fn as_hex_str(&self) -> String {
self.as_slice().as_hex_str()
Expand Down Expand Up @@ -73,3 +89,27 @@ impl AsAsciiStr for U256 {
bytes.as_ascii_str()
}
}

#[cfg(test)]
mod tests {
use crate::network::as_str::{AsAsciiStr, AsHexStr};
use crate::network::specific::U256;

const ETH: u32 = 4543560u32;

#[test]
fn test_as_hex_str() {
let u256 = U256::from(ETH);
let result = u256.as_hex_str();

assert_eq!(result, "455448");
}

#[test]
fn test_as_ascii_str() {
let u256 = U256::from(ETH);
let result = u256.as_ascii_str();

assert_eq!(result, "ETH");
}
}
5 changes: 3 additions & 2 deletions src/network/casper/from_bytes_repr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::network::specific::{FromBytesRepr, U256};
use crate::network::from_bytes_repr::{FromBytesRepr, Sanitized};
use crate::network::specific::U256;

impl FromBytesRepr<Vec<u8>> for U256 {
fn from_bytes_repr(bytes: Vec<u8>) -> Self {
bytes.as_slice().into()
bytes.sanitized().as_slice().into()
}
}
126 changes: 126 additions & 0 deletions src/network/from_bytes_repr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
use crate::network::specific::{Bytes, VALUE_SIZE};

pub trait FromBytesRepr<T> {
fn from_bytes_repr(bytes: T) -> Self;
}

pub trait Sanitized {
fn sanitized(self) -> Self;
}

impl Sanitized for Bytes {
fn sanitized(self) -> Self {
if self.len() <= VALUE_SIZE {
return self;
}

let index = self.len().max(VALUE_SIZE) - VALUE_SIZE;
let remainder = &self[0..index];

if remainder != vec![0; index] {
panic!("Number to big: {:?} digits", self.len())
}

self[index..].into()
}
}

#[cfg(test)]
mod tests {
use crate::network::from_bytes_repr::FromBytesRepr;
use crate::network::specific::{U256, VALUE_SIZE};

#[cfg(feature = "network_radix")]
use crate::network::radix::u256_ext::U256Ext;

#[test]
fn test_from_bytes_repr_single() {
let vec = vec![1];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::from(1u32));
}

#[test]
fn test_from_bytes_repr_double() {
let vec = vec![1, 2];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::from(258u32));
}

#[test]
fn test_from_bytes_repr_simple() {
let vec = vec![1, 2, 3];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::from(66051u32));
}

#[test]
fn test_from_bytes_repr_bigger() {
let vec = vec![101, 202, 255];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::from(6671103u32));
}

#[test]
fn test_from_bytes_repr_empty() {
let result = U256::from_bytes_repr(Vec::new());

assert_eq!(result, U256::from(0u8));
}

#[test]
fn test_from_bytes_repr_trailing_zeroes() {
let vec = vec![1, 2, 3, 0];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::from(16909056u32));
}

#[test]
fn test_from_bytes_repr_leading_zeroes() {
let vec = vec![0, 1, 2, 3];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::from(66051u32));
}

#[allow(clippy::legacy_numeric_constants)]
#[test]
fn test_from_bytes_repr_max() {
let vec = vec![255; VALUE_SIZE];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::max_value());
}

#[test]
fn test_from_bytes_repr_min() {
let vec = vec![0; VALUE_SIZE];
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::from(0u8));
}

#[should_panic(expected = "Number to big")]
#[test]
fn test_from_bytes_repr_too_long() {
let x = VALUE_SIZE as u8 + 1;
let vec = (1..=x).collect();

U256::from_bytes_repr(vec);
}

#[allow(clippy::legacy_numeric_constants)]
#[test]
fn test_from_bytes_repr_too_long_but_zeroes() {
let mut vec = vec![255; VALUE_SIZE + 1];
vec[0] = 0;
let result = U256::from_bytes_repr(vec);

assert_eq!(result, U256::max_value());
}
}
11 changes: 9 additions & 2 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ pub mod assert;
pub mod error;
pub mod print_debug;
pub mod specific;
pub(crate) mod from_bytes_repr;

#[cfg(feature = "network_casper")]
pub mod casper;

#[cfg(feature = "network_casper")]
pub type _Network = casper::Casper;

#[cfg(feature = "network_radix")]
pub mod radix;

#[cfg(feature = "network_radix")]
pub type _Network = radix::Radix;

pub mod flattened;
#[cfg(not(feature = "network_casper"))]
#[cfg(all(not(feature = "network_casper"), not(feature = "network_radix")))]
mod std;

#[cfg(not(feature = "network_casper"))]
#[cfg(all(not(feature = "network_casper"), not(feature = "network_radix")))]
pub type _Network = std::Std;
18 changes: 18 additions & 0 deletions src/network/radix/from_bytes_repr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::network::from_bytes_repr::{FromBytesRepr, Sanitized};
use crate::network::specific::{U256};

impl FromBytesRepr<Vec<u8>> for U256 {
fn from_bytes_repr(bytes: Vec<u8>) -> Self {
match bytes.len() {
0 => U256::ZERO,
1 => U256::from(bytes[0]),
_ => {

// TODO: make it cheaper
let mut bytes_le = bytes.sanitized();
bytes_le.reverse();

U256::from_le_bytes(bytes_le.as_slice())
}}
}
}
38 changes: 38 additions & 0 deletions src/network/radix/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::network::{error::Error, specific::NetworkSpecific};

mod from_bytes_repr;
pub mod u256_ext;

pub struct Radix;

impl NetworkSpecific for Radix {
type BytesRepr = Vec<u8>;
type ValueRepr = radix_common::math::bnum_integer::U256;
type _Self = Self;

const VALUE_SIZE: usize = 32;

fn print(_text: String) {
#[cfg(all(not(test), feature = "print_debug"))]
{
println!("{}", _text);
}

#[cfg(test)]
{
println!("{}", _text);
}
}

fn revert(error: Error) -> ! {
#[cfg(not(test))]
{
panic!("{}", error)
}

#[cfg(test)]
{
panic!("{}", error)
}
}
}
12 changes: 12 additions & 0 deletions src/network/radix/u256_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

use crate::network::specific::U256;

pub trait U256Ext {
fn max_value() -> Self;
}

impl U256Ext for U256 {
fn max_value() -> Self {
Self::MAX
}
}
Loading

0 comments on commit 3ef52b5

Please sign in to comment.