From 52c3fe195c13bc6629dc01b0311ee76dd8c72b57 Mon Sep 17 00:00:00 2001 From: Sergey Ratiashvili Date: Fri, 29 Dec 2023 14:22:36 +0100 Subject: [PATCH] feat: base tests --- contracts/hook-tester/src/contract.rs | 17 +- contracts/puppeteer/src/contract.rs | 63 +- .../generated/contractLib/lidoPuppeteer.ts | 18 +- .../src/testcases/puppeteer.test.ts | 653 +++++++----------- packages/base/src/msg/puppeteer.rs | 2 +- packages/puppeteer-base/src/execute.rs | 4 +- packages/puppeteer-base/src/msg.rs | 4 +- packages/puppeteer-base/src/query.rs | 4 +- packages/puppeteer-base/src/state.rs | 4 +- packages/puppeteer-base/src/sudo.rs | 4 +- 10 files changed, 337 insertions(+), 436 deletions(-) diff --git a/contracts/hook-tester/src/contract.rs b/contracts/hook-tester/src/contract.rs index 6d29027c..d0d1b783 100644 --- a/contracts/hook-tester/src/contract.rs +++ b/contracts/hook-tester/src/contract.rs @@ -6,7 +6,7 @@ use lido_helpers::answer::response; use lido_puppeteer_base::msg::{ResponseHookErrorMsg, ResponseHookMsg, ResponseHookSuccessMsg}; use lido_staking_base::{ msg::hook_tester::{ExecuteMsg, InstantiateMsg, QueryMsg}, - state::hook_tester::{ANSWERS, CONFIG, ERRORS}, + state::hook_tester::{Config, ANSWERS, CONFIG, ERRORS}, }; use neutron_sdk::{ bindings::{msg::NeutronMsg, query::NeutronQuery}, @@ -51,7 +51,7 @@ pub fn execute( validator, amount, timeout, - } => execute_delegate(deps, env, validator, amount, timeout), + } => execute_delegate(deps, env, info, validator, amount, timeout), ExecuteMsg::Undelegate { validator, amount, @@ -87,6 +87,8 @@ fn hook_success( _info: MessageInfo, answer: ResponseHookSuccessMsg, ) -> ContractResult> { + deps.api + .debug(&format!("WASMDEBUG: hook_success: {:?}", answer)); let attrs = vec![attr("action", "hook-success")]; ANSWERS.update(deps.storage, |mut answers| -> ContractResult<_> { answers.push(answer); @@ -101,6 +103,8 @@ fn hook_error( _info: MessageInfo, answer: ResponseHookErrorMsg, ) -> ContractResult> { + deps.api + .debug(&format!("WASMDEBUG: hook_error: {:?}", answer)); let attrs = vec![attr("action", "hook-success")]; ERRORS.update(deps.storage, |mut errors| -> ContractResult<_> { errors.push(answer); @@ -116,16 +120,14 @@ fn execute_set_config( puppeteer_addr: String, ) -> ContractResult> { let attrs = vec![attr("action", "set-config")]; - CONFIG.update(deps.storage, |mut config| -> ContractResult<_> { - config.puppeteer_addr = puppeteer_addr; - Ok(config) - })?; + CONFIG.save(deps.storage, &Config { puppeteer_addr })?; Ok(response("set-config", "hook-tester", attrs)) } fn execute_delegate( deps: DepsMut, env: Env, + info: MessageInfo, validator: String, amount: Uint128, timeout: Option, @@ -135,6 +137,7 @@ fn execute_delegate( attr("action", "delegate"), attr("validator", validator.clone()), attr("amount", amount.to_string()), + attr("funds", format!("{:?}", info.funds)), ]; let msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: config.puppeteer_addr, @@ -144,7 +147,7 @@ fn execute_delegate( timeout, reply_to: env.contract.address.to_string(), })?, - funds: vec![], + funds: info.funds, }); Ok(response("execute-delegate", "hook-tester", attrs).add_message(msg)) } diff --git a/contracts/puppeteer/src/contract.rs b/contracts/puppeteer/src/contract.rs index ed3821d3..4678bfc8 100644 --- a/contracts/puppeteer/src/contract.rs +++ b/contracts/puppeteer/src/contract.rs @@ -30,8 +30,8 @@ use neutron_sdk::{ use lido_puppeteer_base::{ error::ContractResult, msg::{ - PuppeteerHook, QueryMsg, ResponseHookErrorMsg, ResponseHookMsg, ResponseHookSuccessMsg, - Transaction, + QueryMsg, ReceiverExecuteMsg, ResponseHookErrorMsg, ResponseHookMsg, + ResponseHookSuccessMsg, Transaction, }, state::{IcaState, PuppeteerBase, State, TxState, TxStateStatus, ICA_ID}, }; @@ -61,7 +61,6 @@ pub fn instantiate( msg: InstantiateMsg, ) -> NeutronResult { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let owner = deps.api.addr_validate(&msg.owner)?; let allowed_senders = msg .allowed_senders @@ -178,6 +177,10 @@ fn execute_delegate( amount: amount.to_string(), }), }; + deps.api.debug(&format!( + "WASMDEBUG: execute_delegate: delegate_msg: {delegate_msg:?}", + delegate_msg = delegate_msg + )); let submsg = compose_submsg( deps.branch(), @@ -445,6 +448,7 @@ fn sudo_response( request: RequestPacket, data: Binary, ) -> NeutronResult { + deps.api.debug(&format!("WASMDEBUG: sudo response")); let attrs = vec![ attr("action", "sudo_response"), attr("request_id", request.sequence.unwrap_or(0).to_string()), @@ -454,15 +458,20 @@ fn sudo_response( .sequence .ok_or_else(|| StdError::generic_err("sequence not found"))?; let tx_state = puppeteer_base.tx_state.load(deps.storage)?; - if tx_state.status != TxStateStatus::InProgress { - return Err(NeutronError::Std(StdError::generic_err( - "Transaction state is not in progress", - ))); - } + deps.api + .debug(&format!("WASMDEBUG: tx_state {:?}", tx_state)); + ensure_eq!( + tx_state.status, + TxStateStatus::WaitingForAck, + NeutronError::Std(StdError::generic_err( + "Transaction state is not waiting for ack", + )) + ); + deps.api.debug(&format!("WASMDEBUG: sudo response 5")); let reply_to = tx_state .reply_to .ok_or_else(|| StdError::generic_err("reply_to not found"))?; - + deps.api.debug(&format!("WASMDEBUG: sudo response 6")); let transaction = tx_state .transaction .ok_or_else(|| StdError::generic_err("transaction not found"))?; @@ -475,7 +484,6 @@ fn sudo_response( reply_to: None, }, )?; - let msg_data: TxMsgData = TxMsgData::decode(data.as_slice())?; deps.api .debug(&format!("WASMDEBUG: msg_data: data: {msg_data:?}")); @@ -529,16 +537,31 @@ fn sudo_response( lido_puppeteer_base::msg::ResponseAnswer::UnknownResponse {} } }; + deps.api.debug(&format!( + "WASMDEBUG: sudo_response: answer: {answer:?}", + answer = answer + )); + deps.api.debug(&format!( + "WASMDEBUG: json: {request:?}", + request = to_json_binary(&ReceiverExecuteMsg::PuppeteerHook( + ResponseHookMsg::Success(ResponseHookSuccessMsg { + request_id: seq_id, + request: request.clone(), + transaction: transaction.clone(), + answer: answer.clone(), + },) + ))? + )); msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: reply_to.clone(), - msg: to_json_binary(&PuppeteerHook(ResponseHookMsg::Success( - ResponseHookSuccessMsg { + msg: to_json_binary(&ReceiverExecuteMsg::PuppeteerHook( + ResponseHookMsg::Success(ResponseHookSuccessMsg { request_id: seq_id, request: request.clone(), transaction: transaction.clone(), answer, - }, - )))?, + }), + ))?, funds: vec![], })) } @@ -572,9 +595,9 @@ fn sudo_error( let tx_state = puppeteer_base.tx_state.load(deps.storage)?; ensure_eq!( tx_state.status, - TxStateStatus::InProgress, + TxStateStatus::WaitingForAck, NeutronError::Std(StdError::generic_err( - "Transaction state is not in progress", + "Transaction state is not waiting for ack", )) ); let seq_id = request @@ -585,7 +608,7 @@ fn sudo_error( contract_addr: tx_state .reply_to .ok_or_else(|| StdError::generic_err("reply_to not found"))?, - msg: to_json_binary(&PuppeteerHook(ResponseHookMsg::Error( + msg: to_json_binary(&ReceiverExecuteMsg::PuppeteerHook(ResponseHookMsg::Error( ResponseHookErrorMsg { request_id: seq_id, request, @@ -622,9 +645,9 @@ fn sudo_timeout( let tx_state = puppeteer_base.tx_state.load(deps.storage)?; ensure_eq!( tx_state.status, - TxStateStatus::InProgress, + TxStateStatus::WaitingForAck, NeutronError::Std(StdError::generic_err( - "Transaction state is not in progress", + "Transaction state is not waiting for ack", )) ); let puppeteer_base: PuppeteerBase<'_, Config> = Puppeteer::default(); @@ -653,7 +676,7 @@ fn sudo_timeout( contract_addr: tx_state .reply_to .ok_or_else(|| StdError::generic_err("reply_to not found"))?, - msg: to_json_binary(&PuppeteerHook(ResponseHookMsg::Error( + msg: to_json_binary(&ReceiverExecuteMsg::PuppeteerHook(ResponseHookMsg::Error( ResponseHookErrorMsg { request_id: seq_id, request, diff --git a/integration_tests/src/generated/contractLib/lidoPuppeteer.ts b/integration_tests/src/generated/contractLib/lidoPuppeteer.ts index 52adf5ca..dbfeded9 100644 --- a/integration_tests/src/generated/contractLib/lidoPuppeteer.ts +++ b/integration_tests/src/generated/contractLib/lidoPuppeteer.ts @@ -32,11 +32,11 @@ export type Addr = string; * let c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ``` */ export type Uint128 = string; -export type ArrayOfTransfer = Transfer[]; export type IcaState = "none" | "in_progress" | "registered" | "timeout"; +export type ArrayOfTransfer = Transfer[]; export interface LidoPuppeteerSchema { - responses: Config | DelegationsResponse | ArrayOfTransfer | State; + responses: Config | DelegationsResponse | State | ArrayOfTransfer; execute: | RegisterDelegatorDelegationsQueryArgs | SetFeesArgs @@ -81,17 +81,17 @@ export interface Coin { denom: string; [k: string]: unknown; } +export interface State { + ica?: string | null; + ica_state: IcaState; + last_processed_height?: number | null; +} export interface Transfer { amount: string; denom: string; recipient: string; sender: string; } -export interface State { - ica?: string | null; - ica_state: IcaState; - last_processed_height?: number | null; -} export interface RegisterDelegatorDelegationsQueryArgs { validators: string[]; } @@ -171,8 +171,8 @@ export class Client { queryState = async(): Promise => { return this.client.queryContractSmart(this.contractAddress, { state: {} }); } - queryInterchainTransactions = async(): Promise => { - return this.client.queryContractSmart(this.contractAddress, { interchain_transactions: {} }); + queryTransactions = async(): Promise => { + return this.client.queryContractSmart(this.contractAddress, { transactions: {} }); } queryDelegations = async(): Promise => { return this.client.queryContractSmart(this.contractAddress, { delegations: {} }); diff --git a/integration_tests/src/testcases/puppeteer.test.ts b/integration_tests/src/testcases/puppeteer.test.ts index a2b90a96..bfd29b0c 100644 --- a/integration_tests/src/testcases/puppeteer.test.ts +++ b/integration_tests/src/testcases/puppeteer.test.ts @@ -16,7 +16,11 @@ import { setupPark } from '../testSuite'; import fs from 'fs'; import Cosmopark from '@neutron-org/cosmopark'; import { waitFor } from '../helpers/waitFor'; -import { Transfer } from '../generated/contractLib/lidoPuppeteer'; +import { + DelegationsResponse, + Transfer, +} from '../generated/contractLib/lidoPuppeteer'; +import { ResponseHookSuccessMsg } from '../generated/contractLib/lidoHookTester'; const PuppeteerClass = LidoPuppeteer.Client; const HookTesterClass = LidoHookTester.Client; @@ -150,6 +154,16 @@ describe('Interchain puppeteer', () => { } }); + it('set puppeteer address into hook tester', async () => { + const res = await context.hookContractClient.setConfig( + context.account.address, + { + puppeteer_addr: context.contractClient.contractAddress, + }, + ); + expect(res.transactionHash).toBeTruthy(); + }); + it('set fees', async () => { const { contractClient, account } = context; const res = await contractClient.setFees( @@ -233,406 +247,263 @@ describe('Interchain puppeteer', () => { expect(res.code).toEqual(0); }); - // it('query received transactions on neutron side', async () => { - // let txs: Transfer[] = []; - // await waitFor(async () => { - // try { - // const res = await context.contractClient.queryTransactions(); - // txs = res; - // return res.length > 0; - // } catch (e) { - // return false; - // } - // }, 60_000); - // expect(txs).toEqual([ - // { - // amount: '10000000', - // denom: 'stake', - // recipient: context.icaAddress, - // sender: (await context.gaiaWallet.getAccounts())[0].address, - // }, - // ]); - // }); - - // it('delegate tokens on gaia side', async () => { - // const { contractClient, account } = context; - // { - // const wallet = await DirectSecp256k1HdWallet.fromMnemonic( - // context.park.config.master_mnemonic, - // { - // prefix: 'cosmosvaloper', - // hdPaths: [stringToPath("m/44'/118'/1'/0/0") as any], - // }, - // ); - // context.firstValidatorAddress = (await wallet.getAccounts())[0].address; - // } - // { - // const wallet = await DirectSecp256k1HdWallet.fromMnemonic( - // context.park.config.master_mnemonic, - // { - // prefix: 'cosmosvaloper', - // hdPaths: [stringToPath("m/44'/118'/2'/0/0") as any], - // }, - // ); - // context.secondValidatorAddress = (await wallet.getAccounts())[0].address; - // } - // const res = await contractClient.delegate( - // account.address, - // { - // validator: context.firstValidatorAddress, - // amount: '100000', - // timeout: 1, - // }, - // 1.5, - // undefined, - // [{ amount: '1000000', denom: 'untrn' }], - // ); - // expect(res.transactionHash).toBeTruthy(); - // // await context.park.pauseRelayer('hermes', 0); - // await context.park.pauseNetwork('gaia'); - // }); - - // it('query done delegations', async () => { - // const { contractClient } = context; - // let res: Transaction[] = []; - // // await context.park.resumeRelayer('hermes', 0); - // await expect( - // waitFor(async () => { - // res = await contractClient.queryInterchainTransactions(); - // return res.length > 0; - // }, 60_000), - // ).to.rejects.toThrowError(); + it('query received transactions on neutron side', async () => { + let txs: Transfer[] = []; + await waitFor(async () => { + try { + const res = await context.contractClient.queryTransactions(); + txs = res; + return res.length > 0; + } catch (e) { + return false; + } + }, 60_000); + expect(txs).toEqual([ + { + amount: '10000000', + denom: 'stake', + recipient: context.icaAddress, + sender: (await context.gaiaWallet.getAccounts())[0].address, + }, + ]); + }); - // expect(res).toEqual([]); - // }); + it('delegate tokens on gaia side', async () => { + const { hookContractClient, account } = context; + { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic( + context.park.config.master_mnemonic, + { + prefix: 'cosmosvaloper', + hdPaths: [stringToPath("m/44'/118'/1'/0/0") as any], + }, + ); + context.firstValidatorAddress = (await wallet.getAccounts())[0].address; + } + { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic( + context.park.config.master_mnemonic, + { + prefix: 'cosmosvaloper', + hdPaths: [stringToPath("m/44'/118'/2'/0/0") as any], + }, + ); + context.secondValidatorAddress = (await wallet.getAccounts())[0].address; + } + const res = await hookContractClient.delegate( + account.address, + { + validator: context.firstValidatorAddress, + amount: '100000', + timeout: 1000, + }, + 1.5, + undefined, + [{ amount: '1000000', denom: 'untrn' }], + ); + expect(res.transactionHash).toBeTruthy(); + await context.park.pauseNetwork('gaia'); + }); - // it('delegate tokens on gaia side', async () => { - // const { contractClient, account } = context; - // { - // const wallet = await DirectSecp256k1HdWallet.fromMnemonic( - // context.park.config.master_mnemonic, - // { - // prefix: 'cosmosvaloper', - // hdPaths: [stringToPath("m/44'/118'/1'/0/0") as any], - // }, - // ); - // context.firstValidatorAddress = (await wallet.getAccounts())[0].address; - // } - // { - // const wallet = await DirectSecp256k1HdWallet.fromMnemonic( - // context.park.config.master_mnemonic, - // { - // prefix: 'cosmosvaloper', - // hdPaths: [stringToPath("m/44'/118'/2'/0/0") as any], - // }, - // ); - // context.secondValidatorAddress = (await wallet.getAccounts())[0].address; - // } - // const res = await contractClient.delegate( - // account.address, - // { - // validator: context.firstValidatorAddress, - // amount: '100000', - // timeout: 100, - // }, - // 1.5, - // undefined, - // [{ amount: '1000000', denom: 'untrn' }], - // ); - // expect(res.transactionHash).toBeTruthy(); - // }); + it('query done delegations', async () => { + const { hookContractClient } = context; + let res: ResponseHookSuccessMsg[] = []; + await waitFor(async () => { + res = await hookContractClient.queryAnswers(); + return res.length > 0; + }, 60_000); + expect(res.length).toEqual(1); + expect(res[0].answer).toEqual({ + delegate_response: {}, + }); + }); - // it('query done delegations', async () => { - // const { contractClient } = context; - // let res: Transaction[] = []; - // await waitFor(async () => { - // res = await contractClient.queryInterchainTransactions(); - // return res.length > 0; - // }, 60_000); - // expect(res).toEqual([ - // { - // delegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '100000', - // }, - // }, - // ]); - // }); - // it('undelegate tokens on gaia side', async () => { - // const { contractClient, account } = context; - // const res = await contractClient.undelegate( - // account.address, - // { - // validator: context.firstValidatorAddress, - // amount: '1000', - // timeout: 600, - // }, - // 1.5, - // undefined, - // [{ amount: '1000000', denom: 'untrn' }], - // ); - // expect(res.transactionHash).toBeTruthy(); - // }); + it('undelegate tokens on gaia side', async () => { + const { hookContractClient, account } = context; + const res = await hookContractClient.undelegate( + account.address, + { + validator: context.firstValidatorAddress, + amount: '1000', + timeout: 600, + }, + 1.5, + undefined, + [{ amount: '1000000', denom: 'untrn' }], + ); + expect(res.transactionHash).toBeTruthy(); + }); - // it('query done undelegation', async () => { - // const { contractClient } = context; - // let res: Transaction[] = []; - // await waitFor(async () => { - // res = await contractClient.queryInterchainTransactions(); - // return res.length > 1; - // }, 20_000); - // expect(res).toEqual([ - // { - // delegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '100000', - // }, - // }, - // { - // undelegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '1000', - // }, - // }, - // ]); - // }); + it('query done undelegation', async () => { + const { hookContractClient } = context; + let res: ResponseHookSuccessMsg[] = []; + await waitFor(async () => { + res = await hookContractClient.queryAnswers(); + return res.length > 1; + }, 20_000); + expect(res.length).toEqual(2); + expect(res[1].answer).toMatchObject({ + undelegate_response: { + completion_time: { + nanos: expect.any(Number), + seconds: expect.any(Number), + }, + }, + }); + }); - // it('redelegate tokens on gaia side', async () => { - // const { contractClient, account } = context; - // const res = await contractClient.redelegate( - // account.address, - // { - // validator_from: context.firstValidatorAddress, - // validator_to: context.secondValidatorAddress, - // amount: '10000', - // timeout: 600, - // }, - // 1.5, - // undefined, - // [{ amount: '1000000', denom: 'untrn' }], - // ); - // expect(res.transactionHash).toBeTruthy(); - // }); + it('redelegate tokens on gaia side', async () => { + const { hookContractClient, account } = context; + const res = await hookContractClient.redelegate( + account.address, + { + validator_from: context.firstValidatorAddress, + validator_to: context.secondValidatorAddress, + amount: '10000', + timeout: 600, + }, + 1.5, + undefined, + [{ amount: '1000000', denom: 'untrn' }], + ); + expect(res.transactionHash).toBeTruthy(); + }); - // it('query done redelegation', async () => { - // const { contractClient } = context; - // let res: Transaction[] = []; - // await waitFor(async () => { - // res = await contractClient.queryInterchainTransactions(); - // return res.length > 2; - // }, 40_000); - // expect(res).toEqual([ - // { - // delegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '100000', - // }, - // }, - // { - // undelegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '1000', - // }, - // }, - // { - // redelegate: { - // interchain_account_id: 'LIDO', - // validator_from: context.firstValidatorAddress, - // validator_to: context.secondValidatorAddress, - // denom: 'stake', - // amount: '10000', - // }, - // }, - // ]); - // }); + it('query done redelegation', async () => { + const { hookContractClient } = context; + let res: ResponseHookSuccessMsg[] = []; + await waitFor(async () => { + res = await hookContractClient.queryAnswers(); + return res.length > 2; + }, 40_000); + expect(res.length).toEqual(3); + expect(res[2].answer).toEqual({ + begin_redelegate_response: { + completion_time: { + nanos: expect.any(Number), + seconds: expect.any(Number), + }, + }, + }); + }); - // it('tokenize share on gaia side', async () => { - // const { contractClient, account } = context; - // const res = await contractClient.tokenizeShare( - // account.address, - // { - // validator: context.firstValidatorAddress, - // amount: '5000', - // timeout: 600, - // }, - // 1.5, - // undefined, - // [{ amount: '1000000', denom: 'untrn' }], - // ); - // expect(res.transactionHash).toBeTruthy(); - // }); + it('tokenize share on gaia side', async () => { + const { hookContractClient, account } = context; + const res = await hookContractClient.tokenizeShare( + account.address, + { + validator: context.firstValidatorAddress, + amount: '5000', + timeout: 600, + }, + 1.5, + undefined, + [{ amount: '1000000', denom: 'untrn' }], + ); + expect(res.transactionHash).toBeTruthy(); + }); - // it('query done tokenize share', async () => { - // const { contractClient } = context; - // let res: Transaction[] = []; - // await waitFor(async () => { - // res = await contractClient.queryInterchainTransactions(); - // return res.length > 3; - // }, 40_000); - // expect(res).toEqual([ - // { - // delegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '100000', - // }, - // }, - // { - // undelegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '1000', - // }, - // }, - // { - // redelegate: { - // interchain_account_id: 'LIDO', - // validator_from: context.firstValidatorAddress, - // validator_to: context.secondValidatorAddress, - // denom: 'stake', - // amount: '10000', - // }, - // }, - // { - // tokenize_share: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: `${context.firstValidatorAddress}/1`, - // amount: '5000', - // }, - // }, - // ]); - // }); + it('query done tokenize share', async () => { + const { hookContractClient } = context; + let res: ResponseHookSuccessMsg[] = []; + await waitFor(async () => { + res = await hookContractClient.queryAnswers(); + return res.length > 3; + }, 40_000); + expect(res.length).toEqual(4); + expect(res[3].answer).toEqual({ + tokenize_shares_response: { + amount: { + amount: '5000', + denom: `${context.firstValidatorAddress}/1`, + }, + }, + }); + }); - // it('redeem share', async () => { - // const { contractClient, account } = context; - // const res = await contractClient.redeemShare( - // account.address, - // { - // validator: context.firstValidatorAddress, - // amount: '5000', - // timeout: 600, - // denom: `${context.firstValidatorAddress}/1`, - // }, - // 1.5, - // undefined, - // [{ amount: '1000000', denom: 'untrn' }], - // ); - // expect(res.transactionHash).toBeTruthy(); - // }); + it('redeem share', async () => { + const { hookContractClient, account } = context; + const res = await hookContractClient.redeemShare( + account.address, + { + validator: context.firstValidatorAddress, + amount: '5000', + timeout: 600, + denom: `${context.firstValidatorAddress}/1`, + }, + 1.5, + undefined, + [{ amount: '1000000', denom: 'untrn' }], + ); + expect(res.transactionHash).toBeTruthy(); + }); - // it('query done redeem share', async () => { - // const { contractClient } = context; - // let res: Transaction[] = []; - // await waitFor(async () => { - // res = await contractClient.queryInterchainTransactions(); - // return res.length > 4; - // }, 40_000); - // expect(res).toEqual([ - // { - // delegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '100000', - // }, - // }, - // { - // undelegate: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: 'stake', - // amount: '1000', - // }, - // }, - // { - // redelegate: { - // interchain_account_id: 'LIDO', - // validator_from: context.firstValidatorAddress, - // validator_to: context.secondValidatorAddress, - // denom: 'stake', - // amount: '10000', - // }, - // }, - // { - // tokenize_share: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: `${context.firstValidatorAddress}/1`, - // amount: '5000', - // }, - // }, - // { - // redeem_share: { - // interchain_account_id: 'LIDO', - // validator: context.firstValidatorAddress, - // denom: `${context.firstValidatorAddress}/1`, - // amount: '5000', - // }, - // }, - // ]); - // }); + it('query done redeem share', async () => { + const { hookContractClient } = context; + let res: ResponseHookSuccessMsg[] = []; + await waitFor(async () => { + res = await hookContractClient.queryAnswers(); + return res.length > 4; + }, 40_000); + expect(res.length).toEqual(5); + expect(res[4].answer).toEqual({ + redeem_tokensfor_shares_response: { + amount: { + amount: '5000', + denom: 'stake', + }, + }, + }); + }); - // it('register delegations query', async () => { - // const { contractClient, account } = context; - // const res = await contractClient.registerDelegatorDelegationsQuery( - // account.address, - // { - // validators: [ - // context.firstValidatorAddress, - // context.secondValidatorAddress, - // ], - // }, - // 1.5, - // undefined, - // [{ amount: '1000000', denom: 'untrn' }], - // ); - // expect(res.transactionHash).toBeTruthy(); - // }); + it('register delegations query', async () => { + const { contractClient, account } = context; + const res = await contractClient.registerDelegatorDelegationsQuery( + account.address, + { + validators: [ + context.firstValidatorAddress, + context.secondValidatorAddress, + ], + }, + 1.5, + undefined, + [{ amount: '1000000', denom: 'untrn' }], + ); + expect(res.transactionHash).toBeTruthy(); + }); - // it('query delegations query', async () => { - // let delegations: DelegationsResponse; - // await waitFor(async () => { - // delegations = await context.contractClient.queryDelegations(); - // return delegations.delegations.length > 0; - // }); - // delegations.delegations.sort((a, b) => - // a.validator.localeCompare(b.validator), - // ); - // const expected = [ - // { - // delegator: context.icaAddress, - // validator: context.firstValidatorAddress, - // amount: { - // denom: 'stake', - // amount: '89000', - // }, - // }, - // { - // delegator: context.icaAddress, - // validator: context.secondValidatorAddress, - // amount: { - // denom: 'stake', - // amount: '10000', - // }, - // }, - // ]; - // expected.sort((a, b) => a.validator.localeCompare(b.validator)); //fml - // expect(delegations).toMatchObject({ - // delegations: expected, - // last_updated_height: expect.any(Number), - // }); - // }); + it('query delegations query', async () => { + let delegations: DelegationsResponse; + await waitFor(async () => { + delegations = await context.contractClient.queryDelegations(); + return delegations.delegations.length > 0; + }); + delegations.delegations.sort((a, b) => + a.validator.localeCompare(b.validator), + ); + const expected = [ + { + delegator: context.icaAddress, + validator: context.firstValidatorAddress, + amount: { + denom: 'stake', + amount: '89000', + }, + }, + { + delegator: context.icaAddress, + validator: context.secondValidatorAddress, + amount: { + denom: 'stake', + amount: '10000', + }, + }, + ]; + expected.sort((a, b) => a.validator.localeCompare(b.validator)); //fml + expect(delegations).toMatchObject({ + delegations: expected, + last_updated_height: expect.any(Number), + }); + }); }); diff --git a/packages/base/src/msg/puppeteer.rs b/packages/base/src/msg/puppeteer.rs index c7f1e9fd..5fc290a0 100644 --- a/packages/base/src/msg/puppeteer.rs +++ b/packages/base/src/msg/puppeteer.rs @@ -97,7 +97,7 @@ pub enum QueryMsg { #[returns(State)] State {}, #[returns(Vec)] - InterchainTransactions {}, + Transactions {}, #[returns(DelegationsResponse)] Delegations {}, } diff --git a/packages/puppeteer-base/src/execute.rs b/packages/puppeteer-base/src/execute.rs index d9762a9f..9d43d436 100644 --- a/packages/puppeteer-base/src/execute.rs +++ b/packages/puppeteer-base/src/execute.rs @@ -33,7 +33,7 @@ where self.config.save(deps.storage, config)?; self.state.save(deps.storage, &State::default())?; - self.recipient_txs.save(deps.storage, &vec![])?; + self.recipient_transfers.save(deps.storage, &vec![])?; Ok(Response::default()) } @@ -82,6 +82,8 @@ where transaction: Transaction, reply_to: String, ) -> StdResult> { + deps.api + .debug("WASMDEBUG: msg_with_sudo_callback save tx_state InProgress"); self.tx_state.save( deps.storage, &TxState { diff --git a/packages/puppeteer-base/src/msg.rs b/packages/puppeteer-base/src/msg.rs index 37d5661b..f52034a6 100644 --- a/packages/puppeteer-base/src/msg.rs +++ b/packages/puppeteer-base/src/msg.rs @@ -47,7 +47,9 @@ pub enum QueryMsg { } #[cw_serde] -pub struct PuppeteerHook(pub ResponseHookMsg); +pub enum ReceiverExecuteMsg { + PuppeteerHook(ResponseHookMsg), +} #[cw_serde] pub enum ResponseHookMsg { diff --git a/packages/puppeteer-base/src/query.rs b/packages/puppeteer-base/src/query.rs index 173a0073..c5d1d077 100644 --- a/packages/puppeteer-base/src/query.rs +++ b/packages/puppeteer-base/src/query.rs @@ -40,7 +40,7 @@ where } fn query_transactions(&self, deps: Deps, _env: Env) -> StdResult { - let transactions: Vec = self.recipient_txs.load(deps.storage)?; - to_json_binary(&transactions) + let transfers: Vec = self.recipient_transfers.load(deps.storage)?; + to_json_binary(&transfers) } } diff --git a/packages/puppeteer-base/src/state.rs b/packages/puppeteer-base/src/state.rs index 1f4cb562..3bfd3c65 100644 --- a/packages/puppeteer-base/src/state.rs +++ b/packages/puppeteer-base/src/state.rs @@ -12,7 +12,7 @@ where { pub config: Item<'a, T>, pub state: Item<'a, State>, - pub recipient_txs: Item<'a, Vec>, + pub recipient_transfers: Item<'a, Vec>, pub delegations: Item<'a, (Vec, u64)>, pub tx_state: Item<'a, TxState>, pub ibc_fee: Item<'a, IbcFee>, @@ -36,7 +36,7 @@ where Self { config: Item::new("config"), state: Item::new("state"), - recipient_txs: Item::new("txs"), + recipient_transfers: Item::new("transfers"), delegations: Item::new("delegations"), tx_state: Item::new("sudo_payload"), ibc_fee: Item::new("ibc_fee"), diff --git a/packages/puppeteer-base/src/sudo.rs b/packages/puppeteer-base/src/sudo.rs index 8c6d85f4..6c6182fe 100644 --- a/packages/puppeteer-base/src/sudo.rs +++ b/packages/puppeteer-base/src/sudo.rs @@ -53,9 +53,9 @@ where "failed to find a matching transaction message", ))); } - let mut txs = self.recipient_txs.load(deps.storage)?; + let mut txs = self.recipient_transfers.load(deps.storage)?; txs.extend(deposits); - self.recipient_txs.save(deps.storage, &txs)?; + self.recipient_transfers.save(deps.storage, &txs)?; } _ => {} }