Current Limitations? Estimating ETH costs to upload files? Proper way to find answers?

I’m confused and have been for a while.

I keep hitting barriers with using the production network and I struggle to understand them. I don’t use alphanet because I have funds on production (Arbitrum One) and want to understand what Autonomi can actually do right now, so I can feel more confident that it’s possible to develop my ideas on Autonomi (and be economically viable). I dropped out of Infinite Futures without making a pitch, partly because I struggled to figure out if many of my project ideas could be built within Autonomi’s present capabilities/limitations.

If I understand correctly, currently the ETH cost of uploading is way more costly than the ANT cost. So I want to understand how much gas is used per chunk, e.g. does storing two chunks cost 2x the gas of 1 chunk? Does storing 10 chunks cost 10x the gas of 1 chunk? etc. I’m fairly sure the answer is “no” because of batch transactions (paying many nodes simultaneously), but how to estimate total ETH required for uploads has eluded me so far. I thought that one workaround could be to upload several files of varying size, and try to analyse how much gas I’m using for these test files.

I’ve tried using ant-cli for several versions to upload a Linux iso file, and it always fails. The quoting functionality has always taken a long time for me and eventually fails after more than a half hour. I just tried again and it took about an hour “Quoting for 1034 chunks..” before it said “Paying for 1034 chunks..” for a minute or so then failed with “execution reverted”.

$ ls -lah kali-linux-2024.3-installer-amd64.iso
-rw-r--r-- 1 sbosshardt sbosshardt 4.1G Oct 14  2024 kali-linux-2024.3-installer-amd64.iso
$ ant file upload -p kali-linux-2024.3-installer-amd64.iso
Logging to directory: "/home/sbosshardt/.local/share/autonomi/client/logs/log_2025-05-18_12-38-54"
🔗 Connected to the Network                                                                                      
Uploading data to network...
Encrypting file: "kali-linux-2024.3-installer-amd64.iso"..
Successfully encrypted file: "kali-linux-2024.3-installer-amd64.iso"
Quoting for 1034 chunks..
Paying for 1034 chunks..

   0: Failed to upload file
   1: Failed to upload file
   2: Error occurred during payment.
   3: Wallet error: ChunkPaymentsContract(RpcError(ErrorResp(ErrorPayload { code: -32000, message: "execution reverted", data: None })))
   4: Chunk payments contract error: server returned an error response: error code -32000: execution reverted
   5: server returned an error response: error code -32000: execution reverted

Location:
   ant-cli/src/commands/file.rs:86

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

I’ve tried searching the forum but usually don’t find solutions, only people copy/pasting similar error messages.

I’ve tried to find the source code for the quoting contract and searched all the Maidsafe organization on Github but failed to find it. All I found was build artifacts - no Solidity source code. I assumed that Github is a good place to ask development-related questions and asked about this by opening an issue on Github weeks ago but there’s been no activity. I decompiled the smart contract and asked an LLM to do some analysis on it and come up with better variable names. It wrote an explanation document of PaymentVaultNoProxyV2, and mentioned that there is a batchLimit state variable: “Maximum number of payments that can be processed in a single transaction (512)”. But I’m not sure if Claude’s explanation is referring to number of chunks, or number of nodes (of course, I could ask, but I feel like I’m so far into the weeds already). I’m reluctant to publish the decompiled contracts and AI-generated documentation because my question (in the Github issue) about whether it is closed source for a reason was not answered - I don’t know if there’s copyright/licensing restrictions, security concerns, etc.

I tried searching in Discord but couldn’t find insight/solutions to this uploading problem either. I tried visiting the Autonomi developer forum (sister Discourse site) in hopes of finding a good place to discuss documentation-related topics but the forum seems to be unused in recent months.

I feel like I must be missing something to be struggling with understand basic things like limitations like file size, ETH cost to upload, how many chunks can be quoted/bought at a time. I’ve even read rust cargo crates documentation out of desperation. I mean, I figure the point of Autonomi is to be able to upload lots of data. The main documentation for payments I can find gives a newbie-friendly code example of storing “Hello World”, and ant file upload -p <filename> works for me for small files, but how big is too big? Dozens of chunks has worked for me, and 1034 chunks does not.

