- Decentralization Manager
- Operations and reference
- Add a member to a Decentralized Party
Add a member to a Decentralized Party
This guide adds a participant to a Decentralized Party that already exists. The new participant becomes a namespace owner and a host of the party. Decentralization Manager then copies the party’s contracts to it.
The API calls this run the add-party workflow. The web interface calls it Add Member.
- Coordinator: the node of a current host that starts the run.
- Hosts: the participants that host the party and own its namespace today.
- New member: the participant that joins.
Every host and the new member take part in the run. Each of them accepts an invitation on its own node.
For a party that is not a Decentralized Party, use another guide:
- A party with its own key, held by a wallet: Decentralize an external party.
- A party local to one participant: Decentralize an existing party.
Membership and governance changes explains how this run fits with governance membership and thresholds.
Before you start
Section titled “Before you start”Check every item. Decentralization Manager refuses the run, or the run fails partway, when one is missing.
- The new member runs Decentralization Manager. It connects to its own participant. All nodes of a Decentralized Party must run the same release. The code itself accepts any peer that has the same wire version and reports version
0.1.9or later. - The nodes know each other as peers. The coordinator and the new member must list each other. Every host must list the coordinator. Set up the full mesh anyway, because a later run can have a different coordinator. See Connect peers.
- The new member has every DAR that the party uses. The coordinator checks this before it writes any topology. See Check the new member’s DARs.
- The coordinator can read the party’s contracts. The DAR check reads them over the Ledger API, with the party credentials on the coordinator. Open the party page and confirm that Test Auth succeeds.
- No other run is in flight for this party. A node refuses to start a kick, add-party, change-threshold, or contracts run for a party that already has a run in progress on that node. The node counts its runs in either role, as coordinator or as peer. The guard is local to each node. Decentralization Manager does not stop two different nodes from coordinating conflicting runs on the same party.
- You can take the new member offline for a while. Its participant leaves the synchronizer during the run. See Downtime.
If the new member hosted the party before, read Re-adding a former member first.
Check the new member’s DARs
Section titled “Check the new member’s DARs”- Open the party page and click Check DARs. The Packages page opens and compares the party’s hosts.
- Add the new member in the Participants box. It is not a host yet, so Decentralization Manager does not add it for you.
- Turn on Differences only. A red cell with an error icon marks a package that the new member lacks.
- Click the send icon in that cell to distribute the DAR. The new member’s operator accepts it under Approvals. The send icon shows only in a web interface build with admin access.
Package and contract operations describes the DAR workflow and its API.
Downtime
Section titled “Downtime”The new member’s participant disconnects from the synchronizer when it signs the proposals. It reconnects after the contract import ends. While it is disconnected, every party on that participant pauses, not only this party.
The current hosts are not affected. The party keeps transacting on them for the whole run.
Two things set the time offline:
- How fast the current hosts sign.
- How many contracts the party holds.
So brief the operators of the current hosts before you start, so that they accept quickly.
Choose the new threshold
Section titled “Choose the new threshold”The threshold is how many namespace owners must sign a topology change for the party. Decentralization Manager also uses it as the party’s confirmation threshold.
The new threshold must be between 1 and the current number of namespace owners. The new member does not count yet, because it cannot sign until its import completes. The dialog suggests half the owners after the add, rounded up.
The dialog accepts one value above the current number of owners. The node rejects that value with “new_threshold must be between 1 and N”.
To count the new member, run Change Threshold after this run completes. See the Change a threshold section of Membership and governance changes.
Run it in the web interface
Section titled “Run it in the web interface”On the coordinator:
- Open Parties and click the party.
- In the Participants section, click the Add member icon.
- In Participant to Add, pick the new member. The list holds the peers that do not host the party yet.
- Set New Threshold.
- Click Add Member.
The coordinator sends an invitation to every host and to the new member.
On every invited node:
- Open Approvals. The invitation is under Needs your action.
- Click Review ▾. Check the Dec party, the participant under Adding, and the Threshold.
- Click Accept.
The run starts when every invited node has accepted. The coordinator shows the run as a card under Approvals, with one dot for each step. During the copy, the card shows a meter: “Sending ACS” on the coordinator, and “Importing ACS” on the new member.
Run it with the API
Section titled “Run it with the API”The operator API needs an access token from your identity provider. The caller needs the admin role when the node sets DECPM_ADMIN_ROLE. See Authentication and operator roles.
Start the run on the coordinator. Set NEW_THRESHOLD and OLD_THRESHOLD first:
curl -sS -X POST "$COORDINATOR/add-party" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{ "decentralized_party_id": "joint-custody::1220...", "new_participant_id": "custodian-d::1220...", "new_threshold": '"$NEW_THRESHOLD"', "previous_threshold": '"$OLD_THRESHOLD"' }'previous_threshold is for display only. The answer is HTTP 202 with the run’s instance_name.
Accept the invitation on every invited node:
ID=$(curl -sS "$NODE/invitations" -H "Authorization: Bearer $TOKEN" \ | jq -r '.invitations[] | select(.invitation_type == "AddParty") | .id')curl -sS -X POST "$NODE/invitations/accept" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d "{\"id\": \"$ID\"}"Follow the run on the coordinator:
curl -sS "$COORDINATOR/workflows" -H "Authorization: Bearer $TOKEN" \ | jq '.runs[] | select(.instance_name | contains("-add-party-")) | {instance_name, status, current_step, step_index, step_total, error}'What the run does
Section titled “What the run does”| # | Step | Who acts | What happens |
|---|---|---|---|
| 1 | WaitingForPeers |
Coordinator | Waits until every invited node has accepted and connected |
| 2 | GenerateNewMemberKeys |
New member | Creates its namespace key and its Daml signing key in its participant |
| 3 | ExportState |
Coordinator | Reads the party’s topology, checks the threshold, and checks the new member’s packages |
| 4 | CreateProposals |
Coordinator | Builds the new namespace and hosting mappings. The new member gets Canton’s onboarding marker |
| 5 | SignProposals |
All | Every node signs. The new member then disconnects from the synchronizer |
| 6 | SubmitProposals |
Coordinator | Submits the mappings and opens the export of the party’s contracts |
| 7 | SyncAcs |
New member | Imports the contracts block by block, then reconnects |
| 8–12 | Clear the onboarding marker | All | The new member proposes to clear the marker, every node signs, and the coordinator submits |
| 13 | RetireLegacyKeys |
All | Removes the party’s old key mapping, if it has one |
| 14 | Complete |
All | Ends the run |
While the onboarding marker is set, the new member hosts the party but does not confirm for it. The marker clears in steps 8 to 12.
The coordinator signs the namespace proposal in a temporary topology store, and publishes it at step 6. A host that never signs therefore leaves the namespace unchanged. The coordinator publishes the hosting proposal at step 4, because the new member’s import needs it in the new member’s own store. Canton keeps that proposal pending until the new member signs it.
The coordinator’s card can show these steps under their code names, for example “Export state”. Architecture lists the Canton calls behind each step.
After the run
Section titled “After the run”- Check the party page. The new member is in Participants, and Owners has grown by one.
- Give the new member credentials. On the new member’s node, store the party credentials and grant the Canton rights. See the Party credentials section of Authentication and operator roles.
- Add the new member to governance. The topology change does not change the party’s
GovernanceRulescontract. If the party has one, propose a governance add-member action. See the Add a governance member section of Membership and governance changes. - Raise the threshold if the plan requires it. Run Change Threshold to count the new member.
Re-adding a former member
Section titled “Re-adding a former member”A participant that hosted the party before can still own its namespace. For example, it removed its own hosting entry, but stayed a namespace owner. Decentralization Manager detects this case and adds the hosting entry only. The namespace stays as it is.
In this case, the new threshold must equal the current threshold. Change it afterwards with Change Threshold.
Treat a participant that left the party after a failed run as a recovery case. Two rules apply:
- Do not reconnect it while it lacks the party’s contracts. On reconnect, it replays every event that it missed. It judges each event by the topology at that event’s time. So it acts as a host again, and it crashes.
- Purge only what the party alone holds. The participant purges the party’s old contracts before the re-add. Keep every contract that another party on that participant is also a stakeholder of. The copy in step 7 leaves those contracts out, so a contract that you purge by mistake never comes back.
Contact the BitSafe team before you recover a participant in this state.
If something goes wrong
Section titled “If something goes wrong”Decentralization Manager refuses to start the run
Section titled “Decentralization Manager refuses to start the run”| Error says | Do this |
|---|---|
| “is not a configured peer of this node” | Add the new member as a peer on the coordinator |
| “No cached membership for …” | Open Parties and search for the party, to refresh the list. Then start the run again |
| “is already a member of …” | Nothing. The participant already hosts the party |
| “This node is not a member of …” | Start the run from a node that hosts the party |
| “Cannot add yourself as the new participant” | Start the run from the node of a current host, not from the new member |
| “new_threshold must be between 1 and N” | Pick a value up to the current number of owners |
| “already has a … workflow in flight” | Wait for that run to end, or cancel it |
| A list of incompatible peers | Upgrade those nodes to the same release |
The run fails
Section titled “The run fails”The coordinator’s card shows the error. Click Retry on the coordinator, or call POST /workflows/{instance_name}/retry. The run continues from the step that failed.
Do not cancel the run. A cancel does not reconnect the new member. The coordinator cannot retry a cancelled run, so the state that a retry needs is gone.
| Error says | Cause | Do this |
|---|---|---|
| “the new member … is missing N package(s)” | A DAR is missing on the new member | Distribute the DAR, then click Retry |
| “Re-hosting … leaves the namespace as it is” | A former member was re-added with a new threshold | Start a new run with the current threshold |
| “… is quarantined for …” | An earlier copy failed after part of the contracts reached Canton | See Quarantine |
A timeout in RetireLegacyKeys |
Too few upgraded owners are online | Bring the owners online, then click Retry |
| “peer(s) are marked complete but have no … artefact” | The coordinator restarted during a hand-off and lost signatures | Start a new run |
A connected participant that hosts the party without its contracts receives the party’s traffic. That state has crashed a participant on MainNet. Re-adding a former member lists the rules that follow from it.
Quarantine
Section titled “Quarantine”A copy can fail after some contracts already reached the new member’s participant. Canton cannot report how many arrived. Decentralization Manager then quarantines the new member for this party, and it refuses every later copy onto it.
-
Repair the participant with Canton’s
RepairCommitmentsUsingAcs, or restore it from a backup. -
Lift the quarantine on the new member’s node, which ran the import:
Terminal window curl -sS -X DELETE \"$NEW_MEMBER_NODE/acs-import-quarantine?party_id=$PARTY&participant_id=$NEW_MEMBER" \-H "Authorization: Bearer $TOKEN" -
Start a new add-party run.
The DELETE call records your decision only. It repairs nothing. The call answers {"lifted": true} when it removed a quarantine.
Technical sources
Section titled “Technical sources”- Adding a member guide
- Add-party handler and threshold rule
- Add-party workflow steps
- Package preflight
- Contract copy, import window, and quarantine
- Temporary proposal stores
- Add Member dialog
- Architecture
Related pages
Section titled “Related pages”- Membership and governance changes
- Package and contract operations
- Authentication and operator roles
- Backup, recovery, and upgrades
Next step
Section titled “Next step”Add the new member to governance: Membership and governance changes.
Ask the docs
Answers come only from this documentation and can be wrong. Check the linked pages.
Ask a question about BitSafe, CBTC or the developer guides. For example: