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

feat: deploying scripts and predicates #3251

Merged
merged 105 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from 102 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
e9a4026
Adding stub files
arboleya Oct 4, 2024
970838d
Adding TODO
arboleya Oct 4, 2024
aee1626
wip
Torres-ssf Oct 4, 2024
2162603
Removing unused import
arboleya Oct 4, 2024
3d6a61f
wip: configurable scripts working
maschad Oct 4, 2024
623614a
chore: add test for configurable scripts
maschad Oct 4, 2024
a46369f
Merge branch 'st/wip/blob' into aa/feat/deploying-scripts-and-predicates
maschad Oct 4, 2024
df504c0
Updating stubs
arboleya Oct 5, 2024
7b65d27
Renaming file
arboleya Oct 5, 2024
483fab5
Renaming files
arboleya Oct 5, 2024
3a29fa8
Isolating contract-related deployment methods
arboleya Oct 5, 2024
fdd7b2c
Removing file for now
arboleya Oct 5, 2024
d6e9cee
chore: currently the setConfigurableConstants does not properly updat…
maschad Oct 5, 2024
f17ea34
WIP `fuels deploy` CLI command
arboleya Oct 5, 2024
0cff742
Merge branch 'aa/feat/deploying-scripts-and-predicates' of github.com…
arboleya Oct 5, 2024
cb36101
linting
maschad Oct 5, 2024
42d3480
test: make assertions more explicit
danielbate Oct 5, 2024
ce44041
feat: implement predicates/scripts CLI deploy (#3254)
Dhaiwat10 Oct 5, 2024
6f8ff06
add pseudocode for predicates deploy and file saves (#3255)
Dhaiwat10 Oct 5, 2024
6df68fe
chore: refactored script deploy test
petertonysmith94 Oct 5, 2024
2bb2ed3
update getPredicateScriptLoaderInstructions helper
Torres-ssf Oct 5, 2024
5e6cab9
update getPredicateScriptLoaderInstructions helper
Torres-ssf Oct 5, 2024
072933f
remove comments
Torres-ssf Oct 5, 2024
f7e5438
made Script class pristine again
Torres-ssf Oct 5, 2024
6d13def
update test WIP
Torres-ssf Oct 5, 2024
c32e378
Resolving TODOs; making methods synchronous
arboleya Oct 5, 2024
8936577
Lint
arboleya Oct 5, 2024
c975a18
add offset calculation to deployAsBlobTxForScript
Torres-ssf Oct 5, 2024
9616af7
feat: configurables now working with fuel-core ldc branch
maschad Oct 5, 2024
0a9093d
Adding line break
arboleya Oct 5, 2024
0a23398
Re-generating types after deploy, to include deployed binaries
arboleya Oct 5, 2024
444fb76
Merge branch 'aa/feat/deploying-scripts-and-predicates' of github.com…
arboleya Oct 5, 2024
6e97f4c
feat: working on predicate support
maschad Oct 5, 2024
40d6725
chore: fix naming of projects
petertonysmith94 Oct 5, 2024
82a2350
feat: predicates work!
maschad Oct 5, 2024
1f1c06b
chore: added WIP typegen
petertonysmith94 Oct 5, 2024
7334154
Merge branch 'aa/feat/deploying-scripts-and-predicates' of https://gi…
petertonysmith94 Oct 5, 2024
0fc8e5b
Fixing variable names
arboleya Oct 6, 2024
f218489
Upgrading `fuel-core` to `0.37.0`
arboleya Oct 6, 2024
618e3ad
Upgrading fuel asm to `0.58.0`
arboleya Oct 6, 2024
64f5ccc
feat: predicates work but scripts dont work for script w/o configurables
maschad Oct 6, 2024
8b5078f
add TODOs
Torres-ssf Oct 6, 2024
3483533
update comments
Torres-ssf Oct 6, 2024
eea9c8c
injecting default configurables at script loader
Torres-ssf Oct 6, 2024
2f16bdc
Revert "chore: added WIP typegen"
petertonysmith94 Oct 6, 2024
ee5fba5
Revert "Fixing variable names"
petertonysmith94 Oct 6, 2024
00613cc
Update packages/fuels/src/cli/commands/deploy/deployPredicates.ts
arboleya Oct 6, 2024
5021168
Update packages/contract/src/contract-factory.ts
arboleya Oct 6, 2024
2367df2
Merge branch 'aa/feat/deploying-scripts-and-predicates' of https://gi…
petertonysmith94 Oct 6, 2024
f829656
Fixing test
arboleya Oct 6, 2024
a3d1b37
re-adding data length and data to loader generation
Torres-ssf Oct 6, 2024
4b91f6c
remove code to add data to start of loader at Script class
Torres-ssf Oct 6, 2024
07270fa
add more tests
Torres-ssf Oct 6, 2024
fb5cff8
Updating fuel core version in more places
arboleya Oct 6, 2024
5b33d4f
add test case
Torres-ssf Oct 6, 2024
81154d7
ensure blob exists before deploying it
Torres-ssf Oct 6, 2024
3071a1f
Merge branch 'aa/feat/deploying-scripts-and-predicates' of github.com…
Torres-ssf Oct 6, 2024
23e0d49
a hardcoded test
nedsalk Oct 6, 2024
f016591
Adjusting file paths
arboleya Oct 6, 2024
86f584f
Merge branch 'aa/feat/deploying-scripts-and-predicates' of github.com…
arboleya Oct 6, 2024
a88d75c
add new predicate
Torres-ssf Oct 6, 2024
c0c34a7
made getPredicateScriptLoaderInstructions return offset
Torres-ssf Oct 6, 2024
195bec5
refact deployAsBlobTxForScript method
Torres-ssf Oct 6, 2024
f3f8451
improve tests for blob deploys
Torres-ssf Oct 6, 2024
1d3a593
remove test script-deploy
Torres-ssf Oct 6, 2024
a944b45
rename test suite filename
Torres-ssf Oct 6, 2024
3977905
update blob deploy test suite
Torres-ssf Oct 6, 2024
79872da
Merge branch 'aa/feat/deploying-scripts-and-predicates' of github.com…
Torres-ssf Oct 6, 2024
51cd945
return AbstractScript to its pristine state
Torres-ssf Oct 6, 2024
2ade0ab
return ScriptInvocationScope to its pristine state
Torres-ssf Oct 6, 2024
663d00c
return Script class to its pristine state
Torres-ssf Oct 6, 2024
8c68589
update test suite
Torres-ssf Oct 6, 2024
845e21e
chore: deploy to NPM
petertonysmith94 Oct 6, 2024
2d2f69a
remove dummy deployAsBlobTxForPredicate
Torres-ssf Oct 6, 2024
207de01
clean response from deployAsBlobTxForScript
Torres-ssf Oct 6, 2024
6b77969
adjusting blob deploy tests
Torres-ssf Oct 6, 2024
f283230
refact types for fuels deployed programs
Torres-ssf Oct 6, 2024
42ad963
conforming with last commit
Torres-ssf Oct 6, 2024
4bf3635
Merge branch 'aa/feat/deploying-scripts-and-predicates' of github.com…
Torres-ssf Oct 6, 2024
3035687
remove param for deployAsBlobTxForScript
Torres-ssf Oct 6, 2024
fc7885d
remove TODO test case
Torres-ssf Oct 6, 2024
f6db915
modified DeployedScript
Torres-ssf Oct 6, 2024
44d4019
implement helper adjustOffsets helper
Torres-ssf Oct 6, 2024
993dd05
refactor fuels cli deployPredicates and deployScripts
Torres-ssf Oct 6, 2024
197c3a4
saving scripts and predicates ABIs files for fuels deploy command
Torres-ssf Oct 6, 2024
78c9dba
skiping test
Torres-ssf Oct 6, 2024
63228a6
Scanning all predicates/scripts ABIs under directory
arboleya Oct 6, 2024
ab23d2f
Merge branch 'aa/feat/deploying-scripts-and-predicates' of github.com…
arboleya Oct 6, 2024
37c10e7
docs: deploying scripts
danielbate Oct 6, 2024
a9219b1
docs: fix script test
danielbate Oct 6, 2024
7eb997c
docs: remove line
danielbate Oct 6, 2024
245ddd6
fix: update savePredicate and saveScript paths
maschad Oct 6, 2024
3ee5ecc
ci: fix tests
maschad Oct 6, 2024
235f766
chore: ignore snippet deps
maschad Oct 6, 2024
fc0a2cb
chore: revert pretest in doc snips
danielbate Oct 6, 2024
7be910a
Merge branch 'aa/feat/deploying-scripts-and-predicates' of https://gi…
danielbate Oct 6, 2024
4194c7f
docs: fix loader binary
petertonysmith94 Oct 6, 2024
70ee6bf
docs: add predicate deploy
danielbate Oct 6, 2024
2b0c8c7
Merge branch 'aa/feat/deploying-scripts-and-predicates' of https://gi…
danielbate Oct 6, 2024
a7d35f8
Saving and reading loader artifacts from the parent dir
arboleya Oct 7, 2024
030b609
chore: revert docs
danielbate Oct 7, 2024
6a06983
Merge branch 'aa/feat/deploying-scripts-and-predicates' of https://gi…
danielbate Oct 7, 2024
1a4fb58
chore: changeset
danielbate Oct 7, 2024
2c5d6f6
chore: amend changeset
danielbate Oct 7, 2024
5064007
chore: disable PR release
danielbate Oct 7, 2024
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
4 changes: 4 additions & 0 deletions .changeset/sharp-radios-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---
danielbate marked this conversation as resolved.
Show resolved Hide resolved

feat: deploying scripts and predicates
petertonysmith94 marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion .github/workflows/pr-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
name: "Release PR to npm"
runs-on: ubuntu-latest
# comment out if:false to enable release PR to npm
if: false
# if: false
danielbate marked this conversation as resolved.
Show resolved Hide resolved
permissions: write-all
steps:
- name: Checkout
Expand Down
3 changes: 3 additions & 0 deletions .knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"/apps/docs/*",
"/packages/abi-typegen/test/**",
"templates/**",
"/apps/docs-snippets/**",
"/apps/docs-snippets2/**/*.test.ts",
"apps/create-fuels-counter-guide/**"
],
Expand All @@ -28,6 +29,8 @@
"eslint-plugin-react",
"eslint-plugin-react-hooks",
"dotenv",
"kill",
"lsof",
"memfs",
"open",
"textlint",
Expand Down
2 changes: 1 addition & 1 deletion apps/demo-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"pretest": "pnpm original:build"
},
"dependencies": {
"@fuels/vm-asm": "0.57.1",
"@fuels/vm-asm": "0.58.0",
"@types/node": "^22.5.5",
"@types/react-dom": "^18.3",
"@types/react": "^18.3.10",
Expand Down
2 changes: 1 addition & 1 deletion apps/demo-react-cra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.29",
"private": true,
"dependencies": {
"@fuels/vm-asm": "0.57.1",
"@fuels/vm-asm": "0.58.0",
"@testing-library/react": "^16.0.1",
"@types/node": "^22.5.5",
"@types/react": "^18.3.10",
Expand Down
2 changes: 1 addition & 1 deletion apps/demo-react-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"pretest": "pnpm original:build"
},
"dependencies": {
"@fuels/vm-asm": "0.57.1",
"@fuels/vm-asm": "0.58.0",
"fuels": "workspace:*",
"react-dom": "^18.3.1",
"react": "^18.3.1"
Expand Down
8 changes: 6 additions & 2 deletions apps/docs-snippets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
"description": "",
"private": true,
"scripts": {
"pretest": "run-s build:forc type:check",
"build:forc": "pnpm fuels build",
"pretest": "run-s fuels:build type:check",
danielbate marked this conversation as resolved.
Show resolved Hide resolved
"xpretest": "run-s kill-node fuels:build fuels:node fuels:deploy kill-node type:check",
"kill-node": "lsof -t -i:4000 | xargs -r kill",
"fuels:deploy": "pnpm fuels deploy",
"fuels:node": "pnpm fuels node > /dev/null 2>&1 &",
"fuels:build": "pnpm fuels build",
"type:check": "tsc --noEmit"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { readFileSync } from 'fs';
import { ContractFactory, Predicate, Provider, Wallet, hexlify } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';
import { join } from 'path';

import { ConfigurablePin as TypegenPredicate } from '../../../test/typegen';

/**
* @group browser
* @group node
*
* TODO: enable the test and reintroduce the docs
*/
describe.skip('Deploying Predicates', () => {
it('deploys a predicate via loader and calls', async () => {
using launched = await launchTestNode();

const {
provider: testProvider,
wallets: [testWallet, receiver],
} = launched;

const recieverInitialBalance = await receiver.getBalance();

const providerUrl = testProvider.url;
const WALLET_PVT_KEY = hexlify(testWallet.privateKey);

const factory = new ContractFactory(
TypegenPredicate.bytecode,
TypegenPredicate.abi,
testWallet
);
const { waitForResult: waitForDeploy } = await factory.deployAsBlobTxForScript();
await waitForDeploy();

const loaderBytecode = hexlify(
readFileSync(
join(
__dirname,
'../../../test/fixtures/forc-projects/configurable-pin/out/release/configurable-pin.deployed.bin'
)
)
);

// #region deploying-predicates
// #import { Provider, Wallet, hexlify };
// #context import { readFileSync } from 'fs';
// #context import { WALLET_PVT_KEY } from 'path/to/my/env/file';
// #context import { TypegenPredicate } from 'path/to/typegen/outputs';

// First, we will need the loader bytecode that is generated by `fuels deploy`
// #context const loaderBytecode = hexlify(readFileSync('path/to/forc/build/outputs')));

const provider = await Provider.create(providerUrl);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Then we will instantiate the predicate using both the scripts bytecode and it's loader bytecode,
// now we are free to interact with the predicate as we would normally, such as overriding the configurables
const predicate = new Predicate({
bytecode: loaderBytecode,
abi: TypegenPredicate.abi,
data: [1337],
provider,
});

// First, let's fund the predicate
const { waitForResult: waitForFund } = await wallet.transfer(predicate.address, 100_000);
await waitForFund();

const { waitForResult: waitForTransfer } = await predicate.transfer(receiver.address, 1000);
const { gasUsed } = await waitForTransfer();
// #endregion deploying-predicates

const anotherPredicate = new Predicate({
bytecode: TypegenPredicate.bytecode,
abi: TypegenPredicate.abi,
data: [1337],
provider,
});

const { waitForResult: waitForAnotherFund } = await wallet.transfer(
anotherPredicate.address,
100_000
);
await waitForAnotherFund();

const { waitForResult: waitForAnotherTransfer } = await anotherPredicate.transfer(
receiver.address,
1000
);
const { gasUsed: anotherGasUsed } = await waitForAnotherTransfer();

expect(recieverInitialBalance.toNumber()).toBeLessThan(recieverInitialBalance.toNumber());
expect(gasUsed.toNumber()).toBeLessThan(anotherGasUsed.toNumber());
});
});
73 changes: 73 additions & 0 deletions apps/docs-snippets/src/guide/scripts/deploying-scripts.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { readFileSync } from 'fs';
import { ContractFactory, Provider, Script, Wallet, hexlify } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';
import { join } from 'path';

import { SumScript as TypegenScript } from '../../../test/typegen';

/**
* @group browser
* @group node
*
* TODO: enable the test and reintroduce the docs
*/
describe.skip('Deploying Scripts', () => {
it('deploys a script via loader and calls', async () => {
using launched = await launchTestNode();

const {
provider: testProvider,
wallets: [testWallet],
} = launched;

const providerUrl = testProvider.url;
const WALLET_PVT_KEY = hexlify(testWallet.privateKey);

const factory = new ContractFactory(TypegenScript.bytecode, TypegenScript.abi, testWallet);
const { waitForResult: waitForDeploy } = await factory.deployAsBlobTxForScript();
await waitForDeploy();

const loaderBytecode = hexlify(
readFileSync(
join(
__dirname,
'../../../test/fixtures/forc-projects/sum-script/out/release/sum-script-loader.bin'
)
)
);

// #region deploying-scripts
// #import { Provider, Wallet, hexlify };
// #context import { readFileSync } from 'fs';
// #context import { WALLET_PVT_KEY } from 'path/to/my/env/file';
// #context import { TypegenScript } from 'path/to/typegen/outputs';

// First, we will need the loader bytecode that is generated by `fuels deploy`
// #context const loaderBytecode = hexlify(readFileSync('path/to/forc/build/outputs')));

const provider = await Provider.create(providerUrl);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Then we will instantiate the script using both the scripts bytecode and it's loader bytecode
const script = new Script(loaderBytecode, TypegenScript.abi, wallet);

// Now we are free to interact with the script as we would normally, such as overriding the configurables
const configurable = {
AMOUNT: 20,
};
script.setConfigurableConstants(configurable);

const { waitForResult } = await script.functions.main(10).call();
const { value, gasUsed } = await waitForResult();
// #endregion deploying-scripts

const scriptWithoutLoader = new Script(TypegenScript.bytecode, TypegenScript.abi, wallet);
scriptWithoutLoader.setConfigurableConstants(configurable);
const { waitForResult: waitForAnotherResult } = await script.functions.main(10).call();
const { value: anotherValue, gasUsed: anotherGasUsed } = await waitForAnotherResult();

expect(value).toBe(30);
expect(anotherValue).toBe(30);
expect(gasUsed.toNumber()).toBeLessThan(anotherGasUsed.toNumber());
});
});
2 changes: 1 addition & 1 deletion internal/fuel-core/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.36.0
0.37.0
3 changes: 2 additions & 1 deletion nodemon.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"**/out/release/**",
"apps/demo-typegen/src/contract-types/**",
"apps/demo-typegen/src/predicate-types/**",
"apps/demo-typegen/src/script-types/**"
"apps/demo-typegen/src/script-types/**",
"packages/fuels/src/cli/commands/deploy/proxy/types/**"
]
}
2 changes: 1 addition & 1 deletion packages/account/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"@fuel-ts/transactions": "workspace:*",
"@fuel-ts/utils": "workspace:*",
"@fuel-ts/versions": "workspace:*",
"@fuels/vm-asm": "0.57.1",
"@fuels/vm-asm": "0.58.0",
"@noble/curves": "^1.6.0",
"events": "^3.3.0",
"graphql": "^16.9.0",
Expand Down
41 changes: 39 additions & 2 deletions packages/account/src/predicate/predicate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Interface } from '@fuel-ts/abi-coder';
import { Address } from '@fuel-ts/address';
import { ErrorCode, FuelError } from '@fuel-ts/errors';
import type { BytesLike } from '@fuel-ts/interfaces';
import { arrayify, hexlify } from '@fuel-ts/utils';
import { arrayify, hexlify, concat } from '@fuel-ts/utils';

