How scheduling works in the Proof-of-Individuality (POI) system
The PseudonymRound contract (previously named contract Registration) schedules each step of the POI test net 24 hour cycle, so that certain functions can only be called at specific time-periods.
register()
is open for the first 10 hours of the round, and will be open for 12 days in the live 28 day cycle version.
function register() payable atTime(registration, commitment) {
if(userHash[msg.sender] != bytes32(0)) throw; // already registered
if(msg.value < depositSize) throw;
// generate a hash for the given user, using previous entropy,
// senders address and current blocknumber.
bytes32 h = sha3(entropy, msg.sender, block.blockhash(block.number));
entropy = h;
userHash[msg.sender] = h;
Registering creates a userHash
that is used to assign you into a group by random, in the next step commit()
, which deterministically assigns a user to a random group (1-indexed), based on number of users, group size and the user hash.
userGroup[msg.sender] = uint(userHash[msg.sender]) / (uint(maxHash) / numGroups()) + 1;
commit()
is open for 10 hours.
The schedule then moves from commitment to generateAddress, where the pseudonymGroup
that was randomly put together in the previous step is used to generate a pseudonym party address.
function generatePseudonymPartyAddress() atTime(generateAddress, 0) {
uint groupNumber = userGroup[msg.sender];
if(groupNumber == 0) throw; // not in a pseudonymGroup
if(partyAddress[groupNumber] != bytes32(0)) throw;
partyAddress[groupNumber] = sha3(pseudonymGroup[groupNumber]);
}
This here is the partyAddress
for group 1 in the first 24 hour round, which is ongoing at the moment, and the pseudonym event starts in 2 hours, as the schedule goes from generateAddress to pseudonymEvent
Each step over the 24 hour cycle uses what was done in the previous step, and the reason users of the system call the functions themselves, is so that the computations are divided across many transactions, and so that each transaction is small and has a low gas cost.
During the pseudonym event, someone has to call countVotes()
, which deploys the next round.
function countVotes() atTime(pseudonymEvent, 0) {
uint newDepositSize;
if(numUsers != 0) newDepositSize = depositGovernance / numUsers;
proofOfIndividuality.newRound(newDepositSize);
}
I put that there so that those who test the system would have an incentive to call the function that creates the next round. So, submitVerifiedUsers()
is blocked until someone calls countVotes()
, which in turn calls the main contract, and gets the main contract to create a new contract PseudonymRound
.