I’m also confused about whether the cost estimation tool (ant file cost) is getting an estimate for a private file or a public file. Because ant file upload --help shows that there’s a -p flag for a public file but there isn’t one for ant file cost --help. I think that a private status changes the chunk contents and addresses (since there is a datamap in the first chunk), so I’d think the quotes would be for an entirely different set of XOR addresses. And I don’t know whether the quoted cost is in ANT or ETH, e.g. for a 71 MB file:

$ ls -lah NVIDIA-Linux-x86_64-343.36.run
-rw-r--r-- 1 sbosshardt sbosshardt 71M Jan  8  2015 NVIDIA-Linux-x86_64-343.36.run
$ ant file cost NVIDIA-Linux-x86_64-343.36.run
Logging to directory: "/home/sbosshardt/.local/share/autonomi/client/logs/log_2025-05-18_12-57-55"
🔗 Connected to the Network                                                                                       Getting upload cost...
Estimate cost to upload file: NVIDIA-Linux-x86_64-343.36.run
Total cost: 0.000001004560771680

I assume that it’s giving the cost in ANT and not ETH, even though (I think) the ETH cost of uploading is significantly higher than ANT. I don’t know how much higher, but I believe it’s at least an order of magnitude. And if so, it seems like the most significant component of the cost to end-users (ETH) could be provided way more quickly. I mean, I figure why should I care how much ANT an upload costs and wait so long for a quote if the ETH needed costs me >10x more than what the ANT is valued at. Seems like the only reason I’d want to obtain quotes is when I’m actively trying to upload files (since quotes are a required part of the process of paying nodes for storage space). I also don’t know if maybe there is some timeout that’s going on - perhaps ant-cli takes too long to obtain quotes for all the chunks of a file that the upload fails because quotes are expiring before they’ve all been collected?

I have tried many times asking ChatGPT o3 questions, and it usually seems to do a good job answering them. But answers typically take minutes to generate, and it queries dozens of web pages. And I’m not always sure whether its answers are truthful or hallucinated. I can’t shake the feeling that I’m overthinking this and there’s a better way to learn that I’m missing.

7 Likes

I’ve pointed out the importance of this for developers and asked Autonomi to help but got no response.

@neo put forward his understanding on Discord but that’s lost because Discord is rubbish.

Maybe he can post his understanding here.

We really need a proper explanation and formula that can help developers understand this from Autonomi though.

7 Likes

Was talking with Mick on discord and he gave some estimates on cost for a 3 chunk file, which is 5 records being uploaded

  • 3 chunks
  • datamap
  • archive

The estimate for cost also has to include the fee to pay for the transaction processing to process the transfers involved. A transaction can be upto 250 transfers which represents just over 80 records since 3 transfers per record. It is 3 per record because of the payment to 3 nodes per record which pays for the upload to 3 nodes per record.

The cost estimate he gave was a little over 1 million GAS units which is approx 200K GAS units per record/processing.

GAS is actually a unit and there is a cost per GAS unit typically in GWEN (If I got that unit right). But you can specify to the client a “max-fee-per-gas” which is in 10^-18 ARB-ETH. So a fee of 0.01 GWEN is 10 million x 10^-18 ARB-ETH.

From this you can get an approximate maximum fee for uploading a file.

Take the file, work out the number of chunks. There are 80 chunks per transaction. So for up to 80 chunks it will be approx after rounding up to approx 200K per transfer/processing, even though its slightly less (1 million / 6 )

  • chunks * 200K
  • datamap = 200K
  • archive = 200K
  • max of max-fee-per-gas

Thus if 80 chunks then it is
(80 + 1 + 1 + 1) * 200K * max-fee-per-gas * 10^-18 of ARB-ETH

The lowest value allowed by the network of max-fee-per-gas is 10 million and will fail if GAS fee is even higher at the time. But if not then the actual gas fee charged can be lower still, just the network will not allow a lower max gas to be specified.

Thus for 80 chunks and 10 million as the max-fee-per-gas the charge would be approx 0.000168 ARB-ETH $0.42 at current ETH price of $2500

Hope this helps.

Yes, this should be a presented piece of information. But honestly I doubt it will be presented as it is an issue to them since its not as cheap as it was advertised to have been. And I can understand that, maybe not agree, but understand.

It can be cheaper than this if the GAS fee is lower than the network block limit placed on specifying a lower max fee.

10 Likes

That is done by the EVM and a smart contract. I do hope and I do expect, the smart contract to be on display since this is an opensourced project.

5 Likes

That’s helpful, thanks.

