Skip to content
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

fix canister getting stuck after trapping #12

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
89 changes: 48 additions & 41 deletions src/fortune-wheel-booth-backend/main.mo
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Buffer "mo:base/Buffer";
import TrieSet "mo:base/TrieSet";
import Fuzz "mo:fuzz";
import Debug "mo:base/Debug";
import Result "mo:base/Result";

import IcpLedger "canister:icp_ledger";
import ckBtcLedger "canister:ckbtc_ledger";
Expand All @@ -31,7 +32,7 @@ shared ({ caller = initialController }) actor class Main() = self {
type Extraction = {
extractedAt : Time.Time;
prize : Prize;
transactionBlockIndex : ?Nat;
// transactionBlockIndex : ?Nat;
};

// ICP and ckBTC have 8 decimals: 100_000_000
Expand Down Expand Up @@ -116,73 +117,79 @@ shared ({ caller = initialController }) actor class Main() = self {
Option.isSome(extractedPrincipals.get(principal));
};

public shared ({ caller }) func extract(receiver : Principal) : async Extraction {
public shared ({ caller }) func extract(receiver : Principal) : async Result.Result<Extraction, Text> {
if (extracting) {
throw Error.reject("Extraction already in progress");
return #err("Extraction already in progress");
};

if (not isAdmin(caller)) {
throw Error.reject("Only admins can extract");
return #err("Only admins can extract");
};

if (Principal.isAnonymous(receiver)) {
throw Error.reject("Anonymous principal cannot receive prizes");
return #err("Anonymous principal cannot receive prizes");
};

if (Principal.fromText("aaaaa-aa") == receiver) {
throw Error.reject("Management canister cannot receive prizes");
return #err("Management canister cannot receive prizes");
};

if (isPrincipalExtracted(receiver)) {
throw Error.reject("Already extracted for this principal");
return #err("Already extracted for this principal");
};

extracting := true;

let prize = await getRandomPrize();

let transactionBlockIndex = switch (prize) {
case (#icp(amount)) {
?(await transferIcp(receiver, amount, true));
};
case (#ckBtc(amount)) {
?(await transferCkBtc(receiver, amount, true));
};
case (#ckEth(amount)) {
?(await transferCkEth(receiver, amount, true));
};
case (#ckUsdc(amount)) {
?(await transferCkUsdc(receiver, amount, true));
};
case (#special("jackpot")) {
let icp_transfer = transferIcp(receiver, icp_amount, true);
let ckbtc_transfer = transferCkBtc(receiver, ckbtc_amount, true);
let cketh_transfer = transferCkEth(receiver, cketh_amount, true);
let ckusdc_transfer = transferCkUsdc(receiver, ckusdc_amount, true);
let icp_idx = await icp_transfer;
Debug.print("Jackpot: ICP block index: " # debug_show (icp_idx));
let ckbtc_idx = await ckbtc_transfer;
Debug.print("Jackpot: ckBTC block index: " # debug_show (ckbtc_idx));
let cketh_idx = await cketh_transfer;
Debug.print("Jackpot: ckETH block index: " # debug_show (cketh_idx));
let ckusdc_idx = await ckusdc_transfer;
Debug.print("Jackpot: ckUSDC block index: " # debug_show (ckusdc_idx));
null;
try{
switch (prize) {
case (#icp(amount)) {
(ignore await transferIcp(receiver, amount, true));
};
case (#ckBtc(amount)) {
(ignore await transferCkBtc(receiver, amount, true));
};
case (#ckEth(amount)) {
(ignore await transferCkEth(receiver, amount, true));
};
case (#ckUsdc(amount)) {
(ignore await transferCkUsdc(receiver, amount, true));
};
case (#special("jackpot")) {
let icp_transfer = transferIcp(receiver, icp_amount, true);
let ckbtc_transfer = transferCkBtc(receiver, ckbtc_amount, true);
let cketh_transfer = transferCkEth(receiver, cketh_amount, true);
let ckusdc_transfer = transferCkUsdc(receiver, ckusdc_amount, true);
let icp_idx = await icp_transfer;
Debug.print("Jackpot: ICP block index: " # debug_show (icp_idx));
let ckbtc_idx = await ckbtc_transfer;
Debug.print("Jackpot: ckBTC block index: " # debug_show (ckbtc_idx));
let cketh_idx = await cketh_transfer;
Debug.print("Jackpot: ckETH block index: " # debug_show (cketh_idx));
let ckusdc_idx = await ckusdc_transfer;
Debug.print("Jackpot: ckUSDC block index: " # debug_show (ckusdc_idx));
//null;
};
case (_) {};
};
case (_) { null };

} catch (e) {
extracting := false;
return #err("LedgerError: " # Error.message(e));
};

let extraction : Extraction = {
extractedAt = Time.now();
prize;
transactionBlockIndex;
//transactionBlockIndex;
};

extractedPrincipals.put(receiver, extraction);

extracting := false;

extraction;
return #ok(extraction);
};

private func getRandomPrize() : async Prize {
Expand Down Expand Up @@ -231,7 +238,7 @@ shared ({ caller = initialController }) actor class Main() = self {
value;
};
case (#Err(error)) {
throw Error.reject(debug_show (error));
throw Error.reject("ICP: " # debug_show (error));
};
};
};
Expand All @@ -255,7 +262,7 @@ shared ({ caller = initialController }) actor class Main() = self {
value;
};
case (#Err(error)) {
throw Error.reject(debug_show (error));
throw Error.reject("ckBTC: " # debug_show (error));
};
};
};
Expand All @@ -279,7 +286,7 @@ shared ({ caller = initialController }) actor class Main() = self {
value;
};
case (#Err(error)) {
throw Error.reject(debug_show (error));
throw Error.reject("ckETH: " # debug_show (error));
};
};
};
Expand All @@ -303,7 +310,7 @@ shared ({ caller = initialController }) actor class Main() = self {
value;
};
case (#Err(error)) {
throw Error.reject(debug_show (error));
throw Error.reject("ckUSDC: " # debug_show (error));
};
};
};
Expand Down
18 changes: 12 additions & 6 deletions src/fortune-wheel-booth-frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import icpMainLogo from './assets/icp-main-logo.svg';
import useIcState from './hooks/useIcState';

export default function Home() {
const { isAnonymous, logout, handleLogin, adminActor, adminPrincipal } =
const { isAnonymous, logout, handleLogin, adminActor, adminPrincipal} =
useIcState();
const [error, setError] = useState<string | undefined>();
const [debouncePrizeExtraction, setDebouncePrizeExtraction] =
Expand All @@ -32,22 +32,28 @@ export default function Home() {
setDebouncePrizeExtraction(true);
setExtractionResult(undefined);
if (adminActor) {
// canister call can still trap for a number of reasons
try {
const userPrincipal: Principal = Principal.fromText(text);
const extraction = await adminActor.extract(userPrincipal);
console.log('Extraction result:', extraction);
setExtractionResult(extraction);
if ('ok' in extraction) {
setExtractionResult(extraction.ok);
} else {
console.error(extraction);
setError(extraction.err);
if (extraction.err.includes('Only admins can extract')) {
logout();
}
}

setTimeout(() => {
setExtractionResult(undefined);
}, 10_000);
} catch (err: any) {
console.error(err);
const errorMsg = err.message || 'Failed to extract: Unknown error';
setError(errorMsg);
if (errorMsg.includes('Only admins can extract')) {
logout();
}
setError(err);
}
}
setIsExtracting(false);
Expand Down