Skip to content

Commit

Permalink
- update hard gas limit
Browse files Browse the repository at this point in the history
- update estimation calculation to take into account stake/unstake differences
- update and add more tests
  • Loading branch information
simonmcl committed Jun 13, 2024
1 parent 5b8e07f commit c4e01b1
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Sources/KukaiCoreSwift/Models/NetworkConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public struct NetworkConstants: Codable {
}

public func maxGasPerBlock() -> Int {
return Int(hard_gas_limit_per_block) ?? 2600000
return Int(hard_gas_limit_per_block) ?? 1733333
}

public func maxStoragePerOperation() -> Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ public struct BalanceUpdate: Codable {
let change: String
let delegate: String?
let cycle: Int?
let staker: BalanceUpdateStake?
}

public struct BalanceUpdateStake: Codable {
let contract: String
let delegate: String
}

/// The inner `result` key from the `OeprationResponse`
Expand Down
11 changes: 8 additions & 3 deletions Sources/KukaiCoreSwift/Services/FeeEstimatorService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public class FeeEstimatorService {
// To handle issues with sending max Tez, and simulation API not ignoring burn fees etc
// modify the operationPayload contents to send 1 mutez instead of real amount
// This won't effect the returned operations later, as we've made a deep copy first and will use that afte rthe estimation
if $0.operationKind == .transaction, let transOp = $0 as? OperationTransaction, (transOp.destination.prefix(3) != "KT1" && ($0 as? OperationTransaction)?.parameters == nil) {
if $0.operationKind == .transaction, let transOp = $0 as? OperationTransaction, (transOp.destination.prefix(3) != "KT1" && transOp.parameters == nil && transOp.destination != walletAddress) {
transOp.amount = "1" // rpc representation of 1 mutez
}
}
Expand Down Expand Up @@ -236,7 +236,7 @@ public class FeeEstimatorService {
}

for balanceUpdate in content.metadata.operationResult?.balanceUpdates ?? [] {
if balanceUpdate.contract == address {
if balanceUpdate.contract == address || balanceUpdate.staker?.contract == address {
opStorage -= Decimal(string: balanceUpdate.change) ?? 0
}
}
Expand All @@ -261,6 +261,7 @@ public class FeeEstimatorService {
opGas = Decimal(FeeEstimatorService.addGasSafetyMarginTo(gasUsed: opGas.intValue()))



// Convert storage to bytes
opStorage = opStorage / (constants.xtzPerByte().toRpcDecimal() ?? 250)

Expand All @@ -275,7 +276,9 @@ public class FeeEstimatorService {
}
}

// Check whether suggested or estimated gas / sotrage is higher and pick that


// Check whether suggested or estimated gas / storage is higher and pick that
let indexToCheck = index + suggestedCompareIndex
if indexToCheck > -1 {
let op = originalRemoteOps[indexToCheck]
Expand All @@ -290,6 +293,8 @@ public class FeeEstimatorService {
}




// Sum totals for later
totalGas += opGas
totalStorage += opStorage
Expand Down
4 changes: 4 additions & 0 deletions Tests/KukaiCoreSwiftTests/MockConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ public struct MockConstants {
(MockConstants.jsonStub(fromFilename: "simulate_operation-crunchy-swap-response"), MockConstants.http200),
MockPostUrlKey(url: simulateURL1, requestData: MockConstants.jsonStub(fromFilename: "simulate_operation-high-gas-low-storage-request")):
(MockConstants.jsonStub(fromFilename: "simulate_operation-high-gas-low-storage-response"), MockConstants.http200),
MockPostUrlKey(url: simulateURL1, requestData: MockConstants.jsonStub(fromFilename: "simulate_operation-stake-request")):
(MockConstants.jsonStub(fromFilename: "simulate_operation-stake-response"), MockConstants.http200),
MockPostUrlKey(url: simulateURL1, requestData: MockConstants.jsonStub(fromFilename: "simulate_operation-unstake-request")):
(MockConstants.jsonStub(fromFilename: "simulate_operation-unstake-response"), MockConstants.http200),
]

config.urlSession = mockURLSession
Expand Down
78 changes: 76 additions & 2 deletions Tests/KukaiCoreSwiftTests/Services/FeeEstimatorServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ class FeeEstimatorServiceTests: XCTestCase {
wait(for: [expectation1], timeout: 120)
}

// TODO: add teset with and without reveal

// Test that if a dApp suggests a high gas amount, but a low storage amount. That we take the gas, but use our own higher estimated storage
func testJSONPayload3() {
let decoder = JSONDecoder()
Expand Down Expand Up @@ -206,4 +204,80 @@ class FeeEstimatorServiceTests: XCTestCase {

wait(for: [expectation1], timeout: 120)
}

// Test stake
func testJSONPayload4() {
let decoder = JSONDecoder()

let jsonDataRequest1 = MockConstants.jsonStub(fromFilename: "simulate_operation-stake-operations")
let jsonRequestOps1 = (try? decoder.decode([OperationTransaction].self, from: jsonDataRequest1)) ?? []
XCTAssert(jsonRequestOps1.count != 0)

let expectation1 = XCTestExpectation(description: "Estimation service")
let address = MockConstants.defaultHdWallet.address
let key = MockConstants.defaultHdWallet.publicKeyBase58encoded()
estimationService.estimate(operations: jsonRequestOps1, operationMetadata: MockConstants.operationMetadata, constants: MockConstants.networkConstants, walletAddress: address, base58EncodedPublicKey: key) { result in
switch result {
case .success(let result):
XCTAssert(result.operations.count == 1, result.operations.count.description)
XCTAssert(result.operations[0].operationFees.gasLimit == 3703, result.operations[0].operationFees.gasLimit.description)
XCTAssert(result.operations[0].operationFees.storageLimit == 2, result.operations[0].operationFees.storageLimit.description)
XCTAssert(result.operations[0].operationFees.allFees().normalisedRepresentation == "0.001144", result.operations[0].operationFees.allFees().normalisedRepresentation)

let totalGas = result.operations.map({ $0.operationFees.gasLimit }).reduce(0, +)
XCTAssert(totalGas == 3703, totalGas.description)

let totalStorage = result.operations.map({ $0.operationFees.storageLimit }).reduce(0, +)
XCTAssert(totalStorage == 2, totalStorage.description)

let totalFee = result.operations.map({ $0.operationFees.allFees() }).reduce(XTZAmount.zero(), +)
XCTAssert(totalFee.normalisedRepresentation == "0.001144", totalFee.normalisedRepresentation)

case .failure(let error):
XCTFail(error.description)
}

expectation1.fulfill()
}

wait(for: [expectation1], timeout: 120)
}

// Test unstake
func testJSONPayload5() {
let decoder = JSONDecoder()

let jsonDataRequest1 = MockConstants.jsonStub(fromFilename: "simulate_operation-unstake-operations")
let jsonRequestOps1 = (try? decoder.decode([OperationTransaction].self, from: jsonDataRequest1)) ?? []
XCTAssert(jsonRequestOps1.count != 0)

let expectation1 = XCTestExpectation(description: "Estimation service")
let address = MockConstants.defaultHdWallet.address
let key = MockConstants.defaultHdWallet.publicKeyBase58encoded()
estimationService.estimate(operations: jsonRequestOps1, operationMetadata: MockConstants.operationMetadata, constants: MockConstants.networkConstants, walletAddress: address, base58EncodedPublicKey: key) { result in
switch result {
case .success(let result):
XCTAssert(result.operations.count == 1, result.operations.count.description)
XCTAssert(result.operations[0].operationFees.gasLimit == 4335, result.operations[0].operationFees.gasLimit.description)
XCTAssert(result.operations[0].operationFees.storageLimit == 0, result.operations[0].operationFees.storageLimit.description)
XCTAssert(result.operations[0].operationFees.allFees().normalisedRepresentation == "0.000704", result.operations[0].operationFees.allFees().normalisedRepresentation)

let totalGas = result.operations.map({ $0.operationFees.gasLimit }).reduce(0, +)
XCTAssert(totalGas == 4335, totalGas.description)

let totalStorage = result.operations.map({ $0.operationFees.storageLimit }).reduce(0, +)
XCTAssert(totalStorage == 0, totalStorage.description)

let totalFee = result.operations.map({ $0.operationFees.allFees() }).reduce(XTZAmount.zero(), +)
XCTAssert(totalFee.normalisedRepresentation == "0.000704", totalFee.normalisedRepresentation)

case .failure(let error):
XCTFail(error.description)
}

expectation1.fulfill()
}

wait(for: [expectation1], timeout: 120)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"amount": "100000000",
"counter": "10534537",
"destination": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"kind": "transaction",
"parameters": {
"entrypoint": "stake",
"value": {
"prim": "Unit"
}
},
"source": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"chain_id":"NetXxkAx4woPLyu","operation":{"branch":"BLEDGNuADAwZfKK7iZ6PHnu7gZFSXuRPVFXe2PhSnb6aMyKn3mK","contents":[{"amount":"100000000","counter":"143231","destination":"tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss","fee":"0","gas_limit":"5200000","kind":"transaction","parameters":{"entrypoint":"stake","value":{"prim":"Unit"}},"source":"tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss","storage_limit":"60000"}],"signature":"edsigtXomBKi5CTRf5cjATJWSyaRvhfYNHqSUGrn4SdbYRcGwQrUGjzEfQDTuqHhuA8b2d8NarZjz8TRf65WkpQmo423BtomS8Q"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"contents": [
{
"amount": "100000000",
"fee": "0",
"kind": "transaction",
"source": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"destination": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"metadata": {
"balance_updates": [
{
"kind": "contract",
"contract": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"change": "-641",
"origin": "block"
},
{
"kind": "accumulator",
"category": "block fees",
"change": "641",
"origin": "block"
}
],
"operation_result": {
"status": "applied",
"balance_updates": [
{
"kind": "staking",
"category": "delegator_numerator",
"delegator": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"change": "92355529",
"origin": "block"
},
{
"kind": "staking",
"category": "delegate_denominator",
"delegate": "tz1YgDUQV2eXm8pUWNz3S5aWP86iFzNp4jnD",
"change": "92355529",
"origin": "block"
},
{
"kind": "contract",
"contract": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"change": "-100000000",
"origin": "block"
},
{
"kind": "freezer",
"category": "deposits",
"staker": {
"contract": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"delegate": "tz1YgDUQV2eXm8pUWNz3S5aWP86iFzNp4jnD"
},
"change": "100000000",
"origin": "block"
}
],
"consumed_milligas": "3629053"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"kind": "transaction",
"source": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"amount": "1",
"destination": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"parameters": {
"entrypoint": "unstake",
"value": {
"prim": "Unit"
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"chain_id":"NetXxkAx4woPLyu","operation":{"branch":"BLEDGNuADAwZfKK7iZ6PHnu7gZFSXuRPVFXe2PhSnb6aMyKn3mK","contents":[{"amount":"1","counter":"143231","destination":"tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss","fee":"0","gas_limit":"5200000","kind":"transaction","parameters":{"entrypoint":"unstake","value":{"prim":"Unit"}},"source":"tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss","storage_limit":"60000"}],"signature":"edsigtXomBKi5CTRf5cjATJWSyaRvhfYNHqSUGrn4SdbYRcGwQrUGjzEfQDTuqHhuA8b2d8NarZjz8TRf65WkpQmo423BtomS8Q"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"contents": [
{
"kind": "transaction",
"source": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"fee": "0",
"counter": "11240021",
"gas_limit": "866666",
"storage_limit": "60000",
"amount": "1",
"destination": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"parameters": {
"entrypoint": "unstake",
"value": {
"prim": "Unit"
}
},
"metadata": {
"operation_result": {
"status": "applied",
"balance_updates": [
{
"kind": "staking",
"category": "delegate_denominator",
"delegate": "tz1YgDUQV2eXm8pUWNz3S5aWP86iFzNp4jnD",
"change": "-1",
"origin": "block"
},
{
"kind": "staking",
"category": "delegator_numerator",
"delegator": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"change": "-1",
"origin": "block"
},
{
"kind": "freezer",
"category": "deposits",
"staker": {
"contract": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"delegate": "tz1YgDUQV2eXm8pUWNz3S5aWP86iFzNp4jnD"
},
"change": "-1",
"origin": "block"
},
{
"kind": "freezer",
"category": "unstaked_deposits",
"staker": {
"contract": "tz1Ue76bLW7boAcJEZf2kSGcamdBKVi4Kpss",
"delegate": "tz1YgDUQV2eXm8pUWNz3S5aWP86iFzNp4jnD"
},
"cycle": 1064,
"change": "1",
"origin": "block"
}
],
"consumed_milligas": "4249020"
}
}
}
],
"signature": "edsigtXomBKi5CTRf5cjATJWSyaRvhfYNHqSUGrn4SdbYRcGwQrUGjzEfQDTuqHhuA8b2d8NarZjz8TRf65WkpQmo423BtomS8Q"
}

0 comments on commit c4e01b1

Please sign in to comment.