Ethereum has “Gwei” (giga-wei, or one billion wei). A “wei” is the smallest unit of Ethereum and each gwei is equal to one-billionth of an ETH (0.000000001 ETH or 10^-9 ETH).

I’m unsure what the third “+ 1” of “(80 + 1 + 1 + 1)” refers to. I assume that one of the +1’s is for datamap and another +1 is for archive.

I’m not finding occurrences of “archive” in the documentation. At first I thought that maybe it’s a double-counting of datamap. But I do recall that I’ve had multiple files be downloaded and have filenames, so I guess it has to do with mapping filenames to data maps. i.e. each file gets its own datamap.

I still have a ways to go in my understanding.

To explore this further, I figured I’d find try using ant file upload -p <dir> to upload a random folder of some open source files. It takes a few minutes and what’s weird to me is that even though it only has a total of 44 KB over 8 files, uploading this folder reportedly causes 36 chunks to be uploaded. It’s as though each file cannot be smaller than 4 chunks.

$ du -h --max-depth 0 node_modules/are-we-there-yet
44K	node_modules/are-we-there-yet
$ ls -lah node_modules/are-we-there-yet
total 28K
drwxrwxr-x   3 sbosshardt sbosshardt 4.0K Nov  8  2023 .
drwxrwxr-x 101 sbosshardt sbosshardt 4.0K Nov  8  2023 ..
drwxrwxr-x   2 sbosshardt sbosshardt 4.0K Nov  8  2023 lib
-rw-rw-r--   1 sbosshardt sbosshardt  717 Nov  8  2023 LICENSE.md
-rw-rw-r--   1 sbosshardt sbosshardt 1.3K Nov  8  2023 package.json
-rw-rw-r--   1 sbosshardt sbosshardt 6.5K Nov  8  2023 README.md
$ ls -lah node_modules/are-we-there-yet/lib
total 28K
drwxrwxr-x 2 sbosshardt sbosshardt 4.0K Nov  8  2023 .
drwxrwxr-x 3 sbosshardt sbosshardt 4.0K Nov  8  2023 ..
-rw-rw-r-- 1 sbosshardt sbosshardt  163 Nov  8  2023 index.js
-rw-rw-r-- 1 sbosshardt sbosshardt  274 Nov  8  2023 tracker-base.js
-rw-rw-r-- 1 sbosshardt sbosshardt 3.3K Nov  8  2023 tracker-group.js
-rw-rw-r-- 1 sbosshardt sbosshardt  836 Nov  8  2023 tracker.js
-rw-rw-r-- 1 sbosshardt sbosshardt  963 Nov  8  2023 tracker-stream.js
$ ant file upload -p node_modules/are-we-there-yet
Logging to directory: "/home/sbosshardt/.local/share/autonomi/client/logs/log_2025-05-18_20-13-30"
🔗 Connected to the Network                                                                                       Uploading data to network...
Encrypting file: "node_modules/are-we-there-yet/package.json"..
Encrypting file: "node_modules/are-we-there-yet/lib/tracker-base.js"..
Encrypting file: "node_modules/are-we-there-yet/lib/tracker.js"..
Encrypting file: "node_modules/are-we-there-yet/lib/tracker-stream.js"..
Encrypting file: "node_modules/are-we-there-yet/lib/tracker-group.js"..
Encrypting file: "node_modules/are-we-there-yet/lib/index.js"..
Encrypting file: "node_modules/are-we-there-yet/README.md"..
Encrypting file: "node_modules/are-we-there-yet/LICENSE.md"..
Successfully encrypted file: "node_modules/are-we-there-yet/package.json"
Successfully encrypted file: "node_modules/are-we-there-yet/lib/tracker-base.js"
Successfully encrypted file: "node_modules/are-we-there-yet/lib/tracker.js"
Successfully encrypted file: "node_modules/are-we-there-yet/lib/tracker-stream.js"
Successfully encrypted file: "node_modules/are-we-there-yet/lib/tracker-group.js"
Successfully encrypted file: "node_modules/are-we-there-yet/lib/index.js"
Successfully encrypted file: "node_modules/are-we-there-yet/README.md"
Successfully encrypted file: "node_modules/are-we-there-yet/LICENSE.md"
Quoting for 32 chunks..
Paying for 32 chunks..
Chunk payments of 32 chunks completed. 0 chunks were free / already paid for
Uploading file: node_modules/are-we-there-yet/package.json (4 chunks)..
(1/4) Chunk stored at: 2ccb2b31fca92264bf9bde0478cc29861f26304bebded3b7939954eb146c7b40
(2/4) Chunk stored at: fcab28a417c2180c9af4728718e57964eb3cc9f847ab49d91880deff0455289c
(3/4) Chunk stored at: 07581d50ef24746fdc184cbcce94e192e1f5efad3480da439a3e7d4529b87355
(4/4) Chunk stored at: 1b7eb2ae9c1a3fd4b4817c5d521b57e426977d9731ddbb704df8a035616ddb27
Successfully uploaded node_modules/are-we-there-yet/package.json (4 chunks) to: 1b7eb2ae9c1a3fd4b4817c5d521b57e426977d9731ddbb704df8a035616ddb27
Uploading file: node_modules/are-we-there-yet/lib/tracker-base.js (4 chunks)..
(1/4) Chunk stored at: 4b71b73d35fb4afde812e6f702c4441ed137456f5667c81f53de8495ee9c8644
(2/4) Chunk stored at: a7c73056f7d20c16c7c4b4e85c04388664ecee14b7a356e9ce70244fff3ad617
(3/4) Chunk stored at: f7e995b7a08c80566d258d8f39d03816bd9d9f57df5fc3a6615631b8ba83eb85
(4/4) Chunk stored at: a10cb86b46a56178ec660edfb28e16cd0bbcf19e7abf4ef9368b9de08a84b717
Successfully uploaded node_modules/are-we-there-yet/lib/tracker-base.js (4 chunks) to: a10cb86b46a56178ec660edfb28e16cd0bbcf19e7abf4ef9368b9de08a84b717
Uploading file: node_modules/are-we-there-yet/lib/tracker.js (4 chunks)..
(1/4) Chunk stored at: 8ab8f9a18bbde2739715aa0db4e4c6de876a0b64e1091f0e56a21c0fc3d2106e
(2/4) Chunk stored at: b72b0538eab0b9a9936721e67a142b8b6a4dd452b038ee5fe705f483a5d66673
(3/4) Chunk stored at: 13b9df5f5d07d4c799b8489244f902161fb63b2cf3ab6761501b400c307a519f
(4/4) Chunk stored at: 3dfe49ee4f40570fc8b9ab7b38bdd96194e7766e4e6b19e870c01102bc7d515d
Successfully uploaded node_modules/are-we-there-yet/lib/tracker.js (4 chunks) to: 3dfe49ee4f40570fc8b9ab7b38bdd96194e7766e4e6b19e870c01102bc7d515d
Uploading file: node_modules/are-we-there-yet/lib/tracker-stream.js (4 chunks)..
(1/4) Chunk stored at: 88c8b7dc58425f4b19da7049962f4afb7e500e1b5e2a880a079c1391c7381d5d
(2/4) Chunk stored at: c8189c44ad942e54d44e30dc967651fda6f81415dd70423db85ea805119d6f05
(3/4) Chunk stored at: aeb09d811f5055dca3cff0f8b87d498f50f27e0ad0839598cebb055b467410ea
(4/4) Chunk stored at: a5c516aa3f7edf97b5ccbe8fa2e4cf22564ac17ef0148ac1dd3268057d2a0efc
Successfully uploaded node_modules/are-we-there-yet/lib/tracker-stream.js (4 chunks) to: a5c516aa3f7edf97b5ccbe8fa2e4cf22564ac17ef0148ac1dd3268057d2a0efc
Uploading file: node_modules/are-we-there-yet/lib/tracker-group.js (4 chunks)..
(1/4) Chunk stored at: 404a423bb54f1f15e701ea7fc01a1172ad97453e94749e513cdf1c254de3f77c
(2/4) Chunk stored at: 15a7a2bc07e4ea007d2cdc5cd5c77e7223851af0819406cebb3e8e8f24638a94
(3/4) Chunk stored at: c40d10f6dadcfee9f5c6366207540a431da882ff5db145f956245c9c1451dc0e
(4/4) Chunk stored at: 8ea5dca08e06cc00db82c96556bba7356d91b786e125fa9829e41f46ffd918d6
Successfully uploaded node_modules/are-we-there-yet/lib/tracker-group.js (4 chunks) to: 8ea5dca08e06cc00db82c96556bba7356d91b786e125fa9829e41f46ffd918d6
Uploading file: node_modules/are-we-there-yet/lib/index.js (4 chunks)..
(1/4) Chunk stored at: 68d6e768daaf985efa4d96aabfb840a47d07a43280e81e6d7fa2aacd04fe768d
(2/4) Chunk stored at: 37ce710eac071782aee4aa5636130c59fcd708820ef1a5319b5ceeeef26453c5
(3/4) Chunk stored at: 309a43fb919c2af96f6b1d2fd263dbedf813b330eacd3df8d92dfe5d33c67b69
(4/4) Chunk stored at: 4d38b2cb7704a976a02937e7c5379267cd4e2229a81f925f1163934c622baf13
Successfully uploaded node_modules/are-we-there-yet/lib/index.js (4 chunks) to: 4d38b2cb7704a976a02937e7c5379267cd4e2229a81f925f1163934c622baf13
Uploading file: node_modules/are-we-there-yet/README.md (4 chunks)..
(1/4) Chunk stored at: 37ffe851ee68117deb07e80c4af84e0cfad769666804432cc3e9bef4341f5e7b
(2/4) Chunk stored at: 8ee183ff7b8e46b9eddbcfdd7fcbc9fe2657ecbb314f6d7e21e96bb80aef57a7
(3/4) Chunk stored at: 2012c8c776567d18e84e99ba0fa1661872056adc51762aa5173a636f2ed65ae6
(4/4) Chunk stored at: 410aa06d887728315cb20acc5af75e8080921ccc70e339cb859ae280831ef758
Successfully uploaded node_modules/are-we-there-yet/README.md (4 chunks) to: 410aa06d887728315cb20acc5af75e8080921ccc70e339cb859ae280831ef758
Uploading file: node_modules/are-we-there-yet/LICENSE.md (4 chunks)..
(1/4) Chunk stored at: f7dc1ca370178cb6ce3fdd4ede328af4d5b5f249b1fd7a05a8eca17f1c9ad674
(2/4) Chunk stored at: ebb866f0973cf3653307a441f61b3b25279379cb65a573962bc85e214e11d1d6
(3/4) Chunk stored at: cb9854db6ebe6148888476f5986b2609d3dc742a6169592ef88408603aeee771
(4/4) Chunk stored at: 56f3179711fb52cc7a51b9e3f242ea42f4c1bc26ac05dcef2424fddf8cf7500c
Successfully uploaded node_modules/are-we-there-yet/LICENSE.md (4 chunks) to: 56f3179711fb52cc7a51b9e3f242ea42f4c1bc26ac05dcef2424fddf8cf7500c
Upload of 8 files completed in 655.405997516s
Uploading public archive referencing 8 files
Paying for 4 chunks..
Chunk payments of 4 chunks completed. 0 chunks were free / already paid for
(1/4) Chunk stored at: b705aba35412128771bad0752e08878a18f06876d62cbd41442c856d880fb24d
(2/4) Chunk stored at: c88a59dd84a2e95568f42105624dbd1bd4ef52a7b67deb0825a76f62963eab1c
(3/4) Chunk stored at: 0c05a4addcbbd7ad566a7c342dbd7755ef2485db6941ca384e11df1802270bac
(4/4) Chunk stored at: 0b18add3787e10432321532bd395e60e84c4c722cb7440632b4034c97e472457
Successfully uploaded: node_modules/are-we-there-yet
At address: 0b18add3787e10432321532bd395e60e84c4c722cb7440632b4034c97e472457
Number of chunks uploaded: 36
Number of chunks already paid/uploaded: 0
Total cost: 1699551203193 AttoTokens

Downloading (ant file download 0b18add3787e10432321532bd395e60e84c4c722cb7440632b4034c97e472457 .) also takes a few minutes.

Looking up my wallet address in Arbiscan I see that there were 12 token transfers paid by my transaction to 9 wallets. Since the probability of XOR addresses with self-encryption and all is supposed to be uniform, to me the presence of 3 duplicate addresses suggests a significant amount of hosting centralization (few people hosting the lions’ share of nodes).

I’m unsure how to account for 12 token transfers for a directory of 8 small files.

I do see that I sent 0.0000002683771062 ANT (on the order of a millionth of a penny USD assuming an ANT price of around $0.10 USD). I paid a transaction fee of 0.000007946663004 ETH (approximately $0.02 USD). Put another way, the ETH cost for storage is more than the ANT cost on the order of a million-to-one. ?!

Also, I’m not sure why Arbiscan shows “sent 0.0000002683771062 Autonomi (ANT)” when ant-cli said “Total cost: 1699551203193 AttoTokens”. I’m not sure what the difference between ANT and “AttoTokens” are, but I was expecting for the digits to match (yet I see “26837…” and “16995…”, which don’t match).

2 Likes

To process the transfer. ETH requires you to pay for the evm processing time in the ARB node of the smart contract. And its approx the same as a transfer cost and so is included in the transaction cost

If you watch an upload you see the archive upload as the last bit done.

This happens if you upload a folder of single file. When I went through the code they had directed the single file upload to the same routine as the folder. I am guess RUST code treats a single file reference as a special case equivalent to a folder with one file in the get file references in a folder call. So when asking for files in the “folder” the case where the reference points to a file instead of a folder it just supplies the file as the first and only file in a fake folder.

Each file has its own datamap.

So a folder with 10 small (<4MB) files will have 40 chunks plus the archive of the 10 files.

A single file then has 4 chunks plus the factious folder archive of 1 file

There is indeed. Some people running up to 1/2 a million nodes on one address. Well one person is and others are running high numbers of nodes as well but not 1/2 million LOL

That should be only one file of 3 chunks with its datamap. Not sure how else that would be explained. Unless the 8 small files are combined into one larger file of 3 chunks and its datamap

Been that way since TGE

Only change when nodes are storing more than a tiny number of chunks

Not sure either. Was the ant-cli only showing the quoted cost?

3 Likes

Based on the context, I think not. It’s from the last line of the ant file upload -p <dir> output that I copy/pasted.

Ah, the last line is the archive record store cost. And there is 3 nodes to pay for that to store the archive record. This would be just a portion of the transaction cost I guess.

Well it looks like the archive is 4 chunks in size. Or is that 3 chunks and the datamap chunk for the archive

Anything else then I am at a loss to explain

2 Likes

Thanks @neo, that’s really helpful.

Some clarifying points…The above is based on using ANT CLI to upload Public files.

That method currently always creates and upload an archive which is in fact an extra file. But using API, the Archive can be omitted.

Also, when uploading Private files, the datamap of each file is only stored in a PrivateArchive, not on the network. The files themselves are no different, public or private.

Creating a Scratchpad and Pointer cost more to create but are free to update.

API Use

API costs still need clarification because the above all relates to one particular application (ant) not the API.

Internally I think ant batches things together and doesn’t just call the file/data upload APIs. It instead generates the chunks and uploads them in batches, so uploading individual files, particularly small ones will be more costly using the API unless the application implements chunk generation and batched payment for its data.

The API or a library could help a bit with the for different use cases but for now it doesn’t.

2 Likes

Is there any chance this can be explained like I’m 5? For an end user, how much is the cost on average for a upload of say 1 GB

4 Likes

42 cents ARB-ETH for 80 chunks (320MB max) when ETH is 2500

2 Likes

I just realized that I have two transactions (not one) - both for this ant-cli command. They occurred about 9 minutes apart. The other transaction has 96 token transfers paid to 22 wallets. (Node hosting centralization is even more stark here.) It looks like that first transaction is for actually storing the files, while the second transaction is for making an archive that references the files. Maybe there’s a good reason for multiple transactions here or it’s just an implementation quirk, I don’t know - but I would think that the first transaction had the capacity to pay for creation of the public archive too (and save some gas).

So I think that explains this:

To answer your question of how much a 1 GB file costs, it’s about $1.49 I think.

I wrote Python code (below) to calculate gas costs, based on these conversations and examining my transactions. Hopefully it’s accurate.

Make sure to not keep much ETH in your Autonomi wallet - just in case. Something you’re okay if you accidentally waste, like $5-10 worth.

Worth noting that my ant file upload -p <dir> of 8 files (total 44 KB) cost me about $0.17 worth of ETH in transaction fees. I get that by adding the Transaction Fee values from Transaction 1 and Transaction 2. The number of files makes a difference, and this estimator program is only designed for estimating one file.

Output from running my Python program (note 0.3125 GB = 320 MB):

===== Estimate for storing a 0.3125 GB file on Autonomi =====
Chunks: 80
Transfers needed: 243
Transactions needed: 1
Maxed transactions: 0
Maxed transactions gas units: 0
Last transaction transfers: 243
Last transaction gas units: 16,200,000
Gas units used: 16,200,000
Fee: 0.00018902 ETH (189,021.6 gwei)
Total USD: $0.47255

===== Estimate for storing a 1 GB file on Autonomi =====
Chunks: 256
Transfers needed: 771
Transactions needed: 4
Maxed transactions: 3
Maxed transactions gas units: 49,800,000
Last transaction transfers: 21
Last transaction gas units: 1,400,000
Gas units used: 51,200,000
Fee: 0.00059740 ETH (597,401.6 gwei)
Total USD: $1.4935

Python code:

from math import ceil, floor

def print_storage_transaction_cost_estimate(filesize_GB):
    # Variable values
    eth_price = 2500
    eth_price_currency = "USD"
    currency_symbol = "$"
    gas_price_gwei = 0.011668          # gwei / gas-unit  ← copy from explorer
    gas_price_eth  = gas_price_gwei / 1e9   # ETH / gas-unit

    # Constants
    max_transfers_per_transaction = 250
    transfers_per_chunk = 3
    max_chunks_per_transaction = floor(max_transfers_per_transaction / transfers_per_chunk)
    chunk_gas_cost = 200000
    
    # Calculations of how many transfers and transactions are needed.
    # A transfer is a payment to a node.
    # A transaction has transfers for storing (up to 83) chunks.
    filesize_MB = filesize_GB * 1024
    chunks = max(3, ceil(filesize_MB/4))
    # +3 is (datamap + archive + paying for the transaction itself)
    transfers_needed = (chunks * transfers_per_chunk) + 3
    transactions_needed = ceil(transfers_needed / max_transfers_per_transaction)
    
    # Calculate the number of maxed transactions and the gas they consume altogether.
    # A maxed transaction has a number of transfers equal to max_transfers_per_transaction.
    maxed_transactions_needed = transactions_needed - 1
    maxed_transactions_gas = int(maxed_transactions_needed * chunk_gas_cost * max_chunks_per_transaction)

    # Calculate the last transaction's attributes.
    # Typically it has a number of transfers fewer than max_transfers_per_transaction.
    last_transaction_transfers = transfers_needed % max_transfers_per_transaction
    last_transaction_gas = int(last_transaction_transfers * chunk_gas_cost / transfers_per_chunk)

    # Determine totals that the user can expect to spend.
    total_gas_units = maxed_transactions_gas + last_transaction_gas
    fee_gwei = total_gas_units * gas_price_gwei
    fee_eth  = total_gas_units * gas_price_eth
    fee_wei  = int(fee_eth * 1e18)
    total_currency = eth_price * fee_eth

    # Print the estimate and its significant calculated values
    print("===== Estimate for storing a", filesize_GB , "GB file on Autonomi =====")
    print("Chunks:", chunks)
    print("Transfers needed:", transfers_needed)
    print("Transactions needed:", transactions_needed)
    print("Maxed transactions:", maxed_transactions_needed)
    print(f"Maxed transactions gas units: {maxed_transactions_gas:,}")
    print("Last transaction transfers:", last_transaction_transfers)
    print(f"Last transaction gas units: {last_transaction_gas:,}")
    print(f"Gas units used: {total_gas_units:,}")
    print(f"Fee: {fee_eth:.8f} ETH  ({fee_gwei:,.1f} gwei)")
    print("Total "+eth_price_currency+": "+currency_symbol+str(round(total_currency, 5)))
    print("")

# Test case: 320 MB
print_storage_transaction_cost_estimate(0.3125)
# Test case: 1 GB
print_storage_transaction_cost_estimate(1)

Edit: Fixes for Python code relating to gas units and gwei.

2 Likes

Use the --max-fee-per-gas 10000000 option for the ant file upload command and that limits it to the around 42 cents per 80 chunks mark

That 80 chunks is inclusive of any datamap, archive records.

I was thinking along the lines of preventing significant losses by user error, such as accidentally uploading a directory with a lot of files (much greater than 80 chunks). I assume that 80 chunks is not a limit inherent to Autonomi - that payments for more chunks can occur by conducting multiple transactions with the payment contract.

I’m not sure if ant is (or will one day be) capable of paying for more than 80 chunks by calling the payment contract as many times as it needs. I know that ant file upload -p <file> fails when it’s trying to upload 1034 chunks (it’s apparently not screening for file size up front, nor showing an error about >320 MB).

1 Like

If your file is 1000 chunks then it will be creating 12 or 13 transactions to pay for them. It does this now

Ok, good. I just ran my estimator for a 4.1 GB file size (based on the Kali Linux iso I’ve been testing upload with). I don’t currently have enough ETH in that wallet (just 75% of what I need). I’ll send that wallet some ETH and give it another try.

===== Estimate for storing a 4.1 GB file on Autonomi =====
Chunks: 1050
Transfers needed: 3153
Transactions needed: 13
Maxed transactions: 12
Maxed transactions gas units: 199,200,000
Last transaction transfers: 153
Last transaction gas units: 10,200,000
Gas units used: 209,400,000
Fee: 0.00244328 ETH (2,443,279.2 gwei)
Total USD: $6.1082

3 Likes

So the upload failed again. And I’m out about $18 (0.00733689 ETH) - way more expensive than the $6.10 (0.00244328 ETH) my estimator thought this would cost. Whew!

If the --max-fee-per-gas (10,000,000) argument is in wei, that’s less than a tenth of what ant bid for the last (most expensive) transaction (107,680,001).

I didn’t expect the gas price to skyrocket like it did. The latest transaction for this has me paying a gas price about 3x as much as the first transaction. I wonder why the price that ant pays skyrockets that high - bad luck, or “expected behavior”? Transactions on Arbiscan show the “Gas Price Bid” amounts climbed up. Seems like maybe the client should default to some reasonable max-fee-per-gas (and anyone who wants to allow ant’s bid to skyrocket can pass an argument).

Good thing I only transferred about $20 of ETH. I have 10 transactions on Arbiscan for this (three short of what my estimator said I’ll need):

Fee Timestamp Arbiscan Link
0.00150782 2025-05-19 13:37:27 0xb0ad14
0.00093019 2025-05-19 13:37:01 0x1688ad
0.00063203 2025-05-19 13:36:34 0x6fcf2f
0.00061608 2025-05-19 13:36:07 0xc6fff4
0.00060301 2025-05-19 13:35:40 0xfac61e
0.00062964 2025-05-19 13:35:13 0xfbdecf
0.00063317 2025-05-19 13:34:46 0x6f415e
0.00065994 2025-05-19 13:34:19 0x9880c3
0.00055582 2025-05-19 13:33:52 0xaa087b
0.00056919 2025-05-19 13:33:37 0x742724

Here’s the output of trying to upload this file:

$ ant file upload -p ~/Downloads/kali-linux-2024.3-installer-amd64.iso
Logging to directory: "/home/sbosshardt/.local/share/autonomi/client/logs/log_2025-05-19_05-36-34"
🔗 Connected to the Network                                                                                       Uploading data to network...
Encrypting file: "/home/sbosshardt/Downloads/kali-linux-2024.3-installer-amd64.iso"..
Successfully encrypted file: "/home/sbosshardt/Downloads/kali-linux-2024.3-installer-amd64.iso"
Quoting for 1034 chunks..
Paying for 1034 chunks..

   0: Failed to upload file
   1: Failed to upload file
   2: Error occurred during payment.
   3: Wallet error: ChunkPaymentsContract(RpcError(ErrorResp(ErrorPayload { code: -32000, message: "execution reverted", data: None })))
   4: Chunk payments contract error: server returned an error response: error code -32000: execution reverted
   5: server returned an error response: error code -32000: execution reverted

Location:
   ant-cli/src/commands/file.rs:86

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

I’m on the fence about giving up on uploading this file because of the cost. Though perhaps I can get away with just 3 more transactions (remaining chunks) and setting --max-fee-per-gas=10000000.

In case anyone’s curious to see the log from my attempt, I uploaded it:

ant file download 2e1c81faef559e9a232f15c465a6927435af6b32ef00068d7f57cebe322895cb .
2 Likes

Yes wei, 10^-18 arb-eth and 10 million is 0.01 GWEI the minimum you can currently set. This is apparently enforced by the network, I tried 9999999 and it fails with lower than the block limit set by the network. Of course at any time the minimum GAS price can be higher due to GAS skyrocketing. But if the ant file upload --max-fee-per-gas 10000000 is used then the upload simply fails not costing you anything if the gas price is too high

Retries on the other hand will cost at this time.

3 Likes

Don’t know if this is doable/favorable/sensible, to integrate an exchange as an option to upload files.

You can send a minimum of 1 satoshi ANT…