Module agora.consensus.pool.Enrollment
Contains supporting code for managing enrollments registered by nodes on the network to be a validator, which means the enrollment information needs to be confirmed on the consensus protocol to be a validator. The information is stored in a table of SQLite.
Example
test for function of EnrollmentPool
import agora .consensus .PreImage;
import agora .consensus .data .Params;
import agora .consensus .data .Transaction;
import agora .consensus .EnrollmentManager;
import std .algorithm;
auto params = new immutable(ConsensusParams)();
scope storage = new MemoryUTXOSet;
scope pool = new EnrollmentPool(new ManagedDatabase(":memory:"));
KeyPair key_pair = WK .Keys .A;
Enrollment[] enrollments;
Height avail_height;
bool findEnrollment (in Hash, out EnrollmentState) @trusted nothrow
{
return false;
}
Amount getPenaltyDeposit (Hash) @trusted nothrow
{
return 10_000 .coins;
}
genesisSpendable() .map!(txb => txb .refund(key_pair .address) .sign(OutputType .Freeze))
.each!(tx => storage .put(tx));
// Add enrollments
Hash[] utxo_hashes = storage .keys;
foreach (index; 0 .. 3)
{
auto utxo_hash = utxo_hashes[index];
avail_height = Height(params .ValidatorCycle);
enrollments ~= EnrollmentManager .makeEnrollment(utxo_hash, key_pair, avail_height, params .ValidatorCycle);
assert(pool .add(enrollments[$ - 1], avail_height,
storage .getUTXOFinder(), &findEnrollment, &getPenaltyDeposit));
assert(pool .count() == index + 1);
assert(pool .hasEnrollment(utxo_hash, avail_height));
assert(!pool .add(enrollments[$ - 1], avail_height,
storage .getUTXOFinder(), &findEnrollment, &getPenaltyDeposit));
}
// check if enrolled heights are not set
Enrollment[] enrolls = pool .getEnrollments(avail_height);
assert(enrolls .length == 3);
assert(enrolls .isStrictlyMonotonic!("a.utxo_key < b.utxo_key"));
// get a specific enrollment object
Enrollment stored_enroll;
assert((stored_enroll = pool .getEnrollment(utxo_hashes[1],
Height(avail_height + 1))) == Enrollment .init);
assert((stored_enroll = pool .getEnrollment(utxo_hashes[1],
Height(avail_height - 1))) == Enrollment .init);
assert((stored_enroll = pool .getEnrollment(utxo_hashes[1],
avail_height)) == enrollments[1]);
assert((stored_enroll = pool .getEnrollment(utxo_hashes[1])) !=
Enrollment .init);
assert(stored_enroll == enrollments[1]);
// remove an enrollment
pool .remove(utxo_hashes[1]);
assert(pool .count() == 2);
assert(pool .getEnrollment(utxo_hashes[1]) == Enrollment .init);
// test for enrollment block height update
enrolls = pool .getEnrollments(avail_height);
assert(enrolls .length == 2);
avail_height = Height(params .ValidatorCycle);
assert(pool .hasEnrollment(utxo_hashes[0], avail_height));
avail_height = Height(params .ValidatorCycle * 2);
assert(!pool .hasEnrollment(utxo_hashes[0], avail_height));
pool .remove(utxo_hashes[0]);
assert(!pool .hasEnrollment(utxo_hashes[0], avail_height));
pool .remove(utxo_hashes[1]);
pool .remove(utxo_hashes[2]);
assert(pool .getEnrollments(avail_height) .length == 0);
// Reverse ordering
Enrollment[] ordered_enrollments = enrollments .dup;
ordered_enrollments .sort!("a.utxo_key > b.utxo_key");
foreach (ordered_enroll; ordered_enrollments)
assert(pool .add(ordered_enroll, Height(params .ValidatorCycle),
&storage .peekUTXO, &findEnrollment, &getPenaltyDeposit));
enrolls = pool .getEnrollments(Height(params .ValidatorCycle));
assert(enrolls .length == 3);
assert(enrolls .isStrictlyMonotonic!("a.utxo_key < b.utxo_key"));
Classes
Name | Description |
---|---|
EnrollmentPool
|