diff --git a/sharding/contracts/RLP.sol b/sharding/contracts/RLP.sol new file mode 100644 index 0000000000..7397026432 --- /dev/null +++ b/sharding/contracts/RLP.sol @@ -0,0 +1,398 @@ +pragma solidity ^0.4.19; + +/** +* @title RLPReader +* +* RLPReader is used to read and parse RLP encoded data in memory. +* +* @author Andreas Olofsson (androlo1980@gmail.com) +*/ +library RLP { + + uint constant DATA_SHORT_START = 0x80; + uint constant DATA_LONG_START = 0xB8; + uint constant LIST_SHORT_START = 0xC0; + uint constant LIST_LONG_START = 0xF8; + + uint constant DATA_LONG_OFFSET = 0xB7; + uint constant LIST_LONG_OFFSET = 0xF7; + + + struct RLPItem { + uint _unsafe_memPtr; // Pointer to the RLP-encoded bytes. + uint _unsafe_length; // Number of bytes. This is the full length of the string. + } + + struct Iterator { + RLPItem _unsafe_item; // Item that's being iterated over. + uint _unsafe_nextPtr; // Position of the next item in the list. + } + + /* Iterator */ + + function next(Iterator memory self) internal pure returns (RLPItem memory subItem) { + if(hasNext(self)) { + var ptr = self._unsafe_nextPtr; + var itemLength = _itemLength(ptr); + subItem._unsafe_memPtr = ptr; + subItem._unsafe_length = itemLength; + self._unsafe_nextPtr = ptr + itemLength; + } + else + revert(); + } + + function next(Iterator memory self, bool strict) internal pure returns (RLPItem memory subItem) { + subItem = next(self); + require(!strict || _validate(subItem)); + return; + } + + function hasNext(Iterator memory self) internal pure returns (bool) { + var item = self._unsafe_item; + return self._unsafe_nextPtr < item._unsafe_memPtr + item._unsafe_length; + } + + /* RLPItem */ + + /// @dev Creates an RLPItem from an array of RLP encoded bytes. + /// @param self The RLP encoded bytes. + /// @return An RLPItem + function toRLPItem(bytes memory self) internal pure returns (RLPItem memory) { + uint len = self.length; + if (len == 0) { + return RLPItem(0, 0); + } + uint memPtr; + assembly { + memPtr := add(self, 0x20) + } + return RLPItem(memPtr, len); + } + + /// @dev Creates an RLPItem from an array of RLP encoded bytes. + /// @param self The RLP encoded bytes. + /// @param strict Will throw if the data is not RLP encoded. + /// @return An RLPItem + function toRLPItem(bytes memory self, bool strict) internal pure returns (RLPItem memory) { + var item = toRLPItem(self); + if(strict) { + uint len = self.length; + assert(_payloadOffset(item) <= len); + assert(_itemLength(item._unsafe_memPtr) == len); + assert(_validate(item)); + } + return item; + } + + /// @dev Check if the RLP item is null. + /// @param self The RLP item. + /// @return 'true' if the item is null. + function isNull(RLPItem memory self) internal pure returns (bool ret) { + return self._unsafe_length == 0; + } + + /// @dev Check if the RLP item is a list. + /// @param self The RLP item. + /// @return 'true' if the item is a list. + function isList(RLPItem memory self) internal pure returns (bool ret) { + if (self._unsafe_length == 0) + return false; + uint memPtr = self._unsafe_memPtr; + assembly { + ret := iszero(lt(byte(0, mload(memPtr)), 0xC0)) + } + } + + /// @dev Check if the RLP item is data. + /// @param self The RLP item. + /// @return 'true' if the item is data. + function isData(RLPItem memory self) internal pure returns (bool ret) { + if (self._unsafe_length == 0) + return false; + uint memPtr = self._unsafe_memPtr; + assembly { + ret := lt(byte(0, mload(memPtr)), 0xC0) + } + } + + /// @dev Check if the RLP item is empty (string or list). + /// @param self The RLP item. + /// @return 'true' if the item is null. + function isEmpty(RLPItem memory self) internal pure returns (bool ret) { + if(isNull(self)) + return false; + uint b0; + uint memPtr = self._unsafe_memPtr; + assembly { + b0 := byte(0, mload(memPtr)) + } + return (b0 == DATA_SHORT_START || b0 == LIST_SHORT_START); + } + + /// @dev Get the number of items in an RLP encoded list. + /// @param self The RLP item. + /// @return The number of items. + function items(RLPItem memory self) internal pure returns (uint) { + if (!isList(self)) + return 0; + uint b0; + uint memPtr = self._unsafe_memPtr; + assembly { + b0 := byte(0, mload(memPtr)) + } + uint pos = memPtr + _payloadOffset(self); + uint last = memPtr + self._unsafe_length - 1; + uint itms; + while(pos <= last) { + pos += _itemLength(pos); + itms++; + } + return itms; + } + + /// @dev Create an iterator. + /// @param self The RLP item. + /// @return An 'Iterator' over the item. + function iterator(RLPItem memory self) internal pure returns (Iterator memory it) { + require(isList(self)); + uint ptr = self._unsafe_memPtr + _payloadOffset(self); + it._unsafe_item = self; + it._unsafe_nextPtr = ptr; + } + + /// @dev Return the RLP encoded bytes. + /// @param self The RLPItem. + /// @return The bytes. + function toBytes(RLPItem memory self) internal constant returns (bytes memory bts) { + var len = self._unsafe_length; + if (len == 0) + return; + bts = new bytes(len); + _copyToBytes(self._unsafe_memPtr, bts, len); + } + + /// @dev Decode an RLPItem into bytes. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toData(RLPItem memory self) internal constant returns (bytes memory bts) { + require(isData(self)); + var (rStartPos, len) = _decode(self); + bts = new bytes(len); + _copyToBytes(rStartPos, bts, len); + } + + /// @dev Get the list of sub-items from an RLP encoded list. + /// Warning: This is inefficient, as it requires that the list is read twice. + /// @param self The RLP item. + /// @return Array of RLPItems. + function toList(RLPItem memory self) internal pure returns (RLPItem[] memory list) { + require(isList(self)); + var numItems = items(self); + list = new RLPItem[](numItems); + var it = iterator(self); + uint idx; + while(hasNext(it)) { + list[idx] = next(it); + idx++; + } + } + + /// @dev Decode an RLPItem into an ascii string. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toAscii(RLPItem memory self) internal constant returns (string memory str) { + require(isData(self)); + var (rStartPos, len) = _decode(self); + bytes memory bts = new bytes(len); + _copyToBytes(rStartPos, bts, len); + str = string(bts); + } + + /// @dev Decode an RLPItem into a uint. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toUint(RLPItem memory self) internal pure returns (uint data) { + require(isData(self)); + var (rStartPos, len) = _decode(self); + assert(len <= 32 && len != 0); + assembly { + data := div(mload(rStartPos), exp(256, sub(32, len))) + } + } + + /// @dev Decode an RLPItem into a boolean. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toBool(RLPItem memory self) internal pure returns (bool data) { + require(isData(self)); + var (rStartPos, len) = _decode(self); + assert(len == 1); + uint temp; + assembly { + temp := byte(0, mload(rStartPos)) + } + assert(temp <= 1); + return temp == 1 ? true : false; + } + + /// @dev Decode an RLPItem into a byte. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toByte(RLPItem memory self) internal pure returns (byte data) { + require(isData(self)); + var (rStartPos, len) = _decode(self); + assert(len == 1); + uint temp; + assembly { + temp := byte(0, mload(rStartPos)) + } + return byte(temp); + } + + /// @dev Decode an RLPItem into an int. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toInt(RLPItem memory self) internal pure returns (int data) { + return int(toUint(self)); + } + + /// @dev Decode an RLPItem into a bytes32. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toBytes32(RLPItem memory self) internal pure returns (bytes32 data) { + return bytes32(toUint(self)); + } + + /// @dev Decode an RLPItem into an address. This will not work if the + /// RLPItem is a list. + /// @param self The RLPItem. + /// @return The decoded string. + function toAddress(RLPItem memory self) internal pure returns (address data) { + require(isData(self)); + var (rStartPos, len) = _decode(self); + assert(len == 20); + assembly { + data := div(mload(rStartPos), exp(256, 12)) + } + } + + // Get the payload offset. + function _payloadOffset(RLPItem memory self) private pure returns (uint) { + if(self._unsafe_length == 0) + return 0; + uint b0; + uint memPtr = self._unsafe_memPtr; + assembly { + b0 := byte(0, mload(memPtr)) + } + if(b0 < DATA_SHORT_START) + return 0; + if(b0 < DATA_LONG_START || (b0 >= LIST_SHORT_START && b0 < LIST_LONG_START)) + return 1; + if(b0 < LIST_SHORT_START) + return b0 - DATA_LONG_OFFSET + 1; + return b0 - LIST_LONG_OFFSET + 1; + } + + // Get the full length of an RLP item. + function _itemLength(uint memPtr) private pure returns (uint len) { + uint b0; + assembly { + b0 := byte(0, mload(memPtr)) + } + if (b0 < DATA_SHORT_START) + len = 1; + else if (b0 < DATA_LONG_START) + len = b0 - DATA_SHORT_START + 1; + else if (b0 < LIST_SHORT_START) { + assembly { + let bLen := sub(b0, 0xB7) // bytes length (DATA_LONG_OFFSET) + let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length + len := add(1, add(bLen, dLen)) // total length + } + } + else if (b0 < LIST_LONG_START) + len = b0 - LIST_SHORT_START + 1; + else { + assembly { + let bLen := sub(b0, 0xF7) // bytes length (LIST_LONG_OFFSET) + let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length + len := add(1, add(bLen, dLen)) // total length + } + } + } + + // Get start position and length of the data. + function _decode(RLPItem memory self) private pure returns (uint memPtr, uint len) { + require(isData(self)); + uint b0; + uint start = self._unsafe_memPtr; + assembly { + b0 := byte(0, mload(start)) + } + if (b0 < DATA_SHORT_START) { + memPtr = start; + len = 1; + return; + } + if (b0 < DATA_LONG_START) { + len = self._unsafe_length - 1; + memPtr = start + 1; + } else { + uint bLen; + assembly { + bLen := sub(b0, 0xB7) // DATA_LONG_OFFSET + } + len = self._unsafe_length - 1 - bLen; + memPtr = start + bLen + 1; + } + return; + } + + // Assumes that enough memory has been allocated to store in target. + function _copyToBytes(uint btsPtr, bytes memory tgt, uint btsLen) private constant { + // Exploiting the fact that 'tgt' was the last thing to be allocated, + // we can write entire words, and just overwrite any excess. + assembly { + { + let i := 0 // Start at arr + 0x20 + let words := div(add(btsLen, 31), 32) + let rOffset := btsPtr + let wOffset := add(tgt, 0x20) + tag_loop: + jumpi(end, eq(i, words)) + { + let offset := mul(i, 0x20) + mstore(add(wOffset, offset), mload(add(rOffset, offset))) + i := add(i, 1) + } + jump(tag_loop) + end: + mstore(add(tgt, add(0x20, mload(tgt))), 0) + } + } + } + + // Check that an RLP item is valid. + function _validate(RLPItem memory self) private pure returns (bool ret) { + // Check that RLP is well-formed. + uint b0; + uint b1; + uint memPtr = self._unsafe_memPtr; + assembly { + b0 := byte(0, mload(memPtr)) + b1 := byte(1, mload(memPtr)) + } + if(b0 == DATA_SHORT_START + 1 && b1 < DATA_SHORT_START) + return false; + return true; + } +} \ No newline at end of file diff --git a/sharding/contracts/validator_manager.go b/sharding/contracts/validator_manager.go index 9d24468f43..b5d9fb2966 100644 --- a/sharding/contracts/validator_manager.go +++ b/sharding/contracts/validator_manager.go @@ -163,7 +163,7 @@ func (_RLP *RLPTransactorRaw) Transact(opts *bind.TransactOpts, method string, p const SigHasherContractABI = "[]" // SigHasherContractBin is the compiled bytecode used for deploying new contracts. -const SigHasherContractBin = `0x60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00a165627a7a72305820d1e8d7c8f2fa07496a4b23f8a6d60871008288d5fac673be890f35954e859d0f0029` +const SigHasherContractBin = `0x60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00a165627a7a72305820c5e12cfe03e1e876e69b3e7102c7e127c4297a29e99b2f672d5d071d1f25699f0029` // DeploySigHasherContract deploys a new Ethereum contract, binding an instance of SigHasherContract to it. func DeploySigHasherContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SigHasherContract, error) { @@ -306,10 +306,10 @@ func (_SigHasherContract *SigHasherContractTransactorRaw) Transact(opts *bind.Tr } // VMCABI is the input ABI used to generate the binding from. -const VMCABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_validatorIndex\",\"type\":\"int256\"},{\"name\":\"_sig\",\"type\":\"bytes32\"}],\"name\":\"withdraw\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getValidatorsMaxIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_shardId\",\"type\":\"int256\"},{\"name\":\"_txStartgas\",\"type\":\"uint256\"},{\"name\":\"_txGasprice\",\"type\":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes12\"}],\"name\":\"txToShard\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"getAncestorDistance\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_valcodeAddr\",\"type\":\"address\"}],\"name\":\"getShardList\",\"outputs\":[{\"name\":\"\",\"type\":\"bool[100]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getCollationGasLimit\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_expectedPeriodNumber\",\"type\":\"uint256\"}],\"name\":\"getPeriodStartPrevhash\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_shardId\",\"type\":\"int256\"}],\"name\":\"sample\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_receiptId\",\"type\":\"int256\"},{\"name\":\"_txGasprice\",\"type\":\"uint256\"}],\"name\":\"updataGasPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_header\",\"type\":\"bytes\"}],\"name\":\"addHeader\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_validationCodeAddr\",\"type\":\"address\"},{\"name\":\"_returnAddr\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" +const VMCABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"getValidatorsMaxIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_shardId\",\"type\":\"int256\"},{\"name\":\"_txStartgas\",\"type\":\"uint256\"},{\"name\":\"_txGasprice\",\"type\":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes12\"}],\"name\":\"txToShard\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"getAncestorDistance\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_validatorAddr\",\"type\":\"address\"}],\"name\":\"getShardList\",\"outputs\":[{\"name\":\"\",\"type\":\"bool[100]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_validatorIndex\",\"type\":\"int256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getCollationGasLimit\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_expectedPeriodNumber\",\"type\":\"uint256\"}],\"name\":\"getPeriodStartPrevhash\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_shardId\",\"type\":\"int256\"}],\"name\":\"sample\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_receiptId\",\"type\":\"int256\"},{\"name\":\"_txGasprice\",\"type\":\"uint256\"}],\"name\":\"updataGasPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_returnAddr\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_header\",\"type\":\"bytes\"}],\"name\":\"addHeader\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" // VMCBin is the compiled bytecode used for deploying new contracts. -const VMCBin = `0x6060604052341561000f57600080fd5b6000600481905560075568056bc75e2d631000006008556005600981905562061a80600a55600c556064600d819055600e556040517f6164645f686561646572282900000000000000000000000000000000000000008152600c01604051908190039020600f5560108054600160a060020a03191673dffd41e18f04ad8810c83b14fd1426a82e625a7d1790556113f5806100ab6000396000f3006060604052600436106100ae5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630e3b2f0e81146100b35780632b3407f9146100e0578063372a9e2a146101055780635badac531461012f5780635e57c86c14610145578063934586ec1461019d5780639b33f907146101b0578063a8c57753146101c6578063e551e00a146101f8578063f7fecf7d14610206578063f9609f0814610257575b600080fd5b34156100be57600080fd5b6100cc600435602435610271565b604051901515815260200160405180910390f35b34156100eb57600080fd5b6100f3610414565b60405190815260200160405180910390f35b6100f3600160a060020a0360043516602435604435606435600160a060020a0319608435166104bb565b341561013a57600080fd5b6100f36004356105f7565b341561015057600080fd5b610164600160a060020a03600435166105fd565b6040518082610c8080838360005b8381101561018a578082015183820152602001610172565b5050505090500191505060405180910390f35b34156101a857600080fd5b6100f361073b565b34156101bb57600080fd5b6100f3600435610743565b34156101d157600080fd5b6101dc600435610767565b604051600160a060020a03909116815260200160405180910390f35b6100cc60043560243561087e565b341561021157600080fd5b6100cc60046024813581810190830135806020601f820181900481020160405190810160405281815292919060208401838380828437509496506108c395505050505050565b6100f3600160a060020a0360043581169060243516610c61565b60008060006040517f776974686472617700000000000000000000000000000000000000000000000081526008016040519081900390206000868152602081905260409081902060010154600a54929450600160a060020a031691638e19899e918790517c010000000000000000000000000000000000000000000000000000000063ffffffff85160281526004810191909152602401602060405180830381600088803b151561032157600080fd5b87f1151561032e57600080fd5b505050506040518051915050801561040c576000858152602081905260409081902060028101549054600160a060020a039091169181156108fc02919051600060405180830381858888f19350505050151561038957600080fd5b600085815260208181526040808320600181018054600160a060020a03168552600b8452918420805460ff19169055888452918390528282558054600160a060020a03199081169091556002820180549091169055600301556103eb85610de8565b60048054600019019055848260405190815260200160405180910390a18092505b505092915050565b60008060008060008060009450600093506009544381151561043257fe5b059250600754600454019150600090505b6104008112156104ac57818112610459576104ac565b600081815260208190526040902060010154600160a060020a038681169116148015906104985750600081815260208190526040902060030154839013155b156104a4576001840193505b600101610443565b60075484019550505050505090565b60008060e060405190810160409081528782526020808301889052818301879052346060840152600160a060020a0333811660808501528a1660a0840152600160a060020a0319861660c08401526005546000908152600290915220815181556020820151816001015560408201518160020155606082015181600301556080820151600482018054600160a060020a031916600160a060020a039290921691909117905560a0820151600582018054600160a060020a031916600160a060020a039290921691909117905560c0820151600690910155505060058054600181019091558086600160a060020a0389166040517f74785f746f5f73686172642829000000000000000000000000000000000000008152600d01604051809103902060405190815260200160405180910390a39695505050505050565b50600090565b6106056112fb565b61060d6112fb565b60008060008060008060006009544381151561062557fe5b05965060016009548802039550600086121561064057600095505b8540945061064c610414565b6004549094501561072a57600092505b60648360ff16101561072a5760008860ff85166064811061067957fe5b91151560209092020152600091505b60648260ff16101561071f57838560ff8086169085166040519283526020830191909152604080830191909152606090910190519081900390208115156106cb57fe5b06600081815260208190526040902060010154909150600160a060020a038b8116911614156107145760018860ff85166064811061070557fe5b9115156020909202015261071f565b816001019150610688565b82600101925061065c565b8798505b5050505050505050919050565b629896805b90565b600c546000908202600019014381901161075c57600080fd5b804091505b50919050565b6000806000806000806000600c54431015151561078357600080fd5b6009544381151561079057fe5b0595506001600954870203945060008512156107ab57600094505b600c5485409450600190438115156107bf57fe5b0643030340600190049250600d5483896001026040519182526020820152604090810190519081900390208115156107f357fe5b0691506107fe610414565b84898460405192835260208301919091526040808301919091526060909101905190819003902081151561082e57fe5b06600081815260208190526040902060030154909150869013156108555760009650610873565b600081815260208190526040902060010154600160a060020a031696505b505050505050919050565b60008281526002602052604081206004015433600160a060020a039081169116146108a857600080fd5b50600091825260026020819052604090922090910155600190565b6000806108ce611324565b6108d6611336565b6108de611357565b60009350859250838080806109026108fd88600163ffffffff610e0716565b610e6b565b95506101406040519081016040528061092261091d89610ea4565b610ee9565b815260200161093861093389610ea4565b610efa565b815260200161094961091d89610ea4565b815260200161095a61091d89610ea4565b815260200161096b61091d89610ea4565b815260200161098161097c89610ea4565b610f4b565b600160a060020a0316815260200161099b61091d89610ea4565b81526020016109ac61091d89610ea4565b81526020016109bd61091d89610ea4565b81526020016109d36109ce89610ea4565b610f95565b9052945060008551121580156109eb5750600e548551125b15156109f657600080fd5b600c54431015610a0557600080fd5b600c5443811515610a1257fe5b04856020015114610a2257600080fd5b6001600c548660200151020340604086015114610a3e57600080fd5b846040519081526020016040519081900390209350831515610a5c57fe5b60016000865181526020808201929092526040908101600090812087825290925290206001015415610a8a57fe5b846060015115610ada5784606001511580610ad25750600060018187518152602001908152602001600020600087606001518152602081019190915260400160002060010154135b1515610ada57fe5b8460200151601160008751815260200190815260200160002054121515610afd57fe5b610b078551610767565b9250600160a060020a0383161515610b22576000985061072e565b600160008651815260200190815260200160002060008660600151815260208101919091526040016000206001908101540191508161010086015114610b6457fe5b6040805190810160405280866060015181526020018390526001600087518152602080820192909252604090810160009081208882529092529020815181556020820151600190910155506020850151601160008751815260200190815260200160002081905550600160008660000151815260200190815260200160002060006003600088600001518152602001908152602001600020546000191660001916815260200190815260200160002060010154821315610c515760036000865181526020019081526020016000205490508360036000876000015181526020810191909152604001600020555b5060019998505050505050505050565b600160a060020a0382166000908152600b60205260408120548190819060ff1615610c8b57600080fd5b6008543414610c9957600080fd5b506000610ca4610fe3565b1515610cb957610cb2610fea565b9150610d6c565b600454915060095443811515610ccb57fe5b05600101905060806040519081016040908152348252600160a060020a03808816602080850191909152908716828401526060830184905260008581529081905220815181556020820151600182018054600160a060020a031916600160a060020a03929092169190911790556040820151600282018054600160a060020a031916600160a060020a03929092169190911790556060820151600390910155505b600480546001908101909155600160a060020a0386166000818152600b602052604090819020805460ff19169093179092558391517f6465706f736974282900000000000000000000000000000000000000000000008152600901604051809103902060405190815260200160405180910390a2509392505050565b6007805460009081526006602052604090209190915580546001019055565b610e0f6113b2565b610e176113b2565b6000610e2285611021565b91508315610e63578451905080610e3883611072565b1115610e4057fe5b80610e4b83516110f1565b14610e5257fe5b610e5b82611183565b1515610e6357fe5b509392505050565b610e73611336565b6000610e7e836111c5565b1515610e8957600080fd5b610e9283611072565b83519383529092016020820152919050565b610eac6113b2565b600080610eb8846111f0565b156100ae5783602001519150610ecd826110f1565b82845260208085018290528382019086015290505b5050919050565b6000610ef482610efa565b92915050565b6000806000610f0884611213565b1515610f1357600080fd5b610f1c8461123d565b9150915060208111158015610f3057508015155b1515610f3857fe5b806020036101000a825104949350505050565b6000806000610f5984611213565b1515610f6457600080fd5b610f6d8461123d565b909250905060148114610f7c57fe5b6c01000000000000000000000000825104949350505050565b610f9d611324565b600082602001519050801515610fb257610761565b80604051805910610fc05750595b818152601f19601f830116810160200160405290509150610761835183836112ba565b6007541590565b6000610ff4610fe3565b156110025750600019610740565b5060078054600019019081905560009081526006602052604090205490565b6110296113b2565b600080835191508115156110525760408051908101604052600080825260208201529250610ee2565b506020830160408051908101604052908152602081019190915292915050565b60008060008360200151151561108b5760009250610ee2565b83519050805160001a915060808210156110a85760009250610ee2565b60b88210806110c3575060c082101580156110c3575060f882105b156110d15760019250610ee2565b60c08210156110e65760b51982019250610ee2565b5060f5190192915050565b600080825160001a9050608081101561110d5760019150610761565b60b881101561112257607e1981019150610761565b60c081101561114c5760b78103806020036101000a60018501510480820160010193505050610761565b60f88110156111615760be1981019150610761565b60f78103806020036101000a6001850151048082016001019350505050919050565b600080808084519050805160001a9250805160011a91506081831480156111aa5750608082105b156111b857600093506111bd565b600193505b505050919050565b600080826020015115156111dc5760009150610761565b8251905060c0815160001a10159392505050565b60006111fa6113b2565b8251905080602001518151018360200151109392505050565b6000808260200151151561122a5760009150610761565b8251905060c0815160001a109392505050565b600080600080600061124e86611213565b151561125957600080fd5b85519150815160001a9250608083101561127957819450600193506112b2565b60b883101561129757600186602001510393508160010194506112b2565b5060b619820180600160208801510303935080820160010194505b505050915091565b60006020601f83010484602085015b8284146112e857602084028083015181830152600185019450506112c9565b6000865160200187015250505050505050565b610c806040519081016040526064815b60008152600019909101906020018161130b5790505090565b60206040519081016040526000815290565b60606040519081016040528061134a6113b2565b8152602001600081525090565b6101406040519081016040908152600080835260208301819052908201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082015261012081016113ad611324565b905290565b6040805190810160405260008082526020820152905600a165627a7a72305820ac752c2e2510c5d4616642d59dff6585ad73413dba273192b11758fd542c54ec0029` +const VMCBin = `0x6060604052341561000f57600080fd5b6000600481905560075568056bc75e2d631000006008556005600981905562061a80600a55600c556064600d819055600e556040517f6164645f686561646572282900000000000000000000000000000000000000008152600c01604051908190039020600f5560108054600160a060020a03191673dffd41e18f04ad8810c83b14fd1426a82e625a7d179055611340806100ab6000396000f3006060604052600436106100ae5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632b3407f981146100b3578063372a9e2a146100d85780635badac53146101025780635e57c86c146101185780637e62eab814610170578063934586ec146101885780639b33f9071461019b578063a8c57753146101b1578063e551e00a146101e3578063f340fa0114610205578063f7fecf7d14610219575b600080fd5b34156100be57600080fd5b6100c661026a565b60405190815260200160405180910390f35b6100c6600160a060020a0360043516602435604435606435600160a060020a0319608435166102df565b341561010d57600080fd5b6100c660043561041b565b341561012357600080fd5b610137600160a060020a0360043516610421565b6040518082610c8080838360005b8381101561015d578082015183820152602001610145565b5050505090500191505060405180910390f35b341561017b57600080fd5b61018660043561055c565b005b341561019357600080fd5b6100c6610689565b34156101a657600080fd5b6100c6600435610691565b34156101bc57600080fd5b6101c76004356106b5565b604051600160a060020a03909116815260200160405180910390f35b6101f16004356024356107cc565b604051901515815260200160405180910390f35b6100c6600160a060020a0360043516610811565b341561022457600080fd5b6101f160046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061099b95505050505050565b60008060008060008093506009544381151561028257fe5b059250600754600454019150600090505b6104008112156102d1578181126102a9576102d1565b6000818152602081905260409020600301548390136102c9576001840193505b600101610293565b600754840194505050505090565b60008060e060405190810160409081528782526020808301889052818301879052346060840152600160a060020a0333811660808501528a1660a0840152600160a060020a0319861660c08401526005546000908152600290915220815181556020820151816001015560408201518160020155606082015181600301556080820151600482018054600160a060020a031916600160a060020a039290921691909117905560a0820151600582018054600160a060020a031916600160a060020a039290921691909117905560c0820151600690910155505060058054600181019091558086600160a060020a0389166040517f74785f746f5f73686172642829000000000000000000000000000000000000008152600d01604051809103902060405190815260200160405180910390a39695505050505050565b50600090565b610429611246565b610431611246565b60008060008060008060006009544381151561044957fe5b05965060016009548802039550600086121561046457600095505b8540945061047061026a565b6004549094501561054e57600092505b60648360ff16101561054e5760008860ff85166064811061049d57fe5b91151560209092020152600091505b60648260ff16101561054357838560ff8086169085166040519283526020830191909152604080830191909152606090910190519081900390208115156104ef57fe5b06600081815260208190526040902060010154909150600160a060020a038b8116911614156105385760018860ff85166064811061052957fe5b91151560209092020152610543565b8160010191506104ac565b826001019250610480565b509598975050505050505050565b60006040517f7769746864726177000000000000000000000000000000000000000000000000815260080160405190819003902060008381526020819052604090206001015490915033600160a060020a039081169116146105bd57600080fd5b6000828152602081905260409081902060028101549054600160a060020a039091169181156108fc02919051600060405180830381858888f19350505050151561060657600080fd5b600082815260208181526040808320600181018054600160a060020a03168552600b8452918420805460ff19169055858452918390528282558054600160a060020a031990811690915560028201805490911690556003015561066882610d36565b60048054600019019055818160405190815260200160405180910390a15050565b629896805b90565b600c54600090820260001901438190116106aa57600080fd5b804091505b50919050565b6000806000806000806000600c5443101515156106d157600080fd5b600954438115156106de57fe5b0595506001600954870203945060008512156106f957600094505b600c54854094506001904381151561070d57fe5b0643030340600190049250600d54838960010260405191825260208201526040908101905190819003902081151561074157fe5b06915061074c61026a565b84898460405192835260208301919091526040808301919091526060909101905190819003902081151561077c57fe5b06600081815260208190526040902060030154909150869013156107a357600096506107c1565b600081815260208190526040902060010154600160a060020a031696505b505050505050919050565b60008281526002602052604081206004015433600160a060020a039081169116146107f657600080fd5b50600091825260026020819052604090922090910155600190565b600160a060020a0333166000908152600b60205260408120548190819060ff161561083b57600080fd5b600854341461084957600080fd5b506000610854610d55565b151561086957610862610d5c565b915061091c565b60045491506009544381151561087b57fe5b05600101905060806040519081016040908152348252600160a060020a03338116602080850191909152908716828401526060830184905260008581529081905220815181556020820151600182018054600160a060020a031916600160a060020a03929092169190911790556040820151600282018054600160a060020a031916600160a060020a03929092169190911790556060820151600390910155505b600480546001908101909155600160a060020a0333166000818152600b602052604090819020805460ff19169093179092558391517f6465706f736974282900000000000000000000000000000000000000000000008152600901604051809103902060405190815260200160405180910390a28192505b5050919050565b60006109a561126f565b6109ad611281565b6109b56112a2565b84925060008080806109d66109d188600163ffffffff610d9316565b610df7565b9550610140604051908101604052806109f66109f189610e30565b610e72565b8152602001610a0c610a0789610e30565b610e83565b8152602001610a1d6109f189610e30565b8152602001610a2e6109f189610e30565b8152602001610a3f6109f189610e30565b8152602001610a55610a5089610e30565b610ed4565b600160a060020a03168152602001610a6f6109f189610e30565b8152602001610a806109f189610e30565b8152602001610a916109f189610e30565b8152602001610aa7610aa289610e30565b610f1e565b905294506000855112158015610abf5750600e548551125b1515610aca57600080fd5b600c54431015610ad957600080fd5b600c5443811515610ae657fe5b04856020015114610af657600080fd5b6001600c548660200151020340604086015114610b1257600080fd5b846040519081526020016040519081900390209350831515610b3057fe5b60016000865181526020808201929092526040908101600090812087825290925290206001015415610b5e57fe5b846060015115610bae5784606001511580610ba65750600060018187518152602001908152602001600020600087606001518152602081019190915260400160002060010154135b1515610bae57fe5b8460200151601160008751815260200190815260200160002054121515610bd157fe5b610bdb85516106b5565b9250600160a060020a0383161515610bf65760009750610d2a565b600160008651815260200190815260200160002060008660600151815260208101919091526040016000206001908101540191508161010086015114610c3857fe5b6040805190810160405280866060015181526020018390526001600087518152602080820192909252604090810160009081208882529092529020815181556020820151600190910155506020850151601160008751815260200190815260200160002081905550600160008660000151815260200190815260200160002060006003600088600001518152602001908152602001600020546000191660001916815260200190815260200160002060010154821315610d255760036000865181526020019081526020016000205490508360036000876000015181526020810191909152604001600020555b600197505b50505050505050919050565b6007805460009081526006602052604090209190915580546001019055565b6007541590565b6000610d66610d55565b15610d74575060001961068e565b5060078054600019019081905560009081526006602052604090205490565b610d9b6112fd565b610da36112fd565b6000610dae85610f6c565b91508315610def578451905080610dc483610fbd565b1115610dcc57fe5b80610dd7835161103c565b14610dde57fe5b610de7826110ce565b1515610def57fe5b509392505050565b610dff611281565b6000610e0a83611110565b1515610e1557600080fd5b610e1e83610fbd565b83519383529092016020820152919050565b610e386112fd565b600080610e448461113b565b156100ae5783602001519150610e598261103c565b8284526020808501829052838201908601529050610994565b6000610e7d82610e83565b92915050565b6000806000610e918461115e565b1515610e9c57600080fd5b610ea584611188565b9150915060208111158015610eb957508015155b1515610ec157fe5b806020036101000a825104949350505050565b6000806000610ee28461115e565b1515610eed57600080fd5b610ef684611188565b909250905060148114610f0557fe5b6c01000000000000000000000000825104949350505050565b610f2661126f565b600082602001519050801515610f3b576106af565b80604051805910610f495750595b818152601f19601f8301168101602001604052905091506106af83518383611205565b610f746112fd565b60008083519150811515610f9d5760408051908101604052600080825260208201529250610994565b506020830160408051908101604052908152602081019190915292915050565b600080600083602001511515610fd65760009250610994565b83519050805160001a91506080821015610ff35760009250610994565b60b882108061100e575060c0821015801561100e575060f882105b1561101c5760019250610994565b60c08210156110315760b51982019250610994565b5060f5190192915050565b600080825160001a9050608081101561105857600191506106af565b60b881101561106d57607e19810191506106af565b60c08110156110975760b78103806020036101000a600185015104808201600101935050506106af565b60f88110156110ac5760be19810191506106af565b60f78103806020036101000a6001850151048082016001019350505050919050565b600080808084519050805160001a9250805160011a91506081831480156110f55750608082105b156111035760009350611108565b600193505b505050919050565b6000808260200151151561112757600091506106af565b8251905060c0815160001a10159392505050565b60006111456112fd565b8251905080602001518151018360200151109392505050565b6000808260200151151561117557600091506106af565b8251905060c0815160001a109392505050565b60008060008060006111998661115e565b15156111a457600080fd5b85519150815160001a925060808310156111c457819450600193506111fd565b60b88310156111e257600186602001510393508160010194506111fd565b5060b619820180600160208801510303935080820160010194505b505050915091565b60006020601f83010484602085015b8284146112335760208402808301518183015260018501945050611214565b6000865160200187015250505050505050565b610c806040519081016040526064815b6000815260001990910190602001816112565790505090565b60206040519081016040526000815290565b6060604051908101604052806112956112fd565b8152602001600081525090565b6101406040519081016040908152600080835260208301819052908201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082015261012081016112f861126f565b905290565b6040805190810160405260008082526020820152905600a165627a7a723058201e5dfd4590fe444b86534a5417adf73abd6edb65742c9c70d8223afa491d76730029` // DeployVMC deploys a new Ethereum contract, binding an instance of VMC to it. func DeployVMC(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *VMC, error) { @@ -531,28 +531,28 @@ func (_VMC *VMCCallerSession) GetPeriodStartPrevhash(_expectedPeriodNumber *big. // GetShardList is a free data retrieval call binding the contract method 0x5e57c86c. // -// Solidity: function getShardList(_valcodeAddr address) constant returns(bool[100]) -func (_VMC *VMCCaller) GetShardList(opts *bind.CallOpts, _valcodeAddr common.Address) ([100]bool, error) { +// Solidity: function getShardList(_validatorAddr address) constant returns(bool[100]) +func (_VMC *VMCCaller) GetShardList(opts *bind.CallOpts, _validatorAddr common.Address) ([100]bool, error) { var ( ret0 = new([100]bool) ) out := ret0 - err := _VMC.contract.Call(opts, out, "getShardList", _valcodeAddr) + err := _VMC.contract.Call(opts, out, "getShardList", _validatorAddr) return *ret0, err } // GetShardList is a free data retrieval call binding the contract method 0x5e57c86c. // -// Solidity: function getShardList(_valcodeAddr address) constant returns(bool[100]) -func (_VMC *VMCSession) GetShardList(_valcodeAddr common.Address) ([100]bool, error) { - return _VMC.Contract.GetShardList(&_VMC.CallOpts, _valcodeAddr) +// Solidity: function getShardList(_validatorAddr address) constant returns(bool[100]) +func (_VMC *VMCSession) GetShardList(_validatorAddr common.Address) ([100]bool, error) { + return _VMC.Contract.GetShardList(&_VMC.CallOpts, _validatorAddr) } // GetShardList is a free data retrieval call binding the contract method 0x5e57c86c. // -// Solidity: function getShardList(_valcodeAddr address) constant returns(bool[100]) -func (_VMC *VMCCallerSession) GetShardList(_valcodeAddr common.Address) ([100]bool, error) { - return _VMC.Contract.GetShardList(&_VMC.CallOpts, _valcodeAddr) +// Solidity: function getShardList(_validatorAddr address) constant returns(bool[100]) +func (_VMC *VMCCallerSession) GetShardList(_validatorAddr common.Address) ([100]bool, error) { + return _VMC.Contract.GetShardList(&_VMC.CallOpts, _validatorAddr) } // GetValidatorsMaxIndex is a free data retrieval call binding the contract method 0x2b3407f9. @@ -628,25 +628,25 @@ func (_VMC *VMCTransactorSession) AddHeader(_header []byte) (*types.Transaction, return _VMC.Contract.AddHeader(&_VMC.TransactOpts, _header) } -// Deposit is a paid mutator transaction binding the contract method 0xf9609f08. +// Deposit is a paid mutator transaction binding the contract method 0xf340fa01. // -// Solidity: function deposit(_validationCodeAddr address, _returnAddr address) returns(int256) -func (_VMC *VMCTransactor) Deposit(opts *bind.TransactOpts, _validationCodeAddr common.Address, _returnAddr common.Address) (*types.Transaction, error) { - return _VMC.contract.Transact(opts, "deposit", _validationCodeAddr, _returnAddr) +// Solidity: function deposit(_returnAddr address) returns(int256) +func (_VMC *VMCTransactor) Deposit(opts *bind.TransactOpts, _returnAddr common.Address) (*types.Transaction, error) { + return _VMC.contract.Transact(opts, "deposit", _returnAddr) } -// Deposit is a paid mutator transaction binding the contract method 0xf9609f08. +// Deposit is a paid mutator transaction binding the contract method 0xf340fa01. // -// Solidity: function deposit(_validationCodeAddr address, _returnAddr address) returns(int256) -func (_VMC *VMCSession) Deposit(_validationCodeAddr common.Address, _returnAddr common.Address) (*types.Transaction, error) { - return _VMC.Contract.Deposit(&_VMC.TransactOpts, _validationCodeAddr, _returnAddr) +// Solidity: function deposit(_returnAddr address) returns(int256) +func (_VMC *VMCSession) Deposit(_returnAddr common.Address) (*types.Transaction, error) { + return _VMC.Contract.Deposit(&_VMC.TransactOpts, _returnAddr) } -// Deposit is a paid mutator transaction binding the contract method 0xf9609f08. +// Deposit is a paid mutator transaction binding the contract method 0xf340fa01. // -// Solidity: function deposit(_validationCodeAddr address, _returnAddr address) returns(int256) -func (_VMC *VMCTransactorSession) Deposit(_validationCodeAddr common.Address, _returnAddr common.Address) (*types.Transaction, error) { - return _VMC.Contract.Deposit(&_VMC.TransactOpts, _validationCodeAddr, _returnAddr) +// Solidity: function deposit(_returnAddr address) returns(int256) +func (_VMC *VMCTransactorSession) Deposit(_returnAddr common.Address) (*types.Transaction, error) { + return _VMC.Contract.Deposit(&_VMC.TransactOpts, _returnAddr) } // TxToShard is a paid mutator transaction binding the contract method 0x372a9e2a. @@ -691,190 +691,23 @@ func (_VMC *VMCTransactorSession) UpdataGasPrice(_receiptId *big.Int, _txGaspric return _VMC.Contract.UpdataGasPrice(&_VMC.TransactOpts, _receiptId, _txGasprice) } -// Withdraw is a paid mutator transaction binding the contract method 0x0e3b2f0e. +// Withdraw is a paid mutator transaction binding the contract method 0x7e62eab8. // -// Solidity: function withdraw(_validatorIndex int256, _sig bytes32) returns(bool) -func (_VMC *VMCTransactor) Withdraw(opts *bind.TransactOpts, _validatorIndex *big.Int, _sig [32]byte) (*types.Transaction, error) { - return _VMC.contract.Transact(opts, "withdraw", _validatorIndex, _sig) +// Solidity: function withdraw(_validatorIndex int256) returns() +func (_VMC *VMCTransactor) Withdraw(opts *bind.TransactOpts, _validatorIndex *big.Int) (*types.Transaction, error) { + return _VMC.contract.Transact(opts, "withdraw", _validatorIndex) } -// Withdraw is a paid mutator transaction binding the contract method 0x0e3b2f0e. +// Withdraw is a paid mutator transaction binding the contract method 0x7e62eab8. // -// Solidity: function withdraw(_validatorIndex int256, _sig bytes32) returns(bool) -func (_VMC *VMCSession) Withdraw(_validatorIndex *big.Int, _sig [32]byte) (*types.Transaction, error) { - return _VMC.Contract.Withdraw(&_VMC.TransactOpts, _validatorIndex, _sig) +// Solidity: function withdraw(_validatorIndex int256) returns() +func (_VMC *VMCSession) Withdraw(_validatorIndex *big.Int) (*types.Transaction, error) { + return _VMC.Contract.Withdraw(&_VMC.TransactOpts, _validatorIndex) } -// Withdraw is a paid mutator transaction binding the contract method 0x0e3b2f0e. +// Withdraw is a paid mutator transaction binding the contract method 0x7e62eab8. // -// Solidity: function withdraw(_validatorIndex int256, _sig bytes32) returns(bool) -func (_VMC *VMCTransactorSession) Withdraw(_validatorIndex *big.Int, _sig [32]byte) (*types.Transaction, error) { - return _VMC.Contract.Withdraw(&_VMC.TransactOpts, _validatorIndex, _sig) -} - -// ValidatorContractABI is the input ABI used to generate the binding from. -const ValidatorContractABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_sig\",\"type\":\"bytes32\"}],\"name\":\"withdraw\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// ValidatorContractBin is the compiled bytecode used for deploying new contracts. -const ValidatorContractBin = `0x` - -// DeployValidatorContract deploys a new Ethereum contract, binding an instance of ValidatorContract to it. -func DeployValidatorContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ValidatorContract, error) { - parsed, err := abi.JSON(strings.NewReader(ValidatorContractABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ValidatorContractBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &ValidatorContract{ValidatorContractCaller: ValidatorContractCaller{contract: contract}, ValidatorContractTransactor: ValidatorContractTransactor{contract: contract}}, nil -} - -// ValidatorContract is an auto generated Go binding around an Ethereum contract. -type ValidatorContract struct { - ValidatorContractCaller // Read-only binding to the contract - ValidatorContractTransactor // Write-only binding to the contract -} - -// ValidatorContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ValidatorContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ValidatorContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ValidatorContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ValidatorContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ValidatorContractSession struct { - Contract *ValidatorContract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ValidatorContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ValidatorContractCallerSession struct { - Contract *ValidatorContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ValidatorContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ValidatorContractTransactorSession struct { - Contract *ValidatorContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ValidatorContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ValidatorContractRaw struct { - Contract *ValidatorContract // Generic contract binding to access the raw methods on -} - -// ValidatorContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ValidatorContractCallerRaw struct { - Contract *ValidatorContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ValidatorContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ValidatorContractTransactorRaw struct { - Contract *ValidatorContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewValidatorContract creates a new instance of ValidatorContract, bound to a specific deployed contract. -func NewValidatorContract(address common.Address, backend bind.ContractBackend) (*ValidatorContract, error) { - contract, err := bindValidatorContract(address, backend, backend) - if err != nil { - return nil, err - } - return &ValidatorContract{ValidatorContractCaller: ValidatorContractCaller{contract: contract}, ValidatorContractTransactor: ValidatorContractTransactor{contract: contract}}, nil -} - -// NewValidatorContractCaller creates a new read-only instance of ValidatorContract, bound to a specific deployed contract. -func NewValidatorContractCaller(address common.Address, caller bind.ContractCaller) (*ValidatorContractCaller, error) { - contract, err := bindValidatorContract(address, caller, nil) - if err != nil { - return nil, err - } - return &ValidatorContractCaller{contract: contract}, nil -} - -// NewValidatorContractTransactor creates a new write-only instance of ValidatorContract, bound to a specific deployed contract. -func NewValidatorContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorContractTransactor, error) { - contract, err := bindValidatorContract(address, nil, transactor) - if err != nil { - return nil, err - } - return &ValidatorContractTransactor{contract: contract}, nil -} - -// bindValidatorContract binds a generic wrapper to an already deployed contract. -func bindValidatorContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ValidatorContractABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ValidatorContract *ValidatorContractRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _ValidatorContract.Contract.ValidatorContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ValidatorContract *ValidatorContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ValidatorContract.Contract.ValidatorContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ValidatorContract *ValidatorContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ValidatorContract.Contract.ValidatorContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ValidatorContract *ValidatorContractCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _ValidatorContract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ValidatorContract *ValidatorContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ValidatorContract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ValidatorContract *ValidatorContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ValidatorContract.Contract.contract.Transact(opts, method, params...) -} - -// Withdraw is a paid mutator transaction binding the contract method 0x8e19899e. -// -// Solidity: function withdraw(_sig bytes32) returns(bool) -func (_ValidatorContract *ValidatorContractTransactor) Withdraw(opts *bind.TransactOpts, _sig [32]byte) (*types.Transaction, error) { - return _ValidatorContract.contract.Transact(opts, "withdraw", _sig) -} - -// Withdraw is a paid mutator transaction binding the contract method 0x8e19899e. -// -// Solidity: function withdraw(_sig bytes32) returns(bool) -func (_ValidatorContract *ValidatorContractSession) Withdraw(_sig [32]byte) (*types.Transaction, error) { - return _ValidatorContract.Contract.Withdraw(&_ValidatorContract.TransactOpts, _sig) -} - -// Withdraw is a paid mutator transaction binding the contract method 0x8e19899e. -// -// Solidity: function withdraw(_sig bytes32) returns(bool) -func (_ValidatorContract *ValidatorContractTransactorSession) Withdraw(_sig [32]byte) (*types.Transaction, error) { - return _ValidatorContract.Contract.Withdraw(&_ValidatorContract.TransactOpts, _sig) +// Solidity: function withdraw(_validatorIndex int256) returns() +func (_VMC *VMCTransactorSession) Withdraw(_validatorIndex *big.Int) (*types.Transaction, error) { + return _VMC.Contract.Withdraw(&_VMC.TransactOpts, _validatorIndex) } diff --git a/sharding/contracts/validator_manager.sol b/sharding/contracts/validator_manager.sol new file mode 100644 index 0000000000..5aa53302af --- /dev/null +++ b/sharding/contracts/validator_manager.sol @@ -0,0 +1,345 @@ +pragma solidity ^0.4.19; + +import "RLP.sol"; + +interface SigHasherContract { + // function () returns(bytes32); +} + +contract VMC { + using RLP for RLP.RLPItem; + using RLP for RLP.Iterator; + using RLP for bytes; + + struct Validator { + // Amount of wei the validator holds + uint deposit; + // The validator's address + address addr; + // Addess to withdraw to + address returnAddr; + // The cycle number which the validator would be included after + int cycle; + } + + struct CollationHeader { + bytes32 parentCollationHash; + int score; + } + + struct Receipt { + int shardId; + uint txStartgas; + uint txGasprice; + uint value; + address sender; + address to; + bytes32 data; + } + + mapping (int => Validator) validators; + mapping (int => mapping (bytes32 => CollationHeader)) collationHeaders; + mapping (int => Receipt) receipts; + + mapping (int => bytes32) shardHead; + int numValidators; + int numReceipts; + // Indexs of empty slots caused by the function `withdraw` + mapping (int => int) emptySlotsStack; + // The top index of the stack in empty_slots_stack + int emptySlotsStackTop; + + // The exact deposit size which you have to deposit to become a validator + uint depositSize; + // Any given validator randomly gets allocated to some number of shards every SHUFFLING_CYCLE + int shufflingCycleLength; + // Gas limit of the signature validation code + uint sigGasLimit; + // Is a valcode addr deposited now? + mapping (address => bool) isValcodeDeposited; + uint periodLength; + int numValidatorsPerCycle; + int shardCount; + bytes32 addHeaderLogTopic; + SigHasherContract sighasher; + // Log the latest period number of the shard + mapping (int => int) periodHead; + + function VMC() public { + numValidators = 0; + emptySlotsStackTop = 0; + depositSize = 100 ether; + shufflingCycleLength = 5; // FIXME: just modified temporarily for test; + sigGasLimit = 400000; + periodLength = 5; + numValidatorsPerCycle = 100; + shardCount = 100; + addHeaderLogTopic = keccak256("add_header()"); + sighasher = SigHasherContract(0xDFFD41E18F04Ad8810c83B14FD1426a82E625A7D); + } + + function isStackEmpty() internal view returns(bool) { + return emptySlotsStackTop == 0; + } + function stackPush(int index) internal { + emptySlotsStack[emptySlotsStackTop] = index; + ++emptySlotsStackTop; + } + function stackPop() internal returns(int) { + if (isStackEmpty()) + return -1; + --emptySlotsStackTop; + return emptySlotsStack[emptySlotsStackTop]; + } + + function getValidatorsMaxIndex() public view returns(int) { + int activateValidatorNum = 0; + int currentCycle = int(block.number) / shufflingCycleLength; + int allValidatorSlotsNum = numValidators + emptySlotsStackTop; + + // TODO: any better way to iterate the mapping? + for (int i = 0; i < 1024; ++i) { + if (i >= allValidatorSlotsNum) + break; + if (validators[i].cycle <= currentCycle) + activateValidatorNum += 1; + } + return activateValidatorNum + emptySlotsStackTop; + } + + function deposit(address _returnAddr) public payable returns(int) { + require(!isValcodeDeposited[msg.sender]); + require(msg.value == depositSize); + // Find the empty slot index in validators set + int index; + int nextCycle = 0; + if (!isStackEmpty()) + index = stackPop(); + else { + index = int(numValidators); + nextCycle = (int(block.number) / shufflingCycleLength) + 1; + validators[index] = Validator({ + deposit: msg.value, + addr: msg.sender, + returnAddr: _returnAddr, + cycle: nextCycle + }); + } + ++numValidators; + isValcodeDeposited[msg.sender] = true; + + log2(keccak256("deposit()"), bytes32(msg.sender), bytes32(index)); + return index; + } + + function withdraw(int _validatorIndex) public { + var msgHash = keccak256("withdraw"); + require(msg.sender == validators[_validatorIndex].addr); + validators[_validatorIndex].returnAddr.transfer(validators[_validatorIndex].deposit); + isValcodeDeposited[validators[_validatorIndex].addr] = false; + delete validators[_validatorIndex]; + stackPush(_validatorIndex); + --numValidators; + log1(msgHash, bytes32(_validatorIndex)); + } + + function sample(int _shardId) public constant returns(address) { + require(block.number >= periodLength); + var cycle = int(block.number) / shufflingCycleLength; + int cycleStartBlockNumber = cycle * shufflingCycleLength - 1; + if (cycleStartBlockNumber < 0) + cycleStartBlockNumber = 0; + int cycleSeed = int(block.blockhash(uint(cycleStartBlockNumber))); + // originally, error occurs when block.number <= 4 because + // `seed_block_number` becomes negative in these cases. + int seed = int(block.blockhash(block.number - (block.number % uint(periodLength)) - 1)); + + uint indexInSubset = uint(keccak256(seed, bytes32(_shardId))) % uint(numValidatorsPerCycle); + uint validatorIndex = uint(keccak256(cycleSeed, bytes32(_shardId), bytes32(indexInSubset))) % uint(getValidatorsMaxIndex()); + + if (validators[int(validatorIndex)].cycle > cycle) + return 0x0; + else + return validators[int(validatorIndex)].addr; + } + + // Get all possible shard ids that the given _valcodeAddr + // may be sampled in the current cycle + function getShardList(address _validatorAddr) public constant returns(bool[100]) { + bool[100] memory shardList; + int cycle = int(block.number) / shufflingCycleLength; + int cycleStartBlockNumber = cycle * shufflingCycleLength - 1; + if (cycleStartBlockNumber < 0) + cycleStartBlockNumber = 0; + + var cycleSeed = block.blockhash(uint(cycleStartBlockNumber)); + int validatorsMaxIndex = getValidatorsMaxIndex(); + if (numValidators != 0) { + for (uint8 shardId = 0; shardId < 100; ++shardId) { + shardList[shardId] = false; + for (uint8 possibleIndexInSubset = 0; possibleIndexInSubset < 100; ++possibleIndexInSubset) { + uint validatorIndex = uint(keccak256(cycleSeed, bytes32(shardId), bytes32(possibleIndexInSubset))) + % uint(validatorsMaxIndex); + if (_validatorAddr == validators[int(validatorIndex)].addr) { + shardList[shardId] = true; + break; + } + } + } + } + return shardList; + } + + // function checkHeader(int _shardId, bytes32 _periodStartPrevhash, int _expectedPeriodNumber) internal { + // // Check if the header is valid + // assert(_shardId >= 0 && _shardId < shardCount); + // assert(block.number >= periodLength); + // assert(uint(_expectedPeriodNumber) == block.number / periodLength); + // assert(_periodStartPrevhash == block.blockhash(uint(_expectedPeriodNumber)*periodLength - 1)); + + // // Check if this header already exists + // var entireHeaderHash = keccak256(_header); + // assert(entireHeaderHash != bytes32(0)); + // assert(collationHeaders[shardId][entireHeaderHash].score == 0); + // } + + struct Header { + int shardId; + uint expectedPeriodNumber; + bytes32 periodStartPrevhash; + bytes32 parentCollationHash; + bytes32 txListRoot; + address collationCoinbase; + bytes32 postStateRoot; + bytes32 receiptRoot; + int collationNumber; + bytes sig; + } + + function addHeader(bytes _header) public returns(bool) { + // require(_header.length <= 4096); + // TODO + // values = RLPList(header, [num, num, bytes32, bytes32, bytes32, address, bytes32, bytes32, num, bytes]) + // return True + bytes memory mHeader = _header; + var RLPList = mHeader.toRLPItem(true).iterator(); + var header = Header({ + shardId: RLPList.next().toInt(), + expectedPeriodNumber: RLPList.next().toUint(), + periodStartPrevhash: RLPList.next().toBytes32(), + parentCollationHash: RLPList.next().toBytes32(), + txListRoot: RLPList.next().toBytes32(), + collationCoinbase: RLPList.next().toAddress(), + postStateRoot: RLPList.next().toBytes32(), + receiptRoot: RLPList.next().toBytes32(), + collationNumber: RLPList.next().toInt(), + sig: RLPList.next().toBytes() + }); + + // Check if the header is valid + require((header.shardId >= 0) && (header.shardId < shardCount)); + require(block.number >= periodLength); + require(header.expectedPeriodNumber == (block.number / periodLength)); + require(header.periodStartPrevhash == block.blockhash(header.expectedPeriodNumber * periodLength - 1)); + + + // Check if this header already exists + var entireHeaderHash = keccak256(header); + assert(entireHeaderHash != 0x0); + assert(collationHeaders[header.shardId][entireHeaderHash].score == 0); + // Check whether the parent exists. + // if (parent_collation_hash == 0), i.e., is the genesis, + // then there is no need to check. + if (header.parentCollationHash != 0x0) + assert ((header.parentCollationHash == 0x0) || (collationHeaders[header.shardId][header.parentCollationHash].score > 0)); + // Check if only one colllation in one period + assert (periodHead[header.shardId] < int(header.expectedPeriodNumber)); + + // Check the signature with validation_code_addr + var collatorValcodeAddr = sample(header.shardId); + if (collatorValcodeAddr == 0x0) + return false; + + // assembly { + // TODO next block + // } + // sighash = extract32(raw_call(self.sighasher_addr, header, gas=200000, outsize=32), 0) + // assert extract32(raw_call(collator_valcode_addr, concat(sighash, sig), gas=self.sig_gas_limit, outsize=32), 0) == as_bytes32(1) + + // Check score == collation_number + var _score = collationHeaders[header.shardId][header.parentCollationHash].score + 1; + assert(header.collationNumber == _score); + + + // Add the header + collationHeaders[header.shardId][entireHeaderHash] = CollationHeader({ + parentCollationHash: header.parentCollationHash, + score: _score + }); + + // Update the latest period number + periodHead[header.shardId] = int(header.expectedPeriodNumber); + + // Determine the head + if (_score > collationHeaders[header.shardId][shardHead[header.shardId]].score) { + var previousHeadHash = shardHead[header.shardId]; + shardHead[header.shardId] = entireHeaderHash; + // Logs only when `change_head` happens due to the fork + // TODO LOG + // log1([addHeaderLogTopic, keccak256("change_head"), entireHeaderHash], previousHeadHash); + } + // Emit log + // TODO LOG + // log1(addHeaderLogTopic, _header); + + return true; + } + + function getPeriodStartPrevhash(uint _expectedPeriodNumber) public constant returns(bytes32) { + uint blockNumber = _expectedPeriodNumber * periodLength - 1; + require(block.number > blockNumber); + return block.blockhash(blockNumber); + } + + + + // Returns the difference between the block number of this hash and the block + // number of the 10000th ancestor of this hash. + function getAncestorDistance(bytes32 /*_hash*/) public pure returns(bytes32) { + // TODO + } + + // Returns the gas limit that collations can currently have (by default make + // this function always answer 10 million). + function getCollationGasLimit() public pure returns(uint) { + return 10000000; + } + + + // Records a request to deposit msg.value ETH to address to in shard shard_id + // during a future collation. Saves a `receipt ID` for this request, + // also saving `msg.sender`, `msg.value`, `to`, `shard_id`, `startgas`, + // `gasprice`, and `data`. + function txToShard(address _to, int _shardId, uint _txStartgas, uint _txGasprice, bytes12 _data) public payable returns(int) { + receipts[numReceipts] = Receipt({ + shardId: _shardId, + txStartgas: _txStartgas, + txGasprice: _txGasprice, + value: msg.value, + sender: msg.sender, + to: _to, + data: _data + }); + var receiptId = numReceipts; + ++numReceipts; + + log3(keccak256("tx_to_shard()"), bytes32(_to), bytes32(_shardId), bytes32(receiptId)); + return receiptId; + } + + function updataGasPrice(int _receiptId, uint _txGasprice) public payable returns(bool) { + require(receipts[_receiptId].sender == msg.sender); + receipts[_receiptId].txGasprice = _txGasprice; + return true; + } +}