Skip to content

Commit 1687331

Browse files
committed
Add execution report buffer
Integration tests Integration tests
1 parent c682274 commit 1687331

23 files changed

+2150
-0
lines changed

chains/solana/contracts/Anchor.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ test_ccip_receiver = "EvhgrPhTDt4LcSPS2kfJgH6T6XWZ6wT3X9ncDGLT1vui"
2222
test_token_pool = "JuCcZ4smxAYv9QHJ36jshA7pA3FuQ3vQeWLUeAtZduJ"
2323
timelock = "DoajfR5tK24xVw51fWcawUZWhAXD8yrBJVacc13neVQA"
2424
ping_pong_demo = "PPbZmYFf5SPAM9Jhm9mNmYoCwT7icPYVKAfJoMCQovU"
25+
execution_buffer = "buffGjr75PtEtV6D3pbKhaq59CR2qp4mwZDYGspggxZ"
2526

2627
[registry]
2728
url = "https://anchor.projectserum.com"

chains/solana/contracts/Cargo.lock

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chains/solana/contracts/programs/ccip-common/src/seed.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub const CURSES: &[u8] = b"curses";
1212
pub const DEST_CHAIN_STATE: &[u8] = b"dest_chain_state";
1313
pub const NONCE: &[u8] = b"nonce";
1414
pub const ALLOWED_OFFRAMP: &[u8] = b"allowed_offramp";
15+
pub const EXECUTION_BUFFER: &[u8] = b"execution_buffer";
1516

1617
// arbitrary messaging signer
1718
pub const EXTERNAL_EXECUTION_CONFIG: &[u8] = b"external_execution_config";
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "execution_buffer"
3+
version = "0.1.0-dev"
4+
description = "Created with Anchor"
5+
edition = "2021"
6+
7+
[lib]
8+
crate-type = ["cdylib", "lib"]
9+
name = "execution_buffer"
10+
11+
[features]
12+
no-entrypoint = []
13+
no-idl = []
14+
no-log-ix-name = []
15+
cpi = ["no-entrypoint"]
16+
default = []
17+
18+
[dependencies]
19+
solana-program = "1.17.25" # pin solana to 1.17
20+
anchor-lang = { version = "0.29.0", features = ["init-if-needed"] }
21+
anchor-spl = "0.29.0"
22+
bytemuck = "1.7"
23+
ethnum = "1.5"
24+
ccip_common = {path = "../ccip-common"}
25+
ccip_offramp = {path = "../ccip-offramp", features = ["cpi"]}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use crate::state::BufferedReport;
2+
use anchor_lang::prelude::*;
3+
use ccip_common::seed;
4+
5+
pub const ANCHOR_DISCRIMINATOR: usize = 8; // size in bytes
6+
7+
#[derive(Accounts)]
8+
#[instruction(buffer_id: u64, data: Vec<u8>)]
9+
pub struct AppendExecutionReportData<'info> {
10+
#[account(
11+
mut,
12+
seeds = [seed::EXECUTION_BUFFER, authority.key().as_ref(), &buffer_id.to_le_bytes()],
13+
bump,
14+
realloc = ANCHOR_DISCRIMINATOR + BufferedReport::INIT_SPACE + buffered_report.raw_report_data.len() + data.len(),
15+
realloc::payer = authority,
16+
realloc::zero = false
17+
)]
18+
pub buffered_report: Account<'info, BufferedReport>,
19+
20+
#[account(mut)]
21+
pub authority: Signer<'info>,
22+
pub system_program: Program<'info, System>,
23+
}
24+
25+
#[derive(Accounts)]
26+
#[instruction(buffer_id: u64)]
27+
pub struct InitializeExecutionReportBuffer<'info> {
28+
#[account(
29+
init,
30+
seeds = [seed::EXECUTION_BUFFER, authority.key().as_ref(), &buffer_id.to_le_bytes()],
31+
bump,
32+
space = ANCHOR_DISCRIMINATOR + BufferedReport::INIT_SPACE,
33+
payer = authority,
34+
)]
35+
pub buffered_report: Account<'info, BufferedReport>,
36+
37+
#[account(mut)]
38+
pub authority: Signer<'info>,
39+
pub system_program: Program<'info, System>,
40+
}
41+
42+
#[derive(Accounts)]
43+
#[instruction(buffer_id: u64)]
44+
pub struct CloseBuffer<'info> {
45+
#[account(
46+
mut,
47+
seeds = [seed::EXECUTION_BUFFER, authority.key().as_ref(), &buffer_id.to_le_bytes()],
48+
bump,
49+
close = authority,
50+
)]
51+
pub buffered_report: Account<'info, BufferedReport>,
52+
53+
#[account(mut)]
54+
pub authority: Signer<'info>,
55+
}
56+
57+
#[derive(Accounts)]
58+
#[instruction(buffer_id: u64, _token_indices: Vec<u8>)]
59+
pub struct ExecuteContext<'info> {
60+
#[account(
61+
mut,
62+
seeds = [seed::EXECUTION_BUFFER, authority.key().as_ref(), &buffer_id.to_le_bytes()],
63+
bump,
64+
close = authority,
65+
)]
66+
pub buffered_report: Account<'info, BufferedReport>,
67+
// ------------------------
68+
// Accounts for offramp CPI: All validations are done by the offramp
69+
/// CHECK: validated during CPI
70+
pub config: UncheckedAccount<'info>,
71+
/// CHECK: validated during CPI
72+
pub reference_addresses: UncheckedAccount<'info>,
73+
/// CHECK: validated during CPI
74+
pub source_chain: UncheckedAccount<'info>,
75+
/// CHECK: validated during CPI
76+
#[account(mut)]
77+
pub commit_report: UncheckedAccount<'info>,
78+
/// CHECK: validated during CPI
79+
pub offramp: UncheckedAccount<'info>,
80+
/// CHECK: validated during CPI
81+
pub allowed_offramp: UncheckedAccount<'info>,
82+
/// CHECK: validated during CPI
83+
pub rmn_remote: UncheckedAccount<'info>,
84+
/// CHECK: validated during CPI
85+
pub rmn_remote_curses: UncheckedAccount<'info>,
86+
/// CHECK: validated during CPI
87+
pub rmn_remote_config: UncheckedAccount<'info>,
88+
/// CHECK: validated during CPI
89+
pub sysvar_instructions: UncheckedAccount<'info>,
90+
91+
#[account(mut)]
92+
pub authority: Signer<'info>,
93+
pub system_program: Program<'info, System>,
94+
// remaining accounts
95+
// [receiver_program, external_execution_signer, receiver_account, ...user specified accounts from message data for arbitrary messaging]
96+
// +
97+
// [
98+
// ccip_offramp_pools_signer - derivable PDA [seed::EXTERNAL_TOKEN_POOL, pool_program], seeds::program=offramp (not in lookup table)
99+
// user/sender token account (must be associated token account - derivable PDA [wallet_addr, token_program, mint])
100+
// per chain per token config (ccip: billing, ccip admin controlled - derivable PDA [chain_selector, mint])
101+
// pool chain config (pool: custom configs that may include rate limits & remote chain configs, pool admin controlled - derivable [chain_selector, mint])
102+
// token pool lookup table
103+
// token registry PDA
104+
// pool program
105+
// pool config
106+
// pool token account (must be associated token account - derivable PDA [wallet_addr, token_program, mint])
107+
// pool signer
108+
// token program
109+
// token mint
110+
// ccip_router_pools_signer - derivable PDA [seed::EXTERNAL_TOKEN_POOL, pool_program], seeds::program=router (present in lookup table)
111+
// ...additional accounts for pool config
112+
// ] x N tokens
113+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use anchor_lang::prelude::*;
2+
3+
mod context;
4+
use crate::context::*;
5+
6+
mod state;
7+
8+
declare_id!("buffGjr75PtEtV6D3pbKhaq59CR2qp4mwZDYGspggxZ");
9+
10+
#[program]
11+
pub mod execution_buffer {
12+
use super::*;
13+
14+
pub fn manually_execute_buffered<'info>(
15+
ctx: Context<'_, '_, 'info, 'info, ExecuteContext<'info>>,
16+
_buffer_id: u64,
17+
token_indexes: Vec<u8>,
18+
) -> Result<()> {
19+
let cpi_accounts = ccip_offramp::cpi::accounts::ExecuteReportContext {
20+
config: ctx.accounts.config.to_account_info(),
21+
reference_addresses: ctx.accounts.reference_addresses.to_account_info(),
22+
source_chain: ctx.accounts.source_chain.to_account_info(),
23+
commit_report: ctx.accounts.commit_report.to_account_info(),
24+
offramp: ctx.accounts.offramp.to_account_info(),
25+
allowed_offramp: ctx.accounts.allowed_offramp.to_account_info(),
26+
authority: ctx.accounts.authority.to_account_info(),
27+
system_program: ctx.accounts.system_program.to_account_info(),
28+
sysvar_instructions: ctx.accounts.sysvar_instructions.to_account_info(),
29+
rmn_remote: ctx.accounts.rmn_remote.to_account_info(),
30+
rmn_remote_curses: ctx.accounts.rmn_remote_curses.to_account_info(),
31+
rmn_remote_config: ctx.accounts.rmn_remote_config.to_account_info(),
32+
};
33+
let cpi_remaining_accounts = ctx.remaining_accounts.to_vec();
34+
let cpi_context = CpiContext::new(ctx.accounts.offramp.to_account_info(), cpi_accounts)
35+
.with_remaining_accounts(cpi_remaining_accounts);
36+
ccip_offramp::cpi::manually_execute(
37+
cpi_context,
38+
ctx.accounts.buffered_report.raw_report_data.clone(),
39+
token_indexes,
40+
)
41+
}
42+
43+
pub fn append_execution_report_data<'info>(
44+
ctx: Context<'_, '_, 'info, 'info, AppendExecutionReportData>,
45+
_buffer_id: u64,
46+
data: Vec<u8>,
47+
) -> Result<()> {
48+
ctx.accounts
49+
.buffered_report
50+
.raw_report_data
51+
.extend_from_slice(&data);
52+
Ok(())
53+
}
54+
55+
pub fn initialize_execution_report_buffer<'info>(
56+
_ctx: Context<'_, '_, 'info, 'info, InitializeExecutionReportBuffer>,
57+
_buffer_id: u64,
58+
) -> Result<()> {
59+
Ok(())
60+
}
61+
62+
pub fn close_buffer<'info>(
63+
_ctx: Context<'_, '_, 'info, 'info, CloseBuffer>,
64+
_buffer_id: u64,
65+
) -> Result<()> {
66+
Ok(())
67+
}
68+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use anchor_lang::prelude::*;
2+
3+
#[account]
4+
#[derive(Debug, InitSpace)]
5+
pub struct BufferedReport {
6+
#[max_len(0)]
7+
pub raw_report_data: Vec<u8>,
8+
}

0 commit comments

Comments
 (0)