From 28194ada1c1fa86d7b578a0a8eaf44ed432bc8da Mon Sep 17 00:00:00 2001 From: xbtmatt <90358481+xbtmatt@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:13:36 -0700 Subject: [PATCH] Serialization/deserialization fixed --- src/api/transaction_submission.ts | 13 ++++++------- src/bcs/serializer.ts | 10 ++++++++++ src/transactions/instances/transactionArgument.ts | 14 ++++++++++---- tests/unit/script_transaction_arguments.test.ts | 4 +--- tests/unit/transaction_builder.test.ts | 7 ++++++- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/api/transaction_submission.ts b/src/api/transaction_submission.ts index 9334eacfb..90fd3a4c0 100644 --- a/src/api/transaction_submission.ts +++ b/src/api/transaction_submission.ts @@ -15,7 +15,6 @@ import { GenerateSingleSignerRawTransactionInput, SingleSignerTransaction, SimulateTransactionData, - GenerateSingleSignerRawTransactionArgs, } from "../transactions/types"; import { UserTransactionResponse, PendingTransactionResponse } from "../types"; import { @@ -89,12 +88,12 @@ export class TransactionSubmission { const payload = await generateTransactionPayload(data); const rawTransaction = await generateTransaction({ aptosConfig: this.config, - sender: sender, - payload: payload, - options: options, - secondarySignerAddresses: secondarySignerAddresses, - feePayerAddress: feePayerAddress, - } as GenerateSingleSignerRawTransactionArgs); + sender, + payload, + options, + secondarySignerAddresses, + feePayerAddress, + }); return rawTransaction; } diff --git a/src/bcs/serializer.ts b/src/bcs/serializer.ts index 4de550bbf..9fb0e250c 100644 --- a/src/bcs/serializer.ts +++ b/src/bcs/serializer.ts @@ -11,6 +11,7 @@ import { MAX_U256_BIG_INT, } from "./consts"; import { AnyNumber, Uint16, Uint32, Uint8 } from "../types"; +import { Hex } from "../core"; // This class is intended to be used as a base class for all serializable types. // It can be used to facilitate composable serialization of a complex type and @@ -28,6 +29,15 @@ export abstract class Serializable { this.serialize(serializer); return serializer.toUint8Array(); } + + /** + * Helper function to get a value's BCS-serialized bytes as a Hex instance. + * @returns a Hex instance with the BCS-serialized bytes loaded into its underlying Uint8Array + */ + bcsToHex() { //: Hex { + // const bcsBytes = this.bcsToBytes(); + // return Hex.fromHexInput({ hexInput: bcsBytes }); + } } export class Serializer { diff --git a/src/transactions/instances/transactionArgument.ts b/src/transactions/instances/transactionArgument.ts index 867dad34b..1343dad3c 100644 --- a/src/transactions/instances/transactionArgument.ts +++ b/src/transactions/instances/transactionArgument.ts @@ -52,15 +52,21 @@ export class EntryFunctionBytes this.value = new FixedBytes(value); } - // Note that both serialize and serializeForEntryFunction are the same. - // We need them to be equivalent so that when we re-serialize this class as an entry - // function payload's arguments, we don't re-serialize the length prefix. + // Note that to see the Move, BCS-serialized representation of the underlying fixed byte vector, + // we must not serialize the length prefix. + // + // In other words, this class is only used to represent a sequence of bytes that are already + // BCS-serialized as a type. To represent those bytes accurately, the BCS-serialized form is the same exact + // representation. serialize(serializer: Serializer): void { serializer.serialize(this.value); } - // This is necessary to implement the interface, so we can use this class as an EntryFunctionArgument. + // When we serialize these bytes as an entry function argument, we need to + // serialize the length prefix. This essentially converts the underlying fixed byte vector to a type-agnostic + // byte vector to an `any` type. serializeForEntryFunction(serializer: Serializer): void { + serializer.serializeU32AsUleb128(this.value.value.length); serializer.serialize(this); } /** diff --git a/tests/unit/script_transaction_arguments.test.ts b/tests/unit/script_transaction_arguments.test.ts index 31f76e11c..89d10af03 100644 --- a/tests/unit/script_transaction_arguments.test.ts +++ b/tests/unit/script_transaction_arguments.test.ts @@ -103,9 +103,7 @@ describe("Tests for the script transaction argument class", () => { serializer = new Serializer(); input.serializeForScriptFunction(serializer); const deserializer = new Deserializer(serializer.toUint8Array()); - const asdf = ScriptTransactionArgument.deserialize(deserializer); - console.log(asdf); - return asdf; + return ScriptTransactionArgument.deserialize(deserializer); }; expect(deserializeToScriptArg(new U8(1)) instanceof ScriptTransactionArgumentU8).toBe(true); diff --git a/tests/unit/transaction_builder.test.ts b/tests/unit/transaction_builder.test.ts index b22c4cef9..b74e65cd6 100644 --- a/tests/unit/transaction_builder.test.ts +++ b/tests/unit/transaction_builder.test.ts @@ -30,6 +30,7 @@ import { Network } from "../../src/utils/apiEndpoints"; import { SignedTransaction } from "../../src/transactions/instances/signedTransaction"; import { U64 } from "../../src/bcs/serializable/move-primitives"; import { MoveObject } from "../../src/bcs/serializable/move-structs"; +import { Hex } from "../../src/core"; describe("transaction builder", () => { describe("generate transaction payload", () => { @@ -443,7 +444,11 @@ describe("transaction builder", () => { hexInput: "0x5aba8dab1c523be32bd4dafe2cc612f7f8050ce42a3322b60216ef67dc97768c", }), }); - const bob = Account.generate({ scheme: SigningScheme.Ed25519 }); + const bob = Account.fromPrivateKey({ + privateKey: new Ed25519PrivateKey({ + hexInput: "0x5aba8dab1c523be32bd4dafe2cc612f7f8050ce42a3322b60216ef67dc97768c", + }), + }); const payload = generateTransactionPayload({ function: "0x1::aptos_account::transfer", type_arguments: [],