Skip to content

Commit

Permalink
Approve multiple candidates with a single signature (#1191)
Browse files Browse the repository at this point in the history
Initial implementation for the plan discussed here: #701
Built on top of #1178
v0: paritytech/polkadot#7554,

## Overall idea

When approval-voting checks a candidate and is ready to advertise the
approval, defer it in a per-relay chain block until we either have
MAX_APPROVAL_COALESCE_COUNT candidates to sign or a candidate has stayed
MAX_APPROVALS_COALESCE_TICKS in the queue, in both cases we sign what
candidates we have available.

This should allow us to reduce the number of approvals messages we have
to create/send/verify. The parameters are configurable, so we should
find some values that balance:

- Security of the network: Delaying broadcasting of an approval
shouldn't but the finality at risk and to make sure that never happens
we won't delay sending a vote if we are past 2/3 from the no-show time.
- Scalability of the network: MAX_APPROVAL_COALESCE_COUNT = 1 &
MAX_APPROVALS_COALESCE_TICKS =0, is what we have now and we know from
the measurements we did on versi, it bottlenecks
approval-distribution/approval-voting when increase significantly the
number of validators and parachains
- Block storage: In case of disputes we have to import this votes on
chain and that increase the necessary storage with
MAX_APPROVAL_COALESCE_COUNT * CandidateHash per vote. Given that
disputes are not the normal way of the network functioning and we will
limit MAX_APPROVAL_COALESCE_COUNT in the single digits numbers, this
should be good enough. Alternatively, we could try to create a better
way to store this on-chain through indirection, if that's needed.

## Other fixes:
- Fixed the fact that we were sending random assignments to
non-validators, that was wrong because those won't do anything with it
and they won't gossip it either because they do not have a grid topology
set, so we would waste the random assignments.
- Added metrics to be able to debug potential no-shows and
mis-processing of approvals/assignments.

## TODO:
- [x] Get feedback, that this is moving in the right direction. @ordian
@sandreim @eskimor @burdges, let me know what you think.
- [x] More and more testing.
- [x]  Test in versi.
- [x] Make MAX_APPROVAL_COALESCE_COUNT &
MAX_APPROVAL_COALESCE_WAIT_MILLIS a parachain host configuration.
- [x] Make sure the backwards compatibility works correctly
- [x] Make sure this direction is compatible with other streams of work:
#635 &
#742
- [x] Final versi burn-in before merging

---------

Signed-off-by: Alexandru Gheorghe <[email protected]>
  • Loading branch information
alexggh authored Dec 13, 2023
1 parent d18a682 commit a84dd0d
Show file tree
Hide file tree
Showing 82 changed files with 5,878 additions and 1,478 deletions.
8 changes: 8 additions & 0 deletions .gitlab/pipeline/zombienet/polkadot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ zombienet-polkadot-functional-0008-dispute-old-finalized:
--local-dir="${LOCAL_DIR}/functional"
--test="0008-dispute-old-finalized.zndsl"

zombienet-polkadot-functional-0009-approval-voting-coalescing:
extends:
- .zombienet-polkadot-common
script:
- /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh
--local-dir="${LOCAL_DIR}/functional"
--test="0009-approval-voting-coalescing.zndsl"

zombienet-polkadot-smoke-0001-parachains-smoke-test:
extends:
- .zombienet-polkadot-common
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use polkadot_overseer::{ChainApiBackend, RuntimeApiSubsystemClient};
use polkadot_primitives::{
async_backing::{AsyncBackingParams, BackingState},
slashing,
vstaging::NodeFeatures,
vstaging::{ApprovalVotingParams, NodeFeatures},
};
use sc_authority_discovery::{AuthorityDiscovery, Error as AuthorityDiscoveryError};
use sc_client_api::AuxStore;
Expand Down Expand Up @@ -427,6 +427,18 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient {
Ok(self.rpc_client.parachain_host_para_backing_state(at, para_id).await?)
}

/// Approval voting configuration parameters
async fn approval_voting_params(
&self,
at: Hash,
session_index: polkadot_primitives::SessionIndex,
) -> Result<ApprovalVotingParams, ApiError> {
Ok(self
.rpc_client
.parachain_host_staging_approval_voting_params(at, session_index)
.await?)
}

async fn node_features(&self, at: Hash) -> Result<NodeFeatures, ApiError> {
Ok(self.rpc_client.parachain_host_node_features(at).await?)
}
Expand Down
15 changes: 14 additions & 1 deletion cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use cumulus_primitives_core::{
relay_chain::{
async_backing::{AsyncBackingParams, BackingState},
slashing,
vstaging::NodeFeatures,
vstaging::{ApprovalVotingParams, NodeFeatures},
BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo,
Hash as RelayHash, Header as RelayHeader, InboundHrmpMessage, OccupiedCoreAssumption,
Expand Down Expand Up @@ -625,6 +625,19 @@ impl RelayChainRpcClient {
}

#[allow(missing_docs)]
pub async fn parachain_host_staging_approval_voting_params(
&self,
at: RelayHash,
_session_index: SessionIndex,
) -> Result<ApprovalVotingParams, RelayChainError> {
self.call_remote_runtime_function(
"ParachainHost_staging_approval_voting_params",
at,
None::<()>,
)
.await
}

pub async fn parachain_host_para_backing_state(
&self,
at: RelayHash,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use emulated_integration_tests_common::{

// Rococo declaration
decl_test_relay_chains! {
#[api_version(9)]
#[api_version(10)]
pub struct Rococo {
genesis = genesis::genesis(),
on_init = (),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use emulated_integration_tests_common::{

// Westend declaration
decl_test_relay_chains! {
#[api_version(9)]
#[api_version(10)]
pub struct Westend {
genesis = genesis::genesis(),
on_init = (),
Expand Down
1 change: 0 additions & 1 deletion polkadot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ jemalloc-allocator = [
"polkadot-node-core-pvf/jemalloc-allocator",
"polkadot-overseer/jemalloc-allocator",
]
network-protocol-staging = ["polkadot-cli/network-protocol-staging"]


# Enables timeout-based tests supposed to be run only in CI environment as they may be flaky
Expand Down
2 changes: 0 additions & 2 deletions polkadot/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,3 @@ runtime-metrics = [
"polkadot-node-metrics/runtime-metrics",
"service/runtime-metrics",
]

network-protocol-staging = ["service/network-protocol-staging"]
Loading

0 comments on commit a84dd0d

Please sign in to comment.