prysm-pulse/contracts/validator-registration-contract/validator_registration.sol
Nishant Das 75a431c969 Modify PowChain service (#1289)
* changing handling of logs

* gazelle

* removing outdated vars

* fixing tests

* adding vrc bindings to service

* updating vrc sol and bindings

* more changes

* adding trie

* remove functions

* addressing preston's review

* tests

* gazelle

* fixed tests

* note

* Lint

* doc

* exploration test

* adding new methods and tests

* adding log type checker

* lint

* gazelle

* addressing comments
2019-01-16 22:01:21 +08:00

92 lines
3.2 KiB
Solidity

pragma solidity ^0.5.1;
import "./SafeMath.sol";
contract ValidatorRegistration {
event Deposit(
bytes indexed previousReceiptRoot,
bytes data,
bytes merkleTreeIndex
);
event ChainStart(
bytes indexed receiptRoot,
bytes time
);
uint public constant DEPOSIT_SIZE = 32 ether;
// 8 is for our local test net. 2.0 spec is 2**14 == 16384
uint public constant DEPOSITS_FOR_CHAIN_START = 8; // 2**14
uint public constant MIN_TOPUP_SIZE = 1 ether;
uint public constant GWEI_PER_ETH = 10 ** 9;
// Setting MERKLE_TREE_DEPTH to 16 instead of 32 due to gas limit
uint public constant MERKLE_TREE_DEPTH = 16;
uint public constant SECONDS_PER_DAY = 86400;
mapping (uint => bytes) public depositTree;
uint public depositCount;
uint public fullDepositCount;
using SafeMath for uint256;
// When users wish to become a validator by moving ETH from
// 1.0 chian to the 2.0 chain, they should call this function
// sending along DEPOSIT_SIZE ETH and providing depositParams
// as a simple serialize'd DepositParams object of the following
// form:
// {
// 'pubkey': 'uint384',
// 'proof_of_possession': ['uint384'],
// 'withdrawal_credentials`: 'hash32',
// 'randao_commitment`: 'hash32'
// }
function deposit(
bytes memory depositParams
)
public
payable
{
require(
msg.value <= DEPOSIT_SIZE,
"Deposit can't be greater than DEPOSIT_SIZE."
);
require(
msg.value >= MIN_TOPUP_SIZE,
"Deposit can't be lesser than MIN_TOPUP_SIZE."
);
uint index = depositCount + 2 ** MERKLE_TREE_DEPTH;
bytes memory msgGweiInBytes8 = abi.encodePacked(uint64(msg.value/GWEI_PER_ETH));
bytes memory timeStampInBytes8 = abi.encodePacked(uint64(block.timestamp));
bytes memory depositData = abi.encodePacked(msgGweiInBytes8, timeStampInBytes8, depositParams);
bytes memory merkleTreeIndex = abi.encodePacked(uint64(index));
emit Deposit(depositTree[1], depositData, merkleTreeIndex);
depositTree[index] = abi.encodePacked(keccak256(depositData));
for (uint i = 0; i < MERKLE_TREE_DEPTH; i++) {
index = index / 2;
depositTree[index] = abi.encodePacked(keccak256(abi.encodePacked(depositTree[index * 2], depositTree[index * 2 + 1])));
}
depositCount++;
if (msg.value == DEPOSIT_SIZE) {
fullDepositCount++;
// When ChainStart log publishes, beacon chain node initializes the chain and use timestampDayBoundry
// as genesis time.
if (fullDepositCount == DEPOSITS_FOR_CHAIN_START) {
uint timestampDayBoundry = block.timestamp.sub(block.timestamp).mod(SECONDS_PER_DAY).add(SECONDS_PER_DAY);
bytes memory timestampDayBoundryBytes = abi.encodePacked(uint64(timestampDayBoundry));
emit ChainStart(depositTree[1], timestampDayBoundryBytes);
}
}
}
function getDepositRoot() public view returns (bytes memory) {
return depositTree[1];
}
}