Skip to content

Commit

Permalink
feat: Solana CCM fallback (#5316)
Browse files Browse the repository at this point in the history
* We can now witness when Solana CCM transaction fails to execute.

The witnessed result is now part of the SolanaElections.
On Program execution error, fallback transfer is created.

WIP: Add tests and storage migration for SolanaBroadcast and Elections

* Added integration test for CCM fallback mechanism.

* Added storage migration for sol ccm success witnessing.
Clear all egress-success election votes
Migrated Broadcaster storage to newer version of ApiCall

* Corrected Migration in Runtime.

* Call SolanaBroadcaster::egress_success() regardless of if call execution
was successful. This ensures call data are cleared in the broadcaster pallet.

* Commented out a print statement in the unit test

* renamed a member field

* Fixed bouncer test for Solana CCMs

* Fixed bouncer lint

* fix: don't exit if we can't remove a file that already doesn't exist (#5328)

* fix: don't exit if we can't remove a file that already doesn't exist

* Update localnet/common.sh

Co-authored-by: anton-chain <anton@chainflip.io>

---------

Co-authored-by: anton-chain <anton@chainflip.io>

* fix

---------

Co-authored-by: Maxim Shishmarev <msgmaxim@gmail.com>
Co-authored-by: anton-chain <anton@chainflip.io>
Co-authored-by: Daniel <daniel@chainflip.io>
  • Loading branch information
4 people committed Oct 30, 2024
1 parent 91ddcac commit 69480d6
Show file tree
Hide file tree
Showing 18 changed files with 481 additions and 90 deletions.
109 changes: 59 additions & 50 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions bouncer/shared/swapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ function newSolanaCfParameters(maxAccounts: number) {
cfReceiver.is_writable ? 1 : 0,
]);

const fallbackAddrBytes = new PublicKey(getContractAddress('Solana', 'FALLBACK')).toBytes();

const remainingAccounts = [];
const numRemainingAccounts = Math.floor(Math.random() * maxAccounts);

Expand All @@ -104,6 +106,7 @@ function newSolanaCfParameters(maxAccounts: number) {
// Inserted by the codec::Encode
4 * remainingAccounts.length,
...remainingAccounts.flatMap((account) => Array.from(account)),
...fallbackAddrBytes,
]);

return arrayToHexString(cfParameters);
Expand Down
10 changes: 8 additions & 2 deletions bouncer/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ export function getContractAddress(chain: Chain, contract: string): string {
return '8pBPaVfTAcjLeNfC187Fkvi9b1XEFhRNJ95BQXXVksmH';
case 'SWAP_ENDPOINT':
return '35uYgHdfZQT4kHkaaXQ6ZdCkK5LFrsk43btTLbGCRCNT';
case 'FALLBACK':
/// 3wDSVR6YSRDFiWdwsnZZRjAKHKvsmb4fouYVqoBt5yd4vSrY7aQdvtLJKMvEb3AMWGD5fxunfdotvwPwnSChWMWx
return 'CFf51BPWnybvgbZrxy61s4SCCvEohBC7achsPLuoACUG';
default:
throw new Error(`Unsupported contract: ${contract}`);
}
Expand Down Expand Up @@ -723,7 +726,7 @@ export async function observeSolanaCcmEvent(
const remainingAccountSize = publicKeySize + 1;

// Extra byte for the encoded length
const remainingAccountsBytes = cfParameters.slice(remainingAccountSize + 1);
const remainingAccountsBytes = cfParameters.slice(remainingAccountSize + 1, -publicKeySize);

const remainingAccounts = [];
const remainingIsWritable = [];
Expand All @@ -737,7 +740,10 @@ export async function observeSolanaCcmEvent(
remainingIsWritable.push(Boolean(isWritable));
}

return { remainingAccounts, remainingIsWritable };
// fallback account
const fallbackAccount = cfParameters.slice(-publicKeySize);

return { remainingAccounts, remainingIsWritable, fallbackAccount };
}

const connection = getSolConnection();
Expand Down
9 changes: 6 additions & 3 deletions engine/src/witness/sol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,12 @@ impl VoterApi<SolanaEgressWitnessing> for SolanaEgressWitnessingVoter {
<<SolanaEgressWitnessing as ElectoralSystem>::Vote as VoteStorage>::Vote,
anyhow::Error,
> {
Ok(TransactionSuccessDetails {
tx_fee: egress_witnessing::get_finalized_fee(&self.client, signature).await?,
})
egress_witnessing::get_finalized_fee_and_success_status(&self.client, signature)
.await
.map(|(tx_fee, transaction_successful)| TransactionSuccessDetails {
tx_fee,
transaction_successful,
})
}
}

Expand Down
Loading

0 comments on commit 69480d6

Please sign in to comment.