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 balance mock #329

Merged
merged 2 commits into from
Feb 29, 2024
Merged
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
22 changes: 22 additions & 0 deletions assembly/__tests__/vm-mock.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import {
isEvmSignatureValid,
evmGetPubkeyFromSignature,
getOriginOperationId,
balance,
balanceOf,
} from '../std';
import { changeCallStack, resetStorage } from '../vm-mock/storage';
import {
mockAdminContext,
mockBalance,
mockOriginOperationId,
mockSetChainId,
setDeployContext,
Expand Down Expand Up @@ -325,3 +328,22 @@ describe('Testing mocked origin operation id', () => {
expect(opId).not.toBe(mockedOpId);
});
});

describe('balance mock', () => {
it('mock balance', () => {
mockBalance(testAddress.toString(), 9999);
expect(balanceOf(testAddress.toString())).toBe(9999);
});

it('mock contract balance', () => {
mockBalance(contractAddress.toString(), 9999);
expect(balance()).toBe(9999);
});

it('mock contract balance and preserve storage', () => {
Storage.set('thekey', 'thevalue');
mockBalance(contractAddress.toString(), 9999);
expect(balance()).toBe(9999);
expect(Storage.get('thekey')).toBe('thevalue');
});
});
72 changes: 42 additions & 30 deletions vm-mock/vm.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,14 @@ export default function createMockedABI(
* @returns {Uint8Array} - The serialized keys.
*/
function serializeKeys(keysArr) {

const serialized = [];
const lengthBytes = numToLittleEndianBytes(keysArr.length);

serialized.push(...lengthBytes);

for (const key of keysArr) {
const bytes = key.split(',').map(Number);
const bytes = key.split(',');
serialized.push(bytes.length);
serialized.push(...bytes);
}
Expand All @@ -197,7 +198,7 @@ export default function createMockedABI(
* @param {string} address - the address to check
* @returns {boolean} - true if the address prefix is valid
*/
function isRightPrefix(address) {
function isValidPrefix(address) {
const addressPrefix = 'A';
const addressPrefixUserOrSC = ['U', 'S'];
return (
Expand All @@ -212,7 +213,7 @@ export default function createMockedABI(
* @param {string} address - the address to check
* @returns {boolean} - true if the address length is valid
*/
function isRightLength(address) {
function isValidLength(address) {
const minAddressLength = 40;
const maxAddressLength = 60;
return (
Expand Down Expand Up @@ -250,21 +251,22 @@ export default function createMockedABI(
},

assembly_script_set_data(kPtr, vPtr) {
const k = ptrToUint8ArrayString(kPtr);
const key = ptrToUint8ArrayString(kPtr);
const v = getArrayBuffer(vPtr);

const addressStorage = ledger.get(contractAddress).storage;
addressStorage.set(k, v);

addressStorage.set(key, v);
},

assembly_script_get_data(kPtr) {
const k = ptrToUint8ArrayString(kPtr);
const key = ptrToUint8ArrayString(kPtr);

if (ledger.has(contractAddress)) {
const addressStorage = ledger.get(contractAddress).storage;

if (addressStorage.has(k)) {
return newArrayBuffer(addressStorage.get(k));
if (addressStorage.has(key)) {
return newArrayBuffer(addressStorage.get(key));
} else {
throw new Error('Runtime error: data entry not found');
}
Expand Down Expand Up @@ -292,7 +294,8 @@ export default function createMockedABI(

assembly_script_set_data_for(aPtr, kPtr, vPtr) {
const a = ptrToString(aPtr);
const k = ptrToUint8ArrayString(kPtr);

const key = ptrToUint8ArrayString(kPtr);
const v = getArrayBuffer(vPtr);

if (!ledger.has(a)) {
Expand All @@ -302,18 +305,17 @@ export default function createMockedABI(
});
}
const addressStorage = ledger.get(a).storage;
addressStorage.set(k, v);
addressStorage.set(key, v);
},

assembly_script_get_data_for(aPtr, kPtr) {
let v = '';
const a = ptrToString(aPtr);
const k = ptrToUint8ArrayString(kPtr);
const key = ptrToUint8ArrayString(kPtr);

if (ledger.has(a)) {
const addressStorage = ledger.get(a).storage;
if (addressStorage.has(k)) {
return newArrayBuffer(addressStorage.get(k));
if (addressStorage.has(key)) {
return newArrayBuffer(addressStorage.get(key));
} else {
throw new Error('Runtime error: data entry not found');
}
Expand All @@ -323,40 +325,40 @@ export default function createMockedABI(
},

assembly_script_has_data(kPtr) {
const k = ptrToUint8ArrayString(kPtr);
const key = ptrToUint8ArrayString(kPtr);
const addressStorage = ledger.get(contractAddress).storage;
return addressStorage.has(k);
return addressStorage.has(key);
},

assembly_script_has_data_for(aPtr, kPtr) {
const a = ptrToString(aPtr);
const k = ptrToUint8ArrayString(kPtr);
const key = ptrToUint8ArrayString(kPtr);
if (ledger.has(a)) {
const addressStorage = ledger.get(a).storage;
return addressStorage.has(k);
return addressStorage.has(key);
} else {
return false;
}
},

assembly_script_delete_data(kPtr) {
const k = ptrToUint8ArrayString(kPtr);
const key = ptrToUint8ArrayString(kPtr);
if (ledger.has(contractAddress)) {
const addressStorage = ledger.get(contractAddress).storage;
if (!addressStorage.has(k)) {
if (!addressStorage.has(key)) {
throw new Error('Runtime error: data entry not found');
}
addressStorage.delete(k);
addressStorage.delete(key);
} else {
throw new Error(
'Runtime error: address parsing error: ' + contractAddress,
);
}
},

assembly_script_delete_data_for(addressPtr, keyPtr) {
assembly_script_delete_data_for(addressPtr, kPtr) {
const address = ptrToString(addressPtr);
const key = ptrToUint8ArrayString(keyPtr);
const key = ptrToUint8ArrayString(kPtr);

if (!ledger.has(address)) {
throw new Error('Runtime error: address parsing error: ' + address);
Expand All @@ -371,9 +373,9 @@ export default function createMockedABI(
addressStorage.delete(key);
},

assembly_script_append_data(keyPtr, valuePtr) {
assembly_script_append_data(kPtr, valuePtr) {
const address = contractAddress;
const key = ptrToUint8ArrayString(keyPtr);
const key = ptrToUint8ArrayString(kPtr);
const newValue = getArrayBuffer(valuePtr);

if (!ledger.has(address)) {
Expand All @@ -392,9 +394,9 @@ export default function createMockedABI(
addressStorage.set(key, concat);
},

assembly_script_append_data_for(addressPtr, keyPtr, valuePtr) {
assembly_script_append_data_for(addressPtr, kPtr, valuePtr) {
const address = ptrToString(addressPtr);
const key = ptrToUint8ArrayString(keyPtr);
const key = ptrToUint8ArrayString(kPtr);
const newValue = getArrayBuffer(valuePtr);

if (!ledger.has(address)) {
Expand Down Expand Up @@ -520,7 +522,7 @@ export default function createMockedABI(
assembly_script_validate_address(addressPtr) {
const address = ptrToString(addressPtr);

return isRightLength(address) && isRightPrefix(address);
return isValidLength(address) && isValidPrefix(address);
},

assembly_script_print(aPtr) {
Expand All @@ -535,8 +537,8 @@ export default function createMockedABI(
const addressStorage = ledger.get(a).storage;
let keysArr = Array.from(addressStorage.keys());
if (prefix) {
const prefixStr = ptrToUint8ArrayString(prefix);
keysArr = keysArr.filter((key) => {
const prefixStr = ptrToUint8ArrayString(prefix);
return key.startsWith(prefixStr);
});
}
Expand All @@ -550,8 +552,8 @@ export default function createMockedABI(
let keysArr = Array.from(addressStorage.keys());

if (prefix) {
const prefixStr = ptrToUint8ArrayString(prefix);
keysArr = keysArr.filter((key) => {
const prefixStr = ptrToUint8ArrayString(prefix);
return key.startsWith(prefixStr);
});
}
Expand Down Expand Up @@ -731,7 +733,17 @@ export default function createMockedABI(

assembly_script_mock_balance(aPtr, amount) {
const addr = ptrToString(aPtr);
if (!ledger.has(addr)) {
ledger.set(addr, {
storage: new Map(),
contract: '',
balance: BigInt(amount),
});
return;
}
ledger.set(addr, {
storage: ledger.get(addr).storage,
contract: ledger.get(addr).contract,
balance: BigInt(amount),
});
},
Expand Down
Loading