Skip to content

Rework snapshot datastructure for NFT only #7

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
29 changes: 21 additions & 8 deletions lib/cmtat/modules/nft_asset/snapshots.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ module TZIP12 = FA2.NFTExtendable.TZIP12

type snapshot_data = nat

type snapshots = ((timestamp * nat), snapshot_data) map
// TODO
// should be ???
type snapshots = (timestamp, nat set) map

//type snapshots = ((timestamp * nat), snapshot_data) map

type t = {
account_snapshots : (address, snapshots) big_map;
Expand Down Expand Up @@ -136,20 +140,20 @@ let getNextSnapshots (snapshots:t) : timestamp list =

// If there is a scheduled snapshot for the given time returns totalsupply of the snapshot otherwise returns the current totalsupply
let snapshotTotalsupply (time : timestamp) (token_id: nat) (totalsupplies: TOTALSUPPLY.t) (snapshots:t) : nat =
match Map.find_opt (time, token_id) snapshots.totalsupply_snapshots with
match Map.find_opt time snapshots.totalsupply_snapshots with
| None -> (match (Big_map.find_opt token_id totalsupplies) with
| Some(actual) -> actual
| None -> 0n)
| Some(v) -> v
| Some(ids) -> if Set.mem token_id ids then 1n else 0n

// If there is a scheduled snapshot for the given time returns balance of the snapshot otherwise returns the current user balance
let snapshotBalanceOf (time : timestamp) (user: address) (token_id: nat) (ledger: FA2.NFTExtendable.ledger) (snapshots:t) : nat =
match Big_map.find_opt user snapshots.account_snapshots with
| None -> get_for_user_curried(ledger, user, token_id)
| Some(snaps) ->
let value = match Map.find_opt (time, token_id) snaps with
let value = match Map.find_opt time snaps with
| None -> get_for_user_curried(ledger, user, token_id)
| Some (v) -> v
| Some (ids) -> if Set.mem token_id ids then 1n else 0n
in value

////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -158,16 +162,25 @@ let snapshotBalanceOf (time : timestamp) (user: address) (token_id: nat) (ledger
let update_account_snapshot (current_scheduled_snapshot: timestamp) (token_id: nat) (account: address) (account_balance: nat) (snapshots: t) : t =
let new_account_snapshots = match Big_map.find_opt account snapshots.account_snapshots with
| Some(snaps) ->
let new_snaps = Map.update (current_scheduled_snapshot, token_id) (Some(account_balance)) snaps in
let new_current_snaps = match Map.find_opt current_scheduled_snapshot snaps with
| None -> Set.empty
| Some(ids) -> if account_balance = 0n then Set.remove token_id ids else Set.add token_id ids
in
let new_snaps = Map.update current_scheduled_snapshot (Some(new_current_snaps)) snaps in
Big_map.update account (Some(new_snaps)) snapshots.account_snapshots
| None() ->
let snaps = Map.literal([((current_scheduled_snapshot, token_id), account_balance)]) in
let new_current_snaps = if account_balance = 0n then Set.empty else Set.add token_id Set.empty in
let snaps = Map.literal([(current_scheduled_snapshot, new_current_snaps)]) in
Big_map.add account snaps snapshots.account_snapshots
in
{ snapshots with account_snapshots = new_account_snapshots }

let update_totalsupply_snapshot (current_scheduled_snapshot: timestamp) (token_id: nat) (totalsupply_balance: nat) (snapshots: t) : t =
let new_totalsupply_snapshots = Map.update (current_scheduled_snapshot, token_id) (Some(totalsupply_balance)) snapshots.totalsupply_snapshots in
let new_ids = match Map.find_opt current_scheduled_snapshot snapshots.totalsupply_snapshots with
| None -> if totalsupply_balance = 0n then Set.empty else Set.add token_id Set.empty
| Some (ids) -> if totalsupply_balance = 0n then Set.remove token_id ids else Set.add token_id ids
in
let new_totalsupply_snapshots = Map.update current_scheduled_snapshot (Some(new_ids)) snapshots.totalsupply_snapshots in
{ snapshots with totalsupply_snapshots = new_totalsupply_snapshots }

let get_current_scheduled_snapshot (snapshots:t) : timestamp option =
Expand Down
16 changes: 8 additions & 8 deletions test/cmtat/extended_cmtat_nft_asset.test.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -84,26 +84,26 @@ let assert_account_snapshot
let storage = Test.get_storage contract_address in
let () = match Big_map.find_opt owner1 storage.snapshots.account_snapshots with
| Some(snaps) ->
let () = match Map.find_opt (time, token_id_1) snaps with
| Some (v) -> assert(balance1 = v)
let () = match Map.find_opt time snaps with
| Some (ids) -> if balance1 = 0n then assert(Set.mem token_id_1 ids = false) else assert(Set.mem token_id_1 ids = true)
| None -> failwith "Account does not have a snapshot for this time"
in
()
| None -> failwith "[assert_account_snapshot] user 1 has no snapshot"
in
let () = match Big_map.find_opt owner2 storage.snapshots.account_snapshots with
| Some(snaps) ->
let () = match Map.find_opt (time, token_id_2) snaps with
| Some (v) -> assert(balance2 = v)
let () = match Map.find_opt time snaps with
| Some (ids) -> if balance2 = 0n then assert(Set.mem token_id_2 ids = false) else assert(Set.mem token_id_2 ids = true)
| None -> failwith "Account does not have a snapshot for this time"
in
()
| None -> failwith "[assert_account_snapshot] user 2 has no snapshot"
in
let () = match Big_map.find_opt owner3 storage.snapshots.account_snapshots with
| Some(snaps) ->
let () = match Map.find_opt (time, token_id_3) snaps with
| Some (v) -> assert(balance3= v)
let () = match Map.find_opt time snaps with
| Some (ids) -> if balance3 = 0n then assert(Set.mem token_id_3 ids = false) else assert(Set.mem token_id_3 ids = true)
| None -> failwith "Account does not have a snapshot for this time"
in
()
Expand Down Expand Up @@ -136,8 +136,8 @@ let assert_totalsupply_snapshot
(token_id: nat)
(expected: nat) =
let storage = Test.get_storage contract_address in
let () = match Map.find_opt (time, token_id) storage.snapshots.totalsupply_snapshots with
| Some (v) -> assert(expected = v)
let () = match Map.find_opt time storage.snapshots.totalsupply_snapshots with
| Some (ids) -> if expected = 0n then assert(Set.mem token_id ids = false) else assert(Set.mem token_id ids = true)
| None -> failwith "No total supply snapshot for this time"
in
()
Expand Down