Skip to content

Commit 02e05ca

Browse files
zone117xjanniks
andauthored
fix: Increase maximum code body length for contract deploys (#1793)
* fix: deserialize contract-deploy tx with large payload * test: fix file path --------- Co-authored-by: janniks <[email protected]>
1 parent 654ca25 commit 02e05ca

File tree

5 files changed

+37
-3
lines changed

5 files changed

+37
-3
lines changed

package-lock.json

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/transactions/src/constants.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ export const COMPRESSED_PUBKEY_LENGTH_BYTES = 32;
1111
export const UNCOMPRESSED_PUBKEY_LENGTH_BYTES = 64;
1212
export const MEMO_MAX_LENGTH_BYTES = 34;
1313

14+
// https://github.com/stacks-network/stacks-core/blob/31d048c6c345c8cb7be38283385e54870b1c3c83/stacks-common/src/codec/mod.rs#L206
15+
// messages can't be bigger than 16MB plus the preamble and relayers
16+
const MAX_PAYLOAD_LEN = 1 + 16 * 1024 * 1024;
17+
const PREAMBLE_ENCODED_SIZE = 165;
18+
const MAX_RELAYERS_LEN = 16;
19+
const PEER_ADDRESS_ENCODED_SIZE = 16;
20+
const HASH160_ENCODED_SIZE = 20;
21+
const NEIGHBOR_ADDRESS_ENCODED_SIZE = PEER_ADDRESS_ENCODED_SIZE + 2 + HASH160_ENCODED_SIZE;
22+
const RELAY_DATA_ENCODED_SIZE = NEIGHBOR_ADDRESS_ENCODED_SIZE + 4;
23+
export const STRING_MAX_LENGTH =
24+
MAX_PAYLOAD_LEN + (PREAMBLE_ENCODED_SIZE + MAX_RELAYERS_LEN * RELAY_DATA_ENCODED_SIZE);
25+
1426
/**
1527
* The type of transaction (payload) that is being serialized.
1628
* Used internally for serializing and deserializing transactions.

packages/transactions/src/wire/serialization.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
COMPRESSED_PUBKEY_LENGTH_BYTES,
2929
ClarityVersion,
3030
FungibleConditionCode,
31+
STRING_MAX_LENGTH,
3132
MEMO_MAX_LENGTH_BYTES,
3233
NonFungibleConditionCode,
3334
PayloadType,
@@ -541,7 +542,7 @@ export function deserializePayload(serialized: string | Uint8Array | BytesReader
541542
throw new Error(`Cannot recognize ClarityVersion: ${n}`);
542543
});
543544
const smartContractName = deserializeLPString(bytesReader);
544-
const codeBody = deserializeLPString(bytesReader, 4, 100_000);
545+
const codeBody = deserializeLPString(bytesReader, 4, STRING_MAX_LENGTH);
545546
return createSmartContractPayload(smartContractName, codeBody, clarityVersion);
546547
}
547548
case PayloadType.PoisonMicroblock:

packages/transactions/tests/transaction.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
AddressHashMode,
2323
AuthType,
2424
FungibleConditionCode,
25+
PayloadType,
2526
PostConditionMode,
2627
} from '../src/constants';
2728
import { createStacksPublicKey, privateKeyToPublic, publicKeyToHex } from '../src/keys';
@@ -46,6 +47,8 @@ import {
4647
serializeTransaction,
4748
transactionToHex,
4849
} from '../src/transaction';
50+
import fs from 'node:fs';
51+
import assert from 'node:assert';
4952

5053
beforeEach(() => {
5154
fetchMock.resetMocks();
@@ -450,6 +453,25 @@ test('Coinbase pay to alt contract principal recipient deserialization', () => {
450453
expect(deserializedTx.transactionVersion).toBe(TransactionVersion.Testnet);
451454
});
452455

456+
test('deserialize wtf tx', () => {
457+
const largeTxDeployBody = fs.readFileSync('./tests/tx-contract-deploy-large-hex.txt', 'utf8');
458+
const reader = new BytesReader(largeTxDeployBody);
459+
const deserialized = deserializeTransaction(reader);
460+
expect(deserialized.payload).toBeTruthy();
461+
assert(deserialized.payload.payloadType === PayloadType.VersionedSmartContract);
462+
expect(deserialized.payload.contractName.content).toBe('tcat-01');
463+
expect(
464+
deserialized.payload.codeBody.content.startsWith(
465+
`(use-trait nma 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.trait-sip-010.sip-010-trait) (use-trait nmb 'SP2AKWJYC7BNY18W1XXKPGP0YVEK63QJG4793Z2D4.sip-010-trait-ft-standard.sip-010-trait) (use-trait nmc 'SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS.dao-traits-v4.sip010-ft-trait`
466+
)
467+
);
468+
expect(
469+
deserialized.payload.codeBody.content.endsWith(
470+
`(use-trait nma 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.trait-sip-010.sip-010-trait) (use-trait nmb 'SP2AKWJYC7BNY18W1XXKPGP0YVEK63QJG4793Z2D4.sip-010-trait-ft-standard.sip-010-trait) (use-trait nmc 'SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS.dao-traits-v4.sip010-ft-trait`
471+
)
472+
);
473+
});
474+
453475
describe(serializeTransaction.name, () => {
454476
const serializedTx =
455477
'0x8080000000040055a0a92720d20398211cd4c7663d65d018efcc1f00000000000000030000000000000000010118da31f542913e8c56961b87ee4794924e655a28a2034e37ef4823eeddf074747285bd6efdfbd84eecdf62cffa7c1864e683c688f4c105f4db7429066735b4e2010200000000050000000000000000000000000000000000000000000000000000000000000000061aba27f99e007c7f605a8305e318c1abde3cd220ac0b68656c6c6f5f776f726c64';

packages/transactions/tests/tx-contract-deploy-large-hex.txt

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)