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(svm): relay root bundle event #683

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
7 changes: 7 additions & 0 deletions programs/svm-spoke/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ pub struct EnabledDepositRoute {
pub enabled: bool,
}

#[event]
pub struct RelayRootBundleEvent {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is named RelayedRootBundle in EVM. Also the ordering is different (rootBundleId, relayerRefundRoot, slowRelayRoot)

pub relayer_refund_root: [u8; 32],
pub slow_relay_root: [u8; 32],
pub root_bundle_id: u32,
}

// Deposit events
#[event]
pub struct V3FundsDeposited {
Expand Down
16 changes: 12 additions & 4 deletions programs/svm-spoke/src/instructions/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use crate::{
constants::DISCRIMINATOR_SIZE,
constraints::is_local_or_remote_owner,
error::CustomError,
event::{EnabledDepositRoute, PausedDeposits, PausedFills, SetXDomainAdmin},
event::{
EnabledDepositRoute, PausedDeposits, PausedFills, RelayRootBundleEvent, SetXDomainAdmin,
},
initialize_current_time,
state::{RootBundle, Route, State},
};
Expand Down Expand Up @@ -209,6 +211,7 @@ pub fn set_enable_route(
Ok(())
}

#[event_cpi]
#[derive(Accounts)]
pub struct RelayRootBundle<'info> {
#[account(
Expand Down Expand Up @@ -241,10 +244,15 @@ pub fn relay_root_bundle(
let root_bundle = &mut ctx.accounts.root_bundle;
root_bundle.relayer_refund_root = relayer_refund_root;
root_bundle.slow_relay_root = slow_relay_root;

emit_cpi!(RelayRootBundleEvent {
relayer_refund_root,
slow_relay_root,
root_bundle_id: state.root_bundle_id,
});

// Finally, increment the root bundle id
Copy link
Contributor

Choose a reason for hiding this comment

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

not directly related to this PR, but I think its confusing to have prop named root_bundle_id in state account. Instead it should be something to resemble number of relayed bundles or next_root_bundle_id - Maybe add this as TODO here

state.root_bundle_id += 1;

// TODO: add event
Ok(())
}

// TODO: add emergency_delete_root_bundle
61 changes: 48 additions & 13 deletions test/svm/SvmSpoke.Bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Try to relay root bundle as non-owner
let relayRootBundleAccounts = { state: state, rootBundle, signer: nonOwner.publicKey };
let relayRootBundleAccounts = { state: state, rootBundle, signer: nonOwner.publicKey, program: program.programId };
try {
await program.methods
.relayRootBundle(relayerRefundRootArray, slowRelayRootArray)
Expand All @@ -114,7 +114,7 @@ describe("svm_spoke.bundle", () => {
}

// Relay root bundle as owner
relayRootBundleAccounts = { state, rootBundle, signer: owner };
relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods
.relayRootBundle(relayerRefundRootArray, slowRelayRootArray)
.accounts(relayRootBundleAccounts)
Expand Down Expand Up @@ -146,7 +146,7 @@ describe("svm_spoke.bundle", () => {
const seeds2 = [Buffer.from("root_bundle"), state.toBuffer(), rootBundleIdBuffer2];
const [rootBundle2] = PublicKey.findProgramAddressSync(seeds2, program.programId);

relayRootBundleAccounts = { state, rootBundle: rootBundle2, signer: owner };
relayRootBundleAccounts = { state, rootBundle: rootBundle2, signer: owner, program: program.programId };
await program.methods
.relayRootBundle(relayerRefundRootArray2, slowRelayRootArray2)
.accounts(relayRootBundleAccounts)
Expand All @@ -155,6 +155,41 @@ describe("svm_spoke.bundle", () => {
stateAccountData = await program.account.state.fetch(state);
assert.isTrue(stateAccountData.rootBundleId.toString() === "2", "Root bundle index should be 2");
});

it("Tests Event Emission in Relay Root Bundle", async () => {
const relayerRefundRootBuffer = crypto.randomBytes(32);
const relayerRefundRootArray = Array.from(relayerRefundRootBuffer);
const slowRelayRootBuffer = crypto.randomBytes(32);
const slowRelayRootArray = Array.from(slowRelayRootBuffer);

let stateAccountData = await program.account.state.fetch(state);
const rootBundleId = stateAccountData.rootBundleId;
const rootBundleIdBuffer = Buffer.alloc(4);
rootBundleIdBuffer.writeUInt32LE(rootBundleId);
const seeds = [Buffer.from("root_bundle"), state.toBuffer(), rootBundleIdBuffer];
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle as owner
const relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
const tx = await program.methods
.relayRootBundle(relayerRefundRootArray, slowRelayRootArray)
.accounts(relayRootBundleAccounts)
.rpc();

// Wait for event processing
await new Promise((resolve) => setTimeout(resolve, 1000));

// Check for the emitted event
const events = await readEvents(connection, tx, [program]);
const event = events.find((event) => event.name === "relayRootBundleEvent").data;
assert.isTrue(event.rootBundleId.toString() === rootBundleId.toString(), "Root bundle ID should match");
assert.isTrue(
event.relayerRefundRoot.toString() === relayerRefundRootArray.toString(),
"Relayer refund root should match"
);
assert.isTrue(event.slowRelayRoot.toString() === slowRelayRootArray.toString(), "Slow relay root should match");
});

it("Simple Leaf Refunds Relayers", async () => {
const relayerRefundLeaves: RelayerRefundLeafType[] = [];
const relayerARefund = new BN(400000);
Expand Down Expand Up @@ -185,7 +220,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
let relayRootBundleAccounts = { state, rootBundle, signer: owner };
let relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

const remainingAccounts = [
Expand Down Expand Up @@ -316,7 +351,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
let relayRootBundleAccounts = { state, rootBundle, signer: owner };
let relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

const remainingAccounts = [
Expand Down Expand Up @@ -457,7 +492,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
let relayRootBundleAccounts = { state, rootBundle, signer: owner };
let relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

const remainingAccounts = [
Expand Down Expand Up @@ -519,7 +554,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
let relayRootBundleAccounts = { state, rootBundle, signer: owner };
let relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

const remainingAccounts = [
Expand Down Expand Up @@ -581,7 +616,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
let relayRootBundleAccounts = { state, rootBundle, signer: owner };
let relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

const remainingAccounts = [{ pubkey: relayerTA, isWritable: true, isSigner: false }];
Expand Down Expand Up @@ -741,7 +776,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
const relayRootBundleAccounts = { state, rootBundle, signer: owner };
const relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

// Verify valid leaf
Expand Down Expand Up @@ -893,7 +928,7 @@ describe("svm_spoke.bundle", () => {
rootBundleIdBuffer.writeUInt32LE(rootBundleId);
const seeds = [Buffer.from("root_bundle"), state.toBuffer(), rootBundleIdBuffer];
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);
let relayRootBundleAccounts = { state, rootBundle, signer: owner };
let relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();
const proofAsNumbers = proof.map((p) => Array.from(p));
const executeRelayerRefundLeafAccounts = {
Expand Down Expand Up @@ -969,7 +1004,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
const relayRootBundleAccounts = { state, rootBundle, signer: owner };
const relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

const remainingAccounts = [{ pubkey: relayerTA, isWritable: true, isSigner: false }];
Expand Down Expand Up @@ -1043,7 +1078,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
const relayRootBundleAccounts = { state, rootBundle, signer: owner };
const relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

const remainingAccounts = [
Expand Down Expand Up @@ -1146,7 +1181,7 @@ describe("svm_spoke.bundle", () => {
const [rootBundle] = PublicKey.findProgramAddressSync(seeds, program.programId);

// Relay root bundle
const relayRootBundleAccounts = { state, rootBundle, signer: owner };
const relayRootBundleAccounts = { state, rootBundle, signer: owner, program: program.programId };
await program.methods.relayRootBundle(Array.from(root), Array.from(root)).accounts(relayRootBundleAccounts).rpc();

// Pass refund addresses in remaining accounts.
Expand Down
Loading