Our development planning features a Release Cycle of three weeks, providing a consistent stream of updates to the community, developers, and businesses relying on Dusk technology.
The publicly available Dusk Network GitHub contains over 18 active repositories, each focused on a different technical subject. Progress in each is ongoing and can be followed in real-time. The Release Cycle process is currently applied to some of our most active repositories.
Release Cycle planning has not yet been applied to all repositories. When they are, future installments of the Release Cycle updates will see an expansion of repositories in the spotlight.
For the community's benefit, we’ve chosen a selection of some (but not all) of the work that is being done in our repositories, including recent advancements.
We need to support the concept of contract ownership.
Ownership of a contract may help decide who is allowed to execute certain contract methods.
Currently we use the index file to store the leaves of the tree, but we never store the full tree - meaning the leaves together with all the nodes. This would be useful for increasing the speed of root calculations, as well as an easy inspection of the state integrity.
For contracts attributes such as contract's owner or contract's SELF_ID we need the ability of storing and accessing such attributes on a per module (contract) basis. A set of such attributes constitute a contract's metadata. Distinguishing feature of a contract's metadata is that it is managed by the VM and from the point of view of the contract it is immutable. Another way to look at it is that metadata constitutes a context for the contract.
In the context of implementing #180 (Issue #167), we have noticed that there are several concepts that can be grouped together in particular ways to better structure the project, reduce the maintenance burden, and aid in the development of new features.
In particular, there seem to be at least three different categories of data:
- Module data. This is data that is set at module deployment time, and never changes in the lifetime of the module. Examples are:
- Constructor data (transient/not persisted)
- Ownership data
- Self ID
An API should be exposed that hints at, or even enforces, that these things cannot be changed for the lifetime of the module, possibly at deploy time.
- Session data. This is data that is set at the beginning of the session, and never changed for its duration. Examples include:
- What is currently called SessionMetadata - contains universal settable map containing context items like 'height'
In the same way as before, an API should be exposed that hints, or enforces, that these pieces of data are set at the beginning of a session, possibly during instantiation.
- Call data. This is data that is set at the beginning of a call to transact or query. This is data such as:
- (Gas) limit
- Sender (same entity as Ownership)
This should be set when a call is performed.
Part of Piecrust functionality remains untested or it is only indirectly tested. Add more direct tests, especially concerning module deployment, ownership, metadata, persistence, commits.
Add CHANGELOG #127
It looks like every time push_callstack is called, a new module instance is created as existing instance is not found in instance_map.
We should not need to use hex::encode() in places where Display trait is required. Display should be implemented for ModuleId converting it into a hex encoded string in a similar manner to hex::encode.
We need benchmarks in order to track performance throughout the development.
Add benchmarks for the sponge gadget proof creation and verification.
Remove the circuit compilation from all in-circuit benchmarks.
Wrong timestamp #17
The timestamp produced by the app is not decodable by the UI.
This happens only for timestamps parsed from the json inputs.
Indeed the timestamp generated with the --now is parsed correctly.
Serialized amount (with the float2fixed): 4294967296
Do we count the N bits from the least significant or most significant bit? Is the array in little or big endian? Maybe give an example to showcase.
Add in-circuit tests for the composer methods
Add in-circuit tests for the composer methods
Add and refactor in-circuit tests for the composer methods
When adding a range gate with zero bits, any witness always satisfies the circuit.
For Citadel, we need StealthAddress to derive Default.
Some comments in the code assume the committee size to be the number of members in the committee,
while this is actually the number of voting credits assigned to committee members.
The CommitteeSize function decides the committee size depending on the number of provisioners.
This is somewhat inconsistent with the committee 'size' as number of voting credits.
In particular, given how this function behaves, the committee size is set to less than ConsensusMaxCommitteeSize (64) if the number of provisioners is lower than this value.
In createSortitionHash, the i parameter is indicated as an iteration number, which sounds mistakenly related to the SA iterations.
Test harness is not working anymore since rusk switched to piecrust.
DUSK value is wrong #1517
In sortition.go, DUSK (1 unit of DUSK) is set to be 100 000 000 instead of 1 000 000 000.
It should be possible to verify that an item is the leaf of the MerkleOpening.
Once consensus has been running smoothly and producing blocks for a few rounds, some of the nodes encounter the VoteSetTooSmall error. This problem is only observed after activating block re-broadcast on the node side.
For better maintenance and interoperability, the wire message structures have been moved into a node-data crate together with AsyncQueue and ConsensusPublicKey.
verify_step_votes algorithm is needed in the verification of the block certificate. For now we can expose and use it directly in the block acceptance procedure.
DUSK value in dusk-blockchain sortition code was mistakenly set to 100 000 000 instead of 1 000 000 000. It is likely the same occurs in this repo, since the two clients reached consensus.
Right now we have a research paper for Citadel. We need to create a new document with the specifications to be implemented.
Soulbound tokens are items that can not be transferred or sold. We should see if Citadel would be a suitable model for this type of tokens.
Write a new security model for Citadel.
There are some minor fixes to be done in the Protocol 1, in the paper:
- step 1: we can use Blake instead of Poseidon.
- step 1: the hash does not need both inputs.
- step 3: last argument of the mint function should be k_user · G. Or any other point know by both parties, as to encrypt we need a point.
Right now, in step (5) of the protocol a SessionCookie is computed and sent to the network. This serves two purposes:
- Such a struct contains the openings to the commitments, to verify that the user computed the proof correctly.
- The nullifier is linked to a particular SP.
Actually, there is no need to include the openings in the transaction, as only the correct user knows them. Instead, adding only an identifier for the SP would do the trick. So, a SP's stealth address can link the transaction to that particular SP, and later on, the user provides the openings to verify the correctness of the proof. And, at the very same time, the SP is convinced that the user is communicating with them is the one that nullified the license because only them could know the openings.
We need to rethink the values needed for license and request. They were designed thinking on Phoenix, but we agreed on having independent structs. So for instance, the element type is not needed anymore because Citadel must be private-by-default.
We need to implement the new structs defined in the specs:
The methods to use the license in the actual protocol need to be implemented according to the specs.
Citadel used to compute the signature of the transaction hash tx_hashwhere the license nullification is embedded. There were two reasons:
- Prevent malleability (the same transaction needed to append an NFT, thus everything needed to be signed).
- Prove that the user actually knows the license secret key.
As the session cookie is no longer included in the transaction, we can do better: the session stealth address ssa, which indeed needed to be included into the transaction and seen by everyone, will be signed using lsk and verified into the ZKP, instead of using tx_hash. Thus, it becomes a public input of the circuit.
Before the introduction of piecrust, the stake contract didn't have the allowlist field, opting instead to introduce a Stake data structure into the stakes map on an allow transaction. This should be re-done for full-parity.
The functions exposed by the transfer contract shouldn't return bool since they are either pass or fail, and use a panic to signal a failure.
We should extend the block acceptance procedure with full verification of the block header. This should cover block certificate verification as well.
Migrate to piecrust #760
To complete this issue the following issues have been addressed:
- Port transfer contract to piecrust #757
- Port stake contract to piecrust #758
- Port the rusk library to use piecrust #759
- Migrate rusk-recovery to use piecrust #795
- Port the transfer circuits to [email protected] #764
- Port rusk-abi to be compatible with piecrust-uplink #761
- Port the Rusk Test Infrastructure to use Piecrust #773
- Port governance contract to piecrust #854
We are working on deploying the NFT model in Rusk. For that reason, new note types will be used, and are being implemented already in phoenix-core:
0 - Transparent note
1 - Obfuscated note
2 - Transparent NFT note
3 - Obfuscated NFT note
4 - Transparent Message note (this one is NOT appended to the Merkle tree)
5 - Obfuscated Message note (this one is NOT appended to the Merkle tree)
We want Rusk to accept those notes created by the user. Basically, a user will create those, and will add them into a transaction. The ZKP of such a transaction will prove that the user has enough money to pay for the gas, but the new NFT note's commitments will not be part of that ZKP. Actually, NFT notes have no commitment. We can consider setting them to 0 in the code, or creating a new struct.
The Chain component within the Node crate should be responsible for initializing, running, and managing the Consensus mechanism. Several considerations need to be taken into account, including:
- Consensus keys are loaded from encrypted consensus.keys file
- Consensus reads/writes ledger data from/into the RocksDB backend
- EST and VST calls are mocked
- Inbound/outbound message queues are connected to the Kadcast reader/writer.
- Full cancellation of the Consensus routines happens on transition to out-of-sync state.
- Ledger accepts a block on Consensus_Achieved event after a sanity check.
We should port the governance contract to use piecrust instead of rusk-vm.
Upon receiving a transaction wire message from the network, the Mempool service is expected to decode it and attempt to accept it using the acceptance procedure implemented in the Dusk blockchain. To fully integrate the mempool service, there are several sub-tasks that must be considered:
- Introduce a new RocksDB API that verifies whether a transaction hash already exists in the blockchain.
- Remove all accepted transactions from the mempool storage when a block is accepted.
- Equip the Block Generator with a set of mempool transactions to generate a block
The below noted Releases including additions and changes to the repository can be followed on GitHub, for further details on their status and their function in the stack.
Piecrust | v0.2.0
The piecrust repository has now advanced to version 0.2.0
- Added uplink::owner and uplink::self_id. [#158]
- Implemented Display for ModuleId. [#178]
- Added persistence for module metadata. [#167]
- Added DeployData and DeployDataBuilder. [#158]
- Added contract constructor mechanism. [#93]
- Added caching of module compilation outputs. [#162]
- Derive Debug for Session and VM
- Changed deploy API to accept Into<DeployData>. [#158]
- Made modules compile at deploy time rather than on first query/transaction time. [#162]
- Removed errant print statements.
- Removed SELF_ID export from contracts. [#167]
Plonk | v014.0
The plonk repository has now advanced to version 0.14.0
- Add and restructure tests for assert_equal_point [#725]
- Add and restructure tests for assert_equal_public_point [#727]
- Add and restructure tests for append_gate [#737]
- Add and restructure tests for assert_equal and assert_equal_constant [#733]
- Add and restructure tests for logic component [#734]
- Add and restructure tests for range component [#735]
- Add and restructure tests for boolean and select components [#731]
- Add tests for gate_add and gate_mul [#736]
- Add and restructure tests for component_decomposition [#738]
- Remove bit_iterator macro [#632]
- Fix negation of public input values when using composer.append_public [#717]
- Fix assert_equal_point method [#720]
- Fix negation of constant in append_equal_constant [#728]
- Fix negation of public point coordinates in assert_equal_public_point [#728]
- Fix ProverKey::serialization_size and number of coefficients in a constraint [#743]
- Fix range gate for bit_num = 0 [#746]
Poseidon252 | v0.28.2
The Poseidon252 repository has now advanced to version 0.28.2
- Add benchmark for running sponge gadged on 5 BlsScalar (one permutation) [#206]
- Add benchmarks for cypher in native and zk [#197]
As you can see, development is continuous and this list is not exhaustive. For example, minor issues and advancements have also been opened and resolved. The complete series of repositories can be found on GitHub.
Breakthrough developments will receive a separate spotlight, such as our latest deployment of Daylight. Thank you very much for your understanding and feedback as we continue to find the best way to provide the community with transparency and development information.
In A Nutshell: Release Cycle planning
Release Cycle development planning has been adopted by major companies including Google, Mozilla, and during the development of products such as Ubuntu, Kubernetes, and many more. The reason for this is clear: Release Cycle planning improves the predictability of software development for developers and the community alike.
For a more detailed explanation of the concept (along with frequently asked questions) please scroll down to the bottom of this article.
We’ve included a small FAQ section below to make sure the community understands our intention with Release Cycles.
What is Release Cycle planning?
Release Cycle planning means that developmental updates are published at consistent intervals on GitHub; in the case of Dusk Network, every three weeks. These releases describe the latest additions, changes, fixes, and assets added to the tech stack by the development team.
Dusk Network currently has over 18+ active repositories on GitHub, each repository covering a different technical project. Release Cycle planning has not yet been applied to all repositories; the current focus on a single GitHub repository for clarity does not mean there are no ongoing developmental efforts occurring in other areas.
Does being featured in a Release mean Deployment?
The Release Cycle updates does not mean immediate deployments on our testnet. It is a release detailing additions, changes, and fixes to the repositories that we are ready to share with the public. All released content is considered stable, consistent, reviewed, and cross-checked with other repositories.
Are Release Cycle updates a spotlight for major deliverables?
No. The Release Cycle approach is strictly a way to provide a consistent shape for publication of our work in the clearest terms possible. They are not deadlines to be made, nor are they tied to specific development sprints. Release Cycle updates aim to raise attention with the community, and give proper coverage to, publishable GitHub releases. Major deliverables will be given their proper publication in dedicated articles.