New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@keep-network/sortition-pools

Package Overview
Dependencies
Maintainers
5
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@keep-network/sortition-pools

= Sortition Pools

  • 1.2.0-dev.3
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
342
decreased by-15.97%
Maintainers
5
Weekly downloads
 
Created
Source

= Sortition Pools

Sortition pool is a logarithmic data structure used to store the pool of eligible operators weighted by their stakes. In the Keep network the stake consists of staked KEEP tokens. It allows to select a group of operators based on the provided pseudo-random seed and optional bonding requirements.

Each privileged application has its own sortition pool and eligibility is checked when an operator is selected, rejecting and removing ineligible operators from the pool.

A sortition pool provides instant selection results and is less affected by censorship that the ticket selection, although malicious miners can still censor protocol result submissions. Additionally, miners and other actors that can predict the selection seed (due to frontrunning the beacon or a public cached seed being used) may be able to manipulate selection outcomes to some degree by selectively updating the pool. To mitigate this, operators who have joined the pool too recently are ineligible for selection, and the pool and its RNG have been designed to reduce the degrees of freedom available to such an adversary. The fewer outdated operators there are in the pool, the less attack surface the pool presents, so proactive maintenance is also helpful.

== Overview

An operator enters a sortition pool by opting in. The pool checks their eligible tokens stake (including operator status and authorization to slash stakes), and optionally available bonding value (including authorization to seize bonds). The operator pays the transaction fees for the pool update.

Keeping these pools up to date cannot be done eagerly as proliferation of privileged customers could be used to perform DOS attacks by increasing the cost of such updates. When a sortition pool prospectively selects an operator, the selected operator's eligibility status and weight are checked. If the information is out of date in a way that updating it would be detrimental to the operator, the operator is removed from the pool and a new operator is selected from the updated pool. This is to incentivize operators to keep their information up to date.

The number of operator selections required to get n valid non-unique members averages n / (1 - e) where e equals the fraction of weight in the pool belonging to operators whose information is detrimentally out of date. If 50% of the pool weight is outdated, the average number of selections is 6, roughly 2% of ECDSA keeps would require 12 or more operator selections, and more than 20 selections would be extremely rare. Sortition pools that are used more often would be less outdated.

== Optimized higher arity trees

Even though logarithmic data structures are well-known, the particular characteristics of Ethereum smart contracts require specialized optimization to make non-interactive sortition viable.

To enable weighted sortition, each sortition pool would have a weighted tree where each leaf stores an operator and is labeled with the operator's sortition weight, and each branch is labeled with the sum of the weights of its children. To select an operator from the pool, a pseudorandom number in [0, W) (where W is the total sortition weight of the tree) is acquired and used to index into the tree.

A single storage field in the EVM consists of 256 bits/32 bytes. Data structures on the EVM are naturally sparse. An implicit heap can eliminate the need for pointers so the full capacity of each storage field can be used for content data.

KEEP tokens have 18 decimals and the total supply is 1,000,000,000 KEEP. A precise token amount would require roughly 96 bits/12 bytes to store. However, the minimum stake required to participate is expected to be in the region of 1,000~100,000 KEEP.

Instead of using the exact token amount, each operator's sortition weight should use their staker weight as in the Random Beacon group selection. 32 bits is sufficient for all practical purposes.

A storage field can hold 8 values of 32 bits. This gives a theoretical ceiling of 4 billion possible virtual stakers without concern for the exact distribution of weights.

The actual sortition tree has 8 levels, including root and leaves, with the following number of nodes on each level:

  • root: 1
  • level 2: 8
  • level 3: 64
  • level 4: 512
  • level 5: 4ki
  • level 6: 32ki
  • level 7: 256ki
  • leaves: 2Mi

This means that we can store up to 2 mibioperators (a bit over 2 million) in the sortition tree. If the minimum stake is at least TOKEN_SUPPLY / 2**21, the pool will always be able to accommodate all possible operators.

== Usage

=== Bonded Sortition Pool

==== Creating a pool


import "@keep-network/sortition-pools/contracts/api/IStaking.sol"; import "@keep-network/sortition-pools/contracts/api/IBonding.sol"; import "@keep-network/sortition-pools/contracts/BondedSortitionPool.sol"; import "@keep-network/sortition-pools/contracts/BondedSortitionPoolFactory.sol";

(...)

BondedSortitionPoolFactory sortitionPoolFactory;

(...)

address poolAddress = sortitionPoolFactory.createSortitionPool( IStaking(keepStakingContract), IBonding(keepBondingContract), minimumStake, minimumBond, poolWeightDivisor );

BondedSortitionPool pool = BondedSortitionPool(poolAddress);

==== Joining the pool


if (!pool.isOperatorInPool(operator)) { pool.joinPool(operator); }

==== Updating status


if (!pool.isOperatorUpToDate(operator)) { pool.updateOperatorStatus(operator); }

==== Selecting unique signers


address[] memory members = pool.selectSetGroup( groupSize, bytes32(groupSelectionSeed), minimumStake, memberBond );

=== Sortition Pool with no bonding

==== Creating a pool


import "@keep-network/sortition-pools/contracts/SortitionPool.sol"; import "@keep-network/sortition-pools/contracts/SortitionPoolFactory.sol";

(...)

SortitionPoolFactory sortitionPoolFactory;

(...)

address poolAddress = sortitionPoolFactory.createSortitionPool( IStaking(keepStakingContract), minimumStake );

SortitionPool pool = SortitionPool(poolAddress);

==== Joining the pool


if (!pool.isOperatorInPool(operator)) { pool.joinPool(operator); }

==== Updating status


if (!pool.isOperatorUpToDate(operator)) { pool.updateOperatorStatus(operator); }

==== Selecting non-unique signers


address[] memory members = pool.selectGroup( groupSize, bytes32(groupSelectionSeed), minimumStake );

=== Fully Backed Sortition Pool

==== Creating a pool


import "@keep-network/sortition-pools/contracts/api/IBonding.sol"; import "@keep-network/sortition-pools/contracts/FullyBackedSortitionPool.sol"; import "@keep-network/sortition-pools/contracts/FullyBackedSortitionPoolFactory.sol";

(...)

FullyBackedSortitionPoolFactory sortitionPoolFactory;

(...)

address poolAddress = sortitionPoolFactory.createSortitionPool( IBonding(keepBondingContract), minimumStake, bondWeightDivisor );

FullyBackedSortitionPool pool = FullyBackedSortitionPool(poolAddress);

==== Joining the pool


if (!pool.isOperatorInPool(operator)) { pool.joinPool(operator); }

==== Updating status


if (!pool.isOperatorUpToDate(operator)) { pool.updateOperatorStatus(operator); }

==== Selecting unique signers


address[] memory members = pool.selectSetGroup( groupSize, bytes32(groupSelectionSeed), memberBond );

FAQs

Package last updated on 15 Oct 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc