Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: New vault swap encoding RPC & bouncer test #5384

Merged
merged 18 commits into from
Nov 11, 2024
Merged

Conversation

j4m1ef0rd
Copy link
Contributor

@j4m1ef0rd j4m1ef0rd commented Nov 5, 2024

Pull Request

Closes: PRO-1754 & PRO-1752

Checklist

Please conduct a thorough self-review before opening the PR.

  • I am confident that the code works.
  • I have written sufficient tests.
  • I have written and tested required migrations.
  • I have updated documentation where appropriate.

Summary

  • New vault swap encoding RPC to the statechain.
  • Refactored the vault swap encoding RPC on the broker API to just be a pass through.
  • New bouncer test that uses the new RPC to get the encoded data and deposit address, then constructs the Btc transaction and broadcasts it and waits for the swap to go through.

TODO

  • Return private channel address
  • Update documentation
  • Add test to the concurrent tests and possibly add more test swaps.
  • When using the SC RPC's, errors appear with no information, just RpcError: -32603: {error}.

@@ -86,20 +84,6 @@ pub trait Rpc {
asset: Asset,
destination_address: AddressString,
) -> RpcResult<WithdrawFeesDetail>;

#[method(name = "request_swap_parameter_encoding", aliases = ["broker_requestSwapParameterEncoding"])]
async fn request_swap_parameter_encoding(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to keep this in the broker api, and pass it through to the custom rpc.

Comment on lines 78 to 79
#[derive(Clone, Serialize, Deserialize)]
pub enum EncodedVaultSwapParamsBytes {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to use internally tagged enum variants here.

Suggested change
#[derive(Clone, Serialize, Deserialize)]
pub enum EncodedVaultSwapParamsBytes {
#[derive(Clone, Serialize, Deserialize)]
#[serde(tag = "chain")]
pub enum EncodedVaultSwapParamsBytes {

@@ -68,6 +69,33 @@ use std::{
pub mod monitoring;
pub mod order_fills;

#[derive(Clone, Serialize, Deserialize)]
pub struct VaultSwapDetailsHumanreadable {
pub deposit_address: ForeignChainAddressHumanreadable,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We won't need to return an address for every chain - it's only for bitcoin where it depends on the broker_id and current epoch. For other chains there is a vault contract, which is static. We can still return this static address I suppose but calling it a deposit_address is not always accurate.

I would suggest putting this inside the enum's bitcoin variant.


#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize)]
pub enum EncodedVaultSwapParams {
Bitcoin { nulldata_utxo: Vec<u8> },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just use Bytes everywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bytes does not have TypeInfo, which the runtime apis need for some reason.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah... helpful.

I had a dig, we can do this:

Bitcoin {
	#[serde(with = "sp_core::bytes")]
	nulldata_utxo: Vec<u8> },
}

type VanityName = Vec<u8>;

#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize)]
pub struct VaultSwapDetails {
pub deposit_address: ForeignChainAddress,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do the conversion in the runtime so we don't need separate types here vs in the rpc layer.

Take a look at chainflip::ChainAddressConverter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was unable to find a easy way to output the address as hex without using 2 structs or changing EncodedAddress.

Comment on lines 2151 to 2154
output_address: to_encoded_address(
destination_address,
Environment::network_environment,
),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
output_address: to_encoded_address(
destination_address,
Environment::network_environment,
),
output_address: ChainAddressConverter::to_encoded_address(
destination_address,
),

.unwrap_or(1)
.try_into()
.map_err(|_| {
Into::<DispatchErrorWithMessage>::into(DispatchError::from(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These error conversions are quite repetitive - maybe we just need to write the correct From implementation for DispatchErrorWithMessage?

At the very least we could write a struct method to make this more readable. Something like this might do the trick:

impl DispatchErrorWithMessage {
	pub fn from_pallet_error(e: impl Into<DispatchError>) {
		Self::from(e.into())
	}
}

chunk_interval: dca_parameters
.as_ref()
.map(|params| params.chunk_interval)
.unwrap_or(2)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid using a magic number here? Isn't there a constant defined in the swapping pallet?

Comment on lines 2191 to 2192
let btc_key = pallet_cf_threshold_signature::Pallet::<Runtime, BitcoinInstance>::keys(
pallet_cf_threshold_signature::Pallet::<Runtime, BitcoinInstance>::current_key_epoch().unwrap()).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you import the KeyProvider trait you can use BitcoinThresholdSigner::active_epoch_key() for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will get removed when i hook it up to the private channels, so i will leave it for now.

Comment on lines 2193 to 2196
let deposit_address = ForeignChainAddress::Btc(
cf_chains::btc::deposit_address::DepositAddress::new(btc_key.current, 0)
.script_pubkey(),
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can convert to an EncodedAddress here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I output as EncodedAddress it will not be a hex string.

Copy link

codecov bot commented Nov 8, 2024

Codecov Report

Attention: Patch coverage is 20.08547% with 187 lines in your changes missing coverage. Please review.

Project coverage is 71%. Comparing base (daf9e73) to head (6a6d84e).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
state-chain/runtime/src/lib.rs 14% 0 Missing and 78 partials ⚠️
state-chain/custom-rpc/src/lib.rs 0% 33 Missing ⚠️
state-chain/chains/src/address.rs 22% 30 Missing and 2 partials ⚠️
state-chain/runtime/src/runtime_apis.rs 45% 17 Missing and 1 partial ⚠️
api/lib/src/lib.rs 0% 11 Missing ⚠️
state-chain/pallets/cf-swapping/src/lib.rs 10% 9 Missing ⚠️
api/lib/src/lp.rs 0% 5 Missing ⚠️
...ate-chain/traits/src/mocks/swap_limits_provider.rs 0% 1 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff           @@
##            main   #5384    +/-   ##
======================================
- Coverage     72%     71%    -0%     
======================================
  Files        486     486            
  Lines      85973   85977     +4     
  Branches   85973   85977     +4     
======================================
- Hits       61526   61383   -143     
- Misses     21586   21662    +76     
- Partials    2861    2932    +71     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

bouncer/tests/btc_vault_swap.ts Show resolved Hide resolved
bouncer/tests/btc_vault_swap.ts Outdated Show resolved Hide resolved
api/lib/src/lib.rs Outdated Show resolved Hide resolved
@dandanlen
Copy link
Collaborator

LGTM now, but I made some changes/refactors:

  • The error handling could be simplified further by writing the impl for T: Into<DispatchError> instead of DispatchError.
  • There was no need to change how the BrokerApi trait was implemented.
  • Similarly, there was no need to add any methods to the BaseRpcApi, we can just pass through straight to the node via the raw client.
  • I remove the Option from the runtime api as I mentioned above. The runtime api methods are scale encoded, so they don't benefit from being able to 'leave out' the values as we can with a json api.
  • I deduplicated some code from the bitcoin address return type. For example, there's no need for a whole separate type. Also, no need for a ForeignChainAddress since it is always a bitcoin address.
  • I also added the lookup of the private broker id - this was easy to add, i don't see any need to add it in another PR.

.script_pubkey(),
);
let EpochKey { key, .. } = BitcoinThresholdSigner::active_epoch_key()
.expect("We should always have a for the current epoch.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should always have a key for the current epoch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even before vault setup on a localnet?

@dandanlen dandanlen added this pull request to the merge queue Nov 11, 2024
Merged via the queue into main with commit 023261c Nov 11, 2024
49 checks passed
@dandanlen dandanlen deleted the feat/vault-swap-rpc branch November 11, 2024 13:18
@j4m1ef0rd
Copy link
Contributor Author

I also added the lookup of the private broker id - this was easy to add, i don't see any need to add it in another PR.

Main reason was that it breaks the new vault swap bouncer test. I have another PR with this all working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants