sharding: check bit in bytes for notary votes

Former-commit-id: 4c38295fbf89008dda9c43ee6a60472e15726064 [formerly b6594988cb3353751f09ac69863813ca106467df]
Former-commit-id: d2196e99231a1cb0f43d0f5380bb2fdc645a8949
This commit is contained in:
Terence Tsao 2018-04-29 16:31:30 -07:00
parent 3bc4acd4e3
commit 668bbc7478

View File

@ -13,11 +13,10 @@ contract SMC {
bool deposited; bool deposited;
} }
struct CollationHeader { struct CollationRecord {
uint shardId; // Number of the shard ID
bytes32 chunkRoot; // Root hash of the collation body bytes32 chunkRoot; // Root hash of the collation body
uint period; // Period which header should be included address proposer; // Address of the proposer
address proposerAddress; bool isElected; // True if the collation has reached quorum size
} }
// Notary state variables // Notary state variables
@ -29,13 +28,15 @@ contract SMC {
// current vote count of each shard // current vote count of each shard
// first 31 bytes are bitfield of individual notary's vote // first 31 bytes are bitfield of individual notary's vote
// last 1 byte is total notary's vote count // last 1 byte is total notary's vote count
mapping (uint => byte32) public currentVote mapping (uint => bytes32) public currentVote;
// Collation state variables // Collation state variables
// shardId => (period => CollationHeader), collation records been appended by proposer // shardId => (period => CollationHeader), collation records been appended by proposer
mapping (uint => mapping (uint => CollationHeader)) public collationRecords; mapping (uint => mapping (uint => CollationRecord)) public collationRecords;
// shardId => period, latest period which new collation header submitted // shardId => period, last period of the submitted collation header
mapping (uint => uint) public shardLastUpdatedPeriod; mapping (uint => uint) public lastSubmittedCollation;
// shardId => period, last period of the approved collation header
mapping (uint => uint) public lastApprovedCollation;
// Internal help functions variables // Internal help functions variables
// Stack of empty notary slot indicies // Stack of empty notary slot indicies
@ -155,40 +156,26 @@ contract SMC {
emit NotaryReleased(notaryAddress, index); emit NotaryReleased(notaryAddress, index);
} }
/// Calcuates the hash of the header from the input parameters
function computeHeaderHash(
uint256 shardId,
bytes32 parentHash,
bytes32 chunkRoot,
uint256 period,
) public returns(bytes32) {
/*
TODO: Calculate the hash of the collation header from the input parameters
*/
}
/// Add collation header to the main chain, anyone can call this function. It emits a log /// Add collation header to the main chain, anyone can call this function. It emits a log
function addHeader( function addHeader(
uint _shardId, uint _shardId,
uint _period, uint _period,
bytes32 _chunkRoot, bytes32 _chunkRoot
) public { ) public {
require((_shardId >= 0) && (_shardId < SHARD_COUNT)); require((_shardId >= 0) && (_shardId < SHARD_COUNT));
require(block.number >= PERIOD_LENGTH); require(block.number >= PERIOD_LENGTH);
require(_period == block.number / PERIOD_LENGTH); require(_period == block.number / PERIOD_LENGTH);
require(_period > shardLastUpdatedPeriod[_shardId]); require(_period > lastSubmittedCollation[_shardId]);
// Track the numbers of participating notaries in between periods // Track the numbers of participating notaries in between periods
updateNotarySampleSize(); updateNotarySampleSize();
collationRecords[_shardId][_period] = CollationHeader({ collationRecords[_shardId][_period] = CollationRecord({
shardId: _shardId,
chunkRoot: _chunkRoot, chunkRoot: _chunkRoot,
period: _period, proposer: msg.sender
proposerAddress: msg.sender
}); });
shardLastUpdatedPeriod[_shardId] = block.number / PERIOD_LENGTH; lastSubmittedCollation[_shardId] = block.number / PERIOD_LENGTH;
emit HeaderAdded(_shardId, _chunkRoot, _period, msg.sender); emit HeaderAdded(_shardId, _chunkRoot, _period, msg.sender);
} }
@ -199,12 +186,13 @@ contract SMC {
uint _shardId, uint _shardId,
uint _period, uint _period,
uint _index, uint _index,
bytes32 _chunkRoot, bytes32 _chunkRoot
) public { ) public {
require(notaryRegister[msg.sender].deposited) require(notaryRegistry[msg.sender].deposited);
require(collationRecords[_shardId][_period].chunkRoot == _chunkRoot) require(collationRecords[_shardId][_period].chunkRoot == _chunkRoot);
require(!hasVoted(_shardId, _index));
require(getNotaryInCommittee(_shardId, _index) == msg.sender);
require(getNotaryInCommittee(_shardId, _index) == msg.sender)
} }
/// To keep track of notary size in between periods, we call updateNotarySampleSize /// To keep track of notary size in between periods, we call updateNotarySampleSize
@ -239,4 +227,14 @@ contract SMC {
--emptySlotsStackTop; --emptySlotsStackTop;
return emptySlotsStack[emptySlotsStackTop]; return emptySlotsStack[emptySlotsStackTop];
} }
/// Check if a bit is set from a given byte, this function is used to check
/// if a notary has casted the vote, return true if voted, false if not
function hasVoted(uint _shardId, uint _index) internal returns (bool) {
uint byteIndex = _index / 8;
uint bitIndex = _index % 8;
byte _byte = currentVote[_shardId][byteIndex];
byte bitPos = byte(2 ** (7 - bitIndex));
return (_byte & bitPos) == bitPos;
}
} }