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!: deploy contract validation #2796

Merged
merged 23 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
8 changes: 8 additions & 0 deletions .changeset/tall-planes-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@fuel-ts/transactions": minor
"@fuel-ts/contract": patch
"@fuel-ts/account": minor
"@fuel-ts/errors": minor
---

feat!: deploy contract validation
2 changes: 2 additions & 0 deletions apps/docs/src/guide/contracts/deploying-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

This guide walks you through deploying a contract using the SDK, covering loading contract artifacts, initializing a contract factory, and deploying the contract.

> **Note:** The maximum contract deployment size supported by the SDK is 100 KB. The SDK will `throw` an [error](../errors/index.md) for contracts larger than this size.

## 1. Obtaining Contract Artifacts

After writing a contract in Sway and compiling it with `forc build` (<a :href="indexUrl" target="_blank" rel="noreferrer">read more</a> on how to work with Sway), you will obtain two important artifacts: the compiled binary file and the JSON ABI file. These files are required for deploying a contract using the SDK.
Expand Down
10 changes: 8 additions & 2 deletions apps/docs/src/guide/errors/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ When converting a big number into an incompatible format.

Ensure that the value you've supplied to the big number is compatible with the value you are converting to.

### `CONTRACT_SIZE_EXCEEDS_LIMIT`

When the contract size exceeds the maximum contract size limit.

Ensure that the contract size is less than the maximum contract size limit, of 100 KB. This can be validated by checking the bytecode length of the contract.

### `DUPLICATED_POLICY`

When there are more than policies with the same type, for a transaction.
Expand Down Expand Up @@ -174,9 +180,9 @@ When the transaction status received from the node is unexpected.

Check the status received is within `TransactionStatus`.

### `INVALID_TRANSACTION_TYPE`
### `UNSUPPORTED_TRANSACTION_TYPE`

When the transaction type from the Fuel Node is _not_ valid.
When the transaction type from the Fuel Node is _not_ supported.

The type is within [`TransactionType`](../../api/Account/TransactionType.md).

