Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support RPC 0.7.0 #162

Merged
merged 15 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
test_and_lint:
runs-on: macos-12
env:
DEVNET_SHA: 55191ee549b33ccbb0bc9d20dd929e39832a5ea5
DEVNET_SHA: fa1238e8039a53101b5d2d764d3622ff0403a527
steps:
- uses: actions/checkout@v3

Expand Down
7 changes: 4 additions & 3 deletions Sources/Starknet/Crypto/FeeCalculation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ public extension StarknetFeeEstimate {
/// Then multiplies fee by m and does integer division by 100.
///
/// - Parameters:
/// - amountOverhead: how big overhead should be added (as a fraction of amount) to the amount, defaults to 0.1
/// - amountOverhead: how big overhead should be added (as a fraction of amount) to the amount, defaults to 0.5
/// - unitPriceOverhead: how big overhead should be added (as a fraction of unit price) to the unit price, defaults to 0.5
///
/// - Returns: resource bounds with added overhead
func toResourceBounds(amountOverhead: Double = 0.1, unitPriceOverhead: Double = 0.5) -> StarknetResourceBoundsMapping {
let maxAmount = addOverhead(self.gasConsumed.value, amountOverhead).toUInt64AsHexClamped()
func toResourceBounds(amountOverhead: Double = 0.5, unitPriceOverhead: Double = 0.5) -> StarknetResourceBoundsMapping {
let maxAmount = self.gasPrice == .zero ? UInt64AsHex.zero : addOverhead(self.overallFee.value / self.gasPrice.value, amountOverhead).toUInt64AsHexClamped()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are the scenarios for gasPrice equal to zero?

Copy link
Collaborator Author

@DelevoXDG DelevoXDG Mar 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There aren't really any likely scenarios, added these for the same reasons I outlined before:

(0,0) resources can be used in estimateFee / simulateTransactions. It normally shouldn't happen, but I suppose better safe than sorry?


let maxUnitPrice = addOverhead(self.gasPrice.value, unitPriceOverhead).toUInt128AsHexClamped()

let l1Gas = StarknetResourceBounds(maxAmount: maxAmount, maxPricePerUnit: maxUnitPrice)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Starknet/Data/Responses.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ public struct StarknetInvokeTransactionResponse: Decodable, Equatable {
public struct StarknetFeeEstimate: Decodable, Equatable {
public let gasConsumed: Felt
public let gasPrice: Felt
public let dataGasConsumed: Felt
public let dataGasPrice: Felt
public let overallFee: Felt
public let feeUnit: StarknetPriceUnit

enum CodingKeys: String, CodingKey {
case gasConsumed = "gas_consumed"
case gasPrice = "gas_price"
case dataGasConsumed = "data_gas_consumed"
case dataGasPrice = "data_gas_price"
case overallFee = "overall_fee"
case feeUnit = "unit"
}
Expand Down
55 changes: 54 additions & 1 deletion Sources/Starknet/Data/Transaction/Data/ExecutionResources.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,45 @@
import Foundation

public struct StarknetExecutionResources: Decodable, Equatable {
public protocol StarknetResources: Decodable, Equatable {
var steps: Int { get }
var memoryHoles: Int? { get }
var rangeCheckApplications: Int? { get }
var pedersenApplications: Int? { get }
var poseidonApplications: Int? { get }
var ecOpApplications: Int? { get }
var ecdsaApplications: Int? { get }
var bitwiseApplications: Int? { get }
var keccakApplications: Int? { get }
var segmentArena: Int? { get }
}

public struct StarknetComputationResources: StarknetResources {
public let steps: Int
public let memoryHoles: Int?
public let rangeCheckApplications: Int?
public let pedersenApplications: Int?
public let poseidonApplications: Int?
public let ecOpApplications: Int?
public let ecdsaApplications: Int?
public let bitwiseApplications: Int?
public let keccakApplications: Int?
DelevoXDG marked this conversation as resolved.
Show resolved Hide resolved
public let segmentArena: Int?

enum CodingKeys: String, CodingKey {
case steps
case memoryHoles = "memory_holes"
case rangeCheckApplications = "range_check_builtin_applications"
case pedersenApplications = "pedersen_builtin_applications"
case poseidonApplications = "poseidon_builtin_applications"
case ecOpApplications = "ec_op_builtin_applications"
case ecdsaApplications = "ecdsa_builtin_applications"
case bitwiseApplications = "bitwise_builtin_applications"
case keccakApplications = "keccak_builtin_applications"
case segmentArena = "segment_arena_builtin"
}
}

public struct StarknetExecutionResources: StarknetResources {
public let steps: Int
public let memoryHoles: Int?
public let rangeCheckApplications: Int?
Expand All @@ -10,6 +49,8 @@ public struct StarknetExecutionResources: Decodable, Equatable {
public let ecdsaApplications: Int?
public let bitwiseApplications: Int?
public let keccakApplications: Int?
public let segmentArena: Int?
public let dataAvailability: StarknetDataAvailability

enum CodingKeys: String, CodingKey {
case steps
Expand All @@ -21,5 +62,17 @@ public struct StarknetExecutionResources: Decodable, Equatable {
case ecdsaApplications = "ecdsa_builtin_applications"
case bitwiseApplications = "bitwise_builtin_applications"
case keccakApplications = "keccak_builtin_applications"
case segmentArena = "segment_arena_builtin"
case dataAvailability = "data_availability"
}
}

public struct StarknetDataAvailability: Decodable, Equatable {
public let l1Gas: Int
public let l1DataGas: Int

enum CodingKeys: String, CodingKey {
case l1Gas = "l1_gas"
case l1DataGas = "l1_data_gas"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation

public enum StarknetTransactionVersion: String, Codable {
case v0 = "0x0"
case v1 = "0x1"
case v1Query = "0x100000000000000000000000000000001"
case v2 = "0x2"
case v2Query = "0x100000000000000000000000000000002"
case v3 = "0x3"
case v3Query = "0x100000000000000000000000000000003"

public var value: Felt {
Felt(fromHex: self.rawValue)!
}
}
44 changes: 20 additions & 24 deletions Sources/Starknet/Data/Transaction/Transaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Foundation
public struct StarknetInvokeTransactionV3: StarknetInvokeTransaction, StarknetTransactionV3, StarknetExecutableTransaction {
public let type: StarknetTransactionType = .invoke

public let version: Felt
public let version: StarknetTransactionVersion

public let senderAddress: Felt

Expand Down Expand Up @@ -33,7 +33,7 @@ public struct StarknetInvokeTransactionV3: StarknetInvokeTransaction, StarknetTr
self.calldata = calldata
self.signature = signature
self.nonce = nonce
self.version = StarknetInvokeTransactionV3.computeVersion(3, forFeeEstimation: forFeeEstimation)
self.version = forFeeEstimation ? .v3Query : .v3
self.hash = hash
// As of Starknet 0.13, most of v3 fields have hardcoded values.
self.resourceBounds = StarknetResourceBoundsMapping(l1Gas: l1ResourceBounds)
Expand Down Expand Up @@ -66,7 +66,7 @@ public struct StarknetInvokeTransactionV3: StarknetInvokeTransaction, StarknetTr
self.calldata = try container.decode(StarknetCalldata.self, forKey: .calldata)
self.signature = try container.decode(StarknetSignature.self, forKey: .signature)
self.nonce = try container.decode(Felt.self, forKey: .nonce)
self.version = try container.decode(Felt.self, forKey: .version)
self.version = try container.decode(StarknetTransactionVersion.self, forKey: .version)
self.resourceBounds = try container.decode(StarknetResourceBoundsMapping.self, forKey: .resourceBounds)
self.tip = try container.decode(UInt64AsHex.self, forKey: .tip)
self.paymasterData = try container.decode(StarknetPaymasterData.self, forKey: .paymasterData)
Expand All @@ -82,7 +82,7 @@ public struct StarknetInvokeTransactionV3: StarknetInvokeTransaction, StarknetTr
public struct StarknetInvokeTransactionV1: StarknetInvokeTransaction, StarknetDeprecatedTransaction, StarknetExecutableTransaction {
public let type: StarknetTransactionType = .invoke

public let version: Felt
public let version: StarknetTransactionVersion

public let senderAddress: Felt

Expand All @@ -102,7 +102,7 @@ public struct StarknetInvokeTransactionV1: StarknetInvokeTransaction, StarknetDe
self.signature = signature
self.maxFee = maxFee
self.nonce = nonce
self.version = StarknetInvokeTransactionV1.computeVersion(1, forFeeEstimation: forFeeEstimation)
self.version = forFeeEstimation ? .v1Query : .v1
self.hash = hash
}

Expand All @@ -124,7 +124,7 @@ public struct StarknetInvokeTransactionV1: StarknetInvokeTransaction, StarknetDe
self.signature = try container.decode(StarknetSignature.self, forKey: .signature)
self.maxFee = try container.decode(Felt.self, forKey: .maxFee)
self.nonce = try container.decode(Felt.self, forKey: .nonce)
self.version = try container.decode(Felt.self, forKey: .version)
self.version = try container.decode(StarknetTransactionVersion.self, forKey: .version)
self.hash = try container.decodeIfPresent(Felt.self, forKey: .hash)

try verifyTransactionType(container: container, codingKeysType: CodingKeys.self)
Expand All @@ -134,7 +134,7 @@ public struct StarknetInvokeTransactionV1: StarknetInvokeTransaction, StarknetDe
public struct StarknetInvokeTransactionV0: StarknetInvokeTransaction, StarknetDeprecatedTransaction {
public let type: StarknetTransactionType = .invoke

public let version: Felt = .zero
public let version: StarknetTransactionVersion = .v0

public let contractAddress: Felt

Expand Down Expand Up @@ -185,7 +185,7 @@ public struct StarknetInvokeTransactionV0: StarknetInvokeTransaction, StarknetDe
public struct StarknetDeployAccountTransactionV3: StarknetDeployAccountTransaction, StarknetTransactionV3, StarknetExecutableTransaction {
public let type: StarknetTransactionType = .deployAccount

public let version: Felt
public let version: StarknetTransactionVersion

public let signature: StarknetSignature

Expand Down Expand Up @@ -215,7 +215,7 @@ public struct StarknetDeployAccountTransactionV3: StarknetDeployAccountTransacti
self.contractAddressSalt = contractAddressSalt
self.constructorCalldata = constructorCalldata
self.classHash = classHash
self.version = StarknetDeployAccountTransactionV3.computeVersion(3, forFeeEstimation: forFeeEstimation)
self.version = forFeeEstimation ? .v3Query : .v3
self.hash = hash
// As of Starknet 0.13, most of v3 fields have hardcoded values.
self.resourceBounds = StarknetResourceBoundsMapping(l1Gas: l1ResourceBounds)
Expand All @@ -237,7 +237,7 @@ public struct StarknetDeployAccountTransactionV3: StarknetDeployAccountTransacti
self.paymasterData = try container.decode([Felt].self, forKey: .paymasterData)
self.nonceDataAvailabilityMode = try container.decode(StarknetDAMode.self, forKey: .nonceDataAvailabilityMode)
self.feeDataAvailabilityMode = try container.decode(StarknetDAMode.self, forKey: .feeDataAvailabilityMode)
self.version = try container.decode(Felt.self, forKey: .version)
self.version = try container.decode(StarknetTransactionVersion.self, forKey: .version)
self.hash = try container.decodeIfPresent(Felt.self, forKey: .hash)

try verifyTransactionVersion(container: container, codingKeysType: CodingKeys.self)
Expand All @@ -263,7 +263,7 @@ public struct StarknetDeployAccountTransactionV3: StarknetDeployAccountTransacti
public struct StarknetDeployAccountTransactionV1: StarknetDeployAccountTransaction, StarknetDeprecatedTransaction, StarknetExecutableTransaction {
public let type: StarknetTransactionType = .deployAccount

public let version: Felt
public let version: StarknetTransactionVersion

public let signature: StarknetSignature

Expand All @@ -286,7 +286,7 @@ public struct StarknetDeployAccountTransactionV1: StarknetDeployAccountTransacti
self.contractAddressSalt = contractAddressSalt
self.constructorCalldata = constructorCalldata
self.classHash = classHash
self.version = StarknetDeployAccountTransactionV1.computeVersion(1, forFeeEstimation: forFeeEstimation)
self.version = forFeeEstimation ? .v1Query : .v1
self.hash = hash
}

Expand All @@ -298,7 +298,7 @@ public struct StarknetDeployAccountTransactionV1: StarknetDeployAccountTransacti
self.contractAddressSalt = try container.decode(Felt.self, forKey: .contractAddressSalt)
self.constructorCalldata = try container.decode(StarknetCalldata.self, forKey: .constructorCalldata)
self.classHash = try container.decode(Felt.self, forKey: .classHash)
self.version = try container.decode(Felt.self, forKey: .version)
self.version = try container.decode(StarknetTransactionVersion.self, forKey: .version)
self.hash = try container.decodeIfPresent(Felt.self, forKey: .hash)

try verifyTransactionType(container: container, codingKeysType: CodingKeys.self)
Expand All @@ -320,7 +320,7 @@ public struct StarknetDeployAccountTransactionV1: StarknetDeployAccountTransacti
public struct StarknetL1HandlerTransaction: StarknetTransaction {
public let type: StarknetTransactionType = .l1Handler

public let version: Felt = .zero
public let version: StarknetTransactionVersion = .v0

public let nonce: Felt

Expand Down Expand Up @@ -366,7 +366,7 @@ public struct StarknetL1HandlerTransaction: StarknetTransaction {
public struct StarknetDeclareTransactionV3: StarknetDeclareTransaction, StarknetTransactionV3 {
public let type: StarknetTransactionType = .declare

public let version: Felt = 3
public let version: StarknetTransactionVersion = .v3

public let signature: StarknetSignature

Expand Down Expand Up @@ -452,7 +452,7 @@ public struct StarknetDeclareTransactionV0: StarknetDeclareTransaction, Starknet

public let maxFee: Felt

public let version: Felt = .zero
public let version: StarknetTransactionVersion = .v0

public let signature: StarknetSignature

Expand Down Expand Up @@ -498,7 +498,7 @@ public struct StarknetDeclareTransactionV1: StarknetDeclareTransaction, Starknet

public let maxFee: Felt

public let version: Felt = .one
public let version: StarknetTransactionVersion = .v1

public let signature: StarknetSignature

Expand Down Expand Up @@ -549,7 +549,7 @@ public struct StarknetDeclareTransactionV2: StarknetTransaction {

public let maxFee: Felt

public let version: Felt = 2
public let version: StarknetTransactionVersion = .v2

public let signature: StarknetSignature

Expand Down Expand Up @@ -603,7 +603,7 @@ public struct StarknetDeclareTransactionV2: StarknetTransaction {
public struct StarknetDeployTransaction: StarknetTransaction {
public let type: StarknetTransactionType = .deploy

public let version: Felt = .zero
public let version: StarknetTransactionVersion = .v0

public let contractAddressSalt: Felt

Expand Down Expand Up @@ -650,10 +650,6 @@ extension StarknetExecutableTransaction {
private static func estimateVersion(_ version: Felt) -> Felt {
Felt(BigUInt(2).power(128).advanced(by: BigInt(version.value)))!
}

static func computeVersion(_ version: Felt, forFeeEstimation: Bool) -> Felt {
forFeeEstimation ? estimateVersion(version) : version
}
}

// Default deserializer doesn't check if the fields with default values match what is deserialized.
Expand All @@ -668,7 +664,7 @@ extension StarknetTransaction {
}

func verifyTransactionVersion<T>(container: KeyedDecodingContainer<T>, codingKeysType _: T.Type) throws where T: CodingKey {
let version = try container.decode(Felt.self, forKey: T(stringValue: "version")!)
let version = try container.decode(StarknetTransactionVersion.self, forKey: T(stringValue: "version")!)

guard version == self.version else {
throw StarknetTransactionDecodingError.invalidVersion
Expand Down
6 changes: 3 additions & 3 deletions Sources/Starknet/Data/Transaction/TransactionHash.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class StarknetTransactionHashCalculator {

private class func computeCommonDeprecatedTransactionHash(
transactionType: StarknetTransactionType,
version: Felt,
version: StarknetTransactionVersion,
contractAddress: Felt,
entryPointSelector: Felt,
calldata: StarknetCalldata,
Expand All @@ -16,7 +16,7 @@ public class StarknetTransactionHashCalculator {
) -> Felt {
StarknetCurve.pedersenOn(
transactionType.encodedValue,
version,
version.value,
contractAddress,
entryPointSelector,
StarknetCurve.pedersenOn(calldata),
Expand All @@ -38,7 +38,7 @@ public class StarknetTransactionHashCalculator {

return [
transactionType.encodedValue,
version,
version.value,
address,
StarknetPoseidon.poseidonHash(
[tip.value.toFelt()!]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ public protocol StarknetExecutableTransaction: StarknetTransaction {}

public protocol StarknetTransaction: Codable, Hashable, Equatable {
var type: StarknetTransactionType { get }
var version: Felt { get }
var version: StarknetTransactionVersion { get }
var hash: Felt? { get }
}
Loading
Loading