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

Transfer implementation #72

Merged
merged 69 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
cc9cc27
added accounts in the storage for transfers
dhruvja Oct 31, 2023
24f16d8
added mint, burn and send methods
dhruvja Nov 1, 2023
d6545d6
remove signer from storage
dhruvja Nov 2, 2023
721aa47
using ID instead of id()
dhruvja Nov 2, 2023
8bc1c8e
compare pubkeys directlu
dhruvja Nov 2, 2023
9e33c18
rm unneccesary conversions to string
dhruvja Nov 2, 2023
fea16ec
extract getting account info in a seperate method
dhruvja Nov 2, 2023
03fe114
converting u256 to u64
dhruvja Nov 2, 2023
7b4b01d
added wrapped type for Pubkey to implement tryFrom
dhruvja Nov 2, 2023
7caecf5
renamed pubkey
dhruvja Nov 2, 2023
357258e
fixed merge conflicts
dhruvja Nov 2, 2023
02793ac
added suggestions
dhruvja Nov 2, 2023
cf31b02
using converted u64 amount from the method
dhruvja Nov 2, 2023
5d04806
using slice arg instead of vector in transfer impl
dhruvja Nov 2, 2023
997df55
added traits for the wrapped type
dhruvja Nov 3, 2023
8cfad4b
added from trait for pubkey
dhruvja Nov 3, 2023
981c40b
added mocks for creating channel and connection
dhruvja Nov 9, 2023
56d4778
creating PDAs for token mint and escrow accounts for transfer
dhruvja Nov 15, 2023
d96ec9f
added remaining accounts and passing transfer packet
dhruvja Nov 15, 2023
c7c61cf
storing connection and channel for of both client a and b
dhruvja Nov 16, 2023
d968f30
merged with master and fixed conflicts
dhruvja Nov 16, 2023
88488b0
rm redunant code and fix accounts struct
dhruvja Nov 16, 2023
3e5b53e
reallocating data in mock deliver method
dhruvja Nov 16, 2023
5e30f4d
storing time and height in mock deliver
dhruvja Nov 16, 2023
a4e682b
using base denom instead of the complete denom for token mint seed
dhruvja Nov 16, 2023
80668b4
commented excessive logging
dhruvja Nov 16, 2023
7185b8e
Merge remote-tracking branch 'up/master' into HEAD
mina86 Nov 17, 2023
a865302
unwrap
mina86 Nov 17, 2023
b9d71d6
increase trie storage to 10kb and using latest height from client state
dhruvja Nov 18, 2023
f3bb76b
added chain back to method
dhruvja Nov 18, 2023
52f10a8
fmt
dhruvja Nov 18, 2023
7c7eb00
fixed conflicts
dhruvja Nov 18, 2023
d66029e
fixed merge conflicts
dhruvja Nov 18, 2023
6474db7
fix clippy
dhruvja Nov 18, 2023
4e08b5a
fmt
dhruvja Nov 18, 2023
79cce19
fix merge conflicts
dhruvja Nov 18, 2023
bb871d7
Merge remote-tracking branch 'up/master' into HEAD
mina86 Nov 19, 2023
3a5ae71
reduce diff noise
mina86 Nov 19, 2023
89a67cc
Revert "reduce diff noise"
mina86 Nov 19, 2023
ed5a0d0
Merge remote-tracking branch 'up/master' into HEAD
mina86 Nov 19, 2023
a5ca435
added mock deliver in a seperate file
dhruvja Nov 20, 2023
038ef23
Merge branch 'transfer-impl' of https://github.com/ComposableFi/emula…
dhruvja Nov 20, 2023
82d44bf
fixed transfer and added test for both source and dest transfer
dhruvja Nov 21, 2023
53bf9d7
fix merge conflicts
dhruvja Nov 21, 2023
1ec6b1f
added assert in tests to check token balance for tx
dhruvja Nov 21, 2023
06047a3
fix clippy
dhruvja Nov 23, 2023
759575f
fmt
dhruvja Nov 24, 2023
ae9cc9b
fix merge conflicts
dhruvja Nov 24, 2023
83c9d13
bump anchor-spl to lts
dhruvja Nov 24, 2023
9d5212e
added an enum for accountId
dhruvja Nov 26, 2023
d47ca3e
fmt
dhruvja Nov 26, 2023
f027dec
Delete .vscode/settings.json
mina86 Nov 26, 2023
349ae4f
Update Cargo.toml
mina86 Nov 26, 2023
da0e5a0
made const as public and better comments
dhruvja Nov 27, 2023
8ab4b03
remove old accountId in transfers
dhruvja Nov 27, 2023
a43f91a
rename AccountIdx to AccountId
dhruvja Nov 27, 2023
307fab9
use str instead of string for denom while getting escrow acc
dhruvja Nov 27, 2023
f1d7845
better seeds
dhruvja Nov 27, 2023
2c565ca
refactor send_coins_execute
dhruvja Nov 27, 2023
6dffae9
use better method to get get client state in mocks
dhruvja Nov 27, 2023
8459857
update cargo.toml
dhruvja Nov 27, 2023
4da027c
fix clippy
dhruvja Nov 27, 2023
1088028
rm custom error and added try_into
dhruvja Nov 27, 2023
69ee7f0
fmt
dhruvja Nov 27, 2023
98e6fbd
fix suggestions
dhruvja Nov 27, 2023
d7ff0a3
fix suggestions
dhruvja Nov 27, 2023
1d6f717
fmt
dhruvja Nov 27, 2023
3337763
reduce unwraps
dhruvja Nov 27, 2023
ed1d8e6
fmt
dhruvja Nov 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ codegen-units = 1

[workspace.dependencies]
anchor-lang = {version = "0.29.0", features = ["init-if-needed"]}
anchor-spl = "0.29.0"
ascii = "1.1.0"
base64 = { version = "0.21", default-features = false, features = ["alloc"] }
borsh = { version = "0.10.3", default-features = false }
Expand All @@ -33,14 +34,17 @@ hex-literal = "0.4.1"
ibc = { version = "0.47.0", default-features = false, features = ["borsh", "serde"] }
ibc-proto = { version = "0.37.1", default-features = false }
pretty_assertions = "1.4.0"
primitive-types = "0.12.2"
rand = { version = "0.8.5" }
serde = "1"
serde_json = "1"
sha2 = { version = "0.10.7", default-features = false }
solana-client = "1.16.14"
solana-program = "1.16.14"
solana-sdk = "1.16.14"
spl-associated-token-account = "2.2.0"
strum = { version = "0.25.0", default-features = false, features = ["derive"] }
uint = "0.9.5"

blockchain = { path = "common/blockchain" }
lib = { path = "common/lib" }
Expand Down
4 changes: 4 additions & 0 deletions solana/solana-ibc/programs/solana-ibc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ mocks = ["ibc/mocks", "ibc/std"]

[dependencies]
anchor-lang.workspace = true
anchor-spl.workspace = true
base64.workspace = true
bytemuck.workspace = true
derive_more.workspace = true
ibc-proto.workspace = true
ibc.workspace = true
primitive-types.workspace = true
serde.workspace = true
serde_json.workspace = true
spl-associated-token-account.workspace = true
strum.workspace = true
uint.workspace = true

blockchain.workspace = true
lib.workspace = true
Expand Down
14 changes: 8 additions & 6 deletions solana/solana-ibc/programs/solana-ibc/src/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl borsh::BorshDeserialize for AnyClientState {
}
}

impl ClientStateValidation<IbcStorage<'_, '_>> for AnyClientState {
impl ClientStateValidation<IbcStorage<'_, '_, '_>> for AnyClientState {
fn verify_client_message(
&self,
ctx: &IbcStorage,
Expand Down Expand Up @@ -354,7 +354,7 @@ impl ClientStateCommon for AnyClientState {
}
}

impl ClientStateExecution<IbcStorage<'_, '_>> for AnyClientState {
impl ClientStateExecution<IbcStorage<'_, '_, '_>> for AnyClientState {
fn initialise(
&self,
ctx: &mut IbcStorage,
Expand Down Expand Up @@ -442,7 +442,7 @@ impl ClientStateExecution<IbcStorage<'_, '_>> for AnyClientState {
}
}

impl ibc::clients::ics07_tendermint::CommonContext for IbcStorage<'_, '_> {
impl ibc::clients::ics07_tendermint::CommonContext for IbcStorage<'_, '_, '_> {
type ConversionError = &'static str;

type AnyConsensusState = AnyConsensusState;
Expand Down Expand Up @@ -478,7 +478,7 @@ impl ibc::clients::ics07_tendermint::CommonContext for IbcStorage<'_, '_> {
}

#[cfg(any(test, feature = "mocks"))]
impl MockClientContext for IbcStorage<'_, '_> {
impl MockClientContext for IbcStorage<'_, '_, '_> {
type ConversionError = &'static str;
type AnyConsensusState = AnyConsensusState;

Expand All @@ -498,7 +498,9 @@ impl MockClientContext for IbcStorage<'_, '_> {
}
}

impl ibc::clients::ics07_tendermint::ValidationContext for IbcStorage<'_, '_> {
impl ibc::clients::ics07_tendermint::ValidationContext
for IbcStorage<'_, '_, '_>
{
fn next_consensus_state(
&self,
client_id: &ClientId,
Expand All @@ -522,7 +524,7 @@ enum Direction {
Prev,
}

impl IbcStorage<'_, '_> {
impl IbcStorage<'_, '_, '_> {
fn get_consensus_state(
&self,
client_id: &ClientId,
Expand Down
14 changes: 14 additions & 0 deletions solana/solana-ibc/programs/solana-ibc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ impl From<manager::UpdateCandidateError> for Error {
}
}

impl From<ibc::core::ContextError> for Error {
#[inline]
fn from(err: ibc::core::ContextError) -> Self {
Self::RouterError(err.into())
}
}

impl From<ibc::core::ics02_client::error::ClientError> for Error {
#[inline]
fn from(err: ibc::core::ics02_client::error::ClientError) -> Self {
ibc::core::ContextError::from(err).into()
}
}

impl From<Error> for anchor_lang::error::AnchorError {
fn from(err: Error) -> Self {
Self {
Expand Down
14 changes: 8 additions & 6 deletions solana/solana-ibc/programs/solana-ibc/src/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::storage::{self, ids, IbcStorage};

type Result<T = (), E = ibc::core::ContextError> = core::result::Result<T, E>;

impl ClientExecutionContext for IbcStorage<'_, '_> {
impl ClientExecutionContext for IbcStorage<'_, '_, '_> {
type V = Self; // ClientValidationContext
type AnyClientState = AnyClientState;
type AnyConsensusState = AnyConsensusState;
Expand Down Expand Up @@ -118,7 +118,7 @@ impl ClientExecutionContext for IbcStorage<'_, '_> {
height: Height,
timestamp: Timestamp,
) -> Result<(), ContextError> {
msg!("store_update_time({}, {}, {})", client_id, height, timestamp);
// msg!("store_update_time({}, {}, {})", client_id, height, timestamp);
self.borrow_mut()
.private
.client_mut(&client_id, false)?
Expand All @@ -133,7 +133,7 @@ impl ClientExecutionContext for IbcStorage<'_, '_> {
height: Height,
host_height: Height,
) -> Result<(), ContextError> {
msg!("store_update_height({}, {}, {})", client_id, height, host_height);
// msg!("store_update_height({}, {}, {})", client_id, height, host_height);
self.borrow_mut()
.private
.client_mut(&client_id, false)?
Expand All @@ -143,7 +143,9 @@ impl ClientExecutionContext for IbcStorage<'_, '_> {
}
}

impl ExecutionContext for IbcStorage<'_, '_> {
impl ExecutionContext for IbcStorage<'_, '_, '_> {
/// The clients are stored in the vector so we can easily find how many
/// clients were created. So thats why this method doesnt do anything.
fn increase_client_counter(&mut self) -> Result { Ok(()) }

fn store_connection(
Expand Down Expand Up @@ -311,7 +313,7 @@ impl ExecutionContext for IbcStorage<'_, '_> {
fn get_client_execution_context(&mut self) -> &mut Self::E { self }
}

impl storage::IbcStorage<'_, '_> {
impl storage::IbcStorage<'_, '_, '_> {
fn store_commitment(&mut self, key: TrieKey, commitment: &[u8]) -> Result {
// Caller promises that commitment is always 32 bytes.
let commitment = <&CryptoHash>::try_from(commitment).unwrap();
Expand Down Expand Up @@ -340,7 +342,7 @@ impl storage::IbcStorage<'_, '_> {
}
}

impl storage::IbcStorageInner<'_, '_> {
impl storage::IbcStorageInner<'_, '_, '_> {
/// Serialises `value` and stores it in private storage along with its
/// commitment in provable storage.
///
Expand Down
97 changes: 89 additions & 8 deletions solana/solana-ibc/programs/solana-ibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ extern crate alloc;

use anchor_lang::prelude::*;
use anchor_lang::solana_program;
use ibc::core::ics24_host::identifier::PortId;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token::{Mint, Token, TokenAccount};
use borsh::BorshDeserialize;
use ibc::core::ics23_commitment::commitment::CommitmentPrefix;
use ibc::core::ics24_host::identifier::{ChannelId, ClientId, PortId};
use ibc::core::router::{Module, ModuleId, Router};
use ibc::core::MsgEnvelope;
#[cfg(feature = "mocks")]
use mocks::mock_deliver_impl;
use storage::IbcPackets;

pub const CHAIN_SEED: &[u8] = b"chain";
pub const PACKET_SEED: &[u8] = b"packet";
pub const SOLANA_IBC_STORAGE_SEED: &[u8] = b"private";
pub const TRIE_SEED: &[u8] = b"trie";
pub const MINT_ESCROW_SEED: &[u8] = b"mint_escrow";

declare_id!("EnfDJsAK7BGgetnmKzBx86CsgC5kfSPcsktFCQ4YLC81");

Expand All @@ -26,13 +34,13 @@ mod error;
pub mod events;
mod execution_context;
mod host;
#[cfg(feature = "mocks")]
mod mocks;
pub mod storage;
#[cfg(test)]
mod tests;
mod transfer;
mod validation_context;
// mod client_context;


#[anchor_lang::program]
pub mod solana_ibc {
Expand Down Expand Up @@ -110,11 +118,11 @@ pub mod solana_ibc {
ctx: Context<Deliver>,
message: ibc::core::MsgEnvelope,
) -> Result<()> {
msg!("Called deliver method: {:?}", message);
// msg!("Called deliver method: {:?}", message);
let _sender = ctx.accounts.sender.to_account_info();

let private: &mut storage::PrivateStorage = &mut ctx.accounts.storage;
msg!("This is private: {:?}", private);
// msg!("This is private: {:?}", private);
let provable = storage::get_provable_from(&ctx.accounts.trie, "trie")?;
let packets = &mut ctx.accounts.packets;
let host_head = host::Head::get()?;
Expand All @@ -128,6 +136,7 @@ pub mod solana_ibc {
private,
provable,
packets,
accounts: ctx.remaining_accounts.to_vec(),
host_head,
});

Expand All @@ -149,14 +158,43 @@ pub mod solana_ibc {

// `store` is the only reference to inner storage making refcount == 1
// which means try_into_inner will succeed.
let inner = store.try_into_inner().unwrap();
// let inner = store.try_into_inner().unwrap();

msg!("This is final structure {:?}", inner.private);
// msg!("This is final structure {:?}", inner.private);

// msg!("this is length {}", TrieKey::ClientState{ client_id: String::from("hello")}.into());

Ok(())
}

/// Called to set up a connection, channel and store the next
/// sequence. Will panic if called without `mocks` feature.
pub fn mock_deliver(
ctx: Context<MockDeliver>,
port_id: PortId,
channel_id_on_b: ChannelId,
base_denom: String,
commitment_prefix: CommitmentPrefix,
client_id: ClientId,
counterparty_client_id: ClientId,
) -> Result<()> {
#[cfg(feature = "mocks")]
{
mock_deliver_impl(
ctx,
port_id,
channel_id_on_b,
base_denom,
commitment_prefix,
client_id,
counterparty_client_id,
)
.unwrap();
Ok(())
}
#[cfg(not(feature = "mocks"))]
panic!("This method is only for mocks");
}
}

#[derive(Accounts)]
Expand Down Expand Up @@ -226,11 +264,54 @@ pub struct Deliver<'info> {
/// The guest blockchain data.
#[account(init_if_needed, payer = sender, seeds = [CHAIN_SEED], bump, space = 10240)]
chain: Box<Account<'info, chain::ChainData>>,
system_program: Program<'info, System>,
}

#[derive(Accounts)]
#[instruction(port_id: PortId, channel_id_on_b: ChannelId, base_denom: String)]
pub struct MockDeliver<'info> {
#[account(mut)]
sender: Signer<'info>,

/// CHECK:
receiver: AccountInfo<'info>,

/// The account holding private IBC storage.
#[account(mut, seeds = [SOLANA_IBC_STORAGE_SEED],bump)]
storage: Box<Account<'info, storage::PrivateStorage>>,

/// The account holding provable IBC storage, i.e. the trie.
///
/// CHECK: Account’s owner is checked by [`storage::get_provable_from`]
/// function.
#[account(mut , seeds = [TRIE_SEED], bump)]
trie: UncheckedAccount<'info>,

/// The account holding packets.
#[account(mut , seeds = [PACKET_SEED], bump)]
packets: Box<Account<'info, IbcPackets>>,

/// The below accounts are being created for testing purposes only.
/// In real, we would run conditionally create an escrow account when the channel is created.
/// And we could have another method that can create a mint given the denom.
#[account(init_if_needed, payer = sender, seeds = [MINT_ESCROW_SEED], bump, space = 100)]
/// CHECK:
mint_authority: UncheckedAccount<'info>,
#[account(init_if_needed, payer = sender, seeds = [base_denom.as_bytes()], bump, mint::decimals = 6, mint::authority = mint_authority)]
token_mint: Box<Account<'info, Mint>>,
#[account(init_if_needed, payer = sender, seeds = [port_id.as_bytes(), channel_id_on_b.as_bytes(), base_denom.as_bytes()], bump, token::mint = token_mint, token::authority = mint_authority)]
escrow_account: Box<Account<'info, TokenAccount>>,
#[account(init_if_needed, payer = sender, associated_token::mint = token_mint, associated_token::authority = sender)]
sender_token_account: Box<Account<'info, TokenAccount>>,
#[account(init_if_needed, payer = sender, associated_token::mint = token_mint, associated_token::authority = receiver)]
receiver_token_account: Box<Account<'info, TokenAccount>>,

associated_token_program: Program<'info, AssociatedToken>,
token_program: Program<'info, Token>,
system_program: Program<'info, System>,
}

impl Router for storage::IbcStorage<'_, '_> {
impl Router for storage::IbcStorage<'_, '_, '_> {
//
fn get_route(&self, module_id: &ModuleId) -> Option<&dyn Module> {
let module_id = core::borrow::Borrow::borrow(module_id);
Expand Down
Loading
Loading