Skip to content

Commit

Permalink
feat: support multiple contract versions (#739)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael1011 authored Dec 9, 2024
1 parent 3eb8acb commit 4649072
Show file tree
Hide file tree
Showing 42 changed files with 1,832 additions and 685 deletions.
315 changes: 200 additions & 115 deletions boltzr/Cargo.lock

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions boltzr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,22 @@ panic = "abort"
[dependencies]
axum = "0.7.7"
bitcoin_hashes = "0.15.0"
clap = { version = "4.5.20", features = ["derive"] }
clap = { version = "4.5.23", features = ["derive"] }
crossbeam-channel = "0.5.13"
ctrlc = { version = "3.4.5", features = ["termination"] }
dirs = "5.0.1"
num_cpus = "1.16.0"
prost = "0.13.3"
prost = "0.13.4"
rcgen = { version = "0.13.1", features = ["x509-parser"] }
reqwest = { version = "0.12.9", features = ["json"] }
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133"
tokio = { version = "1.38.1", features = ["rt-multi-thread", "macros", "process"] }
toml = "0.8.19"
tonic = { version = "0.12.3", features = ["prost", "tls"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tokio-util = "0.7.12"
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
tokio-util = "0.7.13"
tracing-loki = { version = "0.2.5", optional = true }
futures = "0.3.31"
metrics-process = { version = "2.1.0", optional = true }
Expand All @@ -58,7 +58,7 @@ axum-prometheus = { version = "0.6.1", default-features = false, optional = true
metrics = { version = "0.23.0", optional = true }
diesel_migrations = "2.2.0"
r2d2 = "0.8.10"
diesel = { version = "2.2.4", default-features = false, features = ["postgres", "r2d2", "chrono"] }
diesel = { version = "2.2.6", default-features = false, features = ["postgres", "r2d2", "chrono"] }
strum_macros = "0.26.4"
strum = "0.26.3"
dashmap = "6.1.0"
Expand All @@ -68,17 +68,17 @@ opentelemetry_sdk = { version = "0.25.0", optional = true, features = ["rt-tokio
opentelemetry-otlp = { version = "0.25.0", optional = true }
tracing-opentelemetry = { version = "0.26.0", optional = true }
diesel-tracing = { version = "0.3.0", optional = true, features = ["postgres", "r2d2", "statement-fields"] }
alloy = { version = "0.6.4", features = ["reqwest", "sol-types", "serde", "eip712", "signer-local", "signer-mnemonic", "providers", "transports", "contract", "json"] }
alloy-transport-http = "0.6.4"
alloy = { version = "0.7.3", features = ["reqwest", "sol-types", "serde", "eip712", "signer-local", "signer-mnemonic", "providers", "transports", "contract", "json"] }
alloy-transport-http = "0.7.3"
async-tungstenite = { version = "0.28.0", features = ["tokio-native-tls", "tokio-runtime"] }
async-trait = "0.1.83"
futures-util = "0.3.31"
async-stream = "0.3.6"
anyhow = "1.0.92"
anyhow = "1.0.94"
lightning = { version = "0.0.125", features = ["std"] }
lightning-invoice = { version = "0.32.0", features = ["std"] }
bech32 = "0.9.1"
bitcoin = "0.32.4"
bitcoin = "0.32.5"
elements = "0.25.1"
base64 = "0.22.1"
rust-s3 = "0.35.1"
Expand Down
5 changes: 5 additions & 0 deletions boltzr/protos/boltzr.proto
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ message SignEvmRefundRequest {
// When populated, an ERC20 refund signature will be signed
optional string token_address = 3;
uint64 timeout = 4;

oneof contract {
string address = 5;
uint64 version = 6;
}
}

message SignEvmRefundResponse {
Expand Down
11 changes: 7 additions & 4 deletions boltzr/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,9 @@ lokiNetwork = "someNetwork"
[rsk]
providerEndpoint = "http://127.0.0.1:8545"
etherSwapAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
erc20SwapAddress = "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
[[rsk.contracts]]
etherSwap = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
erc20Swap = "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
[sidecar]
[sidecar.grpc]
Expand Down Expand Up @@ -242,8 +243,10 @@ erc20SwapAddress = "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
config.rsk.unwrap(),
crate::evm::Config {
provider_endpoint: "http://127.0.0.1:8545".to_string(),
ether_swap_address: "0x5FbDB2315678afecb367f032d93F642f64180aa3".to_string(),
erc20_swap_address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512".to_string(),
contracts: vec![crate::evm::ContractAddresses {
ether_swap: "0x5FbDB2315678afecb367f032d93F642f64180aa3".to_string(),
erc20_swap: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512".to_string(),
}],
}
);

Expand Down
71 changes: 63 additions & 8 deletions boltzr/src/evm/contracts/erc20_swap.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use std::error::Error;

use crate::evm::contracts::erc20_swap::ERC20Swap::ERC20SwapInstance;
use crate::evm::contracts::SwapContract;
use alloy::primitives::{Address, U256};
use alloy::providers::Provider;
use alloy::sol;
use alloy::sol_types::Eip712Domain;
use tracing::{debug, info};

use crate::evm::contracts::erc20_swap::ERC20Swap::ERC20SwapInstance;

sol!(
#[allow(clippy::too_many_arguments)]
#[sol(rpc)]
Expand All @@ -31,6 +29,7 @@ pub struct ERC20SwapContract<T, P, N> {
#[allow(dead_code)]
contract: ERC20SwapInstance<T, P, N>,

version: u8,
eip712domain: Eip712Domain,
}

Expand All @@ -40,15 +39,28 @@ impl<
N: alloy::providers::network::Network,
> ERC20SwapContract<T, P, N>
{
pub async fn new(address: Address, provider: P) -> Result<Self, Box<dyn Error>> {
info!("Using {}: {}", NAME, address.to_string());
pub async fn new(address: Address, provider: P) -> anyhow::Result<Self> {
debug!("Using {}: {}", NAME, address.to_string());
let code = provider.get_code_at(address).await?;
if code.is_empty() {
return Err(anyhow::anyhow!(
"no contract at address: {}",
address.to_string()
));
}

let erc20_swap = ERC20Swap::new(address, provider.clone());
let chain_id = provider.get_chain_id().await?;
let version = erc20_swap.version().call().await?._0;
debug!("Found {} version: {}", NAME, version);
info!(
"Found {} ({}) version: {}",
NAME,
address.to_string(),
version
);

Ok(ERC20SwapContract {
version,
contract: erc20_swap,
eip712domain: Eip712Domain::new(
Some(NAME.into()),
Expand All @@ -59,16 +71,59 @@ impl<
),
})
}
}

impl<
T: alloy::transports::Transport + Sync + Send + Clone,
P: Provider<T, N> + Clone + 'static,
N: alloy::providers::network::Network,
> SwapContract for ERC20SwapContract<T, P, N>
{
fn address(&self) -> &Address {
self.contract.address()
}

pub fn eip712_domain(&self) -> &Eip712Domain {
fn version(&self) -> u8 {
self.version
}

fn eip712_domain(&self) -> &Eip712Domain {
&self.eip712domain
}
}

#[cfg(test)]
mod test {
use crate::evm::contracts::erc20_swap::ERC20SwapContract;
use crate::evm::contracts::SwapContract;
use crate::evm::refund_signer::test::ERC20_SWAP_ADDRESS;
use alloy::primitives::Address;

#[tokio::test]
async fn test_address() {
let (_, _, _, provider) = crate::evm::refund_signer::test::setup().await;
let contract = ERC20SwapContract::new(ERC20_SWAP_ADDRESS.parse().unwrap(), provider)
.await
.unwrap();

assert_eq!(
contract.address(),
&ERC20_SWAP_ADDRESS.parse::<Address>().unwrap()
);
}

#[tokio::test]
async fn test_version() {
let (_, _, _, provider) = crate::evm::refund_signer::test::setup().await;
let contract = ERC20SwapContract::new(ERC20_SWAP_ADDRESS.parse().unwrap(), provider)
.await
.unwrap();

assert_eq!(
contract.version(),
contract.contract.version().call().await.unwrap()._0
);
}

#[tokio::test]
async fn test_eip712_domain() {
Expand Down
67 changes: 62 additions & 5 deletions boltzr/src/evm/contracts/ether_swap.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::evm::contracts::ether_swap::EtherSwap::EtherSwapInstance;
use crate::evm::contracts::SwapContract;
use alloy::primitives::{Address, U256};
use alloy::providers::Provider;
use alloy::sol;
use alloy::sol_types::Eip712Domain;
use std::error::Error;
use tracing::{debug, info};

sol!(
Expand All @@ -28,6 +28,7 @@ pub struct EtherSwapContract<T, P, N> {
#[allow(dead_code)]
contract: EtherSwapInstance<T, P, N>,

version: u8,
eip712domain: Eip712Domain,
}

Expand All @@ -37,15 +38,28 @@ impl<
N: alloy::providers::network::Network,
> EtherSwapContract<T, P, N>
{
pub async fn new(address: Address, provider: P) -> Result<Self, Box<dyn Error>> {
info!("Using {}: {}", NAME, address.to_string());
pub async fn new(address: Address, provider: P) -> anyhow::Result<Self> {
debug!("Using {}: {}", NAME, address.to_string());
let code = provider.get_code_at(address).await?;
if code.is_empty() {
return Err(anyhow::anyhow!(
"no contract at address: {}",
address.to_string()
));
}

let ether_swap = EtherSwap::new(address, provider.clone());
let chain_id = provider.get_chain_id().await?;
let version = ether_swap.version().call().await?._0;
debug!("Found {} version: {}", NAME, version);
info!(
"Found {} ({}) version: {}",
NAME,
address.to_string(),
version
);

Ok(EtherSwapContract {
version,
contract: ether_swap,
eip712domain: Eip712Domain::new(
Some(NAME.into()),
Expand All @@ -56,16 +70,59 @@ impl<
),
})
}
}

impl<
T: alloy::transports::Transport + Sync + Send + Clone,
P: Provider<T, N> + Clone + 'static,
N: alloy::providers::network::Network,
> SwapContract for EtherSwapContract<T, P, N>
{
fn address(&self) -> &Address {
self.contract.address()
}

fn version(&self) -> u8 {
self.version
}

pub fn eip712_domain(&self) -> &Eip712Domain {
fn eip712_domain(&self) -> &Eip712Domain {
&self.eip712domain
}
}

#[cfg(test)]
mod test {
use crate::evm::contracts::ether_swap::EtherSwapContract;
use crate::evm::contracts::SwapContract;
use crate::evm::refund_signer::test::ETHER_SWAP_ADDRESS;
use alloy::primitives::Address;

#[tokio::test]
async fn test_address() {
let (_, _, _, provider) = crate::evm::refund_signer::test::setup().await;
let contract = EtherSwapContract::new(ETHER_SWAP_ADDRESS.parse().unwrap(), provider)
.await
.unwrap();

assert_eq!(
contract.address(),
&ETHER_SWAP_ADDRESS.parse::<Address>().unwrap()
);
}

#[tokio::test]
async fn test_version() {
let (_, _, _, provider) = crate::evm::refund_signer::test::setup().await;
let contract = EtherSwapContract::new(ETHER_SWAP_ADDRESS.parse().unwrap(), provider)
.await
.unwrap();

assert_eq!(
contract.version(),
contract.contract.version().call().await.unwrap()._0
);
}

#[tokio::test]
async fn test_eip712_domain() {
Expand Down
10 changes: 10 additions & 0 deletions boltzr/src/evm/contracts/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
use alloy::dyn_abi::Eip712Domain;
use alloy::primitives::Address;

pub mod erc20_swap;
pub mod ether_swap;

pub trait SwapContract {
fn address(&self) -> &Address;
fn version(&self) -> u8;

fn eip712_domain(&self) -> &Eip712Domain;
}
Loading

0 comments on commit 4649072

Please sign in to comment.