Migrating from fixed fees to fee per byte – A developers guide

Welcome, developer!

As you may have seen, we are moving to utilising a minimum fee per byte at block 2,200,000. For more information on the reasons behind this decision, please check out this article from the core team: https://blog.turtlecoin.lol/archives/the-turtlecoin-journey-2-years-and-counting/

What do I have to do?

If you have an application which sends transactions on the TurtleCoin network, you will likely have to update your code to work correctly with fee per byte.

Step one is ensuring you have the latest code. This is currently only available in the development branch on GitHub, but will become a published release once fully tested.

Once you are running version 0.22.0 of the software, you will need to update your code to work with it correctly.

The lazy, expensive way

Since we charge a fee per byte of 5.00 TRTL (Or 500 atomic units) per 256 bytes of transaction, and transactions are limited at 124400 bytes if you’re using the core software, you can just set a fixed fee of 2430 TRTL, or 243000 atomic units.

This fee will always be large enough to cover the biggest transactions, so you can just update your fee parameter in your sendTransaction JSON, for turtle-service, and with wallet-api, update your /send/transaction/advanced fee parameter and you’re done. If you’re currently using /send/transaction/basic with wallet-api, you will either want to migrate to using /send/transaction/advanced, or read on for a method that works with /send/transaction/basic.

However, this is not the cheapest way. In addition, if the minimum fee per byte is increased in a later fork, you will have to update your code again. Booooo!

Read on if you want to make your users like you more. Don’t worry, it’s not hard!

The cheaper way

If you just want to use the minimum fee per byte allowed, all you have to do is not specify the fee parameter in your sendTransaction or /send/transaction/advanced JSON. The wallet application, be it turtle-service, or wallet-api, will then automatically calculate the minimum fee for the transaction. If you are currently using /send/transaction/basic, it does not have a fee parameter, so this is the default behaviour.

Once the transaction is sent, the actual fee paid will be returned along with the transaction hash. This way you can update your database, display the fee to the user, and so on, as needed.

“Hang On!” – I hear you shout. How do you know how much the fee will be before sending the transaction? Not to fear – we’ve thought of that.

turtle-service

With turtle-service, instead of using sendTransaction, you can use createDelayedTransaction. This method works exactly the same as sendTransaction, except it does not relay the transaction to the network – so no funds are sent. It will return the transaction hash, and the fee of the transaction.

If the fee is fine, and you want to send the transaction, you can use the sendDelayedTransaction method.

If you’re not happy with the fee, or want to cancel the transaction for some other reason, use the deleteDelayedTransaction method to cancel the transaction. If you do not delete the delayed transaction, the funds will remain unspendable, so don’t forget this step!

wallet-api

With wallet-api, the process is very similar. Instead of using /transactions/send/basic or /transactions/send/advanced, you can use /transactions/prepare/basic or /transactions/prepare/advanced.

As will turtle-service, these methods are identical to the standard ones, and take all the same parameters.

Again, like turtle-service, these methods will return the fee of the prepared transaction, and the transaction hash.

You can then use /transactions/send/prepared to send your prepared transaction if you are happy with the fee. If you want to cancel a prepared transaction, use the /transactions/prepared/{transaction hash}/ DELETE method.

Unlike turtle-service, a prepared transaction does not lock your funds for spending, and therefore cancelling a prepared transaction is not mandatory. It will, however, save a little bit of RAM usage from not having to store the transaction data.

Due to the funds not being locked, this can result in a previously prepared transaction no longer being possible to be sent – If you sent another transaction meanwhile, it could include inputs that the prepared transaction also included.

Finally, due to a deterministic input selection algorithm, even if your prepared transaction is no longer valid, the fee for sending the same transaction again is likely to be very similar. This means you can essentially use the prepare transaction methods as a means to estimate the fee of a subsequent transaction with the same data.

Specifying the fee per byte

