Skip to content

Commit

Permalink
fix: requested changes
Browse files Browse the repository at this point in the history
Signed-off-by: Ricky Saechao <ricky@launchbadge.com>
  • Loading branch information
RickyLB committed Jun 5, 2024
1 parent 10fb994 commit cd53c1a
Show file tree
Hide file tree
Showing 21 changed files with 124 additions and 301 deletions.
12 changes: 6 additions & 6 deletions Sources/Hedera/Account/AccountBalanceQuery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ public final class AccountBalanceQuery: Query<AccountBalance> {
let mirrorNodeGateway = try MirrorNodeGateway.forNetwork(context.mirrorNetworkNodes, context.ledgerId)
let mirrorNodeService = MirrorNodeService.init(mirrorNodeGateway)

guard case .cryptogetAccountBalance(let proto) = response else {
guard case .cryptogetAccountBalance(var proto) = response else {
throw HError.fromProtobuf("unexpected \(response) received, expected `cryptogetAccountBalance`")
}

let accountId = try AccountId.fromProtobuf(proto.accountID)
let tokenBalanceProto = try await mirrorNodeService.getTokenBalancesForAccount(String(accountId.num))
let tokenBalanceProto = try await mirrorNodeService.getTokenBalancesForAccount(
String(proto.accountID.accountNum))

return AccountBalance(
accountId: accountId, hbars: .fromTinybars(Int64(proto.balance)),
tokensInner: .fromProtobuf(tokenBalanceProto))
proto.tokenBalances = tokenBalanceProto

return try .fromProtobuf(proto)
}

public override func validateChecksums(on ledgerId: LedgerId) throws {
Expand Down
9 changes: 0 additions & 9 deletions Sources/Hedera/Account/AccountId.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,6 @@ public struct AccountId: Sendable, EntityId, ValidateChecksums {
public func toBytes() -> Data {
toProtobufBytes()
}

public func populateAccountIdNum(_ client: Client) async throws -> Self {
let mirrorNodeGateway = try MirrorNodeGateway.forClient(client)
let mirrorNodeService = MirrorNodeService(mirrorNodeGateway)

let accountNumFromMirror = try await mirrorNodeService.getAccountNum(self.evmAddress!.toString())

return Self(shard: shard, realm: realm, num: accountNumFromMirror)
}
}

extension AccountId: TryProtobufCodable {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Hedera/Account/AccountInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public struct AccountInfo: Sendable {
/// Staking metadata for this account.
public let staking: StakingInfo?

/// Staking metadata for this account.
/// Token relationships for this account.
public let tokenRelationships: [TokenId: TokenRelationship]

/// Decode `Self` from protobuf-encoded `bytes`.
Expand Down
34 changes: 4 additions & 30 deletions Sources/Hedera/Account/AccountInfoQuery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,42 +65,16 @@ public final class AccountInfoQuery: Query<AccountInfo> {
let mirrorNodeGateway = try MirrorNodeGateway.forNetwork(context.mirrorNetworkNodes, context.ledgerId)
let mirrorNodeService = MirrorNodeService.init(mirrorNodeGateway)

guard case .cryptoGetInfo(let proto) = response else {
guard case .cryptoGetInfo(var proto) = response else {
throw HError.fromProtobuf("unexpected \(response) received, expected `cryptoGetInfo`")
}

let accountInfo = try AccountInfo.fromProtobuf(proto.accountInfo)
let tokenRelationshipsProto = try await mirrorNodeService.getTokenRelationshipsForAccount(
String(describing: accountInfo.accountId.num))
String(describing: try AccountId.fromProtobuf(proto.accountInfo.accountID).num))

var tokenRelationships: [TokenId: TokenRelationship] = [:]
proto.accountInfo.tokenRelationships = tokenRelationshipsProto

for relationship in tokenRelationshipsProto {
tokenRelationships[.fromProtobuf(relationship.tokenID)] = try TokenRelationship.fromProtobuf(relationship)
}

return AccountInfo(
accountId: accountInfo.accountId,
contractAccountId: accountInfo.contractAccountId,
isDeleted: accountInfo.isDeleted,
proxyAccountId: accountInfo.proxyAccountId,
proxyReceived: accountInfo.proxyReceived,
key: accountInfo.key,
balance: accountInfo.balance,
sendRecordThreshold: accountInfo.sendRecordThreshold,
receiveRecordThreshold: accountInfo.receiveRecordThreshold,
isReceiverSignatureRequired: accountInfo.isReceiverSignatureRequired,
expirationTime: accountInfo.expirationTime,
autoRenewPeriod: accountInfo.autoRenewPeriod,
accountMemo: accountInfo.accountMemo,
ownedNfts: accountInfo.ownedNfts,
maxAutomaticTokenAssociations: accountInfo.maxAutomaticTokenAssociations,
aliasKey: accountInfo.aliasKey,
ethereumNonce: accountInfo.ethereumNonce,
tokenRelationships: tokenRelationships,
ledgerId: accountInfo.ledgerId,
staking: accountInfo.staking
)
return try .fromProtobuf(proto.accountInfo)
}

internal override func validateChecksums(on ledgerId: LedgerId) throws {
Expand Down
10 changes: 8 additions & 2 deletions Sources/Hedera/ChunkedTransaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,10 @@ extension ChunkedTransaction.FirstChunkView: Execute {
self.transaction.regenerateTransactionId
}

internal func makeRequest(_ client: Client, _ transactionId: TransactionId?, _ nodeAccountId: AccountId) throws -> (
internal func makeRequest(
_ ledgerId: LedgerId?, _ mirrorNodeNetworks: [String], _ transactionId: TransactionId?,
_ nodeAccountId: AccountId
) throws -> (
GrpcRequest, Context
) {
assert(transaction.isFrozen)
Expand Down Expand Up @@ -265,7 +268,10 @@ extension ChunkedTransaction.ChunkView: Execute {
self.transaction.regenerateTransactionId
}

internal func makeRequest(_ client: Client, _ transactionId: TransactionId?, _ nodeAccountId: AccountId) throws -> (
internal func makeRequest(
_ ledgerId: LedgerId?, _ mirrorNodeNetworks: [String], _ transactionId: TransactionId?,
_ nodeAccountId: AccountId
) throws -> (
GrpcRequest, Context
) {
assert(transaction.isFrozen)
Expand Down
11 changes: 0 additions & 11 deletions Sources/Hedera/Contract/ContractId.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,6 @@ public struct ContractId: EntityId {
public func toBytes() -> Data {
toProtobufBytes()
}

public func populateContractNum(_ client: Client) async throws -> Self {
let address = try EvmAddress.fromBytes(self.evmAddress!)

let mirrorNodeGateway = try MirrorNodeGateway.forClient(client)
let mirrorNodeService = MirrorNodeService(mirrorNodeGateway)

let contractNum = try await mirrorNodeService.getContractNum(address.toString())

return Self(shard: shard, realm: realm, num: contractNum)
}
}

#if compiler(>=5.7)
Expand Down
4 changes: 2 additions & 2 deletions Sources/Hedera/Contract/ContractInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public struct ContractInfo {

/// The tokens associated to the contract
///
/// Query mirror node
/// Note: Query mirror node for token relationships.
public let tokenRelationships: [TokenId: TokenRelationship]

/// Ledger ID for the network the response was returned from.
Expand Down Expand Up @@ -104,7 +104,7 @@ extension ContractInfo: TryProtobufCodable {

self.init(
contractId: try .fromProtobuf(proto.contractID),
accountId: try AccountId.fromProtobuf(proto.accountID),
accountId: try .fromProtobuf(proto.accountID),
contractAccountId: proto.contractAccountID,
adminKey: try .fromProtobuf(adminKey),
expirationTime: .fromProtobuf(expirationTime),
Expand Down
30 changes: 4 additions & 26 deletions Sources/Hedera/Contract/ContractInfoQuery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public final class ContractInfoQuery: Query<ContractInfo> {
}

internal override func toQueryProtobufWith(_ header: Proto_QueryHeader) -> Proto_Query {

.with { proto in
proto.contractGetInfo = .with { proto in
proto.header = header
Expand All @@ -62,37 +61,16 @@ public final class ContractInfoQuery: Query<ContractInfo> {
let mirrorNodeGateway = try MirrorNodeGateway.forNetwork(context.mirrorNetworkNodes, context.ledgerId)
let mirrorNodeService = MirrorNodeService.init(mirrorNodeGateway)

guard case .contractGetInfo(let proto) = response else {
guard case .contractGetInfo(var proto) = response else {
throw HError.fromProtobuf("unexpected \(response) received, expected `contractGetInfo`")
}

let contractInfo = try ContractInfo.fromProtobuf(proto.contractInfo)
let tokenRelationshipsProto = try await mirrorNodeService.getTokenRelationshipsForAccount(
String(describing: contractInfo.contractId.num))

var tokenRelationships: [TokenId: TokenRelationship] = [:]
String(describing: proto.contractInfo.accountID.accountNum))

for relationship in tokenRelationshipsProto {
tokenRelationships[.fromProtobuf(relationship.tokenID)] = try TokenRelationship.fromProtobuf(relationship)
}
proto.contractInfo.tokenRelationships = tokenRelationshipsProto

return ContractInfo(
contractId: contractInfo.contractId,
accountId: contractInfo.accountId,
contractAccountId: contractInfo.contractAccountId,
adminKey: contractInfo.adminKey,
expirationTime: contractInfo.expirationTime,
autoRenewPeriod: contractInfo.autoRenewPeriod,
storage: contractInfo.storage,
contractMemo: contractInfo.contractMemo,
balance: contractInfo.balance,
isDeleted: contractInfo.isDeleted,
autoRenewAccountId: contractInfo.autoRenewAccountId,
maxAutomaticTokenAssociations: contractInfo.maxAutomaticTokenAssociations,
tokenRelationships: tokenRelationships,
ledgerId: contractInfo.ledgerId,
stakingInfo: contractInfo.stakingInfo
)
return try ContractInfo.fromProtobuf(proto.contractInfo)
}

internal override func validateChecksums(on ledgerId: LedgerId) throws {
Expand Down
17 changes: 12 additions & 5 deletions Sources/Hedera/Execute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ internal protocol Execute {
///
/// A created request is cached per node until any request returns
/// `TransactionExpired`; in which case, the request cache is cleared.
func makeRequest(_ client: Client, _ transactionId: TransactionId?, _ nodeAccountId: AccountId) throws -> (
func makeRequest(
_ ledgerId: LedgerId?, _ mirrorNodeNetworks: [String], _ transactionId: TransactionId?,
_ nodeAccountId: AccountId
) throws -> (
GrpcRequest, Context
)

Expand Down Expand Up @@ -97,7 +100,8 @@ private struct ExecuteContext {
fileprivate let network: Network
fileprivate let backoffConfig: LegacyExponentialBackoff
fileprivate let maxAttempts: Int
fileprivate let client: Client
fileprivate let ledgerId: LedgerId?
fileprivate let mirrorNodeNetworks: [String]
// timeout for a single grpc request.
fileprivate let grpcTimeout: Duration?
}
Expand Down Expand Up @@ -153,7 +157,8 @@ internal func executeAny<E: Execute & ValidateChecksums>(
network: client.net,
backoffConfig: backoffBuilder,
maxAttempts: backoff.maxAttempts,
client: client,
ledgerId: client.ledgerId,
mirrorNodeNetworks: client.mirrorNetwork,
grpcTimeout: nil
),
executable: executable)
Expand Down Expand Up @@ -189,7 +194,8 @@ private func executeAnyInner<E: Execute>(
}

let (nodeAccountId, channel) = ctx.network.channel(for: nodeIndex)
let (request, context) = try executable.makeRequest(ctx.client, transactionId, nodeAccountId)
let (request, context) = try executable.makeRequest(
ctx.ledgerId, ctx.mirrorNodeNetworks, transactionId, nodeAccountId)
let response: E.GrpcResponse

do {
Expand Down Expand Up @@ -313,7 +319,8 @@ private struct NodeIndexesGeneratorMap: AsyncSequence, AsyncIteratorProtocol {
network: ctx.network,
backoffConfig: ctx.backoffConfig,
maxAttempts: ctx.maxAttempts,
client: ctx.client,
ledgerId: ctx.ledgerId,
mirrorNodeNetworks: ctx.mirrorNodeNetworks,
grpcTimeout: ctx.grpcTimeout
),
executable: request
Expand Down
5 changes: 5 additions & 0 deletions Sources/Hedera/HError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public struct HError: Error, CustomStringConvertible {
case queryPaymentPreCheckStatus(status: Status, transactionId: TransactionId)
case queryNoPaymentPreCheckStatus(status: Status)
case basicParse
case mirrorNodeQuery
case keyParse
case keyDerive
case noPayerAccountOrTransactionId
Expand Down Expand Up @@ -86,6 +87,10 @@ public struct HError: Error, CustomStringConvertible {
Self(kind: .basicParse, description: description)
}

internal static func mirrorNodeQuery(_ description: String) -> Self {
Self(kind: .mirrorNodeQuery, description: description)
}

internal static func keyParse(_ description: String) -> Self {
Self(kind: .keyParse, description: "failed to parse a key: \(description)")
}
Expand Down
15 changes: 6 additions & 9 deletions Sources/Hedera/MirrorNodeGateway.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal struct MirrorNodeGateway {

internal func getAccountInfo(_ idOrAliasOrEvmAddress: String) async throws -> [String: Any] {
let fullApiUrl = MirrorNodeRouter.buildApiUrl(
self.mirrorNodeUrl, MirrorNodeRouter.accountsRoute, idOrAliasOrEvmAddress)
self.mirrorNodeUrl, MirrorNodeRouter.MirrorNodeRoute.accountInfoRoute, idOrAliasOrEvmAddress)

let responseBody = try await queryFromMirrorNode(fullApiUrl)

Expand All @@ -56,7 +56,7 @@ internal struct MirrorNodeGateway {

internal func getContractInfo(_ idOrAliasOrEvmAddress: String) async throws -> [String: Any] {
let fullApiUrl = MirrorNodeRouter.buildApiUrl(
self.mirrorNodeUrl, MirrorNodeRouter.contractsRoute, idOrAliasOrEvmAddress)
self.mirrorNodeUrl, MirrorNodeRouter.MirrorNodeRoute.contractInfoRoute, idOrAliasOrEvmAddress)

let responseBody = try await queryFromMirrorNode(fullApiUrl)

Expand All @@ -67,7 +67,7 @@ internal struct MirrorNodeGateway {

internal func getAccountTokens(_ idOrAliasOrEvmAddress: String) async throws -> [String: Any] {
let fullApiUrl = MirrorNodeRouter.buildApiUrl(
self.mirrorNodeUrl, MirrorNodeRouter.tokensAccountRoute, idOrAliasOrEvmAddress)
self.mirrorNodeUrl, MirrorNodeRouter.MirrorNodeRoute.tokenRelationshipsRoute, idOrAliasOrEvmAddress)

let responseBody = try await queryFromMirrorNode(fullApiUrl)

Expand All @@ -82,6 +82,7 @@ internal struct MirrorNodeGateway {
try? httpClient.syncShutdown()
}

// Delay is needed to fetch data from the mirror node.
if apiUrl.contains("127.0.0.1:5551") {
try await Task.sleep(nanoseconds: 1_000_000_000 * 3)
}
Expand All @@ -98,15 +99,11 @@ internal struct MirrorNodeGateway {

func deserializeJson(_ responseBody: String) async throws -> [String: Any] {
guard let jsonData = responseBody.data(using: .utf8) else {
throw NSError(
domain: "InvalidResponseError", code: -1,
userInfo: [NSLocalizedDescriptionKey: "Response body is not valid UTF-8"])
throw HError.mirrorNodeQuery("Response body is not valid UTF-8")
}

guard let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] else {
throw NSError(
domain: "InvalidResponseError", code: -1,
userInfo: [NSLocalizedDescriptionKey: "Response body is not a valid JSON object"])
throw HError.mirrorNodeQuery("Response body is not a valid JSON object")
}

return jsonObject
Expand Down
20 changes: 7 additions & 13 deletions Sources/Hedera/MirrorNodeRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,11 @@ internal struct MirrorNodeRouter {

static let localNodePort = "5551"

public static let accountsRoute = "accounts"
public static let contractsRoute = "contracts"
public static let tokensAccountRoute = "account_tokens"

static let routes: [String: String] = [
accountsRoute: "/accounts/%@",
contractsRoute: "/contracts/%@",
tokensAccountRoute: "/accounts/%@/tokens",
]

private func mirrorNodeRouter() {}
public enum MirrorNodeRoute: String {
case accountInfoRoute = "/accounts/%@"
case contractInfoRoute = "/contracts/%@"
case tokenRelationshipsRoute = "/accounts/%@/tokens"
}

static func getMirrorNodeUrl(_ mirrorNetwork: [String], _ ledgerId: LedgerId?) throws -> String {
var mirrorNodeAddress: String = ""
Expand All @@ -62,7 +56,7 @@ internal struct MirrorNodeRouter {
return fullMirrorNodeUrl
}

static func buildApiUrl(_ mirrorNodeUrl: String, _ route: String, _ id: String) -> String {
return String("\(mirrorNodeUrl)\(apiVersion)\(String(format: "\(String(describing: routes[route]!))", id))")
static func buildApiUrl(_ mirrorNodeUrl: String, _ route: MirrorNodeRoute, _ id: String) -> String {
return String("\(mirrorNodeUrl)\(apiVersion)\(route.rawValue.replacingOccurrences(of: "%@", with: id))")
}
}
Loading

0 comments on commit cd53c1a

Please sign in to comment.