You have probably noticed that the exchange wallets are very slow, even as your own ARRR wallet is basically instant. Is this due to poor exchanges, the ARRR wallet or something else?
We have been hard at work to solve this problem and the first thing to notice, was that no other blockchain is doing anywhere close to the amount of zaddr transactions as ARRR. The fundamental reason of why the exchange wallets slow down is due to how zk-SNARKs are processed. The following is not a 100% technically accurate description, it has been simplified to be able to explain more clearly the fundamental issue.
The ARRR network can be viewed as sending a private transaction by encrypting it so only the receiver can decrypt it. (in reality all nodes are able to validate that the operation is correct, so not all is encrypted). So you can imagine a zaddr (z address) transaction being encrypted and then broadcast to the blockchain. Nobody knows who you sent the funds to, nor that you sent it, nor the amount. All the nodes have to try to decrypt that encrypted transaction to see if they can, and if they can, they will know it was sent to them. Still it is hard to know who sent it, but usually there are off-chain communications that indicate the amount, timing, even the txid, so even though you don't know the sending zaddr, you at least have a way to know who sent it. If the sender is cooperative.
That seems simple enough, so what is the problem with exchanges? The problem is N * B, where N is the number of zaddrs in a wallet and B is the number of transactions of the entire blockchain. For each of the N zaddrs in a wallet, B decryptions need to be done, just to know that it was funds for this wallet. Of course, each decryption takes significant time, lets use a 0.1 seconds as a rough estimate. If the blockchain is doing 60000 transactions per day, a wallet with a single zaddr would take 6000 seconds of processing. For a node that is online this is 6000/86400 = ~7% CPU load. Currently ARRR is doing about 10% of that, so the typical end user node would be at 0.7% CPU core of usage. That is basically next to nothing and why everyone says ARRR is nearly instant. So why are the exchanges so slow?
Let us look at a small exchange with 100 zaddr wallet, using the above numbers, it is already at 70% load with current transaction levels. In the event a rescan is needed, then all transactions from day 1 need to be reprocessed. Unless the small exchange has very fast server, they might not be able to catch up to real-time. That happens when every new block takes longer than the blocktime to process. It seems some exchanges are in this situation, maybe they upgraded to the top of the line server, but that at most does a 10x on processing speed, so at 1000 zaddr, it bogs down. Then there are the exchanges with 10000 zaddr, where they would run into a wall. N*B is a brutal multiplier, especially as B is increasing with more ARRR popularity.
OK, so now you understand the problem and actually it seems like a very big problem without any possible solution. Luckily we have the zero knowledge experts at Zcash to find a solution to this scaling problem. They made this fantastic thing call diversified addresses. It is similar to HD wallet, where a single private key gets many different public addresses. The absolutely critical factor is that with a diversified zaddr, no matter how many diversified addresses you have all you need is a single decryption to determine that the encrypted transaction is from a specific diversified address. No need to even scan all your diversified addresses!
Now the performance equation goes to B, namely the performance will go proportionally to the number of blockchain transactions. A totally fantastic result. However, it was not that simple as we pushed the boundaries. First to 10,000 zaddrs, then to 100,000, then to one million and we are even in the process of making a 10 million zaddr wallet to make sure it will perform as expected. You can see the various performance of the different wallets in the Performance Results section. During our tests we kept finding things that became too slow for practical usage. The reason is that even if each additional address in the wallet slows things down by a single millisecond, a million zaddr wallet would take 1000 seconds which is over 15 minutes. And many things could easily take 10 milliseconds or more, so we had to optimize many different things.
Thanks to the amazing work of CryptoForge, that is able to support exchanges with million(s) of zaddrs. ARRR is lucky to have one of the best zk-SNARKs core devs in the industry.
Migration of existing exchanges
Due to the way diversified addresses work, the new exchanges will have a much easier time as they don't have the original type zaddrs to slow them down. For the existing exchanges, they will need to make all the users generate new deposit zaddr and switch to using them. The performance of the old deposit zaddr will continue to be slow due to the above N * B factor. During this migration, the existing exchanges would need to run two nodes, one for the old zaddr and one for the new diversified zaddrs and when people have stopped using the old deposit zaddr, they would be able to go to a single node.
End user usage of diversified addresses
Due to the way diversified addresses work, there is a slight mathematical linkage between them, so if one is compromised, it could compromise the linkage of other diversified addresses. For this reason, it is recommended that end users do not use the diversified addresses unless you really know what you are doing. You should always have a dedicated private key for a zaddr that you never tell anybody else its zaddr. Only send funds to and from yourself from this special zaddr. Then when you are interacting with others and especially exchanges, use a totally different zaddr. This additional z->z between zaddr having different private keys will totally delink things, even if one is compromised, the other is still private.
We will be working on the wallets to help manage the different types of zaddr that are now possible to create.
Test Machine Specs:
CPU: AMD Ryzen Threadripper 1950x
SSD: Samsung 950 Pro M.2
OS: Ubuntu 16.04
- Address generation
100,000 diversified zs address creation took 3864.2258 seconds. About 1 hour and 7 minutes.
1,000,000 (1 Million) diversified zs address creation took 40583.6817 seconds. About 11 hours and 27 minutes.
- Rescan time for wallet.dat consisting only empty diversified zs addresses
100,000 address rescan time: 13m
1,000,000 address rescan time: 13m 20s
- Rescan time with 1 million addresses with 12117 UTXOs with daemon starting with -rescan param
Rescan time - 28 minutes and 47 seconds
Witness building time - 2 hours 45 minutes and 44 seconds
Total time: 3 hours 14 minutes and 31 seconds
- Rescan time with 1 million addresses with 12117 UTXOs, rescan triggered by importing a private key
Rescan time - 29 minutes and 39 seconds
Witness building time - 2 hours and 52 minutes
Total time - 3 hours 21 minutes and 39 seconds
- Rescan time for importing the rootkey of the diversified zs addresses in an empty wallet.dat
Rescan time - 20 minutes and 39 seconds
Witness building time - 2 hours 57 minutes and 19 seconds
Total time - 3 hours 27 minutes and 58 seconds