Skip to content

Latest commit

 

History

History
95 lines (60 loc) · 7.13 KB

wip-0008.md

File metadata and controls

95 lines (60 loc) · 7.13 KB
    WIP: WIP-0008
    Layer: Consensus (hard fork)
    Title: Limits on data request concurrency
    Author: Adán SDPC 
    Discussions-To: `#dev-general` channel on Witnet Community's Discord server
    Status: Final
    Type: Standards Track
    Created: 2021-01-12
    License: BSD-2-Clause

Abstract

This proposal introduces changes to block validations consisting in hard limits on the number of Witnet data requests that can be processed concurrently.

The goal of this proposal is ensuring that Witnet nodes are not forced to process too many requests at the same time, which could be abused as a denial-of-service attack and pose a serious threat to availability and security of the network and any smart contracts relying on it for its oracle capabilities.

Motivation and Rationale

More than once in the pre-mainnet stage of the Witnet ecosystem, the Witnet testnet faced episodes of severe network disruption caused by some nodes with low computation resources getting clogged when trying to process many data requests at the same time.

This situation has been milder on the Witnet mainnet, as the volume of data request transactions flooding the network is significantly lower, most probably due to their cost in Wit tokens (conversely, testnet tokens had no intrinsic value and node operators may deploy bogus data requests just for the sake of experimenting with redistribution of reputation points).

However, even if this is not a critical issue at these early ages of the ecosystem, it is to be expected that the network undergoes similar situations sooner or later either because of a potential increase on the volume of high-value data requests, or, in absence thereof, a high number of the aforementioned bogus data requests.

One of the early design principles of the Witnet protocol was always that anyone could run a node on commodity, off-the-shelf hardware. The witnet-rust implementation of the protocol was created with this principle in mind, and it will normally perform without any issue on cheap VPSs or even on small single-board computers like the Raspberry Pi. This is crucial for keeping the network neutral, open, and decentralized—under the assumption that a numerous crowd of amateur node operators are less likely to collude or corrupt than a few professional miners.

Although it is hard to know what the node demographics actually are in term of how many resources (CPU, RAM) do have at their disposal, the community has long applied an intuitive rule of thumb consisting in allocating at least 1 CPU or vCPU and 1GB of RAM to each Witnet node. While these requirements should be more than enough most of the time, it is not hard to imagine that nodes like that would easily be disrupted when concurrently processing dozens of data requests, as the testnet experiments proved.

The block limits in WIP-0007 do normally prevent too many requests from being processed at the same time. However, block reorganizations or reversal in the context of superblock consensus can easily cause several data requests to be retried at the same epoch. That is, under an episode of lack of network consensus, data requests can go from any stage (commit, reveal, tally or final) back to the initial published stage. This will cause all pending data requests to concurrently enter the commit stage in the same epoch, leading to the negative side effects explained before.

The witnet-rust implementation of the protocol already enforces some limits to the number of data requests that are posted into a single block. However, these restrictions are only applied when producing block candidates, i.e. block proposers will refrain from including data request transactions if there are already more than a certain number of data requests in the commit, reveal or tally stages; but blocks that exceed those limits are still valid.

There is also a hard limit to the number of retrievals that a witnet-rust node will perform and commit to during a single epoch. This limit was implemented back in March 2020 by pull request #1098, and can be adjusted by node operators through the mining.data_request_max_retrievals_per_epoch setting in the witnet.toml configuration file. Again, this limit is only enforced when mining, and existing consensus rules do not prevent blocks from exceeding such limits.

From a protocol standpoint, all of these restrictions are insufficient, as there exist no block validations that restrict data request concurrency, and alternative protocol implementations may choose not to enforce the same non-consensus limits than witnet-rust does, i.e. blocks produced by those alternative implementations could still potentially disrupt witnet-rust nodes.

Summing up, there is a need for adding new block validation rules that enforce a reasonable limit to data requests concurrency, so as to ensure availability of the network and allow for more consistent and predictable hardware requirements for nodes.

Proposal / Specification

Following entry into force of this proposal, all implementations of the Witnet protocol, at all subsequent protocol epochs, MUST add up the combined weight of all data requests in the commit stage (unsolved weight); and reject every block candidate containing any further data requests whose combined weight (added weight) added to the unsolved weight is strictly greater than the max_dr_weight constant from WIP-0007.

// This example is using JavaScript alike pseudocode

const max_dr_weight = 80_000;
let unsolved_weight = 0;
let added_weight = 0;

for (pending_data_request of data_requests_in_commit_stage) {
    unsolved_weight += pending_transaction.weight();
}

for (new_transaction of block_candidate_data_request_transactions) {
    extra_weight += new_transaction.weight();
}

if (unsolved_weight + added_weight > max_dr_weight) {
    // reject block candidate
} else {
    // continue validating block candidate
}

As of publication time of this proposal, max_dr_weight was 80000.

Reference Implementation

The business logic described in the specification was implemented in witnet-rust by pull request #1790.

Adoption Plan

The changes proposed herein have been already implemented in witnet-rust and the activation of the new consensus rule is scheduled as a community-coordinated hard fork to take place on January 22, 2021 at 9am UTC, as proposed by pull request #1790 and widely announced to the community in a timely manner.

Acknowledgments

This proposal has been cooperatively devised by many individuals from the Witnet development community.

Special thanks to Luis Rubio for the reference implementation in Rust.