Skip to content

Commit

Permalink
Merge branch 'main' into fix/dont-egress-empty-batch
Browse files Browse the repository at this point in the history
  • Loading branch information
dandanlen authored Oct 12, 2023
2 parents b671cf9 + 0887c9a commit bb8aebb
Show file tree
Hide file tree
Showing 32 changed files with 326 additions and 94 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions api/bin/chainflip-broker-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ impl From<chainflip_api::SwapDepositAddress> for BrokerSwapDepositAddress {

#[rpc(server, client, namespace = "broker")]
pub trait Rpc {
#[method(name = "registerAccount")]
#[method(name = "register_account", aliases = ["broker_registerAccount"])]
async fn register_account(&self) -> Result<String, AnyhowRpcError>;

#[method(name = "requestSwapDepositAddress")]
#[method(name = "request_swap_deposit_address", aliases = ["broker_requestSwapDepositAddress"])]
async fn request_swap_deposit_address(
&self,
source_asset: Asset,
Expand Down
20 changes: 10 additions & 10 deletions api/bin/chainflip-lp-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,31 +66,31 @@ pub mod rpc_types {

#[rpc(server, client, namespace = "lp")]
pub trait Rpc {
#[method(name = "registerAccount")]
#[method(name = "register_account")]
async fn register_account(&self) -> Result<Hash, AnyhowRpcError>;

#[method(name = "liquidityDeposit")]
#[method(name = "liquidity_deposit")]
async fn request_liquidity_deposit_address(
&self,
asset: Asset,
) -> Result<String, AnyhowRpcError>;

#[method(name = "registerLiquidityRefundAddress")]
#[method(name = "register_liquidity_refund_address")]
async fn register_liquidity_refund_address(
&self,
chain: ForeignChain,
address: &str,
) -> Result<Hash, AnyhowRpcError>;

#[method(name = "withdrawAsset")]
#[method(name = "withdraw_asset")]
async fn withdraw_asset(
&self,
amount: NumberOrHex,
asset: Asset,
destination_address: &str,
) -> Result<(ForeignChain, u64), AnyhowRpcError>;

#[method(name = "updateRangeOrder")]
#[method(name = "update_range_order")]
async fn update_range_order(
&self,
base_asset: Asset,
Expand All @@ -101,7 +101,7 @@ pub trait Rpc {
size: RangeOrderSize,
) -> Result<Vec<RangeOrderReturn>, AnyhowRpcError>;

#[method(name = "setRangeOrder")]
#[method(name = "set_range_order")]
async fn set_range_order(
&self,
base_asset: Asset,
Expand All @@ -111,7 +111,7 @@ pub trait Rpc {
size: RangeOrderSize,
) -> Result<Vec<RangeOrderReturn>, AnyhowRpcError>;

#[method(name = "updateLimitOrder")]
#[method(name = "update_limit_order")]
async fn update_limit_order(
&self,
sell_asset: Asset,
Expand All @@ -122,7 +122,7 @@ pub trait Rpc {
amount: AssetAmount,
) -> Result<Vec<LimitOrderReturn>, AnyhowRpcError>;

#[method(name = "setLimitOrder")]
#[method(name = "set_limit_order")]
async fn set_limit_order(
&self,
sell_asset: Asset,
Expand All @@ -132,10 +132,10 @@ pub trait Rpc {
amount: AssetAmount,
) -> Result<Vec<LimitOrderReturn>, AnyhowRpcError>;

#[method(name = "assetBalances")]
#[method(name = "asset_balances")]
async fn asset_balances(&self) -> Result<BTreeMap<Asset, u128>, AnyhowRpcError>;

#[method(name = "getOpenSwapChannels")]
#[method(name = "get_open_swap_channels")]
async fn get_open_swap_channels(&self) -> Result<OpenSwapChannels, AnyhowRpcError>;
}

Expand Down
38 changes: 19 additions & 19 deletions bouncer/shared/lp_api_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async function provideLiquidityAndTestAssetBalances() {
let retryCount = 0;
let ethBalance = 0;
do {
const balances = await lpApiRpc(`lp_assetBalances`, []);
const balances = await lpApiRpc(`lp_asset_balances`, []);
ethBalance = balances.Eth;
retryCount++;
if (retryCount > 14) {
Expand All @@ -60,12 +60,12 @@ async function testRegisterLiquidityRefundAddress() {
(event) => event.data.address.Eth === ethAddress,
);

const registerRefundAddress = await lpApiRpc(`lp_registerLiquidityRefundAddress`, [
const registerRefundAddress = await lpApiRpc(`lp_register_liquidity_refund_address`, [
'Ethereum',
ethAddress,
]);
if (!isValidHexHash(await registerRefundAddress)) {
throw new Error(`Unexpected lp_registerLiquidityRefundAddress result`);
throw new Error(`Unexpected lp_register_liquidity_refund_address result`);
}
await observeRefundAddressRegisteredEvent;

Expand All @@ -79,7 +79,7 @@ async function testLiquidityDeposit() {
(event) => event.data.depositAddress.Eth,
);
// TODO: This result will need to be updated after #3995 is merged
const liquidityDepositAddress = await lpApiRpc(`lp_liquidityDeposit`, ['Eth']);
const liquidityDepositAddress = await lpApiRpc(`lp_liquidity_deposit`, ['Eth']);
const liquidityDepositEvent = await observeLiquidityDepositAddressReadyEvent;

assert.strictEqual(
Expand Down Expand Up @@ -107,7 +107,7 @@ async function testLiquidityDeposit() {
async function testWithdrawAsset() {
const oldBalance = await getBalance('ETH', ethAddress);

const [asset, egressId] = await lpApiRpc(`lp_withdrawAsset`, [
const [asset, egressId] = await lpApiRpc(`lp_withdraw_asset`, [
testAssetAmount,
'Eth',
ethAddress,
Expand All @@ -120,18 +120,18 @@ async function testWithdrawAsset() {

async function testRegisterWithExistingLpAccount() {
try {
await lpApiRpc(`lp_registerAccount`, []);
throw new Error(`Unexpected lp_registerAccount result`);
await lpApiRpc(`lp_register_account`, []);
throw new Error(`Unexpected lp_register_account result`);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
// This account is already registered, so the command will fail.
if (!error.message.includes('Could not register account role for account')) {
throw new Error(`Unexpected lp_registerAccount error: ${JSON.stringify(error)}`);
throw new Error(`Unexpected lp_register_account error: ${JSON.stringify(error)}`);
}
}
}

/// Test lp_setRangeOrder and lp_updateRangeOrder by minting, updating, and burning a range order.
/// Test lp_set_range_order and lp_update_range_order by minting, updating, and burning a range order.
async function testRangeOrder() {
const range = { start: 1, end: 2 };
const orderId = 74398; // Arbitrary order id so it does not interfere with other tests
Expand All @@ -143,10 +143,10 @@ async function testRangeOrder() {
};

// Cleanup after any unfinished previous test so it does not interfere with this test
await lpApiRpc(`lp_setRangeOrder`, ['Usdc', 'Eth', orderId, range, zeroAssetAmounts]);
await lpApiRpc(`lp_set_range_order`, ['Usdc', 'Eth', orderId, range, zeroAssetAmounts]);

// Mint a range order
const mintRangeOrder = await lpApiRpc(`lp_setRangeOrder`, [
const mintRangeOrder = await lpApiRpc(`lp_set_range_order`, [
'Usdc',
'Eth',
orderId,
Expand All @@ -171,7 +171,7 @@ async function testRangeOrder() {
);

// Update the range order
const updateRangeOrder = await lpApiRpc(`lp_updateRangeOrder`, [
const updateRangeOrder = await lpApiRpc(`lp_update_range_order`, [
'Usdc',
'Eth',
orderId,
Expand All @@ -197,7 +197,7 @@ async function testRangeOrder() {
);

// Burn the range order
const burnRangeOrder = await lpApiRpc(`lp_setRangeOrder`, [
const burnRangeOrder = await lpApiRpc(`lp_set_range_order`, [
'Usdc',
'Eth',
orderId,
Expand All @@ -220,22 +220,22 @@ async function testRangeOrder() {

async function testGetOpenSwapChannels() {
// TODO: Test with some SwapChannelInfo data
const openSwapChannels = await lpApiRpc(`lp_getOpenSwapChannels`, []);
const openSwapChannels = await lpApiRpc(`lp_get_open_swap_channels`, []);
assert(openSwapChannels.ethereum, `Missing ethereum swap channel info`);
assert(openSwapChannels.polkadot, `Missing polkadot swap channel info`);
assert(openSwapChannels.bitcoin, `Missing bitcoin swap channel info`);
}

/// Test lp_setLimitOrder and lp_updateLimitOrder by minting, updating, and burning a limit order.
/// Test lp_set_limit_order and lp_update_limit_order by minting, updating, and burning a limit order.
async function testLimitOrder() {
const orderId = 98432; // Arbitrary order id so it does not interfere with other tests
const tick = 2;

// Cleanup after any unfinished previous test so it does not interfere with this test
await lpApiRpc(`lp_setLimitOrder`, ['Eth', 'Usdc', orderId, tick, 0]);
await lpApiRpc(`lp_set_limit_order`, ['Eth', 'Usdc', orderId, tick, 0]);

// Mint a limit order
const mintLimitOrder = await lpApiRpc(`lp_setLimitOrder`, [
const mintLimitOrder = await lpApiRpc(`lp_set_limit_order`, [
'Eth',
'Usdc',
orderId,
Expand All @@ -255,7 +255,7 @@ async function testLimitOrder() {
);

// Update the limit order
const updateLimitOrder = await lpApiRpc(`lp_updateLimitOrder`, [
const updateLimitOrder = await lpApiRpc(`lp_update_limit_order`, [
'Eth',
'Usdc',
orderId,
Expand All @@ -276,7 +276,7 @@ async function testLimitOrder() {
);

// Burn the limit order
const burnLimitOrder = await lpApiRpc(`lp_setLimitOrder`, ['Eth', 'Usdc', orderId, tick, 0]);
const burnLimitOrder = await lpApiRpc(`lp_set_limit_order`, ['Eth', 'Usdc', orderId, tick, 0]);
assert(burnLimitOrder.length >= 1, `Empty burn limit order result`);
assert.strictEqual(
burnLimitOrder[0].increase_or_decrease,
Expand Down
8 changes: 6 additions & 2 deletions engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ maintainer-scripts = "package/"
name = "chainflip-engine"
priority = "required"
section = "rust"
systemd-units = { unit-name = "chainflip-engine", enable = false }
assets = [["target/release/chainflip-engine", "usr/bin/", "755"]]
systemd-units = [
{ unit-name = "chainflip-engine", enable = false },
{ unit-name = "chainflip-engine-lsr", enable = false }
]
assets = [["target/release/chainflip-engine", "usr/bin/chainflip-engine-lsr", "755"]]

[package.metadata.deb.variants.development]
maintainer-scripts = "package/development"
Expand Down Expand Up @@ -85,6 +88,7 @@ zmq = { git = "https://github.com/chainflip-io/rust-zmq.git", tag = "chainflip-v
"vendored",
] }
warp = { version = "0.3.6" }
regex = { version = "1"}

# Local deps
cf-chains = { path = "../state-chain/chains" }
Expand Down
4 changes: 2 additions & 2 deletions engine/config/testing/config/Settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ ws_endpoint = "ws://localhost:8545"

[dot.rpc]
# NB: You will need to manually add :443 to the url provided by the provider, as jsonrpsee wants one.
ws_endpoint = "wss://my_fake_polkadot_rpc:443/<secret_key>"
http_endpoint = "http://my_fake_polkadot_rpc:443/<secret_key>"
ws_endpoint = "wss://my_fake_polkadot_rpc:443/secret_key"
http_endpoint = "http://my_fake_polkadot_rpc:443/secret_key"

[btc.rpc]
http_endpoint = "http://localhost:18443"
Expand Down
16 changes: 16 additions & 0 deletions engine/package/perseverance/chainflip-engine-lsr.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[Unit]
Description=Chainflip Validator Engine (LSR)
After=chainflip-node.service

[Service]
Restart=always
RestartSec=30
Type=simple

ExecStart=/usr/bin/chainflip-engine-lsr --config-root /etc/chainflip/
Environment=RUST_LOG="chainflip_engine=debug,multisig=debug,warn,chainflip_engine::p2p=error"
LimitNOFILE=16000
LimitNOFILESoft=16000

[Install]
WantedBy=multi-user.target
16 changes: 16 additions & 0 deletions engine/package/sisyphos/chainflip-engine-lsr.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[Unit]
Description=Chainflip Validator Engine (LSR)
After=chainflip-node.service

[Service]
Restart=always
RestartSec=30
Type=simple

ExecStart=/usr/bin/chainflip-engine-lsr --config-root /etc/chainflip/

LimitNOFILE=16000
LimitNOFILESoft=16000

[Install]
WantedBy=multi-user.target
59 changes: 58 additions & 1 deletion engine/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use config::{Config, ConfigBuilder, ConfigError, Environment, File, Map, Source,
use serde::{de, Deserialize, Deserializer};

pub use anyhow::Result;
use regex::Regex;
use sp_runtime::DeserializeOwned;
use url::Url;

Expand Down Expand Up @@ -106,8 +107,35 @@ pub struct Dot {

impl Dot {
pub fn validate_settings(&self) -> Result<(), ConfigError> {
self.nodes.validate()
self.nodes.validate()?;

// Check that all endpoints have a port number
let validate_dot_endpoints = |endpoints: &WsHttpEndpoints| -> Result<(), ConfigError> {
validate_port_exists(&endpoints.ws_endpoint)
.and_then(|_| validate_port_exists(&endpoints.http_endpoint))
.map_err(|e| {
ConfigError::Message(format!(
"Polkadot node endpoints must include a port number: {e}"
))
})
};
validate_dot_endpoints(&self.nodes.primary)?;
if let Some(backup) = &self.nodes.backup {
validate_dot_endpoints(backup)?;
}
Ok(())
}
}

// Checks that the url has a port number
fn validate_port_exists(url: &SecretUrl) -> Result<()> {
// NB: We are using regex instead of Url because Url.port() returns None for wss/https urls with
// default ports.
let re = Regex::new(r":([0-9]+)").unwrap();
if re.captures(url.as_ref()).is_none() {
bail!("No port found in url: {url}");
}
Ok(())
}

#[derive(Debug, Deserialize, Clone, Default, PartialEq, Eq)]
Expand Down Expand Up @@ -992,4 +1020,33 @@ pub mod tests {
assert!(is_valid_db_path(Path::new("data.errdb")).is_err());
assert!(is_valid_db_path(Path::new("thishasnoextension")).is_err());
}

#[test]
fn test_dot_port_validation() {
let valid_settings = Dot {
nodes: NodeContainer {
primary: WsHttpEndpoints {
ws_endpoint: "wss://valid.endpoint_with_port:443/secret_key".into(),
http_endpoint: "https://valid.endpoint_with_port:443/secret_key".into(),
},
backup: Some(WsHttpEndpoints {
ws_endpoint: "ws://valid.endpoint_with_port:1234".into(),
http_endpoint: "http://valid.endpoint_with_port:6969".into(),
}),
},
};
assert_ok!(valid_settings.validate_settings());

let mut invalid_primary_settings = valid_settings.clone();
invalid_primary_settings.nodes.primary.ws_endpoint =
"ws://invalid.no_port_in_url/secret_key".into();
assert!(invalid_primary_settings.validate_settings().is_err());

let mut invalid_backup_settings = valid_settings.clone();
invalid_backup_settings.nodes.backup = Some(WsHttpEndpoints {
ws_endpoint: "ws://valid.endpoint_with_port:443".into(),
http_endpoint: "http://invalid.no_port_in_url/secret_key".into(),
});
assert!(invalid_backup_settings.validate_settings().is_err());
}
}
Loading

0 comments on commit bb8aebb

Please sign in to comment.