import type { FakeResources } from '../account';
import { Account } from '../account';
Expand Down Expand Up @@ -35,8 +35,16 @@ export type PredicateParams<
abi?: JsonAbi;
data?: TData;
configurableConstants?: TConfigurables;
loaderBytecode?: BytesLike;
};

function getDataOffset(binary: Uint8Array): number {
const buffer = binary.buffer.slice(binary.byteOffset + 8, binary.byteOffset + 16);
const dataView = new DataView(buffer);
const dataOffset = dataView.getBigUint64(0, false); // big-endian
return Number(dataOffset);
}

/**
* `Predicate` provides methods to populate transaction data with predicate information and sending transactions with them.
*/
Expand All @@ -47,6 +55,7 @@ export class Predicate<
bytes: Uint8Array;
predicateData: TData = [] as unknown as TData;
interface?: Interface;
loaderBytecode: BytesLike = '';

/**
* Creates an instance of the Predicate class.
Expand All @@ -63,6 +72,12 @@ export class Predicate<
provider,
data,
configurableConstants,
/**
* TODO: Implement a getBytes method within the Predicate class. This method should return the loaderBytecode if it is set.
* The getBytes method should be used in all places where we use this.bytes.
* Note: Do not set loaderBytecode to a default string here; it should remain undefined when not provided.
*/
loaderBytecode = '',
}: PredicateParams<TData, TConfigurables>) {
const { predicateBytes, predicateInterface } = Predicate.processPredicateData(
bytecode,
Expand All @@ -74,6 +89,7 @@ export class Predicate<

this.bytes = predicateBytes;
this.interface = predicateInterface;
this.loaderBytecode = loaderBytecode;
if (data !== undefined && data.length > 0) {
this.predicateData = data;
}
Expand Down Expand Up @@ -230,7 +246,8 @@ export class Predicate<
private static setConfigurableConstants(
bytes: Uint8Array,
configurableConstants: { [name: string]: unknown },
abiInterface?: Interface
abiInterface?: Interface,
loaderBytecode?: BytesLike
) {
const mutatedBytes = bytes;

Expand Down Expand Up @@ -263,6 +280,26 @@ export class Predicate<

mutatedBytes.set(encoded, offset);
});

if (loaderBytecode) {
/**
* TODO: We mutate the predicate bytes here to be the loader bytes only if the configurables are being set.
* What we actually need to do here is to mutate the loader bytes to include the configurables.
*/
const offset = getDataOffset(bytes);

// update the dataSection here as necessary (with configurables)
const dataSection = mutatedBytes.slice(offset);

const dataSectionLen = dataSection.length;

// Convert dataSectionLen to big-endian bytes
const dataSectionLenBytes = new Uint8Array(8);
const dataSectionLenDataView = new DataView(dataSectionLenBytes.buffer);
dataSectionLenDataView.setBigUint64(0, BigInt(dataSectionLen), false);

mutatedBytes.set(concat([loaderBytecode, dataSectionLenBytes, dataSection]));
}
} catch (err) {
throw new FuelError(
ErrorCode.INVALID_CONFIGURABLE_CONSTANTS,
Expand Down
2 changes: 1 addition & 1 deletion packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ describe('Provider', () => {

const version = await provider.getVersion();

expect(version).toEqual('0.36.0');
expect(version).toEqual('0.37.0');
});

it('can call()', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"@fuel-ts/transactions": "workspace:*",
"@fuel-ts/utils": "workspace:*",
"@fuel-ts/versions": "workspace:*",
"@fuels/vm-asm": "0.57.1",
"@fuels/vm-asm": "0.58.0",
"ramda": "^0.30.1"
},
"devDependencies": {
Expand Down
Loading