Skip to content

Commit

Permalink
fix: stateRoot calculation on sparse merkle tree (FuelLabs#1220)
Browse files Browse the repository at this point in the history
* wip: add storage slot initialization

* chore: remove console and unused vars

* fix: sparseMerkleTree delete implementation

* catch an error in `getForcProject`

* add changeset

---------

Co-authored-by: Dhaiwat / dhai.eth <[email protected]>
  • Loading branch information
luizstacio and Dhaiwat10 authored Sep 1, 2023
1 parent 5e973c0 commit 30ecb94
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 20 deletions.
8 changes: 8 additions & 0 deletions .changeset/mean-walls-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@fuel-ts/docs-snippets": patch
"@fuel-ts/contract": patch
"@fuel-ts/merkle": patch
"@fuel-ts/utils": patch
---

Fix stateRoot calculation on sparse merkle tree
4 changes: 2 additions & 2 deletions apps/docs-snippets/projects/counter/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ storage {
impl Counter for Contract {
#[storage(read)]
fn get_count() -> u64 {
storage.counter.try_read().unwrap_or(0)
storage.counter.read()
}

#[storage(write, read)]
fn increment_count(amount: u64) -> u64 {
let current = storage.counter.try_read().unwrap_or(0);
let current = storage.counter.read();
storage.counter.write(current + amount);
storage.counter.read()
}
Expand Down
4 changes: 3 additions & 1 deletion apps/docs-snippets/src/guide/contracts/multicalls.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ describe(__filename, () => {
);

echoContract = await factory1.deployContract();
counterContract = await factory2.deployContract();
counterContract = await factory2.deployContract({
storageSlots: counterArtifacts.storageSlots,
});
contextContract = await factory3.deployContract();
});

Expand Down
6 changes: 4 additions & 2 deletions apps/docs-snippets/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ export const createAndDeployContractFromProject = async (
project: SnippetProjectEnum
): Promise<Contract> => {
const wallet = await getTestWallet();
const { abiContents, binHexlified } = getSnippetProjectArtifacts(project);
const { abiContents, binHexlified, storageSlots } = getSnippetProjectArtifacts(project);

const contractFactory = new ContractFactory(binHexlified, abiContents, wallet);

return contractFactory.deployContract();
return contractFactory.deployContract({
storageSlots,
});
};

export const defaultTxParams = {
Expand Down
4 changes: 2 additions & 2 deletions packages/contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
"@fuel-ts/program": "workspace:*",
"@fuel-ts/providers": "workspace:*",
"@fuel-ts/transactions": "workspace:*",
"@fuel-ts/utils": "workspace:*",
"@fuel-ts/versions": "workspace:*",
"@fuel-ts/wallet": "workspace:*",
"@fuel-ts/utils": "workspace:*"
"@fuel-ts/wallet": "workspace:*"
},
"devDependencies": {
"@fuel-ts/forc": "workspace:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ struct StructValidation {
}

storage {
var1: u64 = 10,
var1: u64 = 0,
var2: u32 = 20,
var3: u16 = 30,
var4: bool = true,
Expand Down
4 changes: 2 additions & 2 deletions packages/fuel-gauge/src/contract-factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe('Contract Factory', () => {
});

const { value: var1 } = await contract.functions.return_var1().call();
expect(var1.toHex()).toEqual(toHex(10));
expect(var1.toHex()).toEqual(toHex(0));

const { value: var2 } = await contract.functions.return_var2().call();
expect(var2).toEqual(20);
Expand Down Expand Up @@ -157,7 +157,7 @@ describe('Contract Factory', () => {
});

const { value: var1 } = await contract.functions.return_var1().call();
expect(var1.toHex()).toEqual(toHex(10));
expect(var1.toHex()).toEqual(toHex(0));

const { value: var2 } = await contract.functions.return_var2().call();
expect(var2).toEqual(20);
Expand Down
13 changes: 4 additions & 9 deletions packages/merkle/src/sparse/sparseMerkleTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,19 +243,14 @@ export class SparseMerkleTree {

update(key: string, value: string): void {
const [sideNodes, oldLeafHash, oldLeafData] = this.sideNodesForRoot(key, this.root);

let newRoot;
if (value === ZERO) {
newRoot = this.deleteWithSideNodes(key, sideNodes, oldLeafHash, oldLeafData);
} else {
newRoot = this.updateWithSideNodes(key, value, sideNodes, oldLeafHash, oldLeafData);
}

const newRoot = this.updateWithSideNodes(key, value, sideNodes, oldLeafHash, oldLeafData);
this.setRoot(newRoot);
}

delete(key: string): void {
this.update(key, ZERO);
const [sideNodes, oldLeafHash, oldLeafData] = this.sideNodesForRoot(key, this.root);
const newRoot = this.deleteWithSideNodes(key, sideNodes, oldLeafHash, oldLeafData);
this.setRoot(newRoot);
}

prove(key: string): SparseMerkleProof {
Expand Down
19 changes: 18 additions & 1 deletion packages/utils/src/test-utils/getForcProject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { hexlify } from '@ethersproject/bytes';
import { readFileSync } from 'fs';
import { existsSync, readFileSync } from 'fs';
import { basename, join } from 'path';

import { normalizeString } from '../utils/normalizeString';
Expand All @@ -21,6 +21,9 @@ export const getProjectAbiPath = (params: IGetForcProjectParams) =>
export const getProjectBinPath = (params: IGetForcProjectParams) =>
join(getProjectDebugDir(params), `${params.projectName}.bin`);

export const getProjectStorageSlotsPath = (params: IGetForcProjectParams) =>
join(getProjectDebugDir(params), `${params.projectName}-storage_slots.json`);

export const getProjectAbiName = (params: IGetForcProjectParams) => `${params.projectName}-abi`;

export const getProjectNormalizedName = (params: IGetForcProjectParams) =>
Expand All @@ -32,6 +35,15 @@ export const getProjectAbi = (params: IGetForcProjectParams) => {
return abiContents;
};

export const getProjectStorageSlots = (params: IGetForcProjectParams) => {
const storageSlotsFilePath = getProjectStorageSlotsPath(params);
if (!existsSync(storageSlotsFilePath)) {
return [];
}
const storageSlots = JSON.parse(readFileSync(storageSlotsFilePath, 'utf-8'));
return storageSlots;
};

export const getForcProject = <T = unknown>(projectDir: string) => {
const projectName = basename(projectDir);

Expand All @@ -48,11 +60,16 @@ export const getForcProject = <T = unknown>(projectDir: string) => {
const abiName = getProjectAbiName(params);
const abiContents: T = getProjectAbi(params);
const normalizedName = getProjectNormalizedName(params);
const storageSlots: Array<{
key: string;
value: string;
}> = getProjectStorageSlots(params);

const inputGlobal = `${debugDir}/*-abi.json`;

return {
name: projectName,
storageSlots,
normalizedName,
debugDir,
tempDir,
Expand Down

0 comments on commit 30ecb94

Please sign in to comment.