Skip to content

Commit

Permalink
[move]Use some Move 2024 Syntax to update 'utils' example (MystenLabs…
Browse files Browse the repository at this point in the history
…#17511)

## Description 

Use some Move 2024 Syntax to update 'utils' example.

## Test plan 


![test2](https://github.com/MystenLabs/sui/assets/148738263/8b22612d-a8b2-4eda-aa02-252f2bebf4fe)


---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:

---------

Co-authored-by: Ashok Menon <[email protected]>
  • Loading branch information
shaflow01 and amnn authored May 8, 2024
1 parent edd3ece commit 47b139f
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ module utils::epoch_time_lock {

/// Create a new epoch time lock with `epoch`. Aborts if the current epoch is less than the input epoch.
public fun new(epoch: u64, ctx: &TxContext) : EpochTimeLock {
assert!(tx_context::epoch(ctx) < epoch, EEpochAlreadyPassed);
assert!(ctx.epoch() < epoch, EEpochAlreadyPassed);
EpochTimeLock { epoch }
}

/// Destroys an epoch time lock. Aborts if the current epoch is less than the locked epoch.
public fun destroy(lock: EpochTimeLock, ctx: &TxContext) {
let EpochTimeLock { epoch } = lock;
assert!(tx_context::epoch(ctx) >= epoch, EEpochNotYetEnded);
assert!(ctx.epoch() >= epoch, EEpochNotYetEnded);
}

/// Getter for the epoch number.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ module utils::immutable_external_resource {

/// Update the URL, but the digest of the resource must never change.
public fun update(self: &mut ImmutableExternalResource, url: Url) {
sui::url::update(&mut self.url, inner_url(&url))
self.url.update(url.inner_url())
}
}
12 changes: 6 additions & 6 deletions sui_programmability/examples/utils/sources/locked_coin.move
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

module utils::locked_coin {
use sui::balance::{Self, Balance};
use sui::balance::Balance;
use sui::coin::{Self, Coin};
use utils::epoch_time_lock::{Self, EpochTimeLock};

Expand All @@ -25,7 +25,7 @@ module utils::locked_coin {

/// Public getter for the locked coin's value
public fun value<T>(self: &LockedCoin<T>): u64 {
balance::value(&self.balance)
self.balance.value()
}

/// Lock a coin up until `locked_until_epoch`. The input Coin<T> is deleted and a LockedCoin<T>
Expand All @@ -34,7 +34,7 @@ module utils::locked_coin {
public entry fun lock_coin<T>(
coin: Coin<T>, recipient: address, locked_until_epoch: u64, ctx: &mut TxContext
) {
let balance = coin::into_balance(coin);
let balance = coin.into_balance();
new_from_balance(balance, epoch_time_lock::new(locked_until_epoch, ctx), recipient, ctx);
}

Expand All @@ -43,9 +43,9 @@ module utils::locked_coin {
/// to the sender.
public entry fun unlock_coin<T>(locked_coin: LockedCoin<T>, ctx: &mut TxContext) {
let LockedCoin { id, balance, locked_until_epoch } = locked_coin;
object::delete(id);
epoch_time_lock::destroy(locked_until_epoch, ctx);
id.delete();
locked_until_epoch.destroy(ctx);
let coin = coin::from_balance(balance, ctx);
transfer::public_transfer(coin, tx_context::sender(ctx));
transfer::public_transfer(coin, ctx.sender());
}
}
20 changes: 10 additions & 10 deletions sui_programmability/examples/utils/sources/safe.move
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module utils::safe {
// Check that the ids match
assert!(object::id(safe) == capability.safe_id, EInvalidTransferCapability);
// Check that it has not been cancelled
assert!(vec_set::contains(&safe.allowed_safes, &object::id(capability)), ETransferCapabilityRevoked);
assert!(safe.allowed_safes.contains(&object::id(capability)), ETransferCapabilityRevoked);
}

fun check_owner_capability_validity<T>(safe: &Safe<T>, capability: &OwnerCapability<T>) {
Expand All @@ -62,11 +62,11 @@ module utils::safe {
/// Helper function to create a capability.
fun create_capability_<T>(safe: &mut Safe<T>, withdraw_amount: u64, ctx: &mut TxContext): TransferCapability<T> {
let cap_id = object::new(ctx);
vec_set::insert(&mut safe.allowed_safes, object::uid_to_inner(&cap_id));
safe.allowed_safes.insert(cap_id.uid_to_inner());

let capability = TransferCapability {
id: cap_id,
safe_id: object::uid_to_inner(&safe.id),
safe_id: safe.id.uid_to_inner(),
amount: withdraw_amount,
};

Expand Down Expand Up @@ -98,7 +98,7 @@ module utils::safe {
}

public entry fun create<T>(coin: Coin<T>, ctx: &mut TxContext) {
let balance = coin::into_balance(coin);
let balance = coin.into_balance();
let cap = create_<T>(balance, ctx);
transfer::public_transfer(cap, ctx.sender());
}
Expand All @@ -111,20 +111,20 @@ module utils::safe {

/// Deposit funds to the safe
public fun deposit_<T>(safe: &mut Safe<T>, balance: Balance<T>) {
balance::join(&mut safe.balance, balance);
safe.balance.join(balance);
}

/// Deposit funds to the safe
public entry fun deposit<T>(safe: &mut Safe<T>, coin: Coin<T>) {
let balance = coin::into_balance(coin);
let balance = coin.into_balance();
deposit_<T>(safe, balance);
}

/// Withdraw coins from the safe as a `OwnerCapability` holder
public fun withdraw_<T>(safe: &mut Safe<T>, capability: &OwnerCapability<T>, withdraw_amount: u64): Balance<T> {
// Ensures that only the owner can withdraw from the safe.
check_owner_capability_validity(safe, capability);
balance::split(&mut safe.balance, withdraw_amount)
safe.balance.split(withdraw_amount)
}

/// Withdraw coins from the safe as a `OwnerCapability` holder
Expand All @@ -142,20 +142,20 @@ module utils::safe {
// Withdraw funds
assert!(capability.amount >= withdraw_amount, EOverdrawn);
capability.amount = capability.amount - withdraw_amount;
balance::split(&mut safe.balance, withdraw_amount)
safe.balance.split(withdraw_amount)
}

/// Revoke a `TransferCapability` as an `OwnerCapability` holder
public entry fun revoke_transfer_capability<T>(safe: &mut Safe<T>, capability: &OwnerCapability<T>, capability_id: ID) {
// Ensures that only the owner can withdraw from the safe.
check_owner_capability_validity(safe, capability);
vec_set::remove(&mut safe.allowed_safes, &capability_id);
safe.allowed_safes.remove(&capability_id);
}

/// Revoke a `TransferCapability` as its owner
public entry fun self_revoke_transfer_capability<T>(safe: &mut Safe<T>, capability: &TransferCapability<T>) {
check_capability_validity(safe, capability);
vec_set::remove(&mut safe.allowed_safes, &object::id(capability));
safe.allowed_safes.remove(&object::id(capability));
}

/// Create `TransferCapability` as an `OwnerCapability` holder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ module utils::immutable_external_resource_tests {
let digest = sha3_256(hash);
let mut resource = immutable_external_resource::new(url, digest);

assert!(immutable_external_resource::url(&resource) == url, EUrlStringMisMatch);
assert!(immutable_external_resource::digest(&resource) == digest, EHashStringMisMatch);
assert!(resource.url() == url, EUrlStringMisMatch);
assert!(resource.digest() == digest, EHashStringMisMatch);

let new_url_str = ascii::string(x"37414243454647");
let new_url = url::new_unsafe(new_url_str);

immutable_external_resource::update(&mut resource, new_url);
assert!(immutable_external_resource::url(&resource) == new_url, EUrlStringMisMatch);
resource.update(new_url);
assert!(resource.url() == new_url, EUrlStringMisMatch);
}
}
95 changes: 45 additions & 50 deletions sui_programmability/examples/utils/tests/safe_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module utils::safe_tests {
const TEST_DELEGATEE_ADDR: address = @0x1ce1ce1ce;

fun create_safe(scenario: &mut Scenario, owner: address, stored_amount: u64) {
ts::next_tx(scenario, owner);
scenario.next_tx(owner);
{
let coin = coin::mint_for_testing<SUI>(stored_amount, ctx(scenario));
safe::create(coin, ctx(scenario));
Expand All @@ -24,80 +24,78 @@ module utils::safe_tests {
// Delegates the safe to delegatee and return the capability ID.
fun delegate_safe(scenario: &mut Scenario, owner: address, delegate_to: address, delegate_amount: u64): ID {
let id;
ts::next_tx(scenario, owner);
let mut safe = ts::take_shared<Safe<SUI>>(scenario);
let cap = ts::take_from_sender<OwnerCapability<SUI>>(scenario);
let capability = safe::create_transfer_capability(&mut safe, &cap, delegate_amount, ctx(scenario));
scenario.next_tx(owner);
let mut safe = scenario.take_shared<Safe<SUI>>();
let cap = scenario.take_from_sender<OwnerCapability<SUI>>();
let capability = safe.create_transfer_capability(&cap, delegate_amount, ctx(scenario));
id = object::id(&capability);
transfer::public_transfer(capability, delegate_to);
ts::return_to_sender(scenario, cap);
scenario.return_to_sender(cap);
ts::return_shared(safe);
id
}

fun withdraw_as_delegatee(scenario: &mut Scenario, delegatee: address, withdraw_amount: u64) {
ts::next_tx(scenario, delegatee);
let mut safe = ts::take_shared<Safe<SUI>>(scenario);
let mut capability = ts::take_from_sender<TransferCapability<SUI>>(scenario);
let balance = safe::debit(&mut safe, &mut capability, withdraw_amount);
scenario.next_tx(delegatee);
let mut safe = scenario.take_shared<Safe<SUI>>();
let mut capability = scenario.take_from_sender<TransferCapability<SUI>>();
let balance = safe.debit(&mut capability, withdraw_amount);
test_utils::destroy(balance);

ts::return_to_sender(scenario, capability);
scenario.return_to_sender(capability);
ts::return_shared(safe);
}

fun revoke_capability(scenario: &mut Scenario, owner: address, capability_id: ID) {
ts::next_tx(scenario, owner);
let mut safe = ts::take_shared<Safe<SUI>>(scenario);
let cap = ts::take_from_sender<OwnerCapability<SUI>>(scenario);
safe::revoke_transfer_capability(&mut safe, &cap, capability_id);
scenario.next_tx(owner);
let mut safe = scenario.take_shared<Safe<SUI>>();
let cap = scenario.take_from_sender<OwnerCapability<SUI>>();
safe.revoke_transfer_capability(&cap, capability_id);

ts::return_to_sender(scenario, cap);
scenario.return_to_sender(cap);
ts::return_shared(safe);
}

#[test]
/// Ensure that all funds can be withdrawn by the owners
fun test_safe_create_and_withdraw_funds_as_owner() {
let owner = TEST_OWNER_ADDR;
let mut scenario_val = ts::begin(TEST_SENDER_ADDR);
let scenario = &mut scenario_val;
let mut scenario = ts::begin(TEST_SENDER_ADDR);

let initial_funds = 1000u64;
create_safe(scenario, owner, initial_funds);

ts::next_tx(scenario, owner);
let mut safe = ts::take_shared<Safe<SUI>>(scenario);
let cap = ts::take_from_sender<OwnerCapability<SUI>>(scenario);
scenario.next_tx(owner);
let mut safe = scenario.take_shared<Safe<SUI>>();
let cap = scenario.take_from_sender<OwnerCapability<SUI>>();

safe::withdraw(&mut safe, &cap, initial_funds, ts::ctx(scenario));
ts::next_tx(scenario, owner);
let withdrawn_coin = ts::take_from_sender<Coin<SUI>>(scenario);
assert!(coin::value(&withdrawn_coin) == initial_funds, 0);
safe.withdraw(&cap, initial_funds, ts::ctx(scenario));
scenario.next_tx(owner);
let withdrawn_coin = scenario.take_from_sender<Coin<SUI>>();
assert!(withdrawn_coin.value() == initial_funds, 0);

test_utils::destroy(withdrawn_coin);
ts::return_to_sender(scenario, cap);
scenario.return_to_sender(cap);
ts::return_shared(safe);


ts::end(scenario_val);
scenario.end();
}

#[test]
/// Ensure that all funds can be withdrawn to a delegator
fun test_safe_create_and_withdraw_funds_as_delegatee() {
let owner = TEST_OWNER_ADDR;
let delegatee = TEST_DELEGATEE_ADDR;
let mut scenario_val = ts::begin(TEST_SENDER_ADDR);
let scenario = &mut scenario_val;
let mut scenario = ts::begin(TEST_SENDER_ADDR);

let initial_funds = 1000u64;
let delegated_funds = 1000u64;
// Create Safe
create_safe(scenario, owner, initial_funds);
delegate_safe(scenario, owner, delegatee, delegated_funds);
withdraw_as_delegatee(scenario, delegatee, delegated_funds);
ts::end(scenario_val);

scenario.end();
}

#[test]
Expand All @@ -106,8 +104,7 @@ module utils::safe_tests {
fun test_safe_attempt_to_over_withdraw() {
let owner = TEST_OWNER_ADDR;
let delegatee = TEST_DELEGATEE_ADDR;
let mut scenario_val = ts::begin(TEST_SENDER_ADDR);
let scenario = &mut scenario_val;
let mut scenario = ts::begin(TEST_SENDER_ADDR);

let initial_funds = 1000u64;
let delegated_funds = 1000u64;
Expand All @@ -120,7 +117,7 @@ module utils::safe_tests {
// Attempt to withdraw by 1 coin.
withdraw_as_delegatee(scenario, delegatee, 1);

ts::end(scenario_val);
scenario.end();
}

#[test]
Expand All @@ -129,8 +126,7 @@ module utils::safe_tests {
fun test_safe_withdraw_revoked() {
let owner = TEST_OWNER_ADDR;
let delegatee = TEST_DELEGATEE_ADDR;
let mut scenario_val = ts::begin(TEST_SENDER_ADDR);
let scenario = &mut scenario_val;
let mut scenario = ts::begin(TEST_SENDER_ADDR);

let initial_funds = 1000u64;
let delegated_funds = 1000u64;
Expand All @@ -143,37 +139,36 @@ module utils::safe_tests {
// Withdraw funds
withdraw_as_delegatee(scenario, delegatee, delegated_funds);

ts::end(scenario_val);
scenario.end();
}

#[test]
#[expected_failure(abort_code = safe::ETransferCapabilityRevoked)]
/// Ensure owner cannot withdraw funds after revoking itself.
fun test_safe_withdraw_self_revoked() {
let owner = TEST_OWNER_ADDR;
let mut scenario_val = ts::begin(owner);
let scenario = &mut scenario_val;
let mut scenario = ts::begin(owner);

let initial_funds = 1000u64;
create_safe(scenario, owner, initial_funds);

ts::next_tx(scenario, owner);
let cap = ts::take_from_sender<OwnerCapability<SUI>>(scenario);
let mut safe = ts::take_shared<Safe<SUI>>(scenario);
let mut transfer_capability = safe::create_transfer_capability(&mut safe, &cap, initial_funds, ctx(scenario));
scenario.next_tx(owner);
let cap = scenario.take_from_sender<OwnerCapability<SUI>>();
let mut safe = scenario.take_shared<Safe<SUI>>();
let mut transfer_capability = safe.create_transfer_capability(&cap, initial_funds, ctx(scenario));
// Function under test
safe::self_revoke_transfer_capability(&mut safe, &transfer_capability);
safe.self_revoke_transfer_capability(&transfer_capability);
ts::return_shared(safe);

// Try withdraw funds with transfer capability.
ts::next_tx(scenario, owner);
let mut safe = ts::take_shared<Safe<SUI>>(scenario);
let balance = safe::debit(&mut safe, &mut transfer_capability, 1000u64);
scenario.next_tx(owner);
let mut safe = scenario.take_shared<Safe<SUI>>();
let balance = safe.debit(&mut transfer_capability, 1000u64);
test_utils::destroy(balance);

ts::return_shared(safe);
ts::return_to_sender(scenario, cap);
ts::return_to_sender(scenario, transfer_capability);
ts::end(scenario_val);
scenario.return_to_sender(cap);
scenario.return_to_sender(transfer_capability);
scenario.end();
}
}

0 comments on commit 47b139f

Please sign in to comment.