From bf92af49357953dad22d820b0eb67bb5b13bb6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Wed, 4 Dec 2024 15:31:33 +0300 Subject: [PATCH] Tos data reduce (#101) * Stream deconstruct WIP * Minimize stream storage load * Fix comment * Minimize tos data on loads * Generate schema --- contracts/stream/src/contract.rs | 44 +++++++++++++------ contracts/stream/src/state.rs | 5 +-- packages/types/src/stream/msg.rs | 20 ++++++--- packages/types/src/stream/position.rs | 4 -- packages/types/src/stream/stream.rs | 11 +---- tests/src/tests/streamswap_tests/subscribe.rs | 21 +++++++++ ts/types/StreamSwapStream.client.ts | 19 +++++++- ts/types/StreamSwapStream.message-composer.ts | 2 +- ts/types/StreamSwapStream.types.ts | 7 ++- 9 files changed, 94 insertions(+), 39 deletions(-) diff --git a/contracts/stream/src/contract.rs b/contracts/stream/src/contract.rs index 853273f..3ddaabb 100644 --- a/contracts/stream/src/contract.rs +++ b/contracts/stream/src/contract.rs @@ -6,9 +6,9 @@ use crate::stream::{compute_shares_amount, sync_stream, sync_stream_status}; use crate::{circuit_ops, ContractError}; use core::str; use cosmwasm_std::{ - attr, entry_point, to_json_binary, Attribute, BankMsg, Binary, Coin, CosmosMsg, Decimal256, - Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Timestamp, Uint128, - Uint256, + attr, entry_point, to_json_binary, Addr, Attribute, BankMsg, Binary, Coin, CosmosMsg, + Decimal256, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Timestamp, + Uint128, Uint256, }; use cw2::{ensure_from_older_version, set_contract_version}; use cw_storage_plus::Bound; @@ -24,7 +24,7 @@ use streamswap_utils::to_uint256; use crate::pool::pool_operations; use crate::state::{ CONTROLLER_PARAMS, CREATOR_VESTING, POSITIONS, POST_STREAM, STREAM_INFO, STREAM_STATE, - SUBSCRIBER_VESTING, + SUBSCRIBER_VESTING, TOS, TOS_SIGNED, }; use crate::vesting::vesting_operations; use streamswap_types::controller::{CreatePool, Params as ControllerParams, PoolConfig}; @@ -95,13 +95,7 @@ pub fn instantiate( ); STREAM_STATE.save(deps.storage, &stream_state)?; - let stream_info = StreamInfo::new( - stream_admin.clone(), - name.clone(), - treasury.clone(), - url, - tos_version, - ); + let stream_info = StreamInfo::new(stream_admin.clone(), name.clone(), treasury.clone(), url); STREAM_INFO.save(deps.storage, &stream_info)?; let post_stream_actions = @@ -111,6 +105,8 @@ pub fn instantiate( let threshold_state = ThresholdState::new(); threshold_state.set_threshold_if_any(threshold, deps.storage)?; + TOS.save(deps.storage, &tos_version)?; + let mut attrs = vec![ attr("action", "instantiate"), attr("name", name), @@ -322,16 +318,18 @@ pub fn execute_subscribe( sync_stream(&mut stream_state, env.block.time); new_shares = compute_shares_amount(&stream_state, uint256_in_amount, false); // new positions do not update purchase as it has no effect on distribution - let stream_info = STREAM_INFO.load(deps.storage)?; let new_position = Position::new( info.sender.clone(), uint256_in_amount, new_shares, Some(stream_state.dist_index), env.block.time, - stream_info.tos_version.clone(), ); POSITIONS.save(deps.storage, &info.sender, &new_position)?; + + // Save signed TOS + let tos_version = TOS.load(deps.storage)?; + TOS_SIGNED.save(deps.storage, &info.sender, &tos_version)?; } Some(mut position) => { if position.owner != info.sender { @@ -746,6 +744,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::AveragePrice {} => to_json_binary(&query_average_price(deps, env)?), QueryMsg::LastStreamedPrice {} => to_json_binary(&query_last_streamed_price(deps, env)?), QueryMsg::Threshold {} => to_json_binary(&query_threshold_state(deps, env)?), + QueryMsg::ToS { addr } => { + if let Some(addr) = addr { + to_json_binary(&query_tos_signed( + deps, + &deps.api.addr_validate(addr.as_str())?, + )?) + } else { + to_json_binary(&query_tos(deps)?) + } + } } } pub fn query_params(deps: Deps) -> StdResult { @@ -844,3 +852,13 @@ pub fn query_threshold_state(deps: Deps, _env: Env) -> Result, S let threshold = threshold_state.get_threshold(deps.storage)?; Ok(threshold) } + +pub fn query_tos(deps: Deps) -> StdResult { + let tos = TOS.load(deps.storage)?; + Ok(tos) +} + +pub fn query_tos_signed(deps: Deps, addr: &Addr) -> StdResult { + let tos = TOS_SIGNED.load(deps.storage, addr)?; + Ok(tos) +} diff --git a/contracts/stream/src/state.rs b/contracts/stream/src/state.rs index 46f339e..af0b502 100644 --- a/contracts/stream/src/state.rs +++ b/contracts/stream/src/state.rs @@ -14,8 +14,6 @@ pub const STREAM_INFO: Item = Item::new("si"); // Post Stream Action Related Information pub const POST_STREAM: Item = Item::new("ps"); -pub const TOS: Item = Item::new("tos"); - // Subscriber Vesting (owner_addr) -> (contract_addr) pub const SUBSCRIBER_VESTING: Map = Map::new("sub_vest"); @@ -25,6 +23,7 @@ pub const CREATOR_VESTING: Item = Item::new("cr_vest"); // Position (stream_id, owner_addr) -> Position pub const POSITIONS: Map<&Addr, Position> = Map::new("positions"); -/// Terms and services ipfs link signature signed by user +/// Terms and services ipfs link +pub const TOS: Item = Item::new("tos"); /// Both for creator and subscriber pub const TOS_SIGNED: Map<&Addr, String> = Map::new("tos_signed"); diff --git a/packages/types/src/stream/msg.rs b/packages/types/src/stream/msg.rs index 61ceb4d..a927160 100644 --- a/packages/types/src/stream/msg.rs +++ b/packages/types/src/stream/msg.rs @@ -74,6 +74,8 @@ pub enum QueryMsg { LastStreamedPrice {}, #[returns(Uint128)] Threshold {}, + #[returns(String)] + ToS { addr: Option }, } #[cw_serde] @@ -140,18 +142,19 @@ pub struct PositionResponse { pub owner: String, /// Current amount of tokens in buy pool pub in_balance: Uint256, + /// Shares amount position owns pub shares: Uint256, - // Index is used to calculate the distribution a position has + /// Index is used to calculate the distribution a position has pub index: Decimal256, - // Last_updated_time is the time when the position was last updated + /// Last_updated_time is the time when the position was last updated pub last_updated: Timestamp, - // Total amount of `token_out` purchased in tokens at latest calculation + /// Total amount of `token_out` purchased in tokens at latest calculation pub purchased: Uint256, - // Pending purchased accumulates purchases after decimal truncation + /// Pending purchased accumulates purchases after decimal truncation pub pending_purchase: Decimal256, - // Total amount of `token_in` spent tokens at latest calculation + /// Total amount of `token_in` spent tokens at latest calculation pub spent: Uint256, - // Exit date of the position + /// Exit date of the position pub exit_date: Timestamp, } @@ -170,5 +173,10 @@ pub struct LatestStreamedPriceResponse { pub current_streamed_price: Decimal256, } +#[cw_serde] +pub struct TosResponse { + pub tos: String, +} + #[cw_serde] pub struct MigrateMsg {} diff --git a/packages/types/src/stream/position.rs b/packages/types/src/stream/position.rs index 191c7a7..f605994 100644 --- a/packages/types/src/stream/position.rs +++ b/packages/types/src/stream/position.rs @@ -20,8 +20,6 @@ pub struct Position { pub spent: Uint256, // Exit date of the position pub exit_date: Timestamp, - // signed tos version - pub tos_version: String, } impl Position { @@ -31,7 +29,6 @@ impl Position { shares: Uint256, index: Option, last_updated: Timestamp, - tos_version: String, ) -> Self { Position { owner, @@ -43,7 +40,6 @@ impl Position { pending_purchase: Decimal256::zero(), spent: Uint256::zero(), exit_date: Timestamp::from_nanos(0), - tos_version, } } } diff --git a/packages/types/src/stream/stream.rs b/packages/types/src/stream/stream.rs index d3a6c1e..a960d73 100644 --- a/packages/types/src/stream/stream.rs +++ b/packages/types/src/stream/stream.rs @@ -84,24 +84,15 @@ pub struct StreamInfo { /// Stream admin address, where the stream creator can manage the stream, like canceling it in waiting status /// or finalizing it in ended status pub url: Option, - // Tos version - pub tos_version: String, } impl StreamInfo { - pub fn new( - stream_admin: Addr, - name: String, - treasury: Addr, - url: Option, - tos_version: String, - ) -> Self { + pub fn new(stream_admin: Addr, name: String, treasury: Addr, url: Option) -> Self { StreamInfo { stream_admin, name, treasury, url, - tos_version, } } } diff --git a/tests/src/tests/streamswap_tests/subscribe.rs b/tests/src/tests/streamswap_tests/subscribe.rs index 2e16696..2d7ef8b 100644 --- a/tests/src/tests/streamswap_tests/subscribe.rs +++ b/tests/src/tests/streamswap_tests/subscribe.rs @@ -137,6 +137,27 @@ mod subscribe { assert_eq!(position.in_balance, Uint256::from(150u128)); assert_eq!(position.spent, Uint256::zero()); + // check tos + let tos: String = app + .wrap() + .query_wasm_smart( + Addr::unchecked(stream_swap_contract_address.clone()), + &StreamSwapQueryMsg::ToS { addr: None }, + ) + .unwrap(); + + // query position + let tos_signed: String = app + .wrap() + .query_wasm_smart( + Addr::unchecked(stream_swap_contract_address.clone()), + &StreamSwapQueryMsg::ToS { + addr: Some(position.owner), + }, + ) + .unwrap(); + assert_eq!(tos, tos_signed); + // Update stream app.set_block(BlockInfo { height: 2_200, diff --git a/ts/types/StreamSwapStream.client.ts b/ts/types/StreamSwapStream.client.ts index 8e3a11c..7a2d2ad 100644 --- a/ts/types/StreamSwapStream.client.ts +++ b/ts/types/StreamSwapStream.client.ts @@ -6,7 +6,7 @@ import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; import { StdFee } from "@cosmjs/amino"; -import { Timestamp, Uint64, Schedule, Uint128, PoolConfig, Uint256, Binary, InstantiateMsg, VestingConfig, Coin, ExecuteMsg, CreatePool, QueryMsg, Decimal256, AveragePriceResponse, LatestStreamedPriceResponse, PositionsResponse, PositionResponse, Addr, Params, Status, StreamResponse } from "./StreamSwapStream.types"; +import { Timestamp, Uint64, Schedule, Uint128, PoolConfig, Uint256, Binary, InstantiateMsg, VestingConfig, Coin, ExecuteMsg, CreatePool, QueryMsg, Decimal256, AveragePriceResponse, LatestStreamedPriceResponse, PositionsResponse, PositionResponse, Addr, Params, Status, StreamResponse, String } from "./StreamSwapStream.types"; export interface StreamSwapStreamReadOnlyInterface { contractAddress: string; params: () => Promise; @@ -26,6 +26,11 @@ export interface StreamSwapStreamReadOnlyInterface { averagePrice: () => Promise; lastStreamedPrice: () => Promise; threshold: () => Promise; + toS: ({ + addr + }: { + addr?: string; + }) => Promise; } export class StreamSwapStreamQueryClient implements StreamSwapStreamReadOnlyInterface { client: CosmWasmClient; @@ -41,6 +46,7 @@ export class StreamSwapStreamQueryClient implements StreamSwapStreamReadOnlyInte this.averagePrice = this.averagePrice.bind(this); this.lastStreamedPrice = this.lastStreamedPrice.bind(this); this.threshold = this.threshold.bind(this); + this.toS = this.toS.bind(this); } params = async (): Promise => { @@ -93,6 +99,17 @@ export class StreamSwapStreamQueryClient implements StreamSwapStreamReadOnlyInte threshold: {} }); }; + toS = async ({ + addr + }: { + addr?: string; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + to_s: { + addr + } + }); + }; } export interface StreamSwapStreamInterface extends StreamSwapStreamReadOnlyInterface { contractAddress: string; diff --git a/ts/types/StreamSwapStream.message-composer.ts b/ts/types/StreamSwapStream.message-composer.ts index 0b08b35..3e635c8 100644 --- a/ts/types/StreamSwapStream.message-composer.ts +++ b/ts/types/StreamSwapStream.message-composer.ts @@ -7,7 +7,7 @@ import { MsgExecuteContractEncodeObject } from "@cosmjs/cosmwasm-stargate"; import { MsgExecuteContract } from "cosmjs-types/cosmwasm/wasm/v1/tx"; import { toUtf8 } from "@cosmjs/encoding"; -import { Timestamp, Uint64, Schedule, Uint128, PoolConfig, Uint256, Binary, InstantiateMsg, VestingConfig, Coin, ExecuteMsg, CreatePool, QueryMsg, Decimal256, AveragePriceResponse, LatestStreamedPriceResponse, PositionsResponse, PositionResponse, Addr, Params, Status, StreamResponse } from "./StreamSwapStream.types"; +import { Timestamp, Uint64, Schedule, Uint128, PoolConfig, Uint256, Binary, InstantiateMsg, VestingConfig, Coin, ExecuteMsg, CreatePool, QueryMsg, Decimal256, AveragePriceResponse, LatestStreamedPriceResponse, PositionsResponse, PositionResponse, Addr, Params, Status, StreamResponse, String } from "./StreamSwapStream.types"; export interface StreamSwapStreamMsg { contractAddress: string; sender: string; diff --git a/ts/types/StreamSwapStream.types.ts b/ts/types/StreamSwapStream.types.ts index 07faf86..6417bfd 100644 --- a/ts/types/StreamSwapStream.types.ts +++ b/ts/types/StreamSwapStream.types.ts @@ -100,6 +100,10 @@ export type QueryMsg = { last_streamed_price: {}; } | { threshold: {}; +} | { + to_s: { + addr?: string | null; + }; }; export type Decimal256 = string; export interface AveragePriceResponse { @@ -153,4 +157,5 @@ export interface StreamResponse { stream_admin: string; treasury: string; url?: string | null; -} \ No newline at end of file +} +export type String = string; \ No newline at end of file