diff --git a/README.md b/README.md index cc46223..57603e7 100644 --- a/README.md +++ b/README.md @@ -125,3 +125,30 @@ Ethereum style). `authority` is the one who can update the TSS address stored in PDA account. The `initialize` instruction sets nonce to 0. + +# Troubleshooting + +## MacOS error when runngin `anchor test` or `solana-test-validator` + +If you see errors like +``` +Unable to get latest blockhash. Test validator does not look started. Check ".anchor/test-ledger/test-ledger-log.txt" for errors. Consider increasing [test.startup_wait] in Anchor.toml. +``` + +or +```bash +% solana-test-validator --reset +Ledger location: test-ledger +Log: test-ledger/validator.log +Error: failed to start validator: Failed to create ledger at test-ledger: io error: Error checking to unpack genesis archive: Archive error: extra entry found: "._genesis.bin" Regular +``` + +This is because the BSD tar program is not compatible with the GNU tar program. +To fix it: + +```bash +brew install gnu-tar +# Put this in ~/.zshrc +export PATH="/opt/homebrew/opt/gnu-tar/libexec/gnubin:$PATH" +``` +see https://solana.stackexchange.com/questions/4499/blockstore-error-when-starting-solana-test-validator-on-macos-13-0-1 \ No newline at end of file diff --git a/programs/protocol-contracts-solana/src/lib.rs b/programs/protocol-contracts-solana/src/lib.rs index 58f05a9..ad19814 100644 --- a/programs/protocol-contracts-solana/src/lib.rs +++ b/programs/protocol-contracts-solana/src/lib.rs @@ -24,6 +24,8 @@ pub enum Errors { MemoLengthExceeded, #[msg("MemoLengthTooShort")] MemoLengthTooShort, + #[msg("DepositPaused")] + DepositPaused, } declare_id!("94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d"); @@ -42,10 +44,22 @@ pub mod gateway { initialized_pda.tss_address = tss_address; initialized_pda.authority = ctx.accounts.signer.key(); initialized_pda.chain_id = chain_id; + initialized_pda.deposit_paused = false; Ok(()) } + pub fn set_deposit_paused(ctx: Context, deposit_paused: bool) -> Result<()> { + let pda = &mut ctx.accounts.pda; + require!( + ctx.accounts.signer.key() == pda.authority, + Errors::SignerIsNotAuthority + ); + pda.deposit_paused = deposit_paused; + msg!("set_deposit_paused: {:?}", deposit_paused); + Ok(()) + } + pub fn update_tss(ctx: Context, tss_address: [u8; 20]) -> Result<()> { let pda = &mut ctx.accounts.pda; require!( @@ -59,6 +73,10 @@ pub mod gateway { pub fn deposit(ctx: Context, amount: u64, memo: Vec) -> Result<()> { require!(memo.len() >= 20, Errors::MemoLengthTooShort); require!(memo.len() <= 512, Errors::MemoLengthExceeded); + + let pda = &mut ctx.accounts.pda; + require!(!pda.deposit_paused, Errors::DepositPaused); + let cpi_context = CpiContext::new( ctx.accounts.system_program.to_account_info(), system_program::Transfer { @@ -86,6 +104,9 @@ pub mod gateway { let token = &ctx.accounts.token_program; let from = &ctx.accounts.from; + let pda = &mut ctx.accounts.pda; + require!(!pda.deposit_paused, Errors::DepositPaused); + let pda_ata = spl_associated_token_account::get_associated_token_address( &ctx.accounts.pda.key(), &from.mint, @@ -293,12 +314,22 @@ pub struct UpdateTss<'info> { pub signer: Signer<'info>, } +#[derive(Accounts)] +pub struct UpdatePaused<'info> { + #[account(mut)] + pub pda: Account<'info, Pda>, + #[account(mut)] + pub signer: Signer<'info>, +} + + #[account] pub struct Pda { nonce: u64, // ensure that each signature can only be used once tss_address: [u8; 20], // 20 bytes address format of ethereum authority: Pubkey, chain_id: u64, + deposit_paused: bool, } #[cfg(test)] diff --git a/tests/protocol-contracts-solana.ts b/tests/protocol-contracts-solana.ts index 9e3dfde..5e07237 100644 --- a/tests/protocol-contracts-solana.ts +++ b/tests/protocol-contracts-solana.ts @@ -300,6 +300,25 @@ describe("some tests", () => { } }); + it("pause deposit and deposit should fail", async () => { + const newTss = new Uint8Array(20); + randomFillSync(newTss); + // console.log("generated new TSS address", newTss); + await gatewayProgram.methods.setDepositPaused(true).accounts({ + pda: pdaAccount, + }).rpc(); + + // now try deposit, should fail + try { + await gatewayProgram.methods.deposit(new anchor.BN(1_000_000), address).accounts({pda: pdaAccount}).rpc(); + } catch (err) { + console.log("Error message: ", err.message); + expect(err).to.be.instanceof(anchor.AnchorError); + expect(err.message).to.include("DepositPaused"); + } + + }); + });