From 6ff3a2f134f772a96208fa1949d8441d0a545dab Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Sun, 20 Oct 2024 22:39:50 +0200 Subject: [PATCH 01/53] Adapt execution resources in data classes and methods --- .../com/swmansion/starknet/account/Account.kt | 10 +- .../starknet/account/StandardAccount.kt | 12 ++- .../swmansion/starknet/data/types/Block.kt | 19 ++++ .../starknet/data/types/ExecutionResources.kt | 18 ++++ .../swmansion/starknet/data/types/Params.kt | 8 +- .../starknet/data/types/Resources.kt | 98 ------------------- .../starknet/data/types/Responses.kt | 60 +++++++----- .../data/types/SimulatedTransaction.kt | 2 +- .../starknet/deployercontract/Deployer.kt | 5 +- .../deployercontract/StandardDeployer.kt | 7 +- 10 files changed, 100 insertions(+), 139 deletions(-) create mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt delete mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt diff --git a/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt b/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt index 9b963cf5f..915c67288 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt @@ -195,11 +195,13 @@ interface Account { calldata: Calldata, salt: Felt, l1ResourceBounds: ResourceBounds, + l2ResourceBounds: ResourceBounds, forFeeEstimate: Boolean, ): DeployAccountTransactionV3 { val params = DeployAccountParamsV3( nonce = Felt.ZERO, l1ResourceBounds = l1ResourceBounds, + l2ResourceBounds = l2ResourceBounds, ) return signDeployAccountV3(classHash, calldata, salt, params, forFeeEstimate) } @@ -219,10 +221,12 @@ interface Account { calldata: Calldata, salt: Felt, l1ResourceBounds: ResourceBounds, + l2ResourceBounds: ResourceBounds, ): DeployAccountTransactionV3 { val params = DeployAccountParamsV3( nonce = Felt.ZERO, l1ResourceBounds = l1ResourceBounds, + l2ResourceBounds = l2ResourceBounds, ) return signDeployAccountV3(classHash, calldata, salt, params, false) } @@ -334,9 +338,10 @@ interface Account { * * @param calls a list of calls to be executed. * @param l1ResourceBounds L1 resource bounds for the transaction. + * @param l2ResourceBounds L2 resource bounds for the transaction. * @return Invoke function response, containing transaction hash. */ - fun executeV3(calls: List, l1ResourceBounds: ResourceBounds): Request + fun executeV3(calls: List, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request /** * Execute single call using version 1 invoke transaction. @@ -356,9 +361,10 @@ interface Account { * * @param call a call to be executed. * @param l1ResourceBounds L1 resource bounds for the transaction. + * @param l2ResourceBounds L2 resource bounds for the transaction. * @return Invoke function response, containing transaction hash. */ - fun executeV3(call: Call, l1ResourceBounds: ResourceBounds): Request + fun executeV3(call: Call, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request /** * Execute a list of calls using version 1 invoke transaction with automatically estimated fee diff --git a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt index 9c2b9c417..5c9112cd6 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt @@ -314,11 +314,12 @@ class StandardAccount @JvmOverloads constructor( } } - override fun executeV3(calls: List, l1ResourceBounds: ResourceBounds): Request { + override fun executeV3(calls: List, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request { return getNonce().compose { nonce -> val signParams = InvokeParamsV3( nonce = nonce, l1ResourceBounds = l1ResourceBounds, + l2ResourceBounds = l2ResourceBounds, ) val payload = signV3(calls, signParams, false) @@ -343,7 +344,7 @@ class StandardAccount @JvmOverloads constructor( amountMultiplier = estimateAmountMultiplier, unitPriceMultiplier = estimateUnitPriceMultiplier, ) - executeV3(calls, resourceBounds.l1Gas) + executeV3(calls, resourceBounds.l1Gas, resourceBounds.l2Gas) } } @@ -363,7 +364,7 @@ class StandardAccount @JvmOverloads constructor( override fun executeV3(calls: List): Request { return estimateFeeV3(calls).compose { estimateFee -> val resourceBounds = estimateFee.values.first().toResourceBounds() - executeV3(calls, resourceBounds.l1Gas) + executeV3(calls, resourceBounds.l1Gas, resourceBounds.l2Gas) } } @@ -371,8 +372,8 @@ class StandardAccount @JvmOverloads constructor( return executeV1(listOf(call), maxFee) } - override fun executeV3(call: Call, l1ResourceBounds: ResourceBounds): Request { - return executeV3(listOf(call), l1ResourceBounds) + override fun executeV3(call: Call, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request { + return executeV3(listOf(call), l1ResourceBounds, l2ResourceBounds) } override fun executeV1(call: Call, estimateFeeMultiplier: Double): Request { @@ -542,6 +543,7 @@ class StandardAccount @JvmOverloads constructor( val executionParams = InvokeParamsV3( nonce = nonce, l1ResourceBounds = ResourceBounds.ZERO, + l2ResourceBounds = ResourceBounds.ZERO, ) val payload = signV3(calls, executionParams, true) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Block.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Block.kt index a0bc33ee3..378fce319 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Block.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Block.kt @@ -46,6 +46,7 @@ sealed interface Block : StarknetResponse { val sequencerAddress: Felt val parentHash: Felt val l1GasPrice: ResourcePrice + val l2GasPrice: ResourcePrice val l1DataGasPrice: ResourcePrice val l1DataAvailabilityMode: L1DAMode val starknetVersion: String @@ -107,6 +108,9 @@ data class ProcessedBlockWithTransactions( @SerialName("l1_gas_price") override val l1GasPrice: ResourcePrice, + @SerialName("l2_gas_price") + override val l2GasPrice: ResourcePrice, + @SerialName("l1_data_gas_price") override val l1DataGasPrice: ResourcePrice, @@ -137,6 +141,9 @@ data class PendingBlockWithTransactions( @SerialName("l1_gas_price") override val l1GasPrice: ResourcePrice, + @SerialName("l2_gas_price") + override val l2GasPrice: ResourcePrice, + @SerialName("l1_data_gas_price") override val l1DataGasPrice: ResourcePrice, @@ -192,6 +199,9 @@ data class ProcessedBlockWithReceipts( @SerialName("l1_gas_price") override val l1GasPrice: ResourcePrice, + @SerialName("l2_gas_price") + override val l2GasPrice: ResourcePrice, + @SerialName("l1_data_gas_price") override val l1DataGasPrice: ResourcePrice, @@ -219,6 +229,9 @@ data class PendingBlockWithReceipts( @SerialName("l1_gas_price") override val l1GasPrice: ResourcePrice, + @SerialName("l2_gas_price") + override val l2GasPrice: ResourcePrice, + @SerialName("l1_data_gas_price") override val l1DataGasPrice: ResourcePrice, @@ -263,6 +276,9 @@ data class ProcessedBlockWithTransactionHashes( @SerialName("l1_gas_price") override val l1GasPrice: ResourcePrice, + @SerialName("l2_gas_price") + override val l2GasPrice: ResourcePrice, + @SerialName("l1_data_gas_price") override val l1DataGasPrice: ResourcePrice, @@ -290,6 +306,9 @@ data class PendingBlockWithTransactionHashes( @SerialName("l1_gas_price") override val l1GasPrice: ResourcePrice, + @SerialName("l2_gas_price") + override val l2GasPrice: ResourcePrice, + @SerialName("l1_data_gas_price") override val l1DataGasPrice: ResourcePrice, diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt new file mode 100644 index 000000000..eb3eb9f24 --- /dev/null +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt @@ -0,0 +1,18 @@ +@file:JvmName("Resources") + +package com.swmansion.starknet.data.types + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ExecutionResources( + @SerialName("l1_gas") + val l1Gas: Int, + + @SerialName("l1_data_gas") + val l1DataGas: Int, + + @SerialName("l2_gas") + val l2Gas: Int, +) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt index 74fbf6218..f9dc1220e 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt @@ -39,10 +39,11 @@ data class InvokeParamsV3 private constructor( override val nonceDataAvailabilityMode: DAMode, override val feeDataAvailabilityMode: DAMode, ) : ParamsV3() { - constructor(nonce: Felt, l1ResourceBounds: ResourceBounds) : this( + constructor(nonce: Felt, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds) : this( nonce = nonce, resourceBounds = ResourceBoundsMapping( l1Gas = l1ResourceBounds, + l2Gas = l2ResourceBounds ), tip = Uint64.ZERO, paymasterData = emptyList(), @@ -66,10 +67,11 @@ data class DeclareParamsV3 private constructor( override val nonceDataAvailabilityMode: DAMode, override val feeDataAvailabilityMode: DAMode, ) : ParamsV3() { - constructor(nonce: Felt, l1ResourceBounds: ResourceBounds) : this( + constructor(nonce: Felt, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds) : this( nonce = nonce, resourceBounds = ResourceBoundsMapping( l1Gas = l1ResourceBounds, + l2Gas = l2ResourceBounds ), tip = Uint64.ZERO, paymasterData = emptyList(), @@ -96,10 +98,12 @@ data class DeployAccountParamsV3 private constructor( constructor( nonce: Felt = Felt.ZERO, l1ResourceBounds: ResourceBounds, + l2ResourceBounds: ResourceBounds ) : this( nonce = nonce, resourceBounds = ResourceBoundsMapping( l1Gas = l1ResourceBounds, + l2Gas = l2ResourceBounds ), tip = Uint64.ZERO, paymasterData = emptyList(), diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt deleted file mode 100644 index 526bb6e66..000000000 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt +++ /dev/null @@ -1,98 +0,0 @@ -@file:JvmName("Resources") - -package com.swmansion.starknet.data.types - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -sealed class Resources { - abstract val steps: Int - abstract val memoryHoles: Int? - abstract val rangeCheckApplications: Int? - abstract val pedersenApplications: Int? - abstract val poseidonApplications: Int? - abstract val ecOpApplications: Int? - abstract val ecdsaApplications: Int? - abstract val bitwiseApplications: Int? - abstract val keccakApplications: Int? - abstract val segmentArenaApplications: Int? -} - -@Serializable -data class ComputationResources( - @SerialName("steps") - override val steps: Int, - - @SerialName("memory_holes") - override val memoryHoles: Int? = null, - - @SerialName("range_check_builtin_applications") - override val rangeCheckApplications: Int? = null, - - @SerialName("pedersen_builtin_applications") - override val pedersenApplications: Int? = null, - - @SerialName("poseidon_builtin_applications") - override val poseidonApplications: Int? = null, - - @SerialName("ec_op_builtin_applications") - override val ecOpApplications: Int? = null, - - @SerialName("ecdsa_builtin_applications") - override val ecdsaApplications: Int? = null, - - @SerialName("bitwise_builtin_applications") - override val bitwiseApplications: Int? = null, - - @SerialName("keccak_builtin_applications") - override val keccakApplications: Int? = null, - - @SerialName("segment_arena_builtin") - override val segmentArenaApplications: Int? = null, -) : Resources() - -@Serializable -data class ExecutionResources( - @SerialName("steps") - override val steps: Int, - - @SerialName("memory_holes") - override val memoryHoles: Int? = null, - - @SerialName("range_check_builtin_applications") - override val rangeCheckApplications: Int? = null, - - @SerialName("pedersen_builtin_applications") - override val pedersenApplications: Int? = null, - - @SerialName("poseidon_builtin_applications") - override val poseidonApplications: Int? = null, - - @SerialName("ec_op_builtin_applications") - override val ecOpApplications: Int? = null, - - @SerialName("ecdsa_builtin_applications") - override val ecdsaApplications: Int? = null, - - @SerialName("bitwise_builtin_applications") - override val bitwiseApplications: Int? = null, - - @SerialName("keccak_builtin_applications") - override val keccakApplications: Int? = null, - - @SerialName("segment_arena_builtin") - override val segmentArenaApplications: Int? = null, - - @SerialName("data_availability") - val dataAvailability: DataResources, -) : Resources() - -@Serializable -data class DataResources( - @SerialName("l1_gas") - val l1Gas: Int, - - @SerialName("l1_data_gas") - val l1DataGas: Int, -) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index dd0aac7e9..7cf8acd4b 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -43,17 +43,23 @@ data class DeployAccountResponse( @Serializable data class EstimateFeeResponse( - @SerialName("gas_consumed") - val gasConsumed: Felt, + @SerialName("l1_gas_consumed") + val l1GasConsumed: Felt, - @SerialName("gas_price") - val gasPrice: Felt, + @SerialName("l1_gas_price") + val l1GasPrice: Felt, - @SerialName("data_gas_consumed") - val dataGasConsumed: Felt, + @SerialName("l2_gas_consumed") + val l2GasConsumed: Felt, - @SerialName("data_gas_price") - val dataGasPrice: Felt, + @SerialName("l2_gas_price") + val l2GasPrice: Felt, + + @SerialName("l1_data_gas_consumed") + val l1DataGasConsumed: Felt, + + @SerialName("l1_data_gas_price") + val l1DataGasPrice: Felt, @SerialName("overall_fee") val overallFee: Felt, @@ -79,9 +85,11 @@ data class EstimateFeeResponse( /** * Convert estimated fee to resource bounds with applied multipliers. * - * Calculates max amount as maxAmount = [overallFee] / [gasPrice], unless [gasPrice] is 0, then maxAmount is 0. - * Calculates max price per unit as maxPricePerUnit = [gasPrice]. - * Then multiplies maxAmount by round([amountMultiplier] * 100%) and maxPricePerUnit by round([unitPriceMultiplier] * 100%) and performs integer division by 100 on both. + * Calculates max amount l1 as maxAmountL1 = [overallFee] / [l1GasPrice], unless [l1GasPrice] is 0, then maxAmountL1 is 0. + * Calculates max amount l2 as maxAmountL2 = [overallFee] / [l2GasPrice], unless [l2GasPrice] is 0, then maxAmountL2 is 0. + * Calculates max price per unit l1 as maxPricePerUnitL1 = [l1GasPrice]. + * Calculates max price per unit l2 as maxPricePerUnitL2 = [l2GasPrice]. + * Then multiplies maxAmountL1/L2 by round([amountMultiplier] * 100%) and maxPricePerUnitL1/L2 by round([unitPriceMultiplier] * 100%) and performs integer division by 100 on both. * * @param amountMultiplier Multiplier for max amount, defaults to 1.5. * @param unitPriceMultiplier Multiplier for max price per unit, defaults to 1.5. @@ -96,14 +104,22 @@ data class EstimateFeeResponse( require(amountMultiplier >= 0) require(unitPriceMultiplier >= 0) - val maxAmount = when (gasPrice) { + val maxAmountL1 = when (l1GasPrice) { + Felt.ZERO -> Uint64.ZERO + else -> (overallFee.value / l1GasPrice.value).applyMultiplier(amountMultiplier).toUint64 + } + + val maxAmountL2 = when (l2GasPrice) { Felt.ZERO -> Uint64.ZERO - else -> (overallFee.value / gasPrice.value).applyMultiplier(amountMultiplier).toUint64 + else -> (overallFee.value / l2GasPrice.value).applyMultiplier(amountMultiplier).toUint64 } - val maxPricePerUnit = gasPrice.value.applyMultiplier(unitPriceMultiplier).toUint128 + + val maxPricePerUnitL1 = l1GasPrice.value.applyMultiplier(unitPriceMultiplier).toUint128 + val maxPricePerUnitL2 = l2GasPrice.value.applyMultiplier(unitPriceMultiplier).toUint128 return ResourceBoundsMapping( - l1Gas = ResourceBounds(maxAmount = maxAmount, maxPricePerUnit = maxPricePerUnit), + l1Gas = ResourceBounds(maxAmount = maxAmountL1, maxPricePerUnit = maxPricePerUnitL1), + l2Gas = ResourceBounds(maxAmount = maxAmountL2, maxPricePerUnit = maxPricePerUnitL2), ) } @@ -309,10 +325,9 @@ data class PendingStateUpdateResponse( ) : StateUpdate() // TODO: remove SCREAMING_SNAKE_CASE @JsonNames once devnet is updated -@Suppress("DataClassPrivateConstructor") @OptIn(ExperimentalSerializationApi::class) @Serializable -data class ResourceBoundsMapping private constructor( +data class ResourceBoundsMapping( @SerialName("l1_gas") @JsonNames("L1_GAS") val l1Gas: ResourceBounds, @@ -320,16 +335,7 @@ data class ResourceBoundsMapping private constructor( @SerialName("l2_gas") @JsonNames("L2_GAS") val l2Gas: ResourceBounds, -) { - constructor( - l1Gas: ResourceBounds, - ) : this( - // As of Starknet 0.13.0, the L2 gas is not supported - // Because of this, the L2 gas values are hardcoded to 0 - l1Gas = l1Gas, - l2Gas = ResourceBounds.ZERO, - ) -} +) @Serializable data class ResourceBounds( diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt index 3ffaa0edf..8e8b46a84 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt @@ -65,7 +65,7 @@ data class FunctionInvocation( val messages: List, @SerialName("execution_resources") - val computationResources: ComputationResources, + val computationResources: ExecutionResources, ) @Serializable diff --git a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt index f6eb92f46..43152182e 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt @@ -49,6 +49,7 @@ interface Deployer { * @param salt a salt to be used to calculate deployed contract address * @param constructorCalldata constructor calldata * @param l1ResourceBounds L1 resource bounds for the transaction + * @param l2ResourceBounds L2 resource bounds for the transaction * * @throws RequestFailedException * @@ -60,6 +61,7 @@ interface Deployer { salt: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds, + l2ResourceBounds: ResourceBounds, ): Request /** @@ -122,13 +124,14 @@ interface Deployer { * @param classHash a class hash of the declared contract * @param constructorCalldata constructor calldata * @param l1ResourceBounds L1 resource bounds for the transaction + * @param l2ResourceBounds L2 resource bounds for the transaction * * @throws RequestFailedException * @throws SaltGenerationFailedException * * @sample starknet.deployercontract.StandardDeployerTest.testUdcDeployV3WithSpecificFeeAndDefaultParameters */ - fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds): Request + fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request /** * Deploy a contract through Universal Deployer Contract (UDC) using version 1 invoke transaction diff --git a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt index 73bd9c06d..3b5d6094d 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt @@ -32,10 +32,11 @@ class StandardDeployer( salt: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds, + l2ResourceBounds: ResourceBounds, ): Request { val call = buildDeployContractCall(classHash, unique, salt, constructorCalldata) - return account.executeV3(call, l1ResourceBounds).map { ContractDeployment(it.transactionHash) } + return account.executeV3(call, l1ResourceBounds, l2ResourceBounds).map { ContractDeployment(it.transactionHash) } } override fun deployContractV1( @@ -65,9 +66,9 @@ class StandardDeployer( return deployContractV1(classHash, true, salt, constructorCalldata, maxFee) } - override fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds): Request { + override fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request { val salt = randomSalt() - return deployContractV3(classHash, true, salt, constructorCalldata, l1ResourceBounds) + return deployContractV3(classHash, true, salt, constructorCalldata, l1ResourceBounds, l2ResourceBounds) } override fun deployContractV1(classHash: Felt, constructorCalldata: Calldata): Request { From 4c2014dc7a46d0117b038acdbdca86ee793c498b Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Mon, 21 Oct 2024 00:50:25 +0200 Subject: [PATCH 02/53] Update tests --- .../data/TransactionHashCalculatorTest.kt | 15 +++ .../kotlin/network/account/AccountTest.kt | 21 ++- .../starknet/account/StandardAccountTest.kt | 123 ++++++++++++++---- .../kotlin/starknet/crypto/FeeUtilsTest.kt | 40 ++++-- .../deployercontract/StandardDeployerTest.kt | 10 ++ .../provider/response/JsonRpcResponseTest.kt | 16 ++- .../test/kotlin/starknet/signer/SignerTest.kt | 5 + 7 files changed, 181 insertions(+), 49 deletions(-) diff --git a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt index 1ebee6ea3..101e69b1b 100644 --- a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt +++ b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt @@ -123,6 +123,11 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), ), + // TODO: Check if these l2 resources bounds are adequate + l2Gas = ResourceBounds( + maxAmount = Uint64.fromHex("0x186a0"), + maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), + ) ), paymasterData = emptyList(), feeDataAvailabilityMode = DAMode.L1, @@ -148,6 +153,11 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), ), + // TODO: Check if these l2 resources bounds are adequate + l2Gas = ResourceBounds( + maxAmount = Uint64.fromHex("0x186a0"), + maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), + ) ), tip = Uint64.ZERO, paymasterData = emptyList(), @@ -172,6 +182,11 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x2540be400"), ), + // TODO: Check if these resources bounds are adequate + l2Gas = ResourceBounds( + maxAmount = Uint64.fromHex("0x186a0"), + maxPricePerUnit = Uint128.fromHex("0x2540be400"), + ) ), tip = Uint64.ZERO, paymasterData = emptyList(), diff --git a/lib/src/test/kotlin/network/account/AccountTest.kt b/lib/src/test/kotlin/network/account/AccountTest.kt index 06336cc3e..e99b58387 100644 --- a/lib/src/test/kotlin/network/account/AccountTest.kt +++ b/lib/src/test/kotlin/network/account/AccountTest.kt @@ -135,8 +135,10 @@ class AccountTest { val feeEstimateRequest = provider.getEstimateFee(listOf(signedTransaction), BlockTag.LATEST, emptySet()) val feeEstimate = feeEstimateRequest.send().values.first() - assertNotEquals(Felt(0), feeEstimate.gasConsumed) - assertNotEquals(Felt(0), feeEstimate.gasPrice) + assertNotEquals(Felt(0), feeEstimate.l1GasConsumed) + assertNotEquals(Felt(0), feeEstimate.l1GasPrice) + assertNotEquals(Felt(0), feeEstimate.l2GasConsumed) + assertNotEquals(Felt(0), feeEstimate.l2GasPrice) assertNotEquals(Felt(0), feeEstimate.overallFee) } @@ -160,6 +162,7 @@ class AccountTest { val params = DeclareParamsV3( nonce = nonce, l1ResourceBounds = ResourceBounds.ZERO, + l2ResourceBounds = ResourceBounds.ZERO, ) val declareTransactionPayload = account.signDeclareV3( sierraContractDefinition = contractDefinition, @@ -171,8 +174,10 @@ class AccountTest { val feeEstimateRequest = provider.getEstimateFee(listOf(declareTransactionPayload), BlockTag.PENDING) val feeEstimate = feeEstimateRequest.send().values.first() - assertNotEquals(Felt(0), feeEstimate.gasConsumed) - assertNotEquals(Felt(0), feeEstimate.gasPrice) + assertNotEquals(Felt(0), feeEstimate.l1GasConsumed) + assertNotEquals(Felt(0), feeEstimate.l1GasPrice) + assertNotEquals(Felt(0), feeEstimate.l2GasConsumed) + assertNotEquals(Felt(0), feeEstimate.l2GasPrice) assertNotEquals(Felt(0), feeEstimate.overallFee) } @@ -265,9 +270,15 @@ class AccountTest { maxAmount = Uint64(100000), maxPricePerUnit = Uint128(2500000000000), ) + // TODO: Check if these l2 resources bounds are adequate + val l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(100000), + maxPricePerUnit = Uint128(2500000000000), + ) val params = DeclareParamsV3( nonce = nonce, l1ResourceBounds = l1ResourceBounds, + l2ResourceBounds = l2ResourceBounds, ) val declareTransactionPayload = account.signDeclareV3( contractDefinition, @@ -545,6 +556,7 @@ class AccountTest { params = DeployAccountParamsV3( nonce = Felt.ZERO, l1ResourceBounds = ResourceBounds.ZERO, + l2ResourceBounds = ResourceBounds.ZERO, ), forFeeEstimate = true, // BUG: (#344) this should be true, but Pathfinder and Devnet claim that using query version produce invalid signature ) @@ -570,6 +582,7 @@ class AccountTest { val params = DeployAccountParamsV3( nonce = Felt.ZERO, l1ResourceBounds = resourceBounds.l1Gas, + l2ResourceBounds = resourceBounds.l2Gas, ) val payload = deployedAccount.signDeployAccountV3( classHash = classHash, diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index 06b50ff0d..278efdc73 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -56,8 +56,14 @@ class StandardAccountTest { devnetClient.start() val accountDetails = devnetClient.createDeployAccount().details - val legacyAccountDetails = devnetClient.createDeployAccount(classHash = DevnetClient.legacyAccountContractClassHash, accountName = "legacy_account").details - balanceContractAddress = devnetClient.declareDeployContract("Balance", constructorCalldata = listOf(Felt(451))).contractAddress + val legacyAccountDetails = devnetClient.createDeployAccount( + classHash = DevnetClient.legacyAccountContractClassHash, + accountName = "legacy_account", + ).details + balanceContractAddress = devnetClient.declareDeployContract( + "Balance", + constructorCalldata = listOf(Felt(451)), + ).contractAddress accountAddress = accountDetails.address legacyAccountAddress = legacyAccountDetails.address @@ -218,7 +224,7 @@ class StandardAccountTest { assertNotEquals(Felt.ZERO, feeEstimate.overallFee) assertEquals( - feeEstimate.gasPrice.value * feeEstimate.gasConsumed.value + feeEstimate.dataGasPrice.value * feeEstimate.dataGasConsumed.value, + feeEstimate.l1GasPrice.value * feeEstimate.l1GasConsumed.value + feeEstimate.l1DataGasPrice.value * feeEstimate.l1DataGasConsumed.value, feeEstimate.overallFee.value, ) } @@ -236,7 +242,7 @@ class StandardAccountTest { // docsEnd assertNotEquals(Felt.ZERO, feeEstimate.overallFee) assertEquals( - feeEstimate.gasPrice.value * feeEstimate.gasConsumed.value + feeEstimate.dataGasPrice.value * feeEstimate.dataGasConsumed.value, + feeEstimate.l1GasPrice.value * feeEstimate.l1GasConsumed.value + feeEstimate.l1DataGasPrice.value * feeEstimate.l1DataGasConsumed.value + feeEstimate.l2GasPrice.value * feeEstimate.l2GasConsumed.value, feeEstimate.overallFee.value, ) } @@ -253,7 +259,7 @@ class StandardAccountTest { ) val invokeTxV3Payload = account.signV3( call = call, - params = InvokeParamsV3(nonce.value.add(BigInteger.ONE).toFelt, ResourceBounds.ZERO), + params = InvokeParamsV3(nonce.value.add(BigInteger.ONE).toFelt, ResourceBounds.ZERO, ResourceBounds.ZERO), forFeeEstimate = true, ) assertEquals(TransactionVersion.V1_QUERY, invokeTxV1Payload.version) @@ -271,7 +277,7 @@ class StandardAccountTest { feeEstimates.values.forEach { assertNotEquals(Felt.ZERO, it.overallFee) assertEquals( - it.gasPrice.value * it.gasConsumed.value + it.dataGasPrice.value * it.dataGasConsumed.value, + it.l1GasPrice.value * it.l1GasConsumed.value + it.l1DataGasPrice.value * it.l1DataGasConsumed.value + it.l2GasPrice.value * it.l2GasConsumed.value, it.overallFee.value, ) } @@ -286,7 +292,7 @@ class StandardAccountTest { assertNotEquals(Felt.ZERO, feeEstimate.overallFee) assertEquals( - feeEstimate.gasPrice.value * feeEstimate.gasConsumed.value + feeEstimate.dataGasPrice.value * feeEstimate.dataGasConsumed.value, + feeEstimate.l1GasPrice.value * feeEstimate.l1GasConsumed.value + feeEstimate.l1DataGasPrice.value * feeEstimate.l1DataGasConsumed.value + feeEstimate.l2GasPrice.value * feeEstimate.l2GasConsumed.value, feeEstimate.overallFee.value, ) } @@ -297,8 +303,11 @@ class StandardAccountTest { @Test fun estimateFeeForDeclareV2Transaction() { // docsStart - val contractCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json").readText() - val casmCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() + val contractCode = + Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json") + .readText() + val casmCode = + Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() val contractDefinition = Cairo1ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -313,12 +322,13 @@ class StandardAccountTest { // docsEnd assertEquals(TransactionVersion.V2_QUERY, declareTransactionPayload.version) // docsStart - val request = provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) + val request = + provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) val feeEstimate = request.send().values.first() // docsEnd assertNotEquals(Felt.ZERO, feeEstimate.overallFee) assertEquals( - feeEstimate.gasPrice.value * feeEstimate.gasConsumed.value + feeEstimate.dataGasPrice.value * feeEstimate.dataGasConsumed.value, + feeEstimate.l1GasPrice.value * feeEstimate.l1GasConsumed.value + feeEstimate.l1DataGasPrice.value * feeEstimate.l1DataGasConsumed.value + feeEstimate.l2GasPrice.value * feeEstimate.l2GasConsumed.value, feeEstimate.overallFee.value, ) } @@ -326,14 +336,17 @@ class StandardAccountTest { @Test fun estimateFeeForDeclareV3Transaction() { // docsStart - val contractCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json").readText() - val casmCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() + val contractCode = + Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json") + .readText() + val casmCode = + Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() val contractDefinition = Cairo1ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) val nonce = account.getNonce().send() - val params = DeclareParamsV3(nonce = nonce, l1ResourceBounds = ResourceBounds.ZERO) + val params = DeclareParamsV3(nonce = nonce, l1ResourceBounds = ResourceBounds.ZERO, l2ResourceBounds = ResourceBounds.ZERO) val declareTransactionPayload = account.signDeclareV3( contractDefinition, contractCasmDefinition, @@ -343,12 +356,13 @@ class StandardAccountTest { // docsEnd assertEquals(TransactionVersion.V3_QUERY, declareTransactionPayload.version) // docsStart - val request = provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) + val request = + provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) val feeEstimate = request.send().values.first() // docsEnd assertNotEquals(Felt.ZERO, feeEstimate.overallFee) assertEquals( - feeEstimate.gasPrice.value * feeEstimate.gasConsumed.value + feeEstimate.dataGasPrice.value * feeEstimate.dataGasConsumed.value, + feeEstimate.l1GasPrice.value * feeEstimate.l1GasConsumed.value + feeEstimate.l1DataGasPrice.value * feeEstimate.l1DataGasConsumed.value + feeEstimate.l2GasPrice.value * feeEstimate.l2GasConsumed.value, feeEstimate.overallFee.value, ) } @@ -356,8 +370,10 @@ class StandardAccountTest { @Test fun estimateMessageFee() { - val l1l2ContractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.sierra.json").readText() - val l1l2CasmContractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.casm.json").readText() + val l1l2ContractCode = + Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.sierra.json").readText() + val l1l2CasmContractCode = + Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.casm.json").readText() val l1l2ContractDefinition = Cairo2ContractDefinition(l1l2ContractCode) val l1l2CasmContractDefinition = CasmContractDefinition(l1l2CasmContractCode) @@ -390,9 +406,9 @@ class StandardAccountTest { ) val response = request.send() - assertNotEquals(Felt.ZERO, response.gasPrice) + assertNotEquals(Felt.ZERO, (response.l1GasPrice.value + response.l2GasPrice.value).toFelt) assertEquals( - response.gasPrice.value * response.gasConsumed.value + response.dataGasPrice.value * response.dataGasConsumed.value, + response.l1GasPrice.value * response.l1GasConsumed.value + response.l1DataGasPrice.value * response.l1DataGasConsumed.value, response.overallFee.value, ) } @@ -403,8 +419,11 @@ class StandardAccountTest { fun signAndSendDeclareV2Transaction() { devnetClient.prefundAccountEth(accountAddress) // docsStart - val contractCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json").readText() - val casmCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() + val contractCode = + Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json") + .readText() + val casmCode = + Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() val contractDefinition = Cairo1ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -427,8 +446,12 @@ class StandardAccountTest { fun `sign and send declare v2 transaction (cairo compiler v2)`() { devnetClient.prefundAccountEth(accountAddress) - val contractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.sierra.json").readText() - val casmCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.casm.json").readText() + val contractCode = + Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.sierra.json") + .readText() + val casmCode = + Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.casm.json") + .readText() val contractDefinition = Cairo2ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -455,8 +478,12 @@ class StandardAccountTest { placeholderContractPath = Path.of("src/test/resources/contracts_v2/src/placeholder_counter_contract.cairo"), saltedContractPath = Path.of("src/test/resources/contracts_v2/src/salted_counter_contract.cairo"), ) - val contractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.sierra.json").readText() - val casmCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.casm.json").readText() + val contractCode = + Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.sierra.json") + .readText() + val casmCode = + Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.casm.json") + .readText() val contractDefinition = Cairo2ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -468,6 +495,11 @@ class StandardAccountTest { maxAmount = Uint64(100000), maxPricePerUnit = Uint128(1000000000000), ), + // TODO: Check if these l2 resources bounds are adequate + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(100000), + maxPricePerUnit = Uint128(1000000000000), + ), ) val declareTransactionPayload = account.signDeclareV3( contractDefinition, @@ -591,6 +623,10 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(20000), + maxPricePerUnit = Uint128(120000000000), + ), ) val payload = account.signV3(call, params) @@ -699,7 +735,12 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ) - val result = account.executeV3(call, l1ResourceBounds).send() + // TODO: Check if these l2 resources bounds are adequate + val l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(20000), + maxPricePerUnit = Uint128(120000000000), + ) + val result = account.executeV3(call, l1ResourceBounds, l2ResourceBounds).send() val receipt = provider.getTransactionReceipt(result.transactionHash).send() @@ -742,6 +783,11 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), + // TODO: Check if these l2 resources bounds are adequate + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(20000), + maxPricePerUnit = Uint128(120000000000), + ), ) val payload = account.signV3(listOf(call, call, call), params) @@ -960,6 +1006,7 @@ class StandardAccountTest { val params = DeployAccountParamsV3( nonce = Felt.ZERO, l1ResourceBounds = ResourceBounds.ZERO, + l2ResourceBounds = ResourceBounds.ZERO, ) val payloadForFeeEstimation = account.signDeployAccountV3( classHash = accountContractClassHash, @@ -1064,9 +1111,16 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ) + // TODO: Check if these l2 resources bounds are adequate + val l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(20000), + maxPricePerUnit = Uint128(120000000000), + ) + val params = DeployAccountParamsV3( nonce = Felt.ZERO, l1ResourceBounds = l1ResourceBounds, + l2ResourceBounds = l2ResourceBounds, ) // Prefund the new account address with STRK @@ -1222,6 +1276,11 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), + // TODO: Check if these l2 resources bounds are adequate + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(20000), + maxPricePerUnit = Uint128(120000000000), + ), ) val invokeTx = account.signV3(call, params) @@ -1247,6 +1306,11 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), + // TODO: Check if these l2 resources bounds are adequate + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(20000), + maxPricePerUnit = Uint128(120000000000), + ), ) val simulationFlags = setOf() @@ -1328,6 +1392,11 @@ class StandardAccountTest { maxAmount = Uint64(100000), maxPricePerUnit = Uint128(1000000000000), ), + // TODO: Check if these l2 resources bounds are adequate + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(100000), + maxPricePerUnit = Uint128(1000000000000), + ), ), ) diff --git a/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt b/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt index 83dc66ebe..a1fb0a35f 100644 --- a/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt +++ b/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt @@ -9,11 +9,13 @@ import org.junit.jupiter.api.assertThrows class FeeUtilsTest { companion object { val estimateFee = EstimateFeeResponse( - gasConsumed = Felt(1000), - gasPrice = Felt(100), - dataGasConsumed = Felt(200), - dataGasPrice = Felt(50), - overallFee = Felt(1000 * 100 + 200 * 50), // 110000 + l1GasConsumed = Felt(1000), + l1GasPrice = Felt(100), + l1DataGasConsumed = Felt(200), + l1DataGasPrice = Felt(50), + l2GasConsumed = Felt(1000), + l2GasPrice = Felt(100), + overallFee = Felt(1000 * 100 + 200 * 50 + 1000 * 100), // 210000 feeUnit = PriceUnit.WEI, ) } @@ -24,21 +26,21 @@ class FeeUtilsTest { fun `estimate fee to max fee - default`() { val result = estimateFee.toMaxFee() - assertEquals(result, Felt(165000)) + assertEquals(result, Felt(315000)) } @Test fun `estimate fee to max fee - specific multiplier`() { val result = estimateFee.toMaxFee(1.13) - assertEquals(result, Felt(124300)) + assertEquals(result, Felt(237300)) } @Test fun `estimate fee to max fee - 1 multiplier`() { val result = estimateFee.toMaxFee(1.0) - assertEquals(result, Felt(110000)) + assertEquals(result, Felt(210000)) } @Test @@ -56,7 +58,11 @@ class FeeUtilsTest { val result = estimateFee.toResourceBounds() val expected = ResourceBoundsMapping( l1Gas = ResourceBounds( - maxAmount = Uint64(1650), + maxAmount = Uint64(3150), + maxPricePerUnit = Uint128(150), + ), + l2Gas = ResourceBounds( + maxAmount = Uint64(3150), maxPricePerUnit = Uint128(150), ), ) @@ -68,7 +74,12 @@ class FeeUtilsTest { val result = estimateFee.toResourceBounds(1.19, 1.13) val expected = ResourceBoundsMapping( l1Gas = ResourceBounds( - maxAmount = Uint64(1309), + maxAmount = Uint64(2499), + maxPricePerUnit = Uint128(113), + ), + // TODO: Check if these l2 resources bounds are adequate + l2Gas = ResourceBounds( + maxAmount = Uint64(2499), maxPricePerUnit = Uint128(113), ), ) @@ -80,8 +91,13 @@ class FeeUtilsTest { val result = estimateFee.toResourceBounds(1.0, 1.0) val expected = ResourceBoundsMapping( l1Gas = ResourceBounds( - maxAmount = Uint64(1100), - maxPricePerUnit = Uint128(100), + maxAmount = Uint64(2499), + maxPricePerUnit = Uint128(113), + ), + // TODO: Check if these l2 resources bounds are adequate + l2Gas = ResourceBounds( + maxAmount = Uint64(2499), + maxPricePerUnit = Uint128(113), ), ) assertEquals(expected, result) diff --git a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt index fef791471..8a4980d03 100644 --- a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt +++ b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt @@ -111,6 +111,11 @@ object StandardDeployerTest { maxAmount = Uint64(50000), maxPricePerUnit = Uint128(100_000_000_000), ), + // TODO: Check if these l2 resources bounds are adequate + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(50000), + maxPricePerUnit = Uint128(100_000_000_000), + ), ).send() val address = standardDeployer.findContractAddress(deployment).send() @@ -164,6 +169,11 @@ object StandardDeployerTest { maxAmount = Uint64(50000), maxPricePerUnit = Uint128(100_000_000_000), ), + // TODO: Check if these l2 resources bounds are adequate + l2ResourceBounds = ResourceBounds( + maxAmount = Uint64(50000), + maxPricePerUnit = Uint128(100_000_000_000), + ), ).send() val address = standardDeployer.findContractAddress(deployment).send() diff --git a/lib/src/test/kotlin/starknet/provider/response/JsonRpcResponseTest.kt b/lib/src/test/kotlin/starknet/provider/response/JsonRpcResponseTest.kt index a0451e899..b8fec05dd 100644 --- a/lib/src/test/kotlin/starknet/provider/response/JsonRpcResponseTest.kt +++ b/lib/src/test/kotlin/starknet/provider/response/JsonRpcResponseTest.kt @@ -24,10 +24,12 @@ class JsonRpcResponseTest { "uknown_key": "value", "result": { "unknown_primitive": "value", - "gas_consumed": "0x1234", - "gas_price": "0x5678", - "data_gas_consumed": "0xabc", - "data_gas_price": "0x789", + "l1_gas_consumed": "0x1234", + "l1_gas_price": "0x5678", + "l2_gas_consumed": "0x1111", + "l2_gas_price": "0x2222", + "l1_data_gas_consumed": "0xabc", + "l1_data_gas_price": "0x789", "overall_fee": "0x9abc", "unknown_object": {"key_1": "value_1", "key_2": "value_2"}, "unit": "FRI", @@ -44,8 +46,10 @@ class JsonRpcResponseTest { val request = provider.getEstimateMessageFee(message, BlockTag.PENDING) val response = request.send() - assertEquals(Felt.fromHex("0x1234"), response.gasConsumed) - assertEquals(Felt.fromHex("0x5678"), response.gasPrice) + assertEquals(Felt.fromHex("0x1234"), response.l1GasConsumed) + assertEquals(Felt.fromHex("0x5678"), response.l1GasPrice) + assertEquals(Felt.fromHex("0x1111"), response.l2GasConsumed) + assertEquals(Felt.fromHex("0x2222"), response.l2GasPrice) assertEquals(Felt.fromHex("0x9abc"), response.overallFee) assertEquals(PriceUnit.FRI, response.feeUnit) diff --git a/lib/src/test/kotlin/starknet/signer/SignerTest.kt b/lib/src/test/kotlin/starknet/signer/SignerTest.kt index 222ca5dc5..899fd62fb 100644 --- a/lib/src/test/kotlin/starknet/signer/SignerTest.kt +++ b/lib/src/test/kotlin/starknet/signer/SignerTest.kt @@ -41,6 +41,11 @@ internal class SignerTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), + // TODO: Check if these l2 resources bounds are adequate + l2Gas = ResourceBounds( + maxAmount = Uint64(20000), + maxPricePerUnit = Uint128(120000000000), + ), ), ) From 625aa24c57109cb8012d28096fbbf47c7e6e0459 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Mon, 21 Oct 2024 01:24:58 +0200 Subject: [PATCH 03/53] Add failure reason to transaction receipt --- .../starknet/data/types/TransactionReceipt.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt index 738d0afe5..fb5b81913 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt @@ -65,6 +65,7 @@ sealed class TransactionReceipt : StarknetResponse { abstract val actualFee: FeePayment abstract val executionStatus: TransactionExecutionStatus abstract val finalityStatus: TransactionFinalityStatus + abstract val failureReason: String? abstract val revertReason: String? abstract val events: List abstract val messagesSent: List @@ -107,6 +108,9 @@ data class InvokeTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, + @SerialName("failure_reason") + override val failureReason: String? = null, + @SerialName("block_hash") override val blockHash: Felt? = null, @@ -169,6 +173,9 @@ data class DeclareTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, + @SerialName("failure_reason") + override val failureReason: String? = null, + @SerialName("block_hash") override val blockHash: Felt? = null, @@ -230,6 +237,9 @@ data class DeployAccountTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, + @SerialName("failure_reason") + override val failureReason: String? = null, + @SerialName("block_hash") override val blockHash: Felt? = null, @@ -297,6 +307,9 @@ data class DeployTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, + @SerialName("failure_reason") + override val failureReason: String? = null, + @SerialName("block_hash") override val blockHash: Felt? = null, @@ -364,6 +377,9 @@ data class L1HandlerTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, + @SerialName("failure_reason") + override val failureReason: String? = null, + @SerialName("block_hash") override val blockHash: Felt? = null, From b0005b65d8c9fad8e11ea32ed49a7b1479ef694a Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Mon, 21 Oct 2024 10:57:24 +0200 Subject: [PATCH 04/53] Add JSON RPC error data classes --- .../serializers/JsonRpcErrorSerializer.kt | 7 +- .../starknet/provider/rpc/JsonRpcError.kt | 211 ++++++++++++++++++ .../starknet/provider/rpc/JsonRpcResponse.kt | 12 - 3 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt index 33175f653..5ee573691 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt @@ -17,7 +17,6 @@ internal object JsonRpcErrorSerializer : KSerializer { val jsonObject = input.decodeJsonElement().jsonObject val code = jsonObject.getValue("code").jsonPrimitive.content.toInt() - val message = jsonObject.getValue("message").jsonPrimitive.content val data = jsonObject["data"]?.let { when (it) { is JsonPrimitive -> it.jsonPrimitive.content @@ -26,11 +25,7 @@ internal object JsonRpcErrorSerializer : KSerializer { } } - return JsonRpcError( - code = code, - message = message, - data = data, - ) + return JsonRpcError.fromCode(code, data) } override val descriptor: SerialDescriptor diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt new file mode 100644 index 000000000..1e2764c7d --- /dev/null +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt @@ -0,0 +1,211 @@ +package com.swmansion.starknet.provider.rpc + +import kotlinx.serialization.Serializable + +@Serializable +sealed class JsonRpcError { + abstract val code: Int + abstract val message: String + abstract val data: String? + + companion object { + fun fromCode(code: Int, data: String?): JsonRpcError { + return when (code) { + 1 -> FailedToReceiveTransactionError(data = data) + 20 -> ContractNotFoundError(data = data) + 24 -> BlockNotFoundError(data = data) + 27 -> InvalidTransactionIndexError(data = data) + 28 -> ClassHashNotFoundError(data = data) + 29 -> TransactionHashNotFoundError(data = data) + 31 -> PageSizeTooBigError(data = data) + 32 -> NoBlocksError(data = data) + 33 -> InvalidContinuationTokenError(data = data) + 34 -> TooManyKeysInFilterError(data = data) + 40 -> ContractError(data = data) + 41 -> TransactionExecutionError(data = data) + else -> throw IllegalArgumentException("Unknown JSON RPC error code: $code") + } + } + } +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class FailedToReceiveTransactionError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 1, + message = "Failed to write transaction", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class ContractNotFoundError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 20, + message = "Contract not found", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class BlockNotFoundError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 24, + message = "Block not found", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class InvalidTransactionIndexError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 27, + message = "Invalid transaction index in a block", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class ClassHashNotFoundError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 28, + message = "Class hash not found", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class TransactionHashNotFoundError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 29, + message = "Transaction hash not found", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class PageSizeTooBigError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 31, + message = "Requested page size is too big", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class NoBlocksError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 32, + message = "There are no blocks", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class InvalidContinuationTokenError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 33, + message = "The supplied continuation token is invalid or unknown", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class TooManyKeysInFilterError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 34, + message = "Too many keys provided in a filter", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class ContractError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 40, + message = "Contract error", + data = data, + ) +} + +@Suppress("DataClassPrivateConstructor") +@Serializable +data class TransactionExecutionError private constructor( + override val code: Int, + override val message: String, + override val data: String? = null, +) : JsonRpcError() { + @JvmOverloads + constructor(data: String? = null) : this( + code = 41, + message = "Transaction execution error", + data = data, + ) +} + diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt index e2a230c5b..15576a7dd 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt @@ -1,6 +1,5 @@ package com.swmansion.starknet.provider.rpc -import com.swmansion.starknet.data.serializers.JsonRpcErrorSerializer import com.swmansion.starknet.data.types.StarknetResponse import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -20,14 +19,3 @@ internal data class JsonRpcResponse( val error: JsonRpcError? = null, ) -@Serializable(with = JsonRpcErrorSerializer::class) -internal data class JsonRpcError( - @SerialName("code") - val code: Int, - - @SerialName("message") - val message: String, - - @SerialName("data") - val data: String? = null, -) From 4587b9d1bec130f3b5676dd26058bdcdbb8feb64 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Mon, 21 Oct 2024 16:38:11 +0200 Subject: [PATCH 05/53] Add contract execution error --- ...ContractExecutionErrorMessageSerializer.kt | 22 ++ ...ractExecutionErrorPolymorphicSerializer.kt | 21 ++ .../serializers/JsonRpcErrorSerializer.kt | 18 +- .../provider/rpc/BuildJsonHttpDeserializer.kt | 12 +- .../starknet/provider/rpc/JsonRpcError.kt | 208 +++++++++++------- 5 files changed, 192 insertions(+), 89 deletions(-) create mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt create mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt new file mode 100644 index 000000000..383426af6 --- /dev/null +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt @@ -0,0 +1,22 @@ +package com.swmansion.starknet.data.serializers + +import com.swmansion.starknet.provider.rpc.ContractExecutionError +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +internal object ContractExecutionErrorMessageSerializer : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ContractExecutionError.ErrorMessage", PrimitiveKind.STRING) + + override fun deserialize(decoder: Decoder): ContractExecutionError.ErrorMessage { + val stringValue = decoder.decodeString() + return ContractExecutionError.ErrorMessage(stringValue) + } + + override fun serialize(encoder: Encoder, value: ContractExecutionError.ErrorMessage) { + encoder.encodeString(value.value) + } +} \ No newline at end of file diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt new file mode 100644 index 000000000..78f464afd --- /dev/null +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt @@ -0,0 +1,21 @@ +package com.swmansion.starknet.data.serializers + +import com.swmansion.starknet.provider.rpc.ContractExecutionError +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject + +internal object ContractExecutionErrorPolymorphicSerializer : JsonContentPolymorphicSerializer( + ContractExecutionError::class, +) { + override fun selectDeserializer(element: JsonElement): DeserializationStrategy { + // TODO: When "revert_error" is string, element is JsonLiteral (which is an internal type) instead of JsonPrimitive. + // This is problematic, because we cannot add branch for JsonLiteral in when statement. + // Currently it is handled by else branch. + return when (element) { + is JsonObject -> ContractExecutionError.InnerCall.serializer() + else -> ContractExecutionErrorMessageSerializer + } + } +} \ No newline at end of file diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt index 5ee573691..fbbbe786e 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt @@ -1,6 +1,6 @@ package com.swmansion.starknet.data.serializers -import com.swmansion.starknet.provider.rpc.JsonRpcError +import com.swmansion.starknet.provider.rpc.* import kotlinx.serialization.KSerializer import kotlinx.serialization.SerializationException import kotlinx.serialization.descriptors.PrimitiveKind @@ -25,7 +25,21 @@ internal object JsonRpcErrorSerializer : KSerializer { } } - return JsonRpcError.fromCode(code, data) + return when (code) { + 1 -> FailedToReceiveTransactionError() + 20 -> ContractNotFoundError() + 24 -> BlockNotFoundError() + 27 -> InvalidTransactionIndexError() + 28 -> ClassHashNotFoundError() + 29 -> TransactionHashNotFoundError() + 31 -> PageSizeTooBigError() + 32 -> NoBlocksError() + 33 -> InvalidContinuationTokenError() + 34 -> TooManyKeysInFilterError() + 40 -> ContractError(data = data!!) + 41 -> TransactionExecutionError(data = data!!) + else -> throw IllegalArgumentException("Unknown JSON RPC error code: $code") + } } override val descriptor: SerialDescriptor diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt index 51a88df1b..8434ae5bf 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt @@ -20,7 +20,11 @@ private fun getResult( RpcRequestFailedException( code = jsonRpcResponse.error.code, message = jsonRpcResponse.error.message, - data = jsonRpcResponse.error.data, + data = when (val error = jsonRpcResponse.error) { + is ContractError -> Json.encodeToString(error.data) + is TransactionExecutionError -> Json.encodeToString(error.data) + else -> null + }, payload = payload, ), ) @@ -78,7 +82,11 @@ internal fun buildJsonHttpDeserializer( throw RpcRequestFailedException( code = jsonRpcResponse.error.code, message = jsonRpcResponse.error.message, - data = jsonRpcResponse.error.data, + data = when (val error = jsonRpcResponse.error) { + is ContractError -> Json.encodeToString(error.data) + is TransactionExecutionError -> Json.encodeToString(error.data) + else -> null + }, payload = response.body, ) } diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt index 1e2764c7d..c3c474f31 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt @@ -1,32 +1,25 @@ package com.swmansion.starknet.provider.rpc -import kotlinx.serialization.Serializable +import com.swmansion.starknet.data.serializers.ContractExecutionErrorPolymorphicSerializer +import com.swmansion.starknet.data.types.Felt +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.SerialName +import kotlinx.serialization.* +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encodeToString +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.* @Serializable -sealed class JsonRpcError { - abstract val code: Int - abstract val message: String - abstract val data: String? - - companion object { - fun fromCode(code: Int, data: String?): JsonRpcError { - return when (code) { - 1 -> FailedToReceiveTransactionError(data = data) - 20 -> ContractNotFoundError(data = data) - 24 -> BlockNotFoundError(data = data) - 27 -> InvalidTransactionIndexError(data = data) - 28 -> ClassHashNotFoundError(data = data) - 29 -> TransactionHashNotFoundError(data = data) - 31 -> PageSizeTooBigError(data = data) - 32 -> NoBlocksError(data = data) - 33 -> InvalidContinuationTokenError(data = data) - 34 -> TooManyKeysInFilterError(data = data) - 40 -> ContractError(data = data) - 41 -> TransactionExecutionError(data = data) - else -> throw IllegalArgumentException("Unknown JSON RPC error code: $code") - } - } - } +sealed interface JsonRpcError { + @SerialName("code") + val code: Int + + @SerialName("message") + val message: String } @Suppress("DataClassPrivateConstructor") @@ -34,13 +27,10 @@ sealed class JsonRpcError { data class FailedToReceiveTransactionError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( +) : JsonRpcError { + constructor() : this( code = 1, message = "Failed to write transaction", - data = data, ) } @@ -49,13 +39,11 @@ data class FailedToReceiveTransactionError private constructor( data class ContractNotFoundError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 20, message = "Contract not found", - data = data, ) } @@ -64,13 +52,11 @@ data class ContractNotFoundError private constructor( data class BlockNotFoundError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 24, message = "Block not found", - data = data, ) } @@ -79,13 +65,11 @@ data class BlockNotFoundError private constructor( data class InvalidTransactionIndexError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 27, message = "Invalid transaction index in a block", - data = data, ) } @@ -94,13 +78,11 @@ data class InvalidTransactionIndexError private constructor( data class ClassHashNotFoundError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 28, message = "Class hash not found", - data = data, ) } @@ -109,13 +91,11 @@ data class ClassHashNotFoundError private constructor( data class TransactionHashNotFoundError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 29, message = "Transaction hash not found", - data = data, ) } @@ -124,13 +104,11 @@ data class TransactionHashNotFoundError private constructor( data class PageSizeTooBigError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 31, message = "Requested page size is too big", - data = data, ) } @@ -139,13 +117,11 @@ data class PageSizeTooBigError private constructor( data class NoBlocksError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 32, message = "There are no blocks", - data = data, ) } @@ -154,13 +130,11 @@ data class NoBlocksError private constructor( data class InvalidContinuationTokenError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + + ) : JsonRpcError { + constructor() : this( code = 33, message = "The supplied continuation token is invalid or unknown", - data = data, ) } @@ -169,13 +143,10 @@ data class InvalidContinuationTokenError private constructor( data class TooManyKeysInFilterError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( +) : JsonRpcError { + constructor() : this( code = 34, message = "Too many keys provided in a filter", - data = data, ) } @@ -184,28 +155,95 @@ data class TooManyKeysInFilterError private constructor( data class ContractError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + val data: ContractExecutionErrorData, +) : JsonRpcError { + constructor(data: String) : this( code = 40, message = "Contract error", - data = data, + data = Json.decodeFromString(data), ) } +@Serializable +data class ContractExecutionErrorData( + @SerialName("revert_error") + val error: ContractExecutionError, +) + @Suppress("DataClassPrivateConstructor") @Serializable data class TransactionExecutionError private constructor( override val code: Int, override val message: String, - override val data: String? = null, -) : JsonRpcError() { - @JvmOverloads - constructor(data: String? = null) : this( + val data: TransactionExecutionErrorData, +) : JsonRpcError { + constructor(data: String) : this( code = 41, message = "Transaction execution error", - data = data, + data = Json.decodeFromString(data), ) } +@Serializable +data class TransactionExecutionErrorData( + @SerialName("transaction_index") + val transactionIndex: Int, + + @SerialName("execution_error") + val error: ContractExecutionError, +) + + +@Serializable(with = ContractExecutionErrorPolymorphicSerializer::class) +sealed class ContractExecutionError { + @Serializable + data class InnerCall( + @SerialName("contract_address") + val contractAddress: Felt, + + @SerialName("class_hash") + val classHash: Felt, + + @SerialName("selector") + val selector: Felt, + + @SerialName("error") + val error: ContractExecutionError, + ) : ContractExecutionError() + + @Serializable + data class ErrorMessage( + val value: String, + ) : ContractExecutionError() +} + + +fun main() { + val json = Json { + prettyPrint = true + } + + val jsonString = """ + { + "contract_address": "0x123", + "class_hash": "0xabc", + "selector": "0xdef", + "error": { + "contract_address": "0x456", + "class_hash": "0xdef", + "selector": "0xabc", + "error": "some basic error text" + } + } + """.trimIndent() + + // Deserialize JSON string to InnerCallError + val result = json.decodeFromString(jsonString) + + // Print the deserialized object + println(result) + + // Serialize it back to JSON + val serialized = json.encodeToString(result) + println(serialized) +} \ No newline at end of file From 5a96c518f25ea7e22fe224e287706c40c27ebbd5 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 01:24:43 +0200 Subject: [PATCH 06/53] Add `failureReason` to `GetTransactionStatusResponse` --- .../main/kotlin/com/swmansion/starknet/data/types/Responses.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 7cf8acd4b..562da7e18 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -145,6 +145,9 @@ data class GetTransactionStatusResponse( @SerialName("execution_status") val executionStatus: TransactionExecutionStatus? = null, + + @SerialName("failure_reason") + val failureReason: String? = null, ) : StarknetResponse @Serializable From d547cb79c8aa875ea16c94860c75bfd4d18332ea Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 01:30:34 +0200 Subject: [PATCH 07/53] Fix linting --- ...ContractExecutionErrorMessageSerializer.kt | 2 +- ...ractExecutionErrorPolymorphicSerializer.kt | 2 +- .../swmansion/starknet/data/types/Params.kt | 8 +++--- .../starknet/provider/rpc/JsonRpcError.kt | 28 +++++++------------ .../starknet/provider/rpc/JsonRpcResponse.kt | 1 - .../data/TransactionHashCalculatorTest.kt | 6 ++-- 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt index 383426af6..ecdd6b097 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt @@ -19,4 +19,4 @@ internal object ContractExecutionErrorMessageSerializer : KSerializer ContractExecutionErrorMessageSerializer } } -} \ No newline at end of file +} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt index f9dc1220e..d992a9025 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt @@ -43,7 +43,7 @@ data class InvokeParamsV3 private constructor( nonce = nonce, resourceBounds = ResourceBoundsMapping( l1Gas = l1ResourceBounds, - l2Gas = l2ResourceBounds + l2Gas = l2ResourceBounds, ), tip = Uint64.ZERO, paymasterData = emptyList(), @@ -71,7 +71,7 @@ data class DeclareParamsV3 private constructor( nonce = nonce, resourceBounds = ResourceBoundsMapping( l1Gas = l1ResourceBounds, - l2Gas = l2ResourceBounds + l2Gas = l2ResourceBounds, ), tip = Uint64.ZERO, paymasterData = emptyList(), @@ -98,12 +98,12 @@ data class DeployAccountParamsV3 private constructor( constructor( nonce: Felt = Felt.ZERO, l1ResourceBounds: ResourceBounds, - l2ResourceBounds: ResourceBounds + l2ResourceBounds: ResourceBounds, ) : this( nonce = nonce, resourceBounds = ResourceBoundsMapping( l1Gas = l1ResourceBounds, - l2Gas = l2ResourceBounds + l2Gas = l2ResourceBounds, ), tip = Uint64.ZERO, paymasterData = emptyList(), diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt index c3c474f31..712b4a91b 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt @@ -2,15 +2,9 @@ package com.swmansion.starknet.provider.rpc import com.swmansion.starknet.data.serializers.ContractExecutionErrorPolymorphicSerializer import com.swmansion.starknet.data.types.Felt -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.SerialName import kotlinx.serialization.* -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.SerialName import kotlinx.serialization.encodeToString -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.* @Serializable @@ -40,7 +34,7 @@ data class ContractNotFoundError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 20, message = "Contract not found", @@ -53,7 +47,7 @@ data class BlockNotFoundError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 24, message = "Block not found", @@ -66,7 +60,7 @@ data class InvalidTransactionIndexError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 27, message = "Invalid transaction index in a block", @@ -79,7 +73,7 @@ data class ClassHashNotFoundError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 28, message = "Class hash not found", @@ -92,7 +86,7 @@ data class TransactionHashNotFoundError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 29, message = "Transaction hash not found", @@ -105,7 +99,7 @@ data class PageSizeTooBigError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 31, message = "Requested page size is too big", @@ -118,7 +112,7 @@ data class NoBlocksError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 32, message = "There are no blocks", @@ -131,7 +125,7 @@ data class InvalidContinuationTokenError private constructor( override val code: Int, override val message: String, - ) : JsonRpcError { +) : JsonRpcError { constructor() : this( code = 33, message = "The supplied continuation token is invalid or unknown", @@ -193,7 +187,6 @@ data class TransactionExecutionErrorData( val error: ContractExecutionError, ) - @Serializable(with = ContractExecutionErrorPolymorphicSerializer::class) sealed class ContractExecutionError { @Serializable @@ -217,7 +210,6 @@ sealed class ContractExecutionError { ) : ContractExecutionError() } - fun main() { val json = Json { prettyPrint = true @@ -246,4 +238,4 @@ fun main() { // Serialize it back to JSON val serialized = json.encodeToString(result) println(serialized) -} \ No newline at end of file +} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt index 15576a7dd..5335d923c 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt @@ -18,4 +18,3 @@ internal data class JsonRpcResponse( @SerialName("error") val error: JsonRpcError? = null, ) - diff --git a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt index 101e69b1b..ef72c5f2d 100644 --- a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt +++ b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt @@ -127,7 +127,7 @@ internal class TransactionHashCalculatorTest { l2Gas = ResourceBounds( maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), - ) + ), ), paymasterData = emptyList(), feeDataAvailabilityMode = DAMode.L1, @@ -157,7 +157,7 @@ internal class TransactionHashCalculatorTest { l2Gas = ResourceBounds( maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), - ) + ), ), tip = Uint64.ZERO, paymasterData = emptyList(), @@ -186,7 +186,7 @@ internal class TransactionHashCalculatorTest { l2Gas = ResourceBounds( maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x2540be400"), - ) + ), ), tip = Uint64.ZERO, paymasterData = emptyList(), From 25fdf9b9e89305777308b573b95033ecc7ecce7a Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 01:47:45 +0200 Subject: [PATCH 08/53] Add `getMessagesStatus` in providers --- .../com/swmansion/starknet/data/types/Payloads.kt | 6 ++++++ .../com/swmansion/starknet/data/types/Responses.kt | 12 ++++++++++++ .../com/swmansion/starknet/provider/Provider.kt | 9 +++++++++ .../starknet/provider/rpc/JsonRpcProvider.kt | 8 ++++++++ 4 files changed, 35 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt index f1b95c6e6..849241b4d 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt @@ -47,6 +47,12 @@ internal data class GetTransactionStatusPayload( val transactionHash: Felt, ) +@Serializable +internal data class GetMessagesStatusPayload( + @SerialName("transaction_hash") + val transactionHash: NumAsHex, +) + @Serializable internal data class EstimateTransactionFeePayload( @SerialName("request") diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 562da7e18..95c4c866e 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -150,6 +150,18 @@ data class GetTransactionStatusResponse( val failureReason: String? = null, ) : StarknetResponse +@Serializable +data class GetMessagesStatueResponse( + @SerialName("transaction_hash") + val transactionHash: Felt, + + @SerialName("finality_status") + val finalityStatus: TransactionStatus, + + @SerialName("failure_reason") + val failureReason: String? = null, +) : StarknetResponse + @Serializable sealed class Syncing : StarknetResponse { abstract val status: Boolean diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index 556897137..acbf6687f 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -321,6 +321,15 @@ interface Provider { fun getTransactionStatus(transactionHash: Felt): Request + /** + * Get L1 handler transaction data. + * + * Get L1 handler transaction data for all L1 → L2 messages sent by the given L1 transaction. + * + */ + fun getMessageStatus(l1TransactionHash: NumAsHex): Request + + /** * Get the contract class definition. * diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index 3e67f9f9f..f4e87df8e 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -270,6 +270,13 @@ class JsonRpcProvider( return buildRequest(JsonRpcMethod.GET_TRANSACTION_STATUS, params, GetTransactionStatusResponse.serializer()) } + override fun getMessageStatus(l1TransactionHash: NumAsHex): Request { + val payload = GetMessagesStatusPayload(l1TransactionHash) + val params = Json.encodeToJsonElement(payload) + + return buildRequest(JsonRpcMethod.GET_MESSAGES_STATUS, params, GetMessagesStatueResponse.serializer()) + } + /** * @sample starknet.account.StandardAccountTest.InvokeTest.signV1SingleCall */ @@ -884,6 +891,7 @@ private enum class JsonRpcMethod(val methodName: String) { GET_TRANSACTION_BY_HASH("starknet_getTransactionByHash"), GET_TRANSACTION_RECEIPT("starknet_getTransactionReceipt"), GET_TRANSACTION_STATUS("starknet_getTransactionStatus"), + GET_MESSAGES_STATUS("starknet_getMessagesStatus"), DECLARE("starknet_addDeclareTransaction"), GET_EVENTS("starknet_getEvents"), GET_BLOCK_NUMBER("starknet_blockNumber"), From 74658de17182c0cc5e8bd3c791e071acc41fbe6d Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 10:51:16 +0200 Subject: [PATCH 09/53] Add todos for `getMessagesStatus` tests --- lib/src/test/kotlin/network/provider/ProviderTest.kt | 5 +++++ lib/src/test/kotlin/starknet/provider/ProviderTest.kt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/lib/src/test/kotlin/network/provider/ProviderTest.kt b/lib/src/test/kotlin/network/provider/ProviderTest.kt index ab5cb9d54..a04992726 100644 --- a/lib/src/test/kotlin/network/provider/ProviderTest.kt +++ b/lib/src/test/kotlin/network/provider/ProviderTest.kt @@ -114,6 +114,11 @@ class ProviderTest { assertEquals(TransactionExecutionStatus.REVERTED, transactionStatus2.executionStatus) } + @Test + fun `get messages status`() { + // TODO + } + @Test fun `get deploy account v1 transaction`() { assumeTrue(NetworkConfig.isTestEnabled(requiresGas = false)) diff --git a/lib/src/test/kotlin/starknet/provider/ProviderTest.kt b/lib/src/test/kotlin/starknet/provider/ProviderTest.kt index 2932ffc49..c1f2903f5 100644 --- a/lib/src/test/kotlin/starknet/provider/ProviderTest.kt +++ b/lib/src/test/kotlin/starknet/provider/ProviderTest.kt @@ -86,6 +86,11 @@ class ProviderTest { assertEquals(TransactionExecutionStatus.SUCCEEDED, transactionStatus.executionStatus) } + @Test + fun getMessagesStatus() { + // TODO + } + @Test fun callContractWithBlockNumber() { val currentNumber = provider.getBlockNumber().send().value From 84f7dc59279dff94476f5e5c970d74b5b67e5f43 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 13:23:40 +0200 Subject: [PATCH 10/53] Add `getStorageProof` in `Provider` --- .../swmansion/starknet/provider/Provider.kt | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index acbf6687f..a2658cb70 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -3,6 +3,8 @@ package com.swmansion.starknet.provider import com.swmansion.starknet.data.types.* import com.swmansion.starknet.provider.exceptions.RequestFailedException +typealias StorageProofClassHash = Felt + /** * Provider for interacting with Starknet. * @@ -326,6 +328,9 @@ interface Provider { * * Get L1 handler transaction data for all L1 → L2 messages sent by the given L1 transaction. * + * @param l1TransactionHash The hash of the L1 transaction. + * + * @throws RequestFailedException */ fun getMessageStatus(l1TransactionHash: NumAsHex): Request @@ -660,6 +665,29 @@ interface Provider { */ fun getNonce(contractAddress: Felt, blockHash: Felt): Request + // TODO: Add KDocs for getStorageProof + fun getStorageProof(classHashes: List, contractAddresses: List, contractsStorageKeys: List): Request + + fun getStorageProof(contractAddresses: List, contractsStorageKeys: List): Request + + // TODO: Resolve overload conflict +// fun getStorageProof(classHashes: List, contractsStorageKeys: List) + + fun getStorageProof(classHashes: List, contractAddresses: List): Request + + fun getStorageProof(classHashes: List): Request + + // TODO: Resolve overload conflict +// fun getStorageProof(contractAddresses: List) + +// TODO: Resolve overload conflict +// fun getStorageProof(contractAddresses: List) + + fun getStorageProof(contractsStorageKeys: List): Request + + fun getStorageProof(): Request + + /** * Get the block synchronization status. * From 5b814672947ce5b4767f471182b92d4cfa1d1bcc Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 14:23:55 +0200 Subject: [PATCH 11/53] Add `GetStorageProofPayload` --- .../com/swmansion/starknet/data/types/Payloads.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt index 849241b4d..729f3bf2a 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt @@ -89,6 +89,18 @@ internal data class GetNoncePayload( override val blockId: BlockId, ) : PayloadWithBlockId() +@Serializable +internal data class GetStorageProofPayload @JvmOverloads constructor( + @SerialName("class_hashes") + val classHashes: List? = null, + + @SerialName("contract_addresses") + val contractAddresses: List? = null, + + @SerialName("contract_storage_keys") + val contractStorageKeys: List? = null, +) + @Serializable internal data class GetBlockWithTransactionsPayload( @SerialName("block_id") From 07a1f6f46437f8973ad1bbadc212990f544454fd Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 14:24:33 +0200 Subject: [PATCH 12/53] Add `StorageProof`, `MerkleNode`, `ChildrenHashes`, `NodeHashToNodeMapping` --- .../starknet/data/types/Responses.kt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 95c4c866e..339024f6d 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -162,6 +162,18 @@ data class GetMessagesStatueResponse( val failureReason: String? = null, ) : StarknetResponse +@Serializable +data class StorageProof( + @SerialName("classes_proof") + val classesProof: NodeHashToNodeMapping, + + @SerialName("contracts_proof") + val contractsProof: NodeHashToNodeMapping, + + @SerialName("contracts_storage_proofs") + val contractsStorageProofs: List, +) : StarknetResponse + @Serializable sealed class Syncing : StarknetResponse { abstract val status: Boolean @@ -410,3 +422,36 @@ enum class L1DAMode { @SerialName("CALLDATA") CALLDATA, } + +@Serializable +data class MerkleNode( + @SerialName("path") + val path: Int, + + @SerialName("length") + val length: Int, + + @SerialName("value") + val value: Felt, + + @SerialName("children_hashes") + val childrenHashes: ChildrenHashes? = null +) + +@Serializable +data class ChildrenHashes( + @SerialName("left") + val left: Felt, + + @SerialName("right") + val right: Felt +) + +@Serializable +data class NodeHashToNodeMapping( + @SerialName("node_hash") + val nodeHash: Felt, + + @SerialName("node") + val node: MerkleNode +) From 12138c66d17a10637d7baf041673426bcafb2501 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 14:24:50 +0200 Subject: [PATCH 13/53] Add `ContractStorageKey` --- .../starknet/data/types/ContractStorageKey.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt new file mode 100644 index 000000000..4e7e86375 --- /dev/null +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt @@ -0,0 +1,13 @@ +package com.swmansion.starknet.data.types + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ContractStorageKey( + @SerialName("contract_address") + val contractAddress: Felt, + + @SerialName("key") + val key: Felt, +) From 06a8fd9812702b40e7afd32336edacbf7a3418b0 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 14:49:20 +0200 Subject: [PATCH 14/53] Refactor `getStorageProof` --- .../swmansion/starknet/provider/Provider.kt | 36 +++++++------------ .../starknet/provider/rpc/JsonRpcProvider.kt | 17 +++++++++ 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index a2658cb70..8c0b1b1a6 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -3,8 +3,6 @@ package com.swmansion.starknet.provider import com.swmansion.starknet.data.types.* import com.swmansion.starknet.provider.exceptions.RequestFailedException -typealias StorageProofClassHash = Felt - /** * Provider for interacting with Starknet. * @@ -665,28 +663,18 @@ interface Provider { */ fun getNonce(contractAddress: Felt, blockHash: Felt): Request - // TODO: Add KDocs for getStorageProof - fun getStorageProof(classHashes: List, contractAddresses: List, contractsStorageKeys: List): Request - - fun getStorageProof(contractAddresses: List, contractsStorageKeys: List): Request - - // TODO: Resolve overload conflict -// fun getStorageProof(classHashes: List, contractsStorageKeys: List) - - fun getStorageProof(classHashes: List, contractAddresses: List): Request - - fun getStorageProof(classHashes: List): Request - - // TODO: Resolve overload conflict -// fun getStorageProof(contractAddresses: List) - -// TODO: Resolve overload conflict -// fun getStorageProof(contractAddresses: List) - - fun getStorageProof(contractsStorageKeys: List): Request - - fun getStorageProof(): Request - + /** + * Get merkle paths in one of the state tries. + * + * Get merkle paths in one of the state tries: global state, classes, individual contract. + * + * @param classHashes list of class hashes for which we want to prove membership + * @param contractAddresses list of contract addresses for which we want to prove membership + * @param contractsStorageKeys list of contract address and storage keys pairs + * + * @throws RequestFailedException + */ + fun getStorageProof(classHashes: List? = null, contractAddresses: List? = null, contractsStorageKeys: List? = null): Request /** * Get the block synchronization status. diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index f4e87df8e..cf82b698b 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -653,6 +653,22 @@ class JsonRpcProvider( return getNonce(payload) } + private fun getStorageProof(payload: GetStorageProofPayload): HttpRequest { + val jsonPayload = Json.encodeToJsonElement(payload) + + return buildRequest(JsonRpcMethod.GET_STORAGE_PROOF, jsonPayload, StorageProof.serializer()) + } + + override fun getStorageProof ( + classHashes: List?, + contractAddresses: List?, + contractsStorageKeys: List?, + ): Request { + val payload = GetStorageProofPayload(classHashes, contractAddresses, contractsStorageKeys) + + return getStorageProof(payload) + } + /** * @sample starknet.provider.ProviderTest.getSyncInformationNodeNotSyncing */ @@ -907,6 +923,7 @@ private enum class JsonRpcMethod(val methodName: String) { GET_STATE_UPDATE("starknet_getStateUpdate"), GET_TRANSACTION_BY_BLOCK_ID_AND_INDEX("starknet_getTransactionByBlockIdAndIndex"), GET_NONCE("starknet_getNonce"), + GET_STORAGE_PROOF("starknet_getStorageProof"), DEPLOY_ACCOUNT_TRANSACTION("starknet_addDeployAccountTransaction"), SIMULATE_TRANSACTIONS("starknet_simulateTransactions"), } From 31f798c68c921d523a9652282c633f336baed2c1 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 15:00:11 +0200 Subject: [PATCH 15/53] Add `getStorageProof` test with todo --- lib/src/test/kotlin/network/provider/ProviderTest.kt | 5 +++++ lib/src/test/kotlin/starknet/provider/ProviderTest.kt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/lib/src/test/kotlin/network/provider/ProviderTest.kt b/lib/src/test/kotlin/network/provider/ProviderTest.kt index a04992726..51a041fae 100644 --- a/lib/src/test/kotlin/network/provider/ProviderTest.kt +++ b/lib/src/test/kotlin/network/provider/ProviderTest.kt @@ -96,6 +96,11 @@ class ProviderTest { assertEquals(expectedChainId, chainId) } + @Test + fun `get storage proof`() { + // TODO + } + @Test fun `get transaction status`() { assumeTrue(NetworkConfig.isTestEnabled(requiresGas = false)) diff --git a/lib/src/test/kotlin/starknet/provider/ProviderTest.kt b/lib/src/test/kotlin/starknet/provider/ProviderTest.kt index c1f2903f5..2d9054978 100644 --- a/lib/src/test/kotlin/starknet/provider/ProviderTest.kt +++ b/lib/src/test/kotlin/starknet/provider/ProviderTest.kt @@ -820,6 +820,11 @@ class ProviderTest { assertNotNull(response) } + @Test + fun getStorageProof() { + // TODO + } + @Test fun `get pending block with transactions`() { // TODO (#304): We should also test for 'pending' tag, but atm they are not supported in devnet From 0842ce5c222970354d64dee16ef7541f7466f040 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 15:56:28 +0200 Subject: [PATCH 16/53] Fix linting --- .../kotlin/com/swmansion/starknet/data/types/Responses.kt | 6 +++--- .../main/kotlin/com/swmansion/starknet/provider/Provider.kt | 1 - .../com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 339024f6d..996c84ebe 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -435,7 +435,7 @@ data class MerkleNode( val value: Felt, @SerialName("children_hashes") - val childrenHashes: ChildrenHashes? = null + val childrenHashes: ChildrenHashes? = null, ) @Serializable @@ -444,7 +444,7 @@ data class ChildrenHashes( val left: Felt, @SerialName("right") - val right: Felt + val right: Felt, ) @Serializable @@ -453,5 +453,5 @@ data class NodeHashToNodeMapping( val nodeHash: Felt, @SerialName("node") - val node: MerkleNode + val node: MerkleNode, ) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index 8c0b1b1a6..bdb447ec1 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -332,7 +332,6 @@ interface Provider { */ fun getMessageStatus(l1TransactionHash: NumAsHex): Request - /** * Get the contract class definition. * diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index cf82b698b..1174be039 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -659,7 +659,7 @@ class JsonRpcProvider( return buildRequest(JsonRpcMethod.GET_STORAGE_PROOF, jsonPayload, StorageProof.serializer()) } - override fun getStorageProof ( + override fun getStorageProof( classHashes: List?, contractAddresses: List?, contractsStorageKeys: List?, From c77b48b92980b8db3fafeeed4a28e812e7efc80d Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 16:42:26 +0200 Subject: [PATCH 17/53] Remove error-related changes --- ...ContractExecutionErrorMessageSerializer.kt | 22 -- ...ractExecutionErrorPolymorphicSerializer.kt | 21 -- .../serializers/JsonRpcErrorSerializer.kt | 23 +- .../provider/rpc/BuildJsonHttpDeserializer.kt | 12 +- .../starknet/provider/rpc/JsonRpcError.kt | 241 ------------------ .../starknet/provider/rpc/JsonRpcResponse.kt | 13 + 6 files changed, 22 insertions(+), 310 deletions(-) delete mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt delete mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt delete mode 100644 lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt deleted file mode 100644 index ecdd6b097..000000000 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorMessageSerializer.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.swmansion.starknet.data.serializers - -import com.swmansion.starknet.provider.rpc.ContractExecutionError -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -internal object ContractExecutionErrorMessageSerializer : KSerializer { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ContractExecutionError.ErrorMessage", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): ContractExecutionError.ErrorMessage { - val stringValue = decoder.decodeString() - return ContractExecutionError.ErrorMessage(stringValue) - } - - override fun serialize(encoder: Encoder, value: ContractExecutionError.ErrorMessage) { - encoder.encodeString(value.value) - } -} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt deleted file mode 100644 index 9a03cd984..000000000 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/ContractExecutionErrorPolymorphicSerializer.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.swmansion.starknet.data.serializers - -import com.swmansion.starknet.provider.rpc.ContractExecutionError -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.json.JsonContentPolymorphicSerializer -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject - -internal object ContractExecutionErrorPolymorphicSerializer : JsonContentPolymorphicSerializer( - ContractExecutionError::class, -) { - override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - // TODO: When "revert_error" is string, element is JsonLiteral (which is an internal type) instead of JsonPrimitive. - // This is problematic, because we cannot add branch for JsonLiteral in when statement. - // Currently it is handled by else branch. - return when (element) { - is JsonObject -> ContractExecutionError.InnerCall.serializer() - else -> ContractExecutionErrorMessageSerializer - } - } -} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt index fbbbe786e..33175f653 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/JsonRpcErrorSerializer.kt @@ -1,6 +1,6 @@ package com.swmansion.starknet.data.serializers -import com.swmansion.starknet.provider.rpc.* +import com.swmansion.starknet.provider.rpc.JsonRpcError import kotlinx.serialization.KSerializer import kotlinx.serialization.SerializationException import kotlinx.serialization.descriptors.PrimitiveKind @@ -17,6 +17,7 @@ internal object JsonRpcErrorSerializer : KSerializer { val jsonObject = input.decodeJsonElement().jsonObject val code = jsonObject.getValue("code").jsonPrimitive.content.toInt() + val message = jsonObject.getValue("message").jsonPrimitive.content val data = jsonObject["data"]?.let { when (it) { is JsonPrimitive -> it.jsonPrimitive.content @@ -25,21 +26,11 @@ internal object JsonRpcErrorSerializer : KSerializer { } } - return when (code) { - 1 -> FailedToReceiveTransactionError() - 20 -> ContractNotFoundError() - 24 -> BlockNotFoundError() - 27 -> InvalidTransactionIndexError() - 28 -> ClassHashNotFoundError() - 29 -> TransactionHashNotFoundError() - 31 -> PageSizeTooBigError() - 32 -> NoBlocksError() - 33 -> InvalidContinuationTokenError() - 34 -> TooManyKeysInFilterError() - 40 -> ContractError(data = data!!) - 41 -> TransactionExecutionError(data = data!!) - else -> throw IllegalArgumentException("Unknown JSON RPC error code: $code") - } + return JsonRpcError( + code = code, + message = message, + data = data, + ) } override val descriptor: SerialDescriptor diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt index 8434ae5bf..51a88df1b 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/BuildJsonHttpDeserializer.kt @@ -20,11 +20,7 @@ private fun getResult( RpcRequestFailedException( code = jsonRpcResponse.error.code, message = jsonRpcResponse.error.message, - data = when (val error = jsonRpcResponse.error) { - is ContractError -> Json.encodeToString(error.data) - is TransactionExecutionError -> Json.encodeToString(error.data) - else -> null - }, + data = jsonRpcResponse.error.data, payload = payload, ), ) @@ -82,11 +78,7 @@ internal fun buildJsonHttpDeserializer( throw RpcRequestFailedException( code = jsonRpcResponse.error.code, message = jsonRpcResponse.error.message, - data = when (val error = jsonRpcResponse.error) { - is ContractError -> Json.encodeToString(error.data) - is TransactionExecutionError -> Json.encodeToString(error.data) - else -> null - }, + data = jsonRpcResponse.error.data, payload = response.body, ) } diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt deleted file mode 100644 index 712b4a91b..000000000 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcError.kt +++ /dev/null @@ -1,241 +0,0 @@ -package com.swmansion.starknet.provider.rpc - -import com.swmansion.starknet.data.serializers.ContractExecutionErrorPolymorphicSerializer -import com.swmansion.starknet.data.types.Felt -import kotlinx.serialization.* -import kotlinx.serialization.SerialName -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.* - -@Serializable -sealed interface JsonRpcError { - @SerialName("code") - val code: Int - - @SerialName("message") - val message: String -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class FailedToReceiveTransactionError private constructor( - override val code: Int, - override val message: String, -) : JsonRpcError { - constructor() : this( - code = 1, - message = "Failed to write transaction", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class ContractNotFoundError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 20, - message = "Contract not found", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class BlockNotFoundError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 24, - message = "Block not found", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class InvalidTransactionIndexError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 27, - message = "Invalid transaction index in a block", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class ClassHashNotFoundError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 28, - message = "Class hash not found", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class TransactionHashNotFoundError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 29, - message = "Transaction hash not found", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class PageSizeTooBigError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 31, - message = "Requested page size is too big", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class NoBlocksError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 32, - message = "There are no blocks", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class InvalidContinuationTokenError private constructor( - override val code: Int, - override val message: String, - -) : JsonRpcError { - constructor() : this( - code = 33, - message = "The supplied continuation token is invalid or unknown", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class TooManyKeysInFilterError private constructor( - override val code: Int, - override val message: String, -) : JsonRpcError { - constructor() : this( - code = 34, - message = "Too many keys provided in a filter", - ) -} - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class ContractError private constructor( - override val code: Int, - override val message: String, - val data: ContractExecutionErrorData, -) : JsonRpcError { - constructor(data: String) : this( - code = 40, - message = "Contract error", - data = Json.decodeFromString(data), - ) -} - -@Serializable -data class ContractExecutionErrorData( - @SerialName("revert_error") - val error: ContractExecutionError, -) - -@Suppress("DataClassPrivateConstructor") -@Serializable -data class TransactionExecutionError private constructor( - override val code: Int, - override val message: String, - val data: TransactionExecutionErrorData, -) : JsonRpcError { - constructor(data: String) : this( - code = 41, - message = "Transaction execution error", - data = Json.decodeFromString(data), - ) -} - -@Serializable -data class TransactionExecutionErrorData( - @SerialName("transaction_index") - val transactionIndex: Int, - - @SerialName("execution_error") - val error: ContractExecutionError, -) - -@Serializable(with = ContractExecutionErrorPolymorphicSerializer::class) -sealed class ContractExecutionError { - @Serializable - data class InnerCall( - @SerialName("contract_address") - val contractAddress: Felt, - - @SerialName("class_hash") - val classHash: Felt, - - @SerialName("selector") - val selector: Felt, - - @SerialName("error") - val error: ContractExecutionError, - ) : ContractExecutionError() - - @Serializable - data class ErrorMessage( - val value: String, - ) : ContractExecutionError() -} - -fun main() { - val json = Json { - prettyPrint = true - } - - val jsonString = """ - { - "contract_address": "0x123", - "class_hash": "0xabc", - "selector": "0xdef", - "error": { - "contract_address": "0x456", - "class_hash": "0xdef", - "selector": "0xabc", - "error": "some basic error text" - } - } - """.trimIndent() - - // Deserialize JSON string to InnerCallError - val result = json.decodeFromString(jsonString) - - // Print the deserialized object - println(result) - - // Serialize it back to JSON - val serialized = json.encodeToString(result) - println(serialized) -} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt index 5335d923c..e2a230c5b 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcResponse.kt @@ -1,5 +1,6 @@ package com.swmansion.starknet.provider.rpc +import com.swmansion.starknet.data.serializers.JsonRpcErrorSerializer import com.swmansion.starknet.data.types.StarknetResponse import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -18,3 +19,15 @@ internal data class JsonRpcResponse( @SerialName("error") val error: JsonRpcError? = null, ) + +@Serializable(with = JsonRpcErrorSerializer::class) +internal data class JsonRpcError( + @SerialName("code") + val code: Int, + + @SerialName("message") + val message: String, + + @SerialName("data") + val data: String? = null, +) From 66838749e06dbc38a812c341901e8b552696375a Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 16:43:10 +0200 Subject: [PATCH 18/53] Add missing params in KDoc --- lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt b/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt index 915c67288..7947e7758 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt @@ -188,6 +188,8 @@ interface Account { * @param calldata constructor calldata for the contract deployment * @param salt salt used to calculate address of the new contract * @param forFeeEstimate when set to `true`, it changes the version to `2^128+version` so the signed transaction can only be used for fee estimation + * @param l1ResourceBounds L1 resource bounds for the transaction + * @param l2ResourceBounds L2 resource bounds for the transaction * @return signed deploy account payload */ fun signDeployAccountV3( @@ -214,6 +216,8 @@ interface Account { * @param classHash hash of the contract that will be deployed. Has to be declared first! * @param calldata constructor calldata for the contract deployment * @param salt salt used to calculate address of the new contract + * @param l1ResourceBounds L1 resource bounds for the transaction + * @param l2ResourceBounds L2 resource bounds for the transaction * @return signed deploy account payload */ fun signDeployAccountV3( From ddea0387a00a177db356ad9c1533a0e81b3d9af9 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Tue, 22 Oct 2024 18:17:35 +0200 Subject: [PATCH 19/53] Update tests --- .../starknet/data/types/ExecutionResources.kt | 2 - .../starknet/account/StandardAccountTest.kt | 10 +-- .../deployercontract/StandardDeployerTest.kt | 5 +- .../kotlin/starknet/provider/ProviderTest.kt | 79 +++++++------------ 4 files changed, 36 insertions(+), 60 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt index eb3eb9f24..eaf9bcecb 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt @@ -1,5 +1,3 @@ -@file:JvmName("Resources") - package com.swmansion.starknet.data.types import kotlinx.serialization.SerialName diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index 278efdc73..54a52f1b2 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -495,10 +495,9 @@ class StandardAccountTest { maxAmount = Uint64(100000), maxPricePerUnit = Uint128(1000000000000), ), - // TODO: Check if these l2 resources bounds are adequate l2ResourceBounds = ResourceBounds( - maxAmount = Uint64(100000), - maxPricePerUnit = Uint128(1000000000000), + maxAmount = Uint64(0), + maxPricePerUnit = Uint128(0), ), ) val declareTransactionPayload = account.signDeclareV3( @@ -1111,10 +1110,9 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ) - // TODO: Check if these l2 resources bounds are adequate val l2ResourceBounds = ResourceBounds( - maxAmount = Uint64(20000), - maxPricePerUnit = Uint128(120000000000), + maxAmount = Uint64(0), + maxPricePerUnit = Uint128(0), ) val params = DeployAccountParamsV3( diff --git a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt index 8a4980d03..e34c03000 100644 --- a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt +++ b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt @@ -111,10 +111,9 @@ object StandardDeployerTest { maxAmount = Uint64(50000), maxPricePerUnit = Uint128(100_000_000_000), ), - // TODO: Check if these l2 resources bounds are adequate l2ResourceBounds = ResourceBounds( - maxAmount = Uint64(50000), - maxPricePerUnit = Uint128(100_000_000_000), + maxAmount = Uint64(0), + maxPricePerUnit = Uint128(0), ), ).send() val address = standardDeployer.findContractAddress(deployment).send() diff --git a/lib/src/test/kotlin/starknet/provider/ProviderTest.kt b/lib/src/test/kotlin/starknet/provider/ProviderTest.kt index 2d9054978..fd140fba7 100644 --- a/lib/src/test/kotlin/starknet/provider/ProviderTest.kt +++ b/lib/src/test/kotlin/starknet/provider/ProviderTest.kt @@ -342,19 +342,9 @@ class ProviderTest { [], "execution_resources": { - "steps": "999", - "memory_holes": "1", - "range_check_builtin_applications": "21", - "pedersen_builtin_applications": "37", - "poseidon_builtin_applications": "451", - "ec_op_builtin_applications": "123", - "ecdsa_builtin_applications": "789", - "bitwise_builtin_applications": "1", - "keccak_builtin_applications": "1", - "data_availability": { - "l1_gas": "123", - "l1_data_gas": "456" - } + "l1_gas": "123", + "l1_data_gas": "456", + "l2_gas": "789" } } } @@ -411,19 +401,9 @@ class ProviderTest { "finality_status": "ACCEPTED_ON_L2", "execution_resources": { - "steps": "999", - "memory_holes": "1", - "range_check_builtin_applications": "21", - "pedersen_builtin_applications": "37", - "poseidon_builtin_applications": "451", - "ec_op_builtin_applications": "123", - "ecdsa_builtin_applications": "789", - "bitwise_builtin_applications": "1", - "keccak_builtin_applications": "1", - "data_availability": { - "l1_gas": "123", - "l1_data_gas": "456" - } + "l1_gas": "123", + "l1_data_gas": "456", + "l2_gas": "789" } } } @@ -494,19 +474,9 @@ class ProviderTest { ], "execution_resources": { - "steps": "999", - "memory_holes": "1", - "range_check_builtin_applications": "21", - "pedersen_builtin_applications": "37", - "poseidon_builtin_applications": "451", - "ec_op_builtin_applications": "123", - "ecdsa_builtin_applications": "789", - "bitwise_builtin_applications": "1", - "keccak_builtin_applications": "1", - "data_availability": { - "l1_gas": "123", - "l1_data_gas": "456" - } + "l1_gas": "123", + "l1_data_gas": "456", + "l2_gas": "789" }, "message_hash": "0x8000000000000110000000000000000000000000000000000000011111111111" } @@ -841,6 +811,11 @@ class ProviderTest { "price_in_wei": "0x2137", "price_in_fri": "0x1234" }, + "l2_gas_price": + { + "price_in_wei": "0x123", + "price_in_fri": "0x456" + }, "l1_data_gas_price": { "price_in_wei": "0x789", @@ -931,6 +906,11 @@ class ProviderTest { "price_in_wei": "0x2137", "price_in_fri": "0x1234" }, + "l2_gas_price": + { + "price_in_wei": "0x123", + "price_in_fri": "0x456" + }, "l1_data_gas_price": { "price_in_wei": "0x789", @@ -971,11 +951,9 @@ class ProviderTest { [], "execution_resources": { - "steps": "999", - "data_availability": { - "l1_gas": "123", - "l1_data_gas": "456" - } + "l1_gas": "123", + "l1_data_gas": "456", + "l2_gas": "789" } } }, @@ -1009,11 +987,9 @@ class ProviderTest { [], "execution_resources": { - "steps": "999", - "data_availability": { - "l1_gas": "123", - "l1_data_gas": "456" - } + "l1_gas": "123", + "l1_data_gas": "456", + "l2_gas": "789" } } } @@ -1078,6 +1054,11 @@ class ProviderTest { "price_in_wei": "0x2137", "price_in_fri": "0x1234" }, + "l2_gas_price": + { + "price_in_wei": "0x123", + "price_in_fri": "0x456" + }, "l1_data_gas_price": { "price_in_wei": "0x789", From a1358d9e144d71a12f68eade88b8c98ff26dc77a Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Wed, 23 Oct 2024 08:50:38 +0200 Subject: [PATCH 20/53] Rename todo; Fix `getMessagesStatus` name --- lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt | 2 +- .../com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt | 2 +- .../swmansion/starknet/data/TransactionHashCalculatorTest.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index bdb447ec1..cb7356b2d 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -330,7 +330,7 @@ interface Provider { * * @throws RequestFailedException */ - fun getMessageStatus(l1TransactionHash: NumAsHex): Request + fun getMessagesStatus(l1TransactionHash: NumAsHex): Request /** * Get the contract class definition. diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index 1174be039..c87973d8d 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -270,7 +270,7 @@ class JsonRpcProvider( return buildRequest(JsonRpcMethod.GET_TRANSACTION_STATUS, params, GetTransactionStatusResponse.serializer()) } - override fun getMessageStatus(l1TransactionHash: NumAsHex): Request { + override fun getMessagesStatus(l1TransactionHash: NumAsHex): Request { val payload = GetMessagesStatusPayload(l1TransactionHash) val params = Json.encodeToJsonElement(payload) diff --git a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt index ef72c5f2d..1f31aeecf 100644 --- a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt +++ b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt @@ -182,7 +182,7 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x2540be400"), ), - // TODO: Check if these resources bounds are adequate + // TODO: Adjust these resources bounds once devnet and integration are updated l2Gas = ResourceBounds( maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x2540be400"), From 74f35a20f2034070df3f631453b06703ecc81b6a Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Wed, 23 Oct 2024 11:20:36 +0200 Subject: [PATCH 21/53] Rename todos --- .../starknet/data/TransactionHashCalculatorTest.kt | 4 ++-- lib/src/test/kotlin/network/account/AccountTest.kt | 2 +- .../kotlin/starknet/account/StandardAccountTest.kt | 10 +++++----- lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt | 4 ++-- .../starknet/deployercontract/StandardDeployerTest.kt | 2 +- lib/src/test/kotlin/starknet/signer/SignerTest.kt | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt index 1f31aeecf..e27a6644c 100644 --- a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt +++ b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt @@ -123,7 +123,7 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2Gas = ResourceBounds( maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), @@ -153,7 +153,7 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2Gas = ResourceBounds( maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), diff --git a/lib/src/test/kotlin/network/account/AccountTest.kt b/lib/src/test/kotlin/network/account/AccountTest.kt index e99b58387..0a8a4a672 100644 --- a/lib/src/test/kotlin/network/account/AccountTest.kt +++ b/lib/src/test/kotlin/network/account/AccountTest.kt @@ -270,7 +270,7 @@ class AccountTest { maxAmount = Uint64(100000), maxPricePerUnit = Uint128(2500000000000), ) - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests val l2ResourceBounds = ResourceBounds( maxAmount = Uint64(100000), maxPricePerUnit = Uint128(2500000000000), diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index 54a52f1b2..e85f1073f 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -734,7 +734,7 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ) - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests val l2ResourceBounds = ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), @@ -782,7 +782,7 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2ResourceBounds = ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), @@ -1274,7 +1274,7 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2ResourceBounds = ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), @@ -1304,7 +1304,7 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2ResourceBounds = ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), @@ -1390,7 +1390,7 @@ class StandardAccountTest { maxAmount = Uint64(100000), maxPricePerUnit = Uint128(1000000000000), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2ResourceBounds = ResourceBounds( maxAmount = Uint64(100000), maxPricePerUnit = Uint128(1000000000000), diff --git a/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt b/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt index a1fb0a35f..40bc90982 100644 --- a/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt +++ b/lib/src/test/kotlin/starknet/crypto/FeeUtilsTest.kt @@ -77,7 +77,7 @@ class FeeUtilsTest { maxAmount = Uint64(2499), maxPricePerUnit = Uint128(113), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2Gas = ResourceBounds( maxAmount = Uint64(2499), maxPricePerUnit = Uint128(113), @@ -94,7 +94,7 @@ class FeeUtilsTest { maxAmount = Uint64(2499), maxPricePerUnit = Uint128(113), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2Gas = ResourceBounds( maxAmount = Uint64(2499), maxPricePerUnit = Uint128(113), diff --git a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt index e34c03000..aedc5abaa 100644 --- a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt +++ b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt @@ -168,7 +168,7 @@ object StandardDeployerTest { maxAmount = Uint64(50000), maxPricePerUnit = Uint128(100_000_000_000), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2ResourceBounds = ResourceBounds( maxAmount = Uint64(50000), maxPricePerUnit = Uint128(100_000_000_000), diff --git a/lib/src/test/kotlin/starknet/signer/SignerTest.kt b/lib/src/test/kotlin/starknet/signer/SignerTest.kt index 899fd62fb..f410bf3d7 100644 --- a/lib/src/test/kotlin/starknet/signer/SignerTest.kt +++ b/lib/src/test/kotlin/starknet/signer/SignerTest.kt @@ -41,7 +41,7 @@ internal class SignerTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), - // TODO: Check if these l2 resources bounds are adequate + // TODO: Check if these l2 resources need to be updated once we can add tests l2Gas = ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), From 13d81ad61e986467363aedfcad40b6f406512f1f Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Wed, 23 Oct 2024 16:16:13 +0200 Subject: [PATCH 22/53] Fix `NodeHashToNodeMapping` --- .../kotlin/com/swmansion/starknet/data/types/Responses.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 996c84ebe..99261e70c 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -6,6 +6,7 @@ import com.swmansion.starknet.extensions.* import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonNames import java.math.BigInteger import kotlin.math.roundToInt @@ -447,8 +448,10 @@ data class ChildrenHashes( val right: Felt, ) +typealias NodeHashToNodeMapping = List + @Serializable -data class NodeHashToNodeMapping( +data class NodeHashToNodeMappingItem( @SerialName("node_hash") val nodeHash: Felt, From 9097231e2ec09f91043f7f7ce2977f202902f284 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Wed, 23 Oct 2024 16:16:33 +0200 Subject: [PATCH 23/53] Fix linting --- .../main/kotlin/com/swmansion/starknet/data/types/Responses.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 99261e70c..d39144340 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -6,7 +6,6 @@ import com.swmansion.starknet.extensions.* import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonNames import java.math.BigInteger import kotlin.math.roundToInt From 54d16f6cad03940a219254d7abfd80ce4a657ddc Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 00:54:48 +0200 Subject: [PATCH 24/53] Update `getStorageProof` --- .../starknet/data/types/ContractStorageKey.kt | 4 +- .../swmansion/starknet/data/types/Payloads.kt | 3 + .../starknet/data/types/Responses.kt | 186 ++++++++++++++---- .../swmansion/starknet/provider/Provider.kt | 3 +- .../starknet/provider/rpc/JsonRpcProvider.kt | 3 +- 5 files changed, 162 insertions(+), 37 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt index 4e7e86375..ebaa65495 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ContractStorageKey.kt @@ -8,6 +8,6 @@ data class ContractStorageKey( @SerialName("contract_address") val contractAddress: Felt, - @SerialName("key") - val key: Felt, + @SerialName("storage_keys") + val key: List, ) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt index 729f3bf2a..3c44dbd38 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt @@ -91,6 +91,9 @@ internal data class GetNoncePayload( @Serializable internal data class GetStorageProofPayload @JvmOverloads constructor( + @SerialName("block_id") + val blockId: BlockId, + @SerialName("class_hashes") val classHashes: List? = null, diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index d39144340..d598b30e7 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -6,10 +6,14 @@ import com.swmansion.starknet.extensions.* import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonNames import java.math.BigInteger import kotlin.math.roundToInt +typealias NodeHashToNodeMapping = List + + @Serializable data class CallContractResponse( val result: List, @@ -168,12 +172,78 @@ data class StorageProof( val classesProof: NodeHashToNodeMapping, @SerialName("contracts_proof") - val contractsProof: NodeHashToNodeMapping, + val contractsProof: ContractsProof, @SerialName("contracts_storage_proofs") val contractsStorageProofs: List, + + @SerialName("global_roots") + val globalRoots: GlobalRoots ) : StarknetResponse +@Serializable +data class GlobalRoots( + @SerialName("contracts_tree_root") + val contractsTreeRoot: Felt, + + @SerialName("classes_tree_root") + val classesTreeRoot: Felt, + + @SerialName("block_hash") + val blockHash: Felt +) + +@Serializable +data class MerkleNode( + @SerialName("path") + val path: Int, + + @SerialName("length") + val length: Int, + + @SerialName("value") + val value: Felt, + + @SerialName("children_hashes") + val childrenHashes: ChildrenHashes? = null, +) + +@Serializable +data class ChildrenHashes( + @SerialName("left") + val left: Felt, + + @SerialName("right") + val right: Felt, +) + +@Serializable +data class ContractsProof( + @SerialName("nodes") + val nodes: NodeHashToNodeMapping, + + @SerialName("contract_leaves_data") + val contractLeavesData: List +) + +@Serializable +data class ContractLeafData( + @SerialName("nonce") + val nonce: Felt, + + @SerialName("class_hash") + val classHash: Felt +) + +@Serializable +data class NodeHashToNodeMappingItem( + @SerialName("node_hash") + val nodeHash: Felt, + + @SerialName("node") + val node: MerkleNode, +) + @Serializable sealed class Syncing : StarknetResponse { abstract val status: Boolean @@ -423,37 +493,87 @@ enum class L1DAMode { CALLDATA, } -@Serializable -data class MerkleNode( - @SerialName("path") - val path: Int, - - @SerialName("length") - val length: Int, - - @SerialName("value") - val value: Felt, - - @SerialName("children_hashes") - val childrenHashes: ChildrenHashes? = null, -) - -@Serializable -data class ChildrenHashes( - @SerialName("left") - val left: Felt, - - @SerialName("right") - val right: Felt, -) - -typealias NodeHashToNodeMapping = List +fun main() { + println("Hello, World!") + val x = """ + { + "classes_proof": [ + { + "node_hash": "0x1a2b3c4d", + "node": { + "path": 1, + "length": 256, + "value": "0x123456789abcdef", + "children_hashes": { + "left": "0xaaaabbbbcccc", + "right": "0xdddddeeeeeffff" + } + } + }, + { + "node_hash": "0x2b3c4d5e", + "node": { + "path": 2, + "length": 128, + "value": "0xabcdef123456789", + "children_hashes": null + } + } + ], + "contracts_proof": [ + { + "node_hash": "0x3c4d5e6f", + "node": { + "path": 3, + "length": 64, + "value": "0x9876543210fedcba", + "children_hashes": { + "left": "0xbbbbccccdddd", + "right": "0xeeeeffffaaaa" + } + } + } + ], + "contracts_storage_proofs": [ + [ + { + "node_hash": "0x4d5e6f7a", + "node": { + "path": 4, + "length": 32, + "value": "0x1fedcba987654321", + "children_hashes": { + "left": "0xccccddddbbbb", + "right": "0xffffaaaabbbb" + } + } + } + ], + [ + { + "node_hash": "0x5e6f7a8b", + "node": { + "path": 5, + "length": 16, + "value": "0x123123123456", + "children_hashes": null + } + }, + { + "node_hash": "0x5e6f7a8b", + "node": { + "path": 5, + "length": 16, + "value": "0x123123123456", + "children_hashes": null + } + } + ] + ] +} -@Serializable -data class NodeHashToNodeMappingItem( - @SerialName("node_hash") - val nodeHash: Felt, + """.trimIndent() - @SerialName("node") - val node: MerkleNode, -) + val storageProof = Json.decodeFromString(StorageProof.serializer(), x) + print(storageProof) +} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index cb7356b2d..7548dc0b5 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -667,13 +667,14 @@ interface Provider { * * Get merkle paths in one of the state tries: global state, classes, individual contract. * + * @param blockId the hash of the requested block * @param classHashes list of class hashes for which we want to prove membership * @param contractAddresses list of contract addresses for which we want to prove membership * @param contractsStorageKeys list of contract address and storage keys pairs * * @throws RequestFailedException */ - fun getStorageProof(classHashes: List? = null, contractAddresses: List? = null, contractsStorageKeys: List? = null): Request + fun getStorageProof(blockId: BlockId, classHashes: List? = null, contractAddresses: List? = null, contractsStorageKeys: List? = null): Request /** * Get the block synchronization status. diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index c87973d8d..a070db018 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -660,11 +660,12 @@ class JsonRpcProvider( } override fun getStorageProof( + blockId: BlockId, classHashes: List?, contractAddresses: List?, contractsStorageKeys: List?, ): Request { - val payload = GetStorageProofPayload(classHashes, contractAddresses, contractsStorageKeys) + val payload = GetStorageProofPayload(blockId, classHashes, contractAddresses, contractsStorageKeys) return getStorageProof(payload) } From bbd417c51c7fa147994e7b4ed2b4804183c33e1d Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 00:55:04 +0200 Subject: [PATCH 25/53] Fix linting --- .../com/swmansion/starknet/data/types/Responses.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index d598b30e7..61b8c42df 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -13,7 +13,6 @@ import kotlin.math.roundToInt typealias NodeHashToNodeMapping = List - @Serializable data class CallContractResponse( val result: List, @@ -178,7 +177,7 @@ data class StorageProof( val contractsStorageProofs: List, @SerialName("global_roots") - val globalRoots: GlobalRoots + val globalRoots: GlobalRoots, ) : StarknetResponse @Serializable @@ -190,7 +189,7 @@ data class GlobalRoots( val classesTreeRoot: Felt, @SerialName("block_hash") - val blockHash: Felt + val blockHash: Felt, ) @Serializable @@ -223,7 +222,7 @@ data class ContractsProof( val nodes: NodeHashToNodeMapping, @SerialName("contract_leaves_data") - val contractLeavesData: List + val contractLeavesData: List, ) @Serializable @@ -232,7 +231,7 @@ data class ContractLeafData( val nonce: Felt, @SerialName("class_hash") - val classHash: Felt + val classHash: Felt, ) @Serializable From b34bb5243874c8b4759a3c30b41b8061fea8996e Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 00:57:21 +0200 Subject: [PATCH 26/53] Fix typo in `GetMessagesStatusResponse` --- .../kotlin/com/swmansion/starknet/data/types/Responses.kt | 2 +- .../main/kotlin/com/swmansion/starknet/provider/Provider.kt | 2 +- .../com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 61b8c42df..a09947745 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -154,7 +154,7 @@ data class GetTransactionStatusResponse( ) : StarknetResponse @Serializable -data class GetMessagesStatueResponse( +data class GetMessagesStatusResponse( @SerialName("transaction_hash") val transactionHash: Felt, diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index 7548dc0b5..8f9bbffb5 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -330,7 +330,7 @@ interface Provider { * * @throws RequestFailedException */ - fun getMessagesStatus(l1TransactionHash: NumAsHex): Request + fun getMessagesStatus(l1TransactionHash: NumAsHex): Request /** * Get the contract class definition. diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index a070db018..b59a6d724 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -270,11 +270,11 @@ class JsonRpcProvider( return buildRequest(JsonRpcMethod.GET_TRANSACTION_STATUS, params, GetTransactionStatusResponse.serializer()) } - override fun getMessagesStatus(l1TransactionHash: NumAsHex): Request { + override fun getMessagesStatus(l1TransactionHash: NumAsHex): Request { val payload = GetMessagesStatusPayload(l1TransactionHash) val params = Json.encodeToJsonElement(payload) - return buildRequest(JsonRpcMethod.GET_MESSAGES_STATUS, params, GetMessagesStatueResponse.serializer()) + return buildRequest(JsonRpcMethod.GET_MESSAGES_STATUS, params, GetMessagesStatusResponse.serializer()) } /** From 4bf6139baf084a59f76b71702342d34997f0025d Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 01:10:21 +0200 Subject: [PATCH 27/53] Refactor `getMessagesStatus` --- .../swmansion/starknet/provider/rpc/JsonRpcProvider.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index b59a6d724..ad5d9ddf5 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -270,13 +270,18 @@ class JsonRpcProvider( return buildRequest(JsonRpcMethod.GET_TRANSACTION_STATUS, params, GetTransactionStatusResponse.serializer()) } - override fun getMessagesStatus(l1TransactionHash: NumAsHex): Request { - val payload = GetMessagesStatusPayload(l1TransactionHash) + private fun getMessagesStatus(payload: GetMessagesStatusPayload): HttpRequest { val params = Json.encodeToJsonElement(payload) return buildRequest(JsonRpcMethod.GET_MESSAGES_STATUS, params, GetMessagesStatusResponse.serializer()) } + override fun getMessagesStatus(l1TransactionHash: NumAsHex): Request { + val payload = GetMessagesStatusPayload(l1TransactionHash) + + return getMessagesStatus(payload) + } + /** * @sample starknet.account.StandardAccountTest.InvokeTest.signV1SingleCall */ From 97796fade379a540795901e86ab524b0500590ce Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 01:11:11 +0200 Subject: [PATCH 28/53] Update todo text --- .../swmansion/starknet/data/TransactionHashCalculatorTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt index e27a6644c..d9725069b 100644 --- a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt +++ b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt @@ -182,7 +182,7 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x2540be400"), ), - // TODO: Adjust these resources bounds once devnet and integration are updated + // TODO: Check if these l2 resources need to be updated once we can add tests l2Gas = ResourceBounds( maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x2540be400"), From 475a7f76b260acea323c270fa3f295780d7fdeb6 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 01:17:21 +0200 Subject: [PATCH 29/53] Fix transaction hash calculator tests --- .../data/TransactionHashCalculatorTest.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt index d9725069b..f8d059ec9 100644 --- a/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt +++ b/lib/src/test/kotlin/com/swmansion/starknet/data/TransactionHashCalculatorTest.kt @@ -123,10 +123,10 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), ), - // TODO: Check if these l2 resources need to be updated once we can add tests + // TODO: Check if these l2 can be equal to 0 l2Gas = ResourceBounds( - maxAmount = Uint64.fromHex("0x186a0"), - maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), + maxAmount = Uint64.ZERO, + maxPricePerUnit = Uint128.ZERO, ), ), paymasterData = emptyList(), @@ -153,10 +153,10 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), ), - // TODO: Check if these l2 resources need to be updated once we can add tests + // TODO: Check if these l2 can be equal to 0 l2Gas = ResourceBounds( - maxAmount = Uint64.fromHex("0x186a0"), - maxPricePerUnit = Uint128.fromHex("0x5af3107a4000"), + maxAmount = Uint64.ZERO, + maxPricePerUnit = Uint128.ZERO, ), ), tip = Uint64.ZERO, @@ -182,10 +182,10 @@ internal class TransactionHashCalculatorTest { maxAmount = Uint64.fromHex("0x186a0"), maxPricePerUnit = Uint128.fromHex("0x2540be400"), ), - // TODO: Check if these l2 resources need to be updated once we can add tests + // TODO: Check if these l2 can be equal to 0 l2Gas = ResourceBounds( - maxAmount = Uint64.fromHex("0x186a0"), - maxPricePerUnit = Uint128.fromHex("0x2540be400"), + maxAmount = Uint64.ZERO, + maxPricePerUnit = Uint128.ZERO, ), ), tip = Uint64.ZERO, From 9a55b1818c77367a8839f74f87e70f3f176a1ab1 Mon Sep 17 00:00:00 2001 From: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:55:08 +0200 Subject: [PATCH 30/53] Update lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt Co-authored-by: Maksim Zdobnikau <43750648+DelevoXDG@users.noreply.github.com> --- .../main/kotlin/com/swmansion/starknet/data/types/Responses.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index a09947745..3e7df829a 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -92,7 +92,7 @@ data class EstimateFeeResponse( * Calculates max amount l2 as maxAmountL2 = [overallFee] / [l2GasPrice], unless [l2GasPrice] is 0, then maxAmountL2 is 0. * Calculates max price per unit l1 as maxPricePerUnitL1 = [l1GasPrice]. * Calculates max price per unit l2 as maxPricePerUnitL2 = [l2GasPrice]. - * Then multiplies maxAmountL1/L2 by round([amountMultiplier] * 100%) and maxPricePerUnitL1/L2 by round([unitPriceMultiplier] * 100%) and performs integer division by 100 on both. + * Then multiplies maxAmountL1/L2 by round([amountMultiplier] * 100%) and maxPricePerUnitL1/L2 by round([unitPriceMultiplier] * 100%) and performs integer division by 100 on each. * * @param amountMultiplier Multiplier for max amount, defaults to 1.5. * @param unitPriceMultiplier Multiplier for max price per unit, defaults to 1.5. From 836a456c55a91aa67fdaf040d70897e7f3c385b1 Mon Sep 17 00:00:00 2001 From: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:56:20 +0200 Subject: [PATCH 31/53] Update lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt Co-authored-by: Maksim Zdobnikau <43750648+DelevoXDG@users.noreply.github.com> --- .../main/kotlin/com/swmansion/starknet/data/types/Payloads.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt index 3c44dbd38..6583acb4e 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Payloads.kt @@ -90,7 +90,7 @@ internal data class GetNoncePayload( ) : PayloadWithBlockId() @Serializable -internal data class GetStorageProofPayload @JvmOverloads constructor( +internal data class GetStorageProofPayload constructor( @SerialName("block_id") val blockId: BlockId, From b7349734800ed97d0ae0c1b8a6f725dc3163a177 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 12:46:19 +0200 Subject: [PATCH 32/53] Fix `GetMessagesStatusResponse` --- .../main/kotlin/com/swmansion/starknet/data/types/Responses.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index a09947745..a129de1cf 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -12,6 +12,7 @@ import java.math.BigInteger import kotlin.math.roundToInt typealias NodeHashToNodeMapping = List +typealias GetMessagesStatusResponse = List @Serializable data class CallContractResponse( @@ -154,7 +155,7 @@ data class GetTransactionStatusResponse( ) : StarknetResponse @Serializable -data class GetMessagesStatusResponse( +data class MessagesStatus( @SerialName("transaction_hash") val transactionHash: Felt, From 2725046fb6630456c94865b392693490db01d0f7 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 15:50:27 +0200 Subject: [PATCH 33/53] Add `MessageStatusList` data class and serializer --- .../MessageStatusListSerializer.kt | 27 ++++++ .../starknet/data/types/MessageStatusList.kt | 8 ++ .../starknet/data/types/Responses.kt | 89 +------------------ .../swmansion/starknet/provider/Provider.kt | 2 +- .../starknet/provider/rpc/JsonRpcProvider.kt | 8 +- 5 files changed, 42 insertions(+), 92 deletions(-) create mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/serializers/MessageStatusListSerializer.kt create mode 100644 lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/MessageStatusListSerializer.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/MessageStatusListSerializer.kt new file mode 100644 index 000000000..d54fa3f12 --- /dev/null +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/serializers/MessageStatusListSerializer.kt @@ -0,0 +1,27 @@ +package com.swmansion.starknet.data.serializers + +import com.swmansion.starknet.data.types.MessageStatus +import com.swmansion.starknet.data.types.MessageStatusList +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.listSerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +internal object MessageStatusListSerializer : KSerializer { + private val listSerializer = ListSerializer(MessageStatus.serializer()) + + @OptIn(ExperimentalSerializationApi::class) + override val descriptor: SerialDescriptor = listSerialDescriptor() + + override fun serialize(encoder: Encoder, value: MessageStatusList) { + encoder.encodeSerializableValue(listSerializer, value.values) + } + + override fun deserialize(decoder: Decoder): MessageStatusList { + val list = decoder.decodeSerializableValue(listSerializer) + return MessageStatusList(list) + } +} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt new file mode 100644 index 000000000..2a939da08 --- /dev/null +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt @@ -0,0 +1,8 @@ +package com.swmansion.starknet.data.types + +import com.swmansion.starknet.data.serializers.MessageStatusListSerializer +import com.swmansion.starknet.data.serializers.SimulatedTransactionListSerializer +import kotlinx.serialization.Serializable + +@Serializable(with = MessageStatusListSerializer::class) +data class MessageStatusList(val values: List) : StarknetResponse diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 84c17ff5b..d23ea3659 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -6,13 +6,11 @@ import com.swmansion.starknet.extensions.* import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonNames import java.math.BigInteger import kotlin.math.roundToInt typealias NodeHashToNodeMapping = List -typealias GetMessagesStatusResponse = List @Serializable data class CallContractResponse( @@ -155,7 +153,7 @@ data class GetTransactionStatusResponse( ) : StarknetResponse @Serializable -data class MessagesStatus( +data class MessageStatus( @SerialName("transaction_hash") val transactionHash: Felt, @@ -492,88 +490,3 @@ enum class L1DAMode { @SerialName("CALLDATA") CALLDATA, } - -fun main() { - println("Hello, World!") - val x = """ - { - "classes_proof": [ - { - "node_hash": "0x1a2b3c4d", - "node": { - "path": 1, - "length": 256, - "value": "0x123456789abcdef", - "children_hashes": { - "left": "0xaaaabbbbcccc", - "right": "0xdddddeeeeeffff" - } - } - }, - { - "node_hash": "0x2b3c4d5e", - "node": { - "path": 2, - "length": 128, - "value": "0xabcdef123456789", - "children_hashes": null - } - } - ], - "contracts_proof": [ - { - "node_hash": "0x3c4d5e6f", - "node": { - "path": 3, - "length": 64, - "value": "0x9876543210fedcba", - "children_hashes": { - "left": "0xbbbbccccdddd", - "right": "0xeeeeffffaaaa" - } - } - } - ], - "contracts_storage_proofs": [ - [ - { - "node_hash": "0x4d5e6f7a", - "node": { - "path": 4, - "length": 32, - "value": "0x1fedcba987654321", - "children_hashes": { - "left": "0xccccddddbbbb", - "right": "0xffffaaaabbbb" - } - } - } - ], - [ - { - "node_hash": "0x5e6f7a8b", - "node": { - "path": 5, - "length": 16, - "value": "0x123123123456", - "children_hashes": null - } - }, - { - "node_hash": "0x5e6f7a8b", - "node": { - "path": 5, - "length": 16, - "value": "0x123123123456", - "children_hashes": null - } - } - ] - ] -} - - """.trimIndent() - - val storageProof = Json.decodeFromString(StorageProof.serializer(), x) - print(storageProof) -} diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt index 8f9bbffb5..301a142e2 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/Provider.kt @@ -330,7 +330,7 @@ interface Provider { * * @throws RequestFailedException */ - fun getMessagesStatus(l1TransactionHash: NumAsHex): Request + fun getMessagesStatus(l1TransactionHash: NumAsHex): Request /** * Get the contract class definition. diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index ad5d9ddf5..24b1d7e2d 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -6,12 +6,14 @@ import com.swmansion.starknet.data.serializers.BlockWithTransactionsPolymorphicS import com.swmansion.starknet.data.serializers.SyncPolymorphicSerializer import com.swmansion.starknet.data.serializers.TransactionReceiptPolymorphicSerializer import com.swmansion.starknet.data.types.* +import com.swmansion.starknet.data.types.MessageStatusList import com.swmansion.starknet.provider.Provider import com.swmansion.starknet.provider.Request import com.swmansion.starknet.service.http.* import com.swmansion.starknet.service.http.requests.HttpBatchRequest import com.swmansion.starknet.service.http.requests.HttpRequest import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.* /** @@ -270,13 +272,13 @@ class JsonRpcProvider( return buildRequest(JsonRpcMethod.GET_TRANSACTION_STATUS, params, GetTransactionStatusResponse.serializer()) } - private fun getMessagesStatus(payload: GetMessagesStatusPayload): HttpRequest { + private fun getMessagesStatus(payload: GetMessagesStatusPayload): HttpRequest { val params = Json.encodeToJsonElement(payload) - return buildRequest(JsonRpcMethod.GET_MESSAGES_STATUS, params, GetMessagesStatusResponse.serializer()) + return buildRequest(JsonRpcMethod.GET_MESSAGES_STATUS, params, MessageStatusListSerializer) } - override fun getMessagesStatus(l1TransactionHash: NumAsHex): Request { + override fun getMessagesStatus(l1TransactionHash: NumAsHex): HttpRequest { val payload = GetMessagesStatusPayload(l1TransactionHash) return getMessagesStatus(payload) From 18ad358c5ff22a8dd31ec85bba9f9da24499d881 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 15:50:47 +0200 Subject: [PATCH 34/53] Fix linting --- .../com/swmansion/starknet/data/types/MessageStatusList.kt | 1 - .../com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt index 2a939da08..cf83317c3 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/MessageStatusList.kt @@ -1,7 +1,6 @@ package com.swmansion.starknet.data.types import com.swmansion.starknet.data.serializers.MessageStatusListSerializer -import com.swmansion.starknet.data.serializers.SimulatedTransactionListSerializer import kotlinx.serialization.Serializable @Serializable(with = MessageStatusListSerializer::class) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index 24b1d7e2d..675cee279 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -13,7 +13,6 @@ import com.swmansion.starknet.service.http.* import com.swmansion.starknet.service.http.requests.HttpBatchRequest import com.swmansion.starknet.service.http.requests.HttpRequest import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.* /** @@ -272,7 +271,7 @@ class JsonRpcProvider( return buildRequest(JsonRpcMethod.GET_TRANSACTION_STATUS, params, GetTransactionStatusResponse.serializer()) } - private fun getMessagesStatus(payload: GetMessagesStatusPayload): HttpRequest { + private fun getMessagesStatus(payload: GetMessagesStatusPayload): HttpRequest { val params = Json.encodeToJsonElement(payload) return buildRequest(JsonRpcMethod.GET_MESSAGES_STATUS, params, MessageStatusListSerializer) From 54d4402f33c39abf35cff81fcd7e3f09e74cda3e Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 15:53:39 +0200 Subject: [PATCH 35/53] Change return type of `getStorageProof` to `HttpRequest` --- .../com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt index 675cee279..ab944e18f 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/provider/rpc/JsonRpcProvider.kt @@ -670,7 +670,7 @@ class JsonRpcProvider( classHashes: List?, contractAddresses: List?, contractsStorageKeys: List?, - ): Request { + ): HttpRequest { val payload = GetStorageProofPayload(blockId, classHashes, contractAddresses, contractsStorageKeys) return getStorageProof(payload) From 8688732d3fb4c62b27a92a04fc9b7c183a5ed4ff Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 16:22:23 +0200 Subject: [PATCH 36/53] Refactor `NodeHashToNodeMappingItem`; Add `BinaryNode` and `EdgeNode` --- .../starknet/data/types/Responses.kt | 71 +++++++++---------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index d23ea3659..76db049ed 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -177,43 +177,19 @@ data class StorageProof( @SerialName("global_roots") val globalRoots: GlobalRoots, -) : StarknetResponse - -@Serializable -data class GlobalRoots( - @SerialName("contracts_tree_root") - val contractsTreeRoot: Felt, - - @SerialName("classes_tree_root") - val classesTreeRoot: Felt, - - @SerialName("block_hash") - val blockHash: Felt, -) - -@Serializable -data class MerkleNode( - @SerialName("path") - val path: Int, - - @SerialName("length") - val length: Int, - - @SerialName("value") - val value: Felt, - - @SerialName("children_hashes") - val childrenHashes: ChildrenHashes? = null, -) +) : StarknetResponse { + @Serializable + data class GlobalRoots( + @SerialName("contracts_tree_root") + val contractsTreeRoot: Felt, -@Serializable -data class ChildrenHashes( - @SerialName("left") - val left: Felt, + @SerialName("classes_tree_root") + val classesTreeRoot: Felt, - @SerialName("right") - val right: Felt, -) + @SerialName("block_hash") + val blockHash: Felt, + ) +} @Serializable data class ContractsProof( @@ -240,7 +216,30 @@ data class NodeHashToNodeMappingItem( @SerialName("node") val node: MerkleNode, -) +) { + @Serializable + sealed interface MerkleNode + + @Serializable + data class BinaryNode( + @SerialName("left") + val left: Felt, + + @SerialName("right") + val right: Felt, + ) : MerkleNode + @Serializable + data class EdgeNode( + @SerialName("path") + val path: Int, + + @SerialName("length") + val length: Int, + + @SerialName("child") + val value: Felt, + ) : MerkleNode +} @Serializable sealed class Syncing : StarknetResponse { From 797911f417fb4a619f7ff53d3ddba82ad875c895 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 16:22:34 +0200 Subject: [PATCH 37/53] Fix linting --- .../main/kotlin/com/swmansion/starknet/data/types/Responses.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index 76db049ed..eb19c892d 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -228,6 +228,7 @@ data class NodeHashToNodeMappingItem( @SerialName("right") val right: Felt, ) : MerkleNode + @Serializable data class EdgeNode( @SerialName("path") From 11d2eaae152c8ed6f188c2be8e7827ac6d749084 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 16:33:36 +0200 Subject: [PATCH 38/53] Remove unnecessarily added failure reason from tx receipt --- .../starknet/data/types/TransactionReceipt.kt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt index fb5b81913..738d0afe5 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/TransactionReceipt.kt @@ -65,7 +65,6 @@ sealed class TransactionReceipt : StarknetResponse { abstract val actualFee: FeePayment abstract val executionStatus: TransactionExecutionStatus abstract val finalityStatus: TransactionFinalityStatus - abstract val failureReason: String? abstract val revertReason: String? abstract val events: List abstract val messagesSent: List @@ -108,9 +107,6 @@ data class InvokeTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, - @SerialName("failure_reason") - override val failureReason: String? = null, - @SerialName("block_hash") override val blockHash: Felt? = null, @@ -173,9 +169,6 @@ data class DeclareTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, - @SerialName("failure_reason") - override val failureReason: String? = null, - @SerialName("block_hash") override val blockHash: Felt? = null, @@ -237,9 +230,6 @@ data class DeployAccountTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, - @SerialName("failure_reason") - override val failureReason: String? = null, - @SerialName("block_hash") override val blockHash: Felt? = null, @@ -307,9 +297,6 @@ data class DeployTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, - @SerialName("failure_reason") - override val failureReason: String? = null, - @SerialName("block_hash") override val blockHash: Felt? = null, @@ -377,9 +364,6 @@ data class L1HandlerTransactionReceipt private constructor( @SerialName("finality_status") override val finalityStatus: TransactionFinalityStatus, - @SerialName("failure_reason") - override val failureReason: String? = null, - @SerialName("block_hash") override val blockHash: Felt? = null, From 66143804bd7f52c22aa3ae85e7c722147529d6f5 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 16:55:23 +0200 Subject: [PATCH 39/53] Refactor passing resource bounds --- .../com/swmansion/starknet/account/Account.kt | 28 ++++++--------- .../starknet/account/StandardAccount.kt | 14 ++++---- .../swmansion/starknet/data/types/Params.kt | 8 ++--- .../starknet/deployercontract/Deployer.kt | 12 +++---- .../deployercontract/StandardDeployer.kt | 9 +++-- .../kotlin/network/account/AccountTest.kt | 9 ++--- .../starknet/account/StandardAccountTest.kt | 28 +++++++++------ .../deployercontract/StandardDeployerTest.kt | 34 +++++++++++-------- 8 files changed, 70 insertions(+), 72 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt b/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt index 7947e7758..a74960f9b 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/account/Account.kt @@ -188,22 +188,19 @@ interface Account { * @param calldata constructor calldata for the contract deployment * @param salt salt used to calculate address of the new contract * @param forFeeEstimate when set to `true`, it changes the version to `2^128+version` so the signed transaction can only be used for fee estimation - * @param l1ResourceBounds L1 resource bounds for the transaction - * @param l2ResourceBounds L2 resource bounds for the transaction + * @param resourceBounds L1 and L2 resource bounds for the transaction * @return signed deploy account payload */ fun signDeployAccountV3( classHash: Felt, calldata: Calldata, salt: Felt, - l1ResourceBounds: ResourceBounds, - l2ResourceBounds: ResourceBounds, + resourceBounds: ResourceBoundsMapping, forFeeEstimate: Boolean, ): DeployAccountTransactionV3 { val params = DeployAccountParamsV3( nonce = Felt.ZERO, - l1ResourceBounds = l1ResourceBounds, - l2ResourceBounds = l2ResourceBounds, + resourceBounds = resourceBounds, ) return signDeployAccountV3(classHash, calldata, salt, params, forFeeEstimate) } @@ -216,21 +213,18 @@ interface Account { * @param classHash hash of the contract that will be deployed. Has to be declared first! * @param calldata constructor calldata for the contract deployment * @param salt salt used to calculate address of the new contract - * @param l1ResourceBounds L1 resource bounds for the transaction - * @param l2ResourceBounds L2 resource bounds for the transaction + * @param resourceBounds L1 and L2 resource bounds for the transaction * @return signed deploy account payload */ fun signDeployAccountV3( classHash: Felt, calldata: Calldata, salt: Felt, - l1ResourceBounds: ResourceBounds, - l2ResourceBounds: ResourceBounds, + resourceBounds: ResourceBoundsMapping, ): DeployAccountTransactionV3 { val params = DeployAccountParamsV3( nonce = Felt.ZERO, - l1ResourceBounds = l1ResourceBounds, - l2ResourceBounds = l2ResourceBounds, + resourceBounds = resourceBounds, ) return signDeployAccountV3(classHash, calldata, salt, params, false) } @@ -341,11 +335,10 @@ interface Account { * Execute list of calls on Starknet. * * @param calls a list of calls to be executed. - * @param l1ResourceBounds L1 resource bounds for the transaction. - * @param l2ResourceBounds L2 resource bounds for the transaction. + * @param resourceBounds L1 and L2 resource bounds for the transaction * @return Invoke function response, containing transaction hash. */ - fun executeV3(calls: List, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request + fun executeV3(calls: List, resourceBounds: ResourceBoundsMapping): Request /** * Execute single call using version 1 invoke transaction. @@ -364,11 +357,10 @@ interface Account { * Execute single call on Starknet. * * @param call a call to be executed. - * @param l1ResourceBounds L1 resource bounds for the transaction. - * @param l2ResourceBounds L2 resource bounds for the transaction. + * @param resourceBounds L1 and L2 resource bounds for the transaction * @return Invoke function response, containing transaction hash. */ - fun executeV3(call: Call, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request + fun executeV3(call: Call, resourceBounds: ResourceBoundsMapping): Request /** * Execute a list of calls using version 1 invoke transaction with automatically estimated fee diff --git a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt index 5c9112cd6..9b9b14bd2 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt @@ -314,12 +314,12 @@ class StandardAccount @JvmOverloads constructor( } } - override fun executeV3(calls: List, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request { + override fun executeV3(calls: List, resourceBounds: ResourceBoundsMapping): Request { return getNonce().compose { nonce -> val signParams = InvokeParamsV3( nonce = nonce, - l1ResourceBounds = l1ResourceBounds, - l2ResourceBounds = l2ResourceBounds, + l1ResourceBounds = resourceBounds.l1Gas, + l2ResourceBounds = resourceBounds.l2Gas, ) val payload = signV3(calls, signParams, false) @@ -344,7 +344,7 @@ class StandardAccount @JvmOverloads constructor( amountMultiplier = estimateAmountMultiplier, unitPriceMultiplier = estimateUnitPriceMultiplier, ) - executeV3(calls, resourceBounds.l1Gas, resourceBounds.l2Gas) + executeV3(calls, resourceBounds) } } @@ -364,7 +364,7 @@ class StandardAccount @JvmOverloads constructor( override fun executeV3(calls: List): Request { return estimateFeeV3(calls).compose { estimateFee -> val resourceBounds = estimateFee.values.first().toResourceBounds() - executeV3(calls, resourceBounds.l1Gas, resourceBounds.l2Gas) + executeV3(calls, resourceBounds) } } @@ -372,8 +372,8 @@ class StandardAccount @JvmOverloads constructor( return executeV1(listOf(call), maxFee) } - override fun executeV3(call: Call, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request { - return executeV3(listOf(call), l1ResourceBounds, l2ResourceBounds) + override fun executeV3(call: Call, resourceBounds: ResourceBoundsMapping): Request { + return executeV3(listOf(call), resourceBounds) } override fun executeV1(call: Call, estimateFeeMultiplier: Double): Request { diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt index d992a9025..238949d33 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt @@ -97,14 +97,10 @@ data class DeployAccountParamsV3 private constructor( @JvmOverloads constructor( nonce: Felt = Felt.ZERO, - l1ResourceBounds: ResourceBounds, - l2ResourceBounds: ResourceBounds, + resourceBounds: ResourceBoundsMapping, ) : this( nonce = nonce, - resourceBounds = ResourceBoundsMapping( - l1Gas = l1ResourceBounds, - l2Gas = l2ResourceBounds, - ), + resourceBounds = resourceBounds, tip = Uint64.ZERO, paymasterData = emptyList(), nonceDataAvailabilityMode = DAMode.L1, diff --git a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt index 43152182e..eac1b86c0 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt @@ -3,6 +3,7 @@ package com.swmansion.starknet.deployercontract import com.swmansion.starknet.data.types.Calldata import com.swmansion.starknet.data.types.Felt import com.swmansion.starknet.data.types.ResourceBounds +import com.swmansion.starknet.data.types.ResourceBoundsMapping import com.swmansion.starknet.provider.Request import com.swmansion.starknet.provider.exceptions.RequestFailedException @@ -48,8 +49,7 @@ interface Deployer { * @param unique set whether deployed contract address should be based on account address or not * @param salt a salt to be used to calculate deployed contract address * @param constructorCalldata constructor calldata - * @param l1ResourceBounds L1 resource bounds for the transaction - * @param l2ResourceBounds L2 resource bounds for the transaction + * @param resourceBounds L1 and L2 resource bounds for the transaction * * @throws RequestFailedException * @@ -60,8 +60,7 @@ interface Deployer { unique: Boolean, salt: Felt, constructorCalldata: Calldata, - l1ResourceBounds: ResourceBounds, - l2ResourceBounds: ResourceBounds, + resourceBounds: ResourceBoundsMapping, ): Request /** @@ -123,15 +122,14 @@ interface Deployer { * * @param classHash a class hash of the declared contract * @param constructorCalldata constructor calldata - * @param l1ResourceBounds L1 resource bounds for the transaction - * @param l2ResourceBounds L2 resource bounds for the transaction + * @param resourceBounds L1 and L2 resource bounds for the transaction * * @throws RequestFailedException * @throws SaltGenerationFailedException * * @sample starknet.deployercontract.StandardDeployerTest.testUdcDeployV3WithSpecificFeeAndDefaultParameters */ - fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request + fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, resourceBounds: ResourceBoundsMapping): Request /** * Deploy a contract through Universal Deployer Contract (UDC) using version 1 invoke transaction diff --git a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt index 3b5d6094d..18ebe7c81 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt @@ -31,12 +31,11 @@ class StandardDeployer( unique: Boolean, salt: Felt, constructorCalldata: Calldata, - l1ResourceBounds: ResourceBounds, - l2ResourceBounds: ResourceBounds, + resourceBounds: ResourceBoundsMapping ): Request { val call = buildDeployContractCall(classHash, unique, salt, constructorCalldata) - return account.executeV3(call, l1ResourceBounds, l2ResourceBounds).map { ContractDeployment(it.transactionHash) } + return account.executeV3(call, resourceBounds).map { ContractDeployment(it.transactionHash) } } override fun deployContractV1( @@ -66,9 +65,9 @@ class StandardDeployer( return deployContractV1(classHash, true, salt, constructorCalldata, maxFee) } - override fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds): Request { + override fun deployContractV3(classHash: Felt, constructorCalldata: Calldata, resourceBounds: ResourceBoundsMapping): Request { val salt = randomSalt() - return deployContractV3(classHash, true, salt, constructorCalldata, l1ResourceBounds, l2ResourceBounds) + return deployContractV3(classHash, true, salt, constructorCalldata, resourceBounds) } override fun deployContractV1(classHash: Felt, constructorCalldata: Calldata): Request { diff --git a/lib/src/test/kotlin/network/account/AccountTest.kt b/lib/src/test/kotlin/network/account/AccountTest.kt index 0a8a4a672..cae93dfdd 100644 --- a/lib/src/test/kotlin/network/account/AccountTest.kt +++ b/lib/src/test/kotlin/network/account/AccountTest.kt @@ -555,8 +555,10 @@ class AccountTest { calldata = calldata, params = DeployAccountParamsV3( nonce = Felt.ZERO, - l1ResourceBounds = ResourceBounds.ZERO, - l2ResourceBounds = ResourceBounds.ZERO, + resourceBounds = ResourceBoundsMapping( + ResourceBounds.ZERO, + ResourceBounds.ZERO, + ), ), forFeeEstimate = true, // BUG: (#344) this should be true, but Pathfinder and Devnet claim that using query version produce invalid signature ) @@ -581,8 +583,7 @@ class AccountTest { val params = DeployAccountParamsV3( nonce = Felt.ZERO, - l1ResourceBounds = resourceBounds.l1Gas, - l2ResourceBounds = resourceBounds.l2Gas, + resourceBounds = resourceBounds, ) val payload = deployedAccount.signDeployAccountV3( classHash = classHash, diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index e85f1073f..f4ea8a1b8 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -739,7 +739,8 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ) - val result = account.executeV3(call, l1ResourceBounds, l2ResourceBounds).send() + val resourceBounds = ResourceBoundsMapping(l1ResourceBounds, l2ResourceBounds) + val result = account.executeV3(call, resourceBounds).send() val receipt = provider.getTransactionReceipt(result.transactionHash).send() @@ -1004,8 +1005,10 @@ class StandardAccountTest { ) val params = DeployAccountParamsV3( nonce = Felt.ZERO, - l1ResourceBounds = ResourceBounds.ZERO, - l2ResourceBounds = ResourceBounds.ZERO, + resourceBounds = ResourceBoundsMapping( + ResourceBounds.ZERO, + ResourceBounds.ZERO + ) ) val payloadForFeeEstimation = account.signDeployAccountV3( classHash = accountContractClassHash, @@ -1117,8 +1120,7 @@ class StandardAccountTest { val params = DeployAccountParamsV3( nonce = Felt.ZERO, - l1ResourceBounds = l1ResourceBounds, - l2ResourceBounds = l2ResourceBounds, + resourceBounds = ResourceBoundsMapping(l1ResourceBounds, l2ResourceBounds), ) // Prefund the new account address with STRK @@ -1296,20 +1298,24 @@ class StandardAccountTest { val newAccount = StandardAccount(newAccountAddress, privateKey, provider, chainId) devnetClient.prefundAccountStrk(newAccountAddress) - val deployAccountTx = newAccount.signDeployAccountV3( - classHash = accountContractClassHash, - calldata = calldata, - salt = salt, - l1ResourceBounds = ResourceBounds( + + val resourceBounds = ResourceBoundsMapping( + l1Gas = ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), // TODO: Check if these l2 resources need to be updated once we can add tests - l2ResourceBounds = ResourceBounds( + l2Gas = ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), ) + val deployAccountTx = newAccount.signDeployAccountV3( + classHash = accountContractClassHash, + calldata = calldata, + salt = salt, + resourceBounds = resourceBounds, + ) val simulationFlags = setOf() val simulationResult = provider.simulateTransactions( diff --git a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt index aedc5abaa..37294cc23 100644 --- a/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt +++ b/lib/src/test/kotlin/starknet/deployercontract/StandardDeployerTest.kt @@ -102,19 +102,22 @@ object StandardDeployerTest { @Test fun testUdcDeployV3WithSpecificResourceBounds() { val initialBalance = Felt(1000) - val deployment = standardDeployer.deployContractV3( - classHash = balanceContractClassHash, - unique = true, - salt = Felt(302), - constructorCalldata = listOf(initialBalance), - l1ResourceBounds = ResourceBounds( + val resourceBounds = ResourceBoundsMapping( + l1Gas = ResourceBounds( maxAmount = Uint64(50000), maxPricePerUnit = Uint128(100_000_000_000), ), - l2ResourceBounds = ResourceBounds( + l2Gas = ResourceBounds( maxAmount = Uint64(0), maxPricePerUnit = Uint128(0), ), + ) + val deployment = standardDeployer.deployContractV3( + classHash = balanceContractClassHash, + unique = true, + salt = Felt(302), + constructorCalldata = listOf(initialBalance), + resourceBounds = resourceBounds, ).send() val address = standardDeployer.findContractAddress(deployment).send() @@ -161,18 +164,21 @@ object StandardDeployerTest { @Test fun testUdcDeployV3WithSpecificFeeAndDefaultParameters() { val initialBalance = Felt(1000) - val deployment = standardDeployer.deployContractV3( - classHash = balanceContractClassHash, - constructorCalldata = listOf(initialBalance), - l1ResourceBounds = ResourceBounds( + val resourceBounds = ResourceBoundsMapping( + l1Gas = ResourceBounds( maxAmount = Uint64(50000), maxPricePerUnit = Uint128(100_000_000_000), ), // TODO: Check if these l2 resources need to be updated once we can add tests - l2ResourceBounds = ResourceBounds( - maxAmount = Uint64(50000), - maxPricePerUnit = Uint128(100_000_000_000), + l2Gas = ResourceBounds( + maxAmount = Uint64(0), + maxPricePerUnit = Uint128(0), ), + ) + val deployment = standardDeployer.deployContractV3( + classHash = balanceContractClassHash, + constructorCalldata = listOf(initialBalance), + resourceBounds = resourceBounds, ).send() val address = standardDeployer.findContractAddress(deployment).send() From 303317fee5f6aa99dff1f377cc8a97fc3e7dd211 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 16:55:37 +0200 Subject: [PATCH 40/53] Fix linting --- .../com/swmansion/starknet/deployercontract/Deployer.kt | 1 - .../swmansion/starknet/deployercontract/StandardDeployer.kt | 2 +- lib/src/test/kotlin/starknet/account/StandardAccountTest.kt | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt index eac1b86c0..3f292dca3 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/Deployer.kt @@ -2,7 +2,6 @@ package com.swmansion.starknet.deployercontract import com.swmansion.starknet.data.types.Calldata import com.swmansion.starknet.data.types.Felt -import com.swmansion.starknet.data.types.ResourceBounds import com.swmansion.starknet.data.types.ResourceBoundsMapping import com.swmansion.starknet.provider.Request import com.swmansion.starknet.provider.exceptions.RequestFailedException diff --git a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt index 18ebe7c81..b67d75b64 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/deployercontract/StandardDeployer.kt @@ -31,7 +31,7 @@ class StandardDeployer( unique: Boolean, salt: Felt, constructorCalldata: Calldata, - resourceBounds: ResourceBoundsMapping + resourceBounds: ResourceBoundsMapping, ): Request { val call = buildDeployContractCall(classHash, unique, salt, constructorCalldata) diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index f4ea8a1b8..775a31929 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -1007,8 +1007,8 @@ class StandardAccountTest { nonce = Felt.ZERO, resourceBounds = ResourceBoundsMapping( ResourceBounds.ZERO, - ResourceBounds.ZERO - ) + ResourceBounds.ZERO, + ), ) val payloadForFeeEstimation = account.signDeployAccountV3( classHash = accountContractClassHash, From a183504f4cf0013c2d7176247b3b384af2f2b5bf Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 17:31:59 +0200 Subject: [PATCH 41/53] Update `DeclareParamsV3` and `InvokeParamsV3` constructor params --- .../com/swmansion/starknet/data/types/Params.kt | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt index 238949d33..1b1592562 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Params.kt @@ -39,12 +39,9 @@ data class InvokeParamsV3 private constructor( override val nonceDataAvailabilityMode: DAMode, override val feeDataAvailabilityMode: DAMode, ) : ParamsV3() { - constructor(nonce: Felt, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds) : this( + constructor(nonce: Felt, resourceBounds: ResourceBoundsMapping) : this( nonce = nonce, - resourceBounds = ResourceBoundsMapping( - l1Gas = l1ResourceBounds, - l2Gas = l2ResourceBounds, - ), + resourceBounds = resourceBounds, tip = Uint64.ZERO, paymasterData = emptyList(), accountDeploymentData = emptyList(), @@ -67,12 +64,9 @@ data class DeclareParamsV3 private constructor( override val nonceDataAvailabilityMode: DAMode, override val feeDataAvailabilityMode: DAMode, ) : ParamsV3() { - constructor(nonce: Felt, l1ResourceBounds: ResourceBounds, l2ResourceBounds: ResourceBounds) : this( + constructor(nonce: Felt, resourceBounds: ResourceBoundsMapping) : this( nonce = nonce, - resourceBounds = ResourceBoundsMapping( - l1Gas = l1ResourceBounds, - l2Gas = l2ResourceBounds, - ), + resourceBounds = resourceBounds, tip = Uint64.ZERO, paymasterData = emptyList(), accountDeploymentData = emptyList(), From 635c6a67387cafb9b0abef744b1f2d6a73a4b365 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 17:41:24 +0200 Subject: [PATCH 42/53] Fix resource bounds params in `StandardAccount` --- .../com/swmansion/starknet/account/StandardAccount.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt index 9b9b14bd2..bbca69aa9 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt @@ -318,8 +318,7 @@ class StandardAccount @JvmOverloads constructor( return getNonce().compose { nonce -> val signParams = InvokeParamsV3( nonce = nonce, - l1ResourceBounds = resourceBounds.l1Gas, - l2ResourceBounds = resourceBounds.l2Gas, + resourceBounds = resourceBounds, ) val payload = signV3(calls, signParams, false) @@ -542,8 +541,10 @@ class StandardAccount @JvmOverloads constructor( private fun buildEstimateFeeV3Payload(calls: List, nonce: Felt): List { val executionParams = InvokeParamsV3( nonce = nonce, - l1ResourceBounds = ResourceBounds.ZERO, - l2ResourceBounds = ResourceBounds.ZERO, + resourceBounds = ResourceBoundsMapping( + ResourceBounds.ZERO, + ResourceBounds.ZERO, + ) ) val payload = signV3(calls, executionParams, true) From a380e39e233bdd238a7697761f4827b8e721e05c Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 17:41:41 +0200 Subject: [PATCH 43/53] Fix linting --- .../kotlin/com/swmansion/starknet/account/StandardAccount.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt index bbca69aa9..6e3f160df 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/account/StandardAccount.kt @@ -544,7 +544,7 @@ class StandardAccount @JvmOverloads constructor( resourceBounds = ResourceBoundsMapping( ResourceBounds.ZERO, ResourceBounds.ZERO, - ) + ), ) val payload = signV3(calls, executionParams, true) From 3af0e5c41ec69b572cbe993e357c1f6c8742295e Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 18:14:44 +0200 Subject: [PATCH 44/53] Add fixes for resource bounds --- .../starknet/data/types/Responses.kt | 2 +- .../kotlin/network/account/AccountTest.kt | 12 ++- .../starknet/account/StandardAccountTest.kt | 91 ++++++++++--------- 3 files changed, 59 insertions(+), 46 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt index eb19c892d..6d8cc54b9 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Responses.kt @@ -162,7 +162,7 @@ data class MessageStatus( @SerialName("failure_reason") val failureReason: String? = null, -) : StarknetResponse +) @Serializable data class StorageProof( diff --git a/lib/src/test/kotlin/network/account/AccountTest.kt b/lib/src/test/kotlin/network/account/AccountTest.kt index cae93dfdd..48888d4ef 100644 --- a/lib/src/test/kotlin/network/account/AccountTest.kt +++ b/lib/src/test/kotlin/network/account/AccountTest.kt @@ -161,8 +161,10 @@ class AccountTest { val nonce = account.getNonce().send() val params = DeclareParamsV3( nonce = nonce, - l1ResourceBounds = ResourceBounds.ZERO, - l2ResourceBounds = ResourceBounds.ZERO, + resourceBounds = ResourceBoundsMapping( + ResourceBounds.ZERO, + ResourceBounds.ZERO, + ) ) val declareTransactionPayload = account.signDeclareV3( sierraContractDefinition = contractDefinition, @@ -277,8 +279,10 @@ class AccountTest { ) val params = DeclareParamsV3( nonce = nonce, - l1ResourceBounds = l1ResourceBounds, - l2ResourceBounds = l2ResourceBounds, + resourceBounds = ResourceBoundsMapping( + l1Gas = l1ResourceBounds, + l2Gas = l2ResourceBounds, + ), ) val declareTransactionPayload = account.signDeclareV3( contractDefinition, diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index 775a31929..222e2d89b 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -259,7 +259,9 @@ class StandardAccountTest { ) val invokeTxV3Payload = account.signV3( call = call, - params = InvokeParamsV3(nonce.value.add(BigInteger.ONE).toFelt, ResourceBounds.ZERO, ResourceBounds.ZERO), + params = InvokeParamsV3( + nonce = nonce.value.add(BigInteger.ONE).toFelt, + resourceBounds = ResourceBoundsMapping(ResourceBounds.ZERO, ResourceBounds.ZERO)), forFeeEstimate = true, ) assertEquals(TransactionVersion.V1_QUERY, invokeTxV1Payload.version) @@ -346,7 +348,13 @@ class StandardAccountTest { val contractCasmDefinition = CasmContractDefinition(casmCode) val nonce = account.getNonce().send() - val params = DeclareParamsV3(nonce = nonce, l1ResourceBounds = ResourceBounds.ZERO, l2ResourceBounds = ResourceBounds.ZERO) + val params = DeclareParamsV3( + nonce = nonce, + resourceBounds = ResourceBoundsMapping( + ResourceBounds.ZERO, + ResourceBounds.ZERO, + ) + ) val declareTransactionPayload = account.signDeclareV3( contractDefinition, contractCasmDefinition, @@ -489,16 +497,16 @@ class StandardAccountTest { val contractCasmDefinition = CasmContractDefinition(casmCode) val nonce = account.getNonce().send() - val params = DeclareParamsV3( - nonce = nonce, - l1ResourceBounds = ResourceBounds( + val resourceBounds = ResourceBoundsMapping( + ResourceBounds( maxAmount = Uint64(100000), maxPricePerUnit = Uint128(1000000000000), ), - l2ResourceBounds = ResourceBounds( - maxAmount = Uint64(0), - maxPricePerUnit = Uint128(0), - ), + ResourceBounds.ZERO, + ) + val params = DeclareParamsV3( + nonce = nonce, + resourceBounds = resourceBounds, ) val declareTransactionPayload = account.signDeclareV3( contractDefinition, @@ -616,17 +624,20 @@ class StandardAccountTest { entrypoint = "increase_balance", ) - val params = InvokeParamsV3( - nonce = account.getNonce().send(), - l1ResourceBounds = ResourceBounds( + val resourceBounds = ResourceBoundsMapping( + ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), - l2ResourceBounds = ResourceBounds( + ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), ) + val params = InvokeParamsV3( + nonce = account.getNonce().send(), + resourceBounds = resourceBounds, + ) val payload = account.signV3(call, params) val request = provider.invokeFunction(payload) @@ -777,18 +788,21 @@ class StandardAccountTest { calldata = listOf(Felt(10)), ) - val params = InvokeParamsV3( - nonce = account.getNonce().send(), - l1ResourceBounds = ResourceBounds( + val resourceBounds = ResourceBoundsMapping( + ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), // TODO: Check if these l2 resources need to be updated once we can add tests - l2ResourceBounds = ResourceBounds( + ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), ) + val params = InvokeParamsV3( + nonce = account.getNonce().send(), + resourceBounds = resourceBounds, + ) val payload = account.signV3(listOf(call, call, call), params) val response = provider.invokeFunction(payload).send() @@ -1270,17 +1284,20 @@ class StandardAccountTest { val nonce = account.getNonce().send() val call = Call(balanceContractAddress, "increase_balance", listOf(Felt(1000))) - val params = InvokeParamsV3( - nonce = nonce, - l1ResourceBounds = ResourceBounds( + val resourceBounds = ResourceBoundsMapping( + ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), // TODO: Check if these l2 resources need to be updated once we can add tests - l2ResourceBounds = ResourceBounds( + ResourceBounds( maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), + ) + val params = InvokeParamsV3( + nonce = nonce, + resourceBounds = resourceBounds, ) val invokeTx = account.signV3(call, params) @@ -1299,17 +1316,6 @@ class StandardAccountTest { devnetClient.prefundAccountStrk(newAccountAddress) - val resourceBounds = ResourceBoundsMapping( - l1Gas = ResourceBounds( - maxAmount = Uint64(20000), - maxPricePerUnit = Uint128(120000000000), - ), - // TODO: Check if these l2 resources need to be updated once we can add tests - l2Gas = ResourceBounds( - maxAmount = Uint64(20000), - maxPricePerUnit = Uint128(120000000000), - ), - ) val deployAccountTx = newAccount.signDeployAccountV3( classHash = accountContractClassHash, calldata = calldata, @@ -1387,20 +1393,23 @@ class StandardAccountTest { val casmContractDefinition = CasmContractDefinition(casmCode) val nonce = account.getNonce().send() + val resourceBounds = ResourceBoundsMapping( + ResourceBounds( + maxAmount = Uint64(100000), + maxPricePerUnit = Uint128(1000000000000), + ), + // TODO: Check if these l2 resources need to be updated once we can add tests + ResourceBounds( + maxAmount = Uint64(100000), + maxPricePerUnit = Uint128(1000000000000), + ), + ) val declareTransactionPayload = account.signDeclareV3( contractDefinition, casmContractDefinition, DeclareParamsV3( nonce = nonce, - l1ResourceBounds = ResourceBounds( - maxAmount = Uint64(100000), - maxPricePerUnit = Uint128(1000000000000), - ), - // TODO: Check if these l2 resources need to be updated once we can add tests - l2ResourceBounds = ResourceBounds( - maxAmount = Uint64(100000), - maxPricePerUnit = Uint128(1000000000000), - ), + resourceBounds = resourceBounds, ), ) From 63b8bd850749e8ef05ad9b6ed9ed450d39f2adfd Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Thu, 24 Oct 2024 18:15:02 +0200 Subject: [PATCH 45/53] Fix linting --- lib/src/test/kotlin/network/account/AccountTest.kt | 2 +- .../test/kotlin/starknet/account/StandardAccountTest.kt | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/test/kotlin/network/account/AccountTest.kt b/lib/src/test/kotlin/network/account/AccountTest.kt index 48888d4ef..db46511bd 100644 --- a/lib/src/test/kotlin/network/account/AccountTest.kt +++ b/lib/src/test/kotlin/network/account/AccountTest.kt @@ -164,7 +164,7 @@ class AccountTest { resourceBounds = ResourceBoundsMapping( ResourceBounds.ZERO, ResourceBounds.ZERO, - ) + ), ) val declareTransactionPayload = account.signDeclareV3( sierraContractDefinition = contractDefinition, diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index 222e2d89b..2ccd18c90 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -261,7 +261,8 @@ class StandardAccountTest { call = call, params = InvokeParamsV3( nonce = nonce.value.add(BigInteger.ONE).toFelt, - resourceBounds = ResourceBoundsMapping(ResourceBounds.ZERO, ResourceBounds.ZERO)), + resourceBounds = ResourceBoundsMapping(ResourceBounds.ZERO, ResourceBounds.ZERO), + ), forFeeEstimate = true, ) assertEquals(TransactionVersion.V1_QUERY, invokeTxV1Payload.version) @@ -353,7 +354,7 @@ class StandardAccountTest { resourceBounds = ResourceBoundsMapping( ResourceBounds.ZERO, ResourceBounds.ZERO, - ) + ), ) val declareTransactionPayload = account.signDeclareV3( contractDefinition, @@ -1294,7 +1295,7 @@ class StandardAccountTest { maxAmount = Uint64(20000), maxPricePerUnit = Uint128(120000000000), ), - ) + ) val params = InvokeParamsV3( nonce = nonce, resourceBounds = resourceBounds, From 1e6190b76ad0d560551c46f47a56d14be0fd5990 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 10:07:20 +0200 Subject: [PATCH 46/53] Rename `computationResources` to executionResources` --- .../com/swmansion/starknet/data/types/SimulatedTransaction.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt index 8e8b46a84..bc99a38a7 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt @@ -65,7 +65,7 @@ data class FunctionInvocation( val messages: List, @SerialName("execution_resources") - val computationResources: ExecutionResources, + val executionResources: ExecutionResources, ) @Serializable From a8722bb9cad4b4183d65649ee90fc0ae9803c2a3 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 10:07:48 +0200 Subject: [PATCH 47/53] Update mock jsons in tests --- .../starknet/account/StandardAccountTest.kt | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index 2ccd18c90..c185c83c7 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -1448,11 +1448,9 @@ class StandardAccountTest { "revert_reason": "Placeholder revert reason." }, "execution_resources": { - "steps": 582, - "data_availability": { - "l1_gas": "123", - "l1_data_gas": "456" - } + "l1_gas": "123", + "l1_data_gas": "456", + "l2_gas": "789" } } } @@ -1572,11 +1570,9 @@ class StandardAccountTest { } }, "execution_resources": { - "steps": 1600, - "data_availability": { - "l1_gas": "123", - "l1_data_gas": "456" - } + "l1_gas": "123", + "l1_data_gas": "456", + "l2_gas": "789" } } } From 56885932f7ede9277c810ae32a0378c92a9f1a07 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 10:11:48 +0200 Subject: [PATCH 48/53] Add `InnerCallExecutionResources` --- .../swmansion/starknet/data/types/ExecutionResources.kt | 9 +++++++++ .../starknet/data/types/SimulatedTransaction.kt | 2 +- .../test/kotlin/starknet/account/StandardAccountTest.kt | 6 ++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt index eaf9bcecb..c611f2191 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt @@ -14,3 +14,12 @@ data class ExecutionResources( @SerialName("l2_gas") val l2Gas: Int, ) + +@Serializable +data class InnerCallExecutionResources( + @SerialName("l1_gas") + val l1Gas: Int, + + @SerialName("l2_gas") + val l2Gas: Int, +) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt index bc99a38a7..f5c18b4ba 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/SimulatedTransaction.kt @@ -65,7 +65,7 @@ data class FunctionInvocation( val messages: List, @SerialName("execution_resources") - val executionResources: ExecutionResources, + val executionResources: InnerCallExecutionResources, ) @Serializable diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index c185c83c7..b73993360 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -1546,7 +1546,8 @@ class StandardAccountTest { ], "messages": [], "execution_resources": { - "steps": 582 + "l1_gas": "123", + "l2_gas": "456" } } ], @@ -1566,7 +1567,8 @@ class StandardAccountTest { } ], "execution_resources": { - "steps": 800 + "l1_gas": "123", + "l2_gas": "789" } }, "execution_resources": { From 8f3061fd900d8f54d533b4cbcb640da39b3f758f Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 10:20:41 +0200 Subject: [PATCH 49/53] Add `DataResources` sealed class --- .../{ExecutionResources.kt => Resources.kt} | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) rename lib/src/main/kotlin/com/swmansion/starknet/data/types/{ExecutionResources.kt => Resources.kt} (60%) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt similarity index 60% rename from lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt rename to lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt index c611f2191..e32d9d1bb 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/ExecutionResources.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt @@ -3,23 +3,29 @@ package com.swmansion.starknet.data.types import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +@Serializable +sealed class DataResources { + abstract val l1Gas: Int + abstract val l2Gas: Int +} + @Serializable data class ExecutionResources( @SerialName("l1_gas") - val l1Gas: Int, + override val l1Gas: Int, @SerialName("l1_data_gas") val l1DataGas: Int, @SerialName("l2_gas") - val l2Gas: Int, -) + override val l2Gas: Int, +): DataResources() @Serializable data class InnerCallExecutionResources( @SerialName("l1_gas") - val l1Gas: Int, + override val l1Gas: Int, @SerialName("l2_gas") - val l2Gas: Int, -) + override val l2Gas: Int, +): DataResources() From 96dbac32f20aad1f92efe50de169f292e33f587d Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 10:20:58 +0200 Subject: [PATCH 50/53] Fix linting --- .../kotlin/com/swmansion/starknet/data/types/Resources.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt index e32d9d1bb..518f09f5a 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt @@ -19,7 +19,7 @@ data class ExecutionResources( @SerialName("l2_gas") override val l2Gas: Int, -): DataResources() +) : DataResources() @Serializable data class InnerCallExecutionResources( @@ -28,4 +28,4 @@ data class InnerCallExecutionResources( @SerialName("l2_gas") override val l2Gas: Int, -): DataResources() +) : DataResources() From 25fe29c02235eed5ae630dde21b550324bb831b2 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 12:15:43 +0200 Subject: [PATCH 51/53] Rename `DataResources` to `Resources` --- .../kotlin/com/swmansion/starknet/data/types/Resources.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt index 518f09f5a..4fddab55b 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -sealed class DataResources { +sealed class Resources { abstract val l1Gas: Int abstract val l2Gas: Int } @@ -19,7 +19,7 @@ data class ExecutionResources( @SerialName("l2_gas") override val l2Gas: Int, -) : DataResources() +) : Resources() @Serializable data class InnerCallExecutionResources( @@ -28,4 +28,4 @@ data class InnerCallExecutionResources( @SerialName("l2_gas") override val l2Gas: Int, -) : DataResources() +) : Resources() From 2b1c4784f42664193a66cb36de659077e5038937 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 12:33:46 +0200 Subject: [PATCH 52/53] Restore `JvmName` annotation in `Resources.kt` --- .../main/kotlin/com/swmansion/starknet/data/types/Resources.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt index 4fddab55b..6467c053c 100644 --- a/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt +++ b/lib/src/main/kotlin/com/swmansion/starknet/data/types/Resources.kt @@ -1,3 +1,5 @@ +@file:JvmName("Resources") + package com.swmansion.starknet.data.types import kotlinx.serialization.SerialName From 8215452a7e0b222eee4993bccd454861d05c5c40 Mon Sep 17 00:00:00 2001 From: Fiiranek Date: Fri, 25 Oct 2024 18:58:33 +0200 Subject: [PATCH 53/53] Remove unnecessary formatting changes --- .../starknet/account/StandardAccountTest.kt | 59 +++++-------------- 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt index b73993360..f2deeff88 100644 --- a/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt +++ b/lib/src/test/kotlin/starknet/account/StandardAccountTest.kt @@ -56,14 +56,8 @@ class StandardAccountTest { devnetClient.start() val accountDetails = devnetClient.createDeployAccount().details - val legacyAccountDetails = devnetClient.createDeployAccount( - classHash = DevnetClient.legacyAccountContractClassHash, - accountName = "legacy_account", - ).details - balanceContractAddress = devnetClient.declareDeployContract( - "Balance", - constructorCalldata = listOf(Felt(451)), - ).contractAddress + val legacyAccountDetails = devnetClient.createDeployAccount(classHash = DevnetClient.legacyAccountContractClassHash, accountName = "legacy_account").details + balanceContractAddress = devnetClient.declareDeployContract("Balance", constructorCalldata = listOf(Felt(451))).contractAddress accountAddress = accountDetails.address legacyAccountAddress = legacyAccountDetails.address @@ -306,11 +300,8 @@ class StandardAccountTest { @Test fun estimateFeeForDeclareV2Transaction() { // docsStart - val contractCode = - Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json") - .readText() - val casmCode = - Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() + val contractCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json").readText() + val casmCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() val contractDefinition = Cairo1ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -325,8 +316,7 @@ class StandardAccountTest { // docsEnd assertEquals(TransactionVersion.V2_QUERY, declareTransactionPayload.version) // docsStart - val request = - provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) + val request = provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) val feeEstimate = request.send().values.first() // docsEnd assertNotEquals(Felt.ZERO, feeEstimate.overallFee) @@ -339,11 +329,8 @@ class StandardAccountTest { @Test fun estimateFeeForDeclareV3Transaction() { // docsStart - val contractCode = - Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json") - .readText() - val casmCode = - Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() + val contractCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json").readText() + val casmCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() val contractDefinition = Cairo1ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -365,8 +352,7 @@ class StandardAccountTest { // docsEnd assertEquals(TransactionVersion.V3_QUERY, declareTransactionPayload.version) // docsStart - val request = - provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) + val request = provider.getEstimateFee(payload = listOf(declareTransactionPayload), simulationFlags = emptySet()) val feeEstimate = request.send().values.first() // docsEnd assertNotEquals(Felt.ZERO, feeEstimate.overallFee) @@ -379,10 +365,8 @@ class StandardAccountTest { @Test fun estimateMessageFee() { - val l1l2ContractCode = - Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.sierra.json").readText() - val l1l2CasmContractCode = - Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.casm.json").readText() + val l1l2ContractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.sierra.json").readText() + val l1l2CasmContractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_l1_l2.casm.json").readText() val l1l2ContractDefinition = Cairo2ContractDefinition(l1l2ContractCode) val l1l2CasmContractDefinition = CasmContractDefinition(l1l2CasmContractCode) @@ -428,11 +412,8 @@ class StandardAccountTest { fun signAndSendDeclareV2Transaction() { devnetClient.prefundAccountEth(accountAddress) // docsStart - val contractCode = - Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json") - .readText() - val casmCode = - Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() + val contractCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.sierra.json").readText() + val casmCode = Path.of("src/test/resources/contracts_v1/target/release/ContractsV1_HelloStarknet.casm.json").readText() val contractDefinition = Cairo1ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -455,12 +436,8 @@ class StandardAccountTest { fun `sign and send declare v2 transaction (cairo compiler v2)`() { devnetClient.prefundAccountEth(accountAddress) - val contractCode = - Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.sierra.json") - .readText() - val casmCode = - Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.casm.json") - .readText() + val contractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.sierra.json").readText() + val casmCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_CounterContract.casm.json").readText() val contractDefinition = Cairo2ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode) @@ -487,12 +464,8 @@ class StandardAccountTest { placeholderContractPath = Path.of("src/test/resources/contracts_v2/src/placeholder_counter_contract.cairo"), saltedContractPath = Path.of("src/test/resources/contracts_v2/src/salted_counter_contract.cairo"), ) - val contractCode = - Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.sierra.json") - .readText() - val casmCode = - Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.casm.json") - .readText() + val contractCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.sierra.json").readText() + val casmCode = Path.of("src/test/resources/contracts_v2/target/release/ContractsV2_SaltedCounterContract.casm.json").readText() val contractDefinition = Cairo2ContractDefinition(contractCode) val contractCasmDefinition = CasmContractDefinition(casmCode)