The NNS is 34 right now if I am not mistaken, but will grow larger shortly. Indeed, 34 nodes with a good degree of decentralization in terms of node allocations over node providers and data centers is pretty strong already.
We want to maintain roughly the same security / decentralization level for the threshold ECDSA subnet, i.e., it is expected to also grow over time. Note that there will be only 1 threshold ECDSA subnet in the beginning and we will only add additional ones if there is a need, e.g., from a throughput perspective.
Progress update
Now that the Bitcoin developer preview has been released, we are fully focussing on finalizing the final release of the feature in the Q1 Chromium release. The main items we need to work on are listed next:
- Finalizing the integration with the IC protocol stack
- āMovingā the BTC canister code into the replica
- Provide an API for transaction fees (incl. finalizing discussions and design)
- System tests
Thanks a lot for the detailed answer! I am simply trying to understand how hard/expensive it is to compromise a subnet (of 34 nodes in this case) once the Total Value Locked in Bitcoin DeFi (once integration complete) starts to become significant. One can imagine that when the TVL is significantly larger than the cost to compromise 2/3 of 34 nodes, that there is a, potentially big, incentive to actually attack that subnet. Does this make sense?
@icpbull You are very correct IMO that as the TVL increases the subnet will become a much more lucrative target. Thus we must design mitigation mechanisms to protect ourselves against open attack vectors.
There are multiple attack vectors. One is an outside attack like youāre suggesting, not originating from the node operators themselves. This could be done through exploiting security flaws in the canister environment, by deploying a canister with an exploit. We are protecting against that with security audits and canister process sandboxing and hopefully more.
You could envision another type of attack through the network, since the nodes are exposed to the Internet. To plug that vector we have to ensure that the node hardware, software, configuration, and data center and everything about the setup is prepared to prevent an attack. In this case you would need to compromise 1/3 + 1 of the nodes (Iām pretty sure thatās the exact threshold to actually break consensus) to even begin to cause an issue. Though itās my understanding that even with a 1/3 + 1 compromise the threshold private key would be safe. You would need to hack into 2/3 of the nodes to actually get to the key shares or to take over consensus. Keep in mind that the subnets are designed to maximize the decentralization of the nodes by multiple factors, including node operator, data center, jurisdiction, etc.
Outside attacks on large subnets would be incredibly difficult to pull off IMO, unless each node had some common fatal security hole. But we can mitigate these vectors through excellent security practices, code reviews, security audits, all that.
The IC is different than Bitcoin or Ethereum. You canāt just directly buy your way into an attack (you could through the NNS by accumulating a massive amount of voting power, technically). So the security concerns in some way are much different than proof of work chains.
My biggest concern is collusion between node operators. Since they are currently all publicly known, and the subnet configurations are basically static, node operators have ample opportunity to get to know each other and form relationships that could eventually lead to a compromise.
Thatās why I suggest the following mitigations eventually be implemented:
- Trusted Execution Environments, which will hide canister code and state from node operators. The major vulnerability remaining with TEEs is side-channel attacks.
- Multi-party Computation, which combined with TEEs provide BFT guarantees on the privacy of the canister code and state. This would greatly mitigate side-channel attacks, since you would need 1/3 + 1 node operators to perform a side-channel attack and then work together to perform the MPC
- Automatic node rotation/shuffling, this would break up the opportunity for node operators to collude once we have a larger number of node operators, as subnet assignment would be temporary and hopefully random. It would become incredibly difficult to form relationships with other node operators and target the appropriate canisters or key pairs (hopefully)
The three mitigations above combined provide an incredible amount of security in my opinion. And fortunately for all of us these three mitigations are on the tentative roadmap.
BTW Iām not on the DFINITY team and Iām not a cryptographer or security researcher (but I enjoy thinking about both).
Thanks so much for the detailed answer! You basically read my mind . I also think that collusion between node operators is the biggest concern that we have and that node shuffling is basically the only way to solve that.
Our team is currently working on a proposal for the API for obtaining information on the fee structure of recent blocks. This information will be important to make a decent guess about the required fees to include in a transaction. This API was missing in the developer preview release and will be added to the final release.
My colleague @THLO will post a proposal once its ready so we can discuss it here.
Just to anticipate the gist of the proposal: The fees API will return information on the fee distribution in recent blocks, e.g., in the form of percentiles, which would allow the canister to make an informed choice on the fees it should provide for a transaction it wants to get mined.
Note that the BTC functionality on the IC does currently not have any information on the Bitcoin mempool, so we need to use what we have to compute the fees: BTC blocks.
Any thoughts already now?
Something similar to Ethereum Gas Station might be worth looking into. They have three main fee options calculated for you (safe low, standard, fast), and I believe they explain their methodology: https://ethgasstation.info
Can Dfinity speak to any PR or marketing strategies in place, to be engaged once integration has because live?
Other than word of mouth, how will the crypto market be made aware of this important mechanism for BTC?
Following the typical public relations approach for the Bitcoin release would mean that the Chromium milestone in which the feature will be activated on IC mainnet will be announced at least via a press release, YouTube videos, maybe an event, forum posts, articles by independent journalists, and other outreach to the public to be sure that the information reaches relevant audiences. Of course, word of mouth will also play a role that the information gets further disseminated.
The concrete communications strategy for the event still needs to be worked out, but the above describes some of the more important channels we use in making such important milestones public.
Does this answer your question on the PR strategy?
Yes, thanks! And if there are additional strategies to be used for the Chromium release, or the other subsequent milestones, please share the details. Much appreciated!
I wonder what the best marketing channel to reach blockchain developers is.
I think if you can get the main point across, that this integration is direct and does not use trusted bridges or custodians, and instead uses threshold signatures whose private key shares are stored on-chainā¦ I think open-minded blockchain developers will āget itā and buy in.
But how do you reach them?
Thatās a good question. Essentially, the hope is that we will reach them by communicating on all the channels that @dieter.sommer mentioned.
If anybody here has some contacts in the Bitcoin space, feel free to spread the news! I will certainly do so.
As @dieter.sommer mentioned, we are working on an API extension to make it easier for developers to choose āreasonableā fees for their Bitcoin transactions.
The challenge is that most wallets rely on the state of the mempool (with fees typically being lower when the mempool size is smaller).
Fees are estimated by measuring how long transactions with certain fees stay in the mempool (using some kind of regression model, which is also the case for the Ethereum Gas Station that @lastmjs mentioned above).
We cannot use such an approach because we do not have any information about the mempool in the Bitcoin canister.
Instead, we plan to rely simply on the fees observed in recent blocks and provide this factual information in the form of the following API:
get_current_fees(step_size: u64) -> CurrentFeeResponse
where CurrentFeeResponse
will contain percentiles in Satoshi/byte over the last 10,000 transactions (usually around 4 blocks).
For example, a step size of 10
would result in a response containing the 10th, 20th, ā¦, 100th percentile. If the step size is 25
, the response will contain the 25th, 50th, 75th, and 100th percentile.
Developers can then choose themselves what level of fees is appropriate for their applications.
Experiments showed that this (simple) mechanism yields a good approximation of current fees.
If you have any questions/concerns/suggestions for improvements, let me know!
This sounds great, but in addition to that it would be nice to get a safe low, standard, and fast option returned. Some developers may want fine-grained control, but the DX of just choosing one of three simple options is amazing IMO.
I see two approaches to get three āsafeā options: First, you can use the 25th (slow), 50th (standard), and 75th (fast) percentile.
In numbers, that would be 1.9 Satoshi/byte (slow), 3.2 Satoshi/byte (standard), and 5.3 Satoshi/byte (fast) when considering block 724881 and its predecessors.
If you check out some of the online Bitcoin fee calculators, youāll see that these numbers are pretty reasonable.
Alternatively, once the HTTP call feature is ready, a canister could be built that interacts with such fee calculators or the mempool directly to provide the same estimated fees as any Bitcoin wallet.
Hey guys, I am very excited about the bitcoin integration and eagerly waiting for the release.
I wanted to provide feedback based on my target use cases. Common denominator feature missing is finding the sender of bitcoins. From the provided APIs, I am not sure if we can do that (please let me know if we can indeed do it!).
I also thought about creating āreceiverā canisters just to create a new BTC address where we can uniquely identify sender but it turns out to be very costly. Similar effect can be achieved if we can have sub-accounts.
I would love to know what you guys think and if these changes can be accommodated in the release.
The API does support BIP32 derived addresses from the key associated with each canister. Does this correspond to what you meant by āsub-accountsā?
You are right, the current API only makes (unspent) outputs available but no inputs, so you canāt determine where the outputs came from.
However, as @victorshoup pointed out, you can use BIP-32 derived addresses, which can āencodeā the sender. This approach should cover a wide range of use cases.
Is there a specific use case that you have in mind where this approach wonāt work?
Progress update
Let me give you a progress update after not having given one for some time.
We made very good progress with the implementation according to our goals. We will be finalizing the IC stack integration in the next 1 to 2 weeks and expect to have the feature working in an end-to-end fashion by then. We are now facing a challenge because of the huge amount of state that the feature requires and the way the data structures are currently implemented, which will take some additional time to overcome. We might need to make our stable hash map PoC that directly uses stable memory production ready in order to resolve our issues with memory.
Regarding testing, we intend to do first tests on large (RAM-wise) testnets and, once successful and us being confident enough that everything works as it should, make a first deployment to a subnet on IC mainnet to test in the real environment.
The rollout towards general availability of the feature will likely comprise an initial launch that gives only access to Bitcoin testnet so that remaining bugs can be found and fixed before we roll out Bitcoin mainnet access on IC mainnet.
One question regarding rollout we are discussing right now is whether we also want to release threshold ECDSA initially with a test key that will be deleted after some time and replaced with the production one. This would be in lockstep with the Bitcoin testnet / mainnet deployments. Opinions?
This is an issue I think many face: how to store large amounts of data in stable memory.
Right now, I believe the per-canister stable memory limit is still at 8 GB. Also, Iām assuming youāre writing this in Rust instead of Motoko. Either way, the only way for a canister to take full advantage of the 8 GB is to directly store data in stable memory at a very low level (as opposed to using higher level abstractions like Motoko stable variables). Itās not ergonomic and more difficult to test.
Iām curious what kind of improvements you are making so that the stable hash map is production ready?