Testnet DayLight | Release Cycle Update #18


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.


Open issues

Ownership of Contracts #158

We need to support the concept of contract ownership.

Ownership of a contract may help decide who is allowed to execute certain contract methods.

Store the merkle tree of contracts #166

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.

Secure Persistent Metadata for Contracts #167

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.

Better structure and data encapsulation #181

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.

Implement Missing Tests #184

Part of Piecrust functionality remains untested or it is only indirectly tested. Add more direct tests, especially concerning module deployment, ownership, metadata, persistence, commits.

Closed issues


push_callstack not storing module instances #162

It looks like every time push_callstack is called, a new module instance is created as existing instance is not found in instance_map.

ModuleId should implement Display #178

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.



Closed issues

Add benchmarks for PoseidonCipher ZK and non-ZK #198

We need benchmarks in order to track performance throughout the development.

Add benchmarks for poseidon sponge #206

Add benchmarks for the sponge gadget proof creation and verification.

Remove the benchmarking of circuit compilation #209

Remove the circuit compilation from all in-circuit benchmarks.



Closed issues

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.

Wrong amount serialized #19


Amount: 1.0

Serialized amount (with the float2fixed): 4294967296



Closed issues

Document component decomposition with examples #704

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.

Refactor and add tests for component_range #735

Add in-circuit tests for the composer methods

  • component_range

Add tests for gate_add and gate_mul #736

Add in-circuit tests for the composer methods

  • gate_add
  • gate_mul

Refactor and add tests for component_decomposition #738

Add and refactor in-circuit tests for the composer methods

  • append_gate

No range check when num_bits = 0 #746

When adding a range gate with zero bits, any witness always satisfies the circuit.


Closed issues

Derive Default for StealthAddress #81

For Citadel, we need StealthAddress to derive Default.



Open issues

Improve Generation code documentation #1508

Fix extractCommitteeMember #1511

Update Block Generation README #1513

Fix committee size comments #1519

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.

Make CommitteeSize consistent with size #1520

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.

Closed issues

Update README on Deterministic Sortition #1507

After #1491,summarize Deterministic Sortition algorithm in this README.

Fix createSortitionHash description #1509

In createSortitionHash, the i parameter is indicated as an iteration number, which sounds mistakenly related to the SA iterations.

Test harness doesn't work #1514

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.


Open issues

Add Merkle opening verification #1

It should be possible to verify that an item is the leaf of the MerkleOpening.


Open issues

Resolve VoteSetTooSmall error in consensus accumulator #53

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.

Closed issues

Substitute msg-related structs with ones implemented in node-data crate #44

For better maintenance and interoperability, the wire message structures have been moved into a node-data crate together with AsyncQueue and ConsensusPublicKey.

Add get_mempool_txs method to Operations trait #47

Expose verify_step_votes algorithm #50

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.

Fix value of DUSK in Sortition #51

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.


Open issues

Define Citadel Specs #21

Right now we have a research paper for Citadel. We need to create a new document with the specifications to be implemented.

See if we can use Citadel for Soulbound tokens #25

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.

Design a security model for Citadel #26

Write a new security model for Citadel.

Fix protocol steps #27

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.

Research on improving the management of the SessionCookie #28

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.

Research on the elements included in the license and request #29

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.

Implement the new structs #30

We need to implement the new structs defined in the specs:

  • Request
  • License
  • LicenseProverParameters
  • Session
  • SessionCookie

Implement license methods #32

The methods to use the license in the actual protocol need to be implemented according to the specs.

Research on changing the tx_hash by the ssa #33

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.

Closed issues

Write the General Overview in the Citadel specs #22

Write the Protocol Sections in the Citadel specs #23


Open issues

Remove allowlist data structure from the stake contract #858

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.

Transfer contract functions shouldn't return #859

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.

node: Implement block header verification #863

We should extend the block acceptance procedure with full verification of the block header. This should cover block certificate verification as well.

Closed issues

Migrate to piecrust #760

To complete this issue the following issues have been addressed:

Allow users to mint NFT notes #828

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.

node: Integrate Node library with Consensus crate #850

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.

Port governance contract to piecrust #854

We should port the governance contract to use piecrust instead of rusk-vm.

node: Accept transaction in mempool #855

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

node-data: Add support for read/write a transaction wire message #860


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.

[Read more about our Release Cycle planning here]