If you desire to pay a higher than minimum fee per byte, we have you covered. Simply include the feePerByte argument in your transaction JSON, in replacement of the fee parameter. This value can be a floating point value, and should be greater or equal to the minimum fee per byte of 1.953125.

Examples

turtle-service example

Request before fee per byte
{
   "jsonrpc":"2.0",
   "id":1,
   "password":"passw0rd",
   "method":"sendTransaction",
   "params":{
      "transfers":[
         {
            "address":"TRTLxxxx...",
            "amount":5000
         }
      ]
   },
   "fee": 10
}
Response before fee per byte
{
  "id":1,
  "jsonrpc":"2.0",
  "result":{
    "transactionHash":"ae57e..."
  }
}
Above: Before, Below: After
Request after fee per byte
{
   "jsonrpc":"2.0",
   "id":1,
   "password":"passw0rd",
   "method":"sendTransaction",
   "params":{
      "transfers":[
         {
            "address":"TRTLxxxx...",
            "amount":5000
         }
      ]
   },
}
Response
{
  "id":1,
  "jsonrpc":"2.0",
  "result":{
    "transactionHash":"ae57e...",
    "fee": 4500
  }
}

wallet-api example

Before fee per byte

Request before fee per byte
{
  "destinations": {
    "address": "TRTLv2Fyavy8CXG8BPEbNeCHFZ1fuDCYCZ3vW5H5LXN4K2M2MHUpTENip9bbavpHvvPwb4NDkBWrNgURAd5DB38FHXWZyoBh4wW",
    "amount": 1234
  },
  "fee": 10,
  "sourceAddresses": "TRTLv2Fyavy8CXG8BPEbNeCHFZ1fuDCYCZ3vW5H5LXN4K2M2MHUpTENip9bbavpHvvPwb4NDkBWrNgURAd5DB38FHXWZyoBh4wW"
}
Response before fee per byte
{
  "transactionHash": "396e2a782c9ce9993982c6f93e305b05306d0e5794f57157fbac78581443c55f"
}

After fee per byte

Request after fee per byte
{
  "destinations": {
    "address": "TRTLv2Fyavy8CXG8BPEbNeCHFZ1fuDCYCZ3vW5H5LXN4K2M2MHUpTENip9bbavpHvvPwb4NDkBWrNgURAd5DB38FHXWZyoBh4wW",
    "amount": 1234
  },
  "sourceAddresses": "TRTLv2Fyavy8CXG8BPEbNeCHFZ1fuDCYCZ3vW5H5LXN4K2M2MHUpTENip9bbavpHvvPwb4NDkBWrNgURAd5DB38FHXWZyoBh4wW"
}
Response after fee per byte
{
  "transactionHash": "396e2a782c9ce9993982c6f93e305b05306d0e5794f57157fbac78581443c55f",
  "fee": 1000,
  "relayedToNetwork": true
}

Suggestions

There are a few things you can do as a service operator to decrease the fees you pay.

The first is sending round number outputs. For example, sending a transaction of 20000 TRTL will result in a single output, while sending a transaction of 22222 TRTL will result in 5 outputs. Outputs are not the only thing that make a transaction bigger, but this is one of the variables that you can easily control.

The second is increasing default payouts. Instead of creating 10 transactions of 1000 TRTL, and thus creating 10 outputs, you can instead create 1 transaction of 10000 TRTL, which will only create a single output.

Applying these changes will result in you paying less fees, and will also mean your users pay less fees when they come to spend their funds – they will have less resulting inputs in their wallet, so will create smaller, cheaper, transactions.

Closing remarks

Confused? Want some more help?

Start by checking out the documentation of the API you are using.

Finally, if you just can’t get the hang of it, or want some clarification on how it all works, stop by the #dev_learning or #dev_general channels in our discord, and we’ll happily help you out. If you’re not in discord already, you can find the invite at chat.turtlecoin.lol.

Happy Hacking!

Clap

(107)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.