UNPKG

as-soroban-sdk

Version:

AssemblyScript SDK for writing contracts for Soroban.

562 lines (483 loc) 15 kB
import {BoolVal, errorCodeArithDomain, errorTypeObject, fromFalse, fromTrue, fromU128Pieces, getErrorCode, getErrorType, isError, isU128Small, toU128Low64, fromU128Small, toU128High64, toU128Small, isU128Object, fromU32, fromU64} from "../../lib/value"; import { u128Add, u128Compare, u128Div, u128IsEqual, u128IsGreaterThan, u128IsLowerThan, u128Mul, u128MulDiv, u128Pow, u128RemEuclid, u128Shl, u128Shr, u128Sub } from "../../lib/arithm128"; import * as context from "../../lib/context"; import { Vec } from "../../lib/vec"; import * as u128 from "../../lib/u128_math"; export function testU128Add():BoolVal { let falseVal = fromFalse(); // small + small let lhs = fromU128Small(2); let rhs = fromU128Small(2); let res = u128Add(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 4) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // small + obj lhs = fromU128Pieces(u64Max, 10) res = u128Add(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 12 || hi != u64Max) { return falseVal; } } else { return falseVal; } // obj + obj lhs = fromU128Pieces(1, u64Max); rhs = fromU128Pieces(10, 1); res = u128Add(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 0 || hi != 12) { return falseVal; } } else { return falseVal; } // overflow lhs = fromU128Pieces(u64Max, u64Max); res = u128Add(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testU128Sub():BoolVal { let falseVal = fromFalse(); // small - small let lhs = fromU128Small(4); let rhs = fromU128Small(2); let res = u128Sub(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 2) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // obj - small lhs = fromU128Pieces(u64Max, 10) res = u128Sub(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 8 || hi != u64Max) { return falseVal; } } else { return falseVal; } // obj - obj lhs = fromU128Pieces(10, u64Max); rhs = fromU128Pieces(9, 10); res = u128Sub(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != u64Max - 10 || hi != 1) { return falseVal; } } else { return falseVal; } // overflow 1 lhs = fromU128Small(2); rhs = fromU128Small(4); res = u128Sub(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } // overflow 2 rhs = fromU128Pieces(200, u64Max); res = u128Sub(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } // overflow 3 lhs = fromU128Pieces(100, u64Max); rhs = fromU128Pieces(200, u64Max); res = u128Sub(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testU128Mul():BoolVal { let falseVal = fromFalse(); // small * small let lhs = fromU128Small(2); let rhs = fromU128Small(2); let res = u128Mul(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 4) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // small * obj lhs = fromU128Pieces(10, 10) res = u128Mul(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 20 || hi != 20) { return falseVal; } } else { return falseVal; } // obj * obj lhs = fromU128Pieces(0, 75057594000000000); rhs = fromU128Pieces(0, 75057594000000000); res = u128Mul(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 219342094686224384 || hi != 305400367379626) { return falseVal; } let b_lo = u128.mul(75057594000000000, 0, 75057594000000000, 0); let b_hi = u128.__hi; /*let vals = new Vec(); vals.pushBack(res); vals.pushBack(fromU64(b_lo)); vals.pushBack(fromU64(b_hi)); context.log("cmp ", vals);*/ if (!u128IsEqual(res, fromU128Pieces(b_hi, b_lo))) { return falseVal; } } else { return falseVal; } // obj * obj / obj (muldiv) let number = fromU128Pieces(0, 75057594000000000); let nominator = fromU128Pieces(1000, 75057594000000000); let denominator = fromU128Pieces(0, 300); res = u128MulDiv(number, nominator, denominator); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 13897278342510149632 || hi != 250192998001224598) { return falseVal; } let b_lo = u128.muldiv(75057594000000000, 0, 75057594000000000, 1000, 300, 0); let b_hi = u128.__hi; if (!u128IsEqual(res, fromU128Pieces(b_hi, b_lo))) { return falseVal; } } else { return falseVal; } // overflow lhs = fromU128Pieces(u64Max, u64Max); rhs = fromU128Pieces(u64Max, u64Max); res = u128Mul(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testU128Div():BoolVal { let falseVal = fromFalse(); // small / small let lhs = fromU128Small(4); let rhs = fromU128Small(2); let res = u128Div(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 2) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // small / obj lhs = fromU128Pieces(10, 10) res = u128Div(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 5 || hi != 5) { return falseVal; } } else { return falseVal; } // obj + obj lhs = fromU128Pieces(u64Max, u64Max); rhs = fromU128Pieces(0, 75057594000000000); res = u128Div(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 14164472563176641127 || hi != 245) { return falseVal; } let b_lo = u128.div(u64Max, u64Max, 75057594000000000, 0); let b_hi = u128.__hi; /*let vals = new Vec(); vals.pushBack(fromU64(lo)); vals.pushBack(fromU64(hi)); vals.pushBack(fromU64(b_lo)); vals.pushBack(fromU64(b_hi)); context.log("cmp ", vals);*/ if (!u128.eq(b_lo, b_hi, lo, hi)) { return falseVal; } } else { return falseVal; } // overflow lhs = fromU128Pieces(u64Max, u64Max); rhs = fromU128Small(0); res = u128Div(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testU128RemEuclid():BoolVal { let falseVal = fromFalse(); // small % small let lhs = fromU128Small(4); let rhs = fromU128Small(3); let res = u128RemEuclid(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 1) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // obj % small lhs = fromU128Pieces(0, 7505759400002) res = u128RemEuclid(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 2) { return falseVal; } // obj % obj lhs = fromU128Pieces(0, 75057594000000015); rhs = fromU128Pieces(0, 75057594000000000); res = u128RemEuclid(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 15) { return falseVal; } // overflow lhs = fromU128Pieces(u64Max, u64Max); rhs = fromU128Small(0); res = u128RemEuclid(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testU128Pow():BoolVal { let falseVal = fromFalse(); // small ^ u32 let lhs = fromU128Small(2); let rhs = fromU32(2); let res = u128Pow(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 4) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // obj ^ u32 lhs = fromU128Pieces(0, 75057594000000000); res = u128Pow(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 219342094686224384 || hi != 305400367379626) { return falseVal; } let b_lo = u128.pow(75057594000000000, 0, 2); let b_hi = u128.__hi; /*let vals = new Vec(); vals.pushBack(fromU64(lo)); vals.pushBack(fromU64(hi)); vals.pushBack(fromU64(b_lo)); vals.pushBack(fromU64(b_hi)); context.log("cmp ", vals);*/ if (!u128.eq(b_lo, b_hi, lo, hi)) { return falseVal; } } else { return falseVal; } // overflow lhs = fromU128Pieces(u64Max, u64Max); res = u128Pow(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testU128Shl():BoolVal { let falseVal = fromFalse(); // small << u32 let lhs = fromU128Small(2); let rhs = fromU32(2); let res = u128Shl(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 8) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // obj << small lhs = fromU128Pieces(0, 75057594000000000); rhs = fromU32(10); res = u128Shl(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 3071999961161793536 || hi != 4) { return falseVal; } let b_lo = u128.shl(75057594000000000, 0, 10); let b_hi = u128.__hi; /*let vals = new Vec(); vals.pushBack(fromU64(lo)); vals.pushBack(fromU64(hi)); vals.pushBack(fromU64(b_lo)); vals.pushBack(fromU64(b_hi)); context.log("cmp ", vals);*/ if (!u128.eq(b_lo, b_hi, lo, hi)) { return falseVal; } } else { return falseVal; } // overflow lhs = fromU128Pieces(u64Max, u64Max); res = u128Shl(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testU128Shr():BoolVal { let falseVal = fromFalse(); // small << u32 let lhs = fromU128Small(8); let rhs = fromU32(2); let res = u128Shr(lhs, rhs); if (!isU128Small(res) || toU128Small(res) != 2) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // obj << small lhs = fromU128Pieces(4, 3071999961161793536); rhs = fromU32(10); res = u128Shr(lhs, rhs); if (isU128Object(res)) { let lo = toU128Low64(res); let hi = toU128High64(res); if (lo != 75057594000000000 || hi != 0) { return falseVal; } let b_lo = u128.shr(3071999961161793536, 4, 10); let b_hi = u128.__hi; /*let vals = new Vec(); vals.pushBack(fromU64(lo)); vals.pushBack(fromU64(hi)); vals.pushBack(fromU64(b_lo)); vals.pushBack(fromU64(b_hi)); context.log("cmp ", vals);*/ if (!u128.eq(b_lo, b_hi, lo, hi)) { return falseVal; } } else { return falseVal; } // this will trap: /*lhs = fromU128Small(0); rhs = fromU32(4294967290); res = u128Shr(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; }*/ return fromTrue(); } export function testU128Util():BoolVal { let falseVal = fromFalse(); if (u128Compare(fromU128Small(8), fromU128Small(8)) != 0) { return falseVal; } if (!u128IsEqual(fromU128Small(8), fromU128Small(8))) { return falseVal; } if (u128Compare(fromU128Small(7), fromU128Small(8)) != -1) { return falseVal; } if (u128IsEqual(fromU128Small(7), fromU128Small(8))) { return falseVal; } if (u128IsGreaterThan(fromU128Small(7), fromU128Small(8))) { return falseVal; } if (!u128IsLowerThan(fromU128Small(7), fromU128Small(8))) { return falseVal; } if (u128Compare(fromU128Small(9), fromU128Small(8)) != 1) { return falseVal; } if (u128Compare(fromU128Pieces(1,5), fromU128Pieces(1,5)) != 0) { return falseVal; } if (!u128IsEqual(fromU128Pieces(1,5), fromU128Pieces(1,5))) { return falseVal; } if (u128Compare(fromU128Pieces(1,4), fromU128Pieces(1,5)) != -1) { return falseVal; } if (!u128IsLowerThan(fromU128Pieces(1,4), fromU128Pieces(1,5))) { return falseVal; } if (u128IsGreaterThan(fromU128Pieces(1,4), fromU128Pieces(1,5))) { return falseVal; } if (u128Compare(fromU128Pieces(1,6), fromU128Pieces(1,5)) != 1) { return falseVal; } if (!u128IsGreaterThan(fromU128Pieces(1,6), fromU128Pieces(1,5))) { return falseVal; } if (u128IsLowerThan(fromU128Pieces(1,6), fromU128Pieces(1,5))) { return falseVal; } if (u128Compare(fromU128Pieces(1,5), fromU128Small(8)) != 1) { return falseVal; } if (u128IsEqual(fromU128Pieces(1,5), fromU128Small(8))) { return falseVal; } if (u128Compare(fromU128Pieces(1,5), fromU128Small(-8)) != 1) { return falseVal; } if (u128IsEqual(fromU128Pieces(1,5), fromU128Small(-8))) { return falseVal; } return fromTrue(); }