Expand Down
2 changes: 2 additions & 0 deletions apps/docs/src/guide/fuels-cli/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ npx fuels@{{fuels}} deploy
> [!NOTE] Note
> We recommend using the `fuels deploy` command only when you are deploying contracts to a local node.
> If you are deploying contracts to a live network like the Testnet, we recommend using the [`forc deploy`](https://docs.fuel.network/docs/intro/quickstart-contract/#deploy-to-testnet) command instead.
>
> Additionally, the maximum contract deployment size supported by the SDK is 100 KB. The SDK will `throw` an [error](../errors/index.md) for contracts larger than this size.

The `fuels deploy` command does two things:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,13 @@ describe('transactionRequestify', () => {
expect(txRequest.witnesses).toEqual(txRequestLike.witnesses);
});

it('should throw error if invalid transaction type', () => {
it('should throw error if unsupported transaction type', () => {
const txRequestLike = {
type: 5,
type: 1234,
};

expect(() => transactionRequestify(txRequestLike)).toThrow('Invalid transaction type: 5');
expect(() => transactionRequestify(txRequestLike)).toThrow(
'Unsupported transaction type: 1234'
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export const transactionRequestify = (obj: TransactionRequestLike): TransactionR
return CreateTransactionRequest.from(obj);
}
default: {
throw new FuelError(ErrorCode.INVALID_TRANSACTION_TYPE, `Invalid transaction type: ${type}.`);
throw new FuelError(
ErrorCode.UNSUPPORTED_TRANSACTION_TYPE,
`Unsupported transaction type: ${type}.`
);
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ describe('operations', () => {
expect(getTransactionTypeName(TransactionType.Script)).toBe(TransactionTypeName.Script);

expect(() => getTransactionTypeName('' as unknown as TransactionType)).toThrowError(
'Invalid transaction type: '
'Unsupported transaction type: '
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export function getTransactionTypeName(transactionType: TransactionType): Transa
return TransactionTypeName.Script;
default:
throw new FuelError(
ErrorCode.INVALID_TRANSACTION_TYPE,
`Invalid transaction type: ${transactionType}.`
ErrorCode.UNSUPPORTED_TRANSACTION_TYPE,
`Unsupported transaction type: ${transactionType}.`
);
}
}
Expand Down
15 changes: 14 additions & 1 deletion packages/contract/src/contract-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import { Contract } from '@fuel-ts/program';
import type { StorageSlot } from '@fuel-ts/transactions';
import { arrayify, isDefined } from '@fuel-ts/utils';

import { getContractId, getContractStorageRoot, hexlifyWithPrefix } from './util';
import {
MAX_CONTRACT_SIZE,
getContractId,
getContractStorageRoot,
hexlifyWithPrefix,
} from './util';

/**
* Options for deploying a contract.
Expand Down Expand Up @@ -149,7 +154,15 @@ export default class ContractFactory {
async deployContract<TContract extends Contract = Contract>(
deployContractOptions: DeployContractOptions = {}
): Promise<DeployContractResult<TContract>> {
if (this.bytecode.length > MAX_CONTRACT_SIZE) {
throw new FuelError(
ErrorCode.CONTRACT_SIZE_EXCEEDS_LIMIT,
'Contract bytecode is too large. Max contract size is 100KB'
);
}

const { contractId, transactionRequest } = await this.prepareDeploy(deployContractOptions);

const account = this.getAccount();

const transactionResponse = await account.sendTransaction(transactionRequest, {
Expand Down
3 changes: 3 additions & 0 deletions packages/contract/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { calcRoot, SparseMerkleTree } from '@fuel-ts/merkle';
import type { StorageSlot } from '@fuel-ts/transactions';
import { chunkAndPadBytes, hexlify, concat, arrayify } from '@fuel-ts/utils';

// Max contract size in bytes is 100KB
export const MAX_CONTRACT_SIZE = 102400;

/**
* @hidden
*
Expand Down
3 changes: 2 additions & 1 deletion packages/errors/src/error-codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,12 @@ export enum ErrorCode {
INVALID_TRANSACTION_INPUT = 'invalid-transaction-input',
INVALID_TRANSACTION_OUTPUT = 'invalid-transaction-output',
INVALID_TRANSACTION_STATUS = 'invalid-transaction-status',
INVALID_TRANSACTION_TYPE = 'invalid-transaction-type',
UNSUPPORTED_TRANSACTION_TYPE = 'unsupported-transaction-type',
TRANSACTION_ERROR = 'transaction-error',
INVALID_POLICY_TYPE = 'invalid-policy-type',
DUPLICATED_POLICY = 'duplicated-policy',
TRANSACTION_SQUEEZED_OUT = 'transaction-squeezed-out',
CONTRACT_SIZE_EXCEEDS_LIMIT = 'contract-size-exceeds-limit',

// receipt
INVALID_RECEIPT_TYPE = 'invalid-receipt-type',
Expand Down
18 changes: 18 additions & 0 deletions packages/fuel-gauge/src/contract-factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,22 @@ describe('Contract Factory', () => {
)
);
});

it('should not deploy contracts greater than 100KB', async () => {
using launched = await launchTestNode();
const {
wallets: [wallet],
} = launched;

const largeByteCode = `0x${'00'.repeat(112400)}`;
const factory = new ContractFactory(largeByteCode, StorageTestContractAbi__factory.abi, wallet);

await expectToThrowFuelError(
async () => factory.deployContract(),
new FuelError(
ErrorCode.CONTRACT_SIZE_EXCEEDS_LIMIT,
'Contract bytecode is too large. Max contract size is 100KB'
)
);
});
});
8 changes: 4 additions & 4 deletions packages/transactions/src/coders/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -628,8 +628,8 @@ export class TransactionCoder extends Coder<Transaction, Transaction> {
}
default: {
throw new FuelError(
ErrorCode.INVALID_TRANSACTION_TYPE,
`Invalid transaction type: ${type}`
ErrorCode.UNSUPPORTED_TRANSACTION_TYPE,
`Unsupported transaction type: ${type}`
);
}
}
Expand Down Expand Up @@ -667,8 +667,8 @@ export class TransactionCoder extends Coder<Transaction, Transaction> {
}
default: {
throw new FuelError(
ErrorCode.INVALID_TRANSACTION_TYPE,
`Invalid transaction type: ${type}`
ErrorCode.UNSUPPORTED_TRANSACTION_TYPE,
`Unsupported transaction type: ${type}`
);
}
}
Expand Down
8 changes: 4 additions & 4 deletions packages/transactions/src/coders/upgrade-purpose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export class UpgradePurposeCoder extends Coder<UpgradePurpose, UpgradePurpose> {

default: {
throw new FuelError(
ErrorCode.INVALID_TRANSACTION_TYPE,
`Invalid transaction type: ${type}`
ErrorCode.UNSUPPORTED_TRANSACTION_TYPE,
`Unsupported transaction type: ${type}`
);
}
}
Expand Down Expand Up @@ -94,8 +94,8 @@ export class UpgradePurposeCoder extends Coder<UpgradePurpose, UpgradePurpose> {

default: {
throw new FuelError(
ErrorCode.INVALID_TRANSACTION_TYPE,
`Invalid transaction type: ${type}`
ErrorCode.UNSUPPORTED_TRANSACTION_TYPE,
`Unsupported transaction type: ${type}`
);
}
}
Expand Down
Loading