Skip to content

Commit

Permalink
Merge branch 'master' into upgradeable-contract-components
Browse files Browse the repository at this point in the history
  • Loading branch information
ngrinkevich committed Jun 21, 2019
2 parents 856e316 + 793cca1 commit 22d3089
Show file tree
Hide file tree
Showing 19 changed files with 496 additions and 431 deletions.
164 changes: 0 additions & 164 deletions cmd/relay.go

This file was deleted.

20 changes: 16 additions & 4 deletions contracts/solidity/contracts/KeepRandomBeaconServiceImplV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,22 @@ contract KeepRandomBeaconServiceImplV1 is Ownable, DelayedWithdrawal {
* @return An uint256 representing uniquely generated entry Id.
*/
function requestRelayEntry(uint256 seed) public payable returns (uint256) {
require(
msg.value >= _minPayment,
"Payment is less than required minimum."
);

_entryCounter++;

return requestRelayEntry(seed, address(0), "");
}

/**
* @dev Creates a request to generate a new relay entry, which will include a
* random number (by signing the previous entry's random number).
* @param seed Initial seed random value from the client. It should be a cryptographically generated random value.
* @param callbackContract Callback contract address. Callback is called once a new relay entry has been generated.
* @param callbackMethod Callback contract method signature. String representation of your method with a single
* uint256 input parameter i.e. "relayEntryCallback(uint256)".
* @return An uint256 representing uniquely generated relay request ID. It is also returned as part of the event.
*/
function requestRelayEntry(uint256 seed, address callbackContract, string memory callbackMethod) public payable returns (uint256) {

_entryCounter++;

Expand Down
29 changes: 29 additions & 0 deletions contracts/solidity/contracts/examples/CallbackContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
pragma solidity ^0.5.4;


/**
* @title CallbackContract
* @dev Example callback contract for Random Beacon.
*/
contract CallbackContract {

uint256 internal _lastEntry;

/**
* @dev Example of a callback method. Method signature can be
* calculated as bytes4(keccak256("callback(uint256)")
*/
function callback(uint256 requestResponse)
public
{
_lastEntry = requestResponse;
}

/**
* @dev Returns previous entry.
*/
function lastEntry() public view returns (uint256)
{
return _lastEntry;
}
}
32 changes: 32 additions & 0 deletions contracts/solidity/scripts/genesis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const KeepRandomBeaconService = artifacts.require('KeepRandomBeaconService.sol')
const KeepRandomBeaconServiceImplV1 = artifacts.require("KeepRandomBeaconServiceImplV1.sol")

// The data below should match genesis relay request data defined on contract
// initialization i.e. in 2_deploy_contracts.js. Successful genesis entry will
// trigger creation of the first group that will be chosen to respond on the
// next relay request, resulting another relay entry with creation of another
// group and so on.

// https://www.wolframalpha.com/input/?i=pi+to+78+digits
const previousEntry = web3.utils.toBN('31415926535897932384626433832795028841971693993751058209749445923078164062862')

// https://www.wolframalpha.com/input/?i=e+to+78+digits
const seed = web3.utils.toBN('27182818284590452353602874713526624977572470936999595749669676277240766303535')

// Data generated using client keep-core/pkg/bls package signing previous entry using master secret key '123'
const groupPubKey = "0x1f1954b33144db2b5c90da089e8bde287ec7089d5d6433f3b6becaefdb678b1b2a9de38d14bef2cf9afc3c698a4211fa7ada7b4f036a2dfef0dc122b423259d0"
const groupSignature = web3.utils.toBN('10920102476789591414949377782104707130412218726336356788412941355500907533021')

module.exports = async function () {

const keepRandomBeaconService = await KeepRandomBeaconService.deployed()
let contract = await KeepRandomBeaconServiceImplV1.at(keepRandomBeaconService.address)
try {
await contract.relayEntry(1, groupSignature, groupPubKey, previousEntry, seed)
console.log('Genesis entry successfully submitted.')
} catch(error) {
console.error('Genesis entry submission failed with', error)
}

process.exit()
}
31 changes: 31 additions & 0 deletions contracts/solidity/scripts/request-relay-entry-with-callback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const crypto = require("crypto")
const KeepRandomBeaconServiceImplV1 = artifacts.require("KeepRandomBeaconServiceImplV1.sol");
const KeepRandomBeaconService = artifacts.require('KeepRandomBeaconService.sol');

// Example usage:
// truffle exec ./scripts/request-relay-entry-with-callback.js yourContractAddress "callbackMethodName" payment
// truffle exec ./scripts/request-relay-entry-with-callback.js 0x9F57C01059057d821c6b4B04A4598322661C934F "callback(uint256)" 100

module.exports = async function() {

const keepRandomBeaconService = await KeepRandomBeaconService.deployed()
const contractInstance = await KeepRandomBeaconServiceImplV1.at(keepRandomBeaconService.address)

try {
let tx = await contractInstance.methods['requestRelayEntry(uint256,address,string)'](crypto.randomBytes(32), process.argv[4], process.argv[5], {value: process.argv[6]})
console.log('Successfully requested relay entry with a callback. RequestId =', tx.logs[0].args.requestID.toString())
console.log(
'\n---Transaction Summary---' + '\n' +
'From:' + tx.receipt.from + '\n' +
'To:' + tx.receipt.to + '\n' +
'BlockNumber:' + tx.receipt.blockNumber + '\n' +
'TotalGas:' + tx.receipt.cumulativeGasUsed + '\n' +
'TransactionHash:' + tx.receipt.transactionHash + '\n' +
'--------------------------'
)
} catch(error) {
console.error('Request failed with', error)
}

process.exit()
}
53 changes: 20 additions & 33 deletions contracts/solidity/scripts/request-relay-entry.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,27 @@
const KeepRandomBeaconServiceImplV1 = artifacts.require("KeepRandomBeaconServiceImplV1");
const crypto = require("crypto")
const KeepRandomBeaconServiceImplV1 = artifacts.require("KeepRandomBeaconServiceImplV1.sol");
const KeepRandomBeaconService = artifacts.require('KeepRandomBeaconService.sol');

module.exports = async function() {

const keepRandomBeaconServiceProxy = await KeepRandomBeaconService.deployed();
const keepRandomBeaconService = await KeepRandomBeaconService.deployed()
const contractInstance = await KeepRandomBeaconServiceImplV1.at(keepRandomBeaconService.address)

async function requestRelayEntry() {

let crypto = require("crypto");
let KeepRandomBeaconContractAddress = await KeepRandomBeaconServiceImplV1.at(keepRandomBeaconServiceProxy.address);

// Generate 32 byte sort of random number
try {
relayEntrySeed = crypto.randomBytes(32);
}
catch(error) {
console.error(error);
}

try {
let requestEntry = await KeepRandomBeaconContractAddress.requestRelayEntry(relayEntrySeed, {value: 2});
console.log(
'---Transaction Summary---' + '\n' +
'From:' + requestEntry.receipt.from + '\n' +
'To:' + requestEntry.receipt.to + '\n' +
'BlockNumber:' + requestEntry.receipt.blockNumber + '\n' +
'TotalGas:' + requestEntry.receipt.cumulativeGasUsed + '\n' +
'TransactionHash:' + requestEntry.receipt.transactionHash + '\n' +
'--------------------------'
);
}
catch(error) {
console.log('Request Failed:');
console.error(error);
}
try {
let tx = await contractInstance.requestRelayEntry(crypto.randomBytes(32), {value: 2})
console.log('Successfully requested relay entry with RequestId =', tx.logs[0].args.requestID.toString())
console.log(
'\n---Transaction Summary---' + '\n' +
'From:' + tx.receipt.from + '\n' +
'To:' + tx.receipt.to + '\n' +
'BlockNumber:' + tx.receipt.blockNumber + '\n' +
'TotalGas:' + tx.receipt.cumulativeGasUsed + '\n' +
'TransactionHash:' + tx.receipt.transactionHash + '\n' +
'--------------------------'
)
} catch(error) {
console.error('Request failed with', error)
}

requestRelayEntry();
}
process.exit()
}
44 changes: 44 additions & 0 deletions contracts/solidity/test/TestKeepRandomBeaconCallback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {bls} from './helpers/data';
const Proxy = artifacts.require('./KeepRandomBeacon.sol');
const KeepRandomBeacon = artifacts.require('./KeepRandomBeaconImplV1.sol');
const KeepGroupStub = artifacts.require('./KeepGroupStub.sol');
const CallbackContract = artifacts.require('./examples/CallbackContract.sol');

contract('TestKeepRandomBeaconCallback', function() {
const relayRequestTimeout = 10;
let impl, proxy, keepRandomBeacon, callbackContract, keepGroupStub;

before(async () => {
impl = await KeepRandomBeacon.new();
proxy = await Proxy.new(impl.address);
keepRandomBeacon = await KeepRandomBeacon.at(proxy.address);

keepGroupStub = await KeepGroupStub.new();
await keepRandomBeacon.initialize(1, 1, bls.previousEntry, bls.groupPubKey, keepGroupStub.address,
relayRequestTimeout);
callbackContract = await CallbackContract.new();
});

it("should produce entry if callback contract was not provided", async function() {
let tx = await keepRandomBeacon.requestRelayEntry(bls.seed, {value: 10});
let requestId = tx.logs[0].args.requestID;
await keepRandomBeacon.relayEntry(requestId, bls.groupSignature, bls.groupPubKey, bls.previousEntry, bls.seed);

let result = await keepRandomBeacon.previousEntry();
assert.isTrue(result.eq(bls.groupSignature), "Value should be updated on beacon contract.");
});

it("should successfully call method on a callback contract", async function() {
let tx = await keepRandomBeacon.methods['requestRelayEntry(uint256,address,string)'](bls.seed, callbackContract.address, "callback(uint256)", {value: 10});
let requestId = tx.logs[0].args.requestID;

let result = await callbackContract.lastEntry();
assert.isFalse(result.eq(bls.groupSignature), "Entry value on the callback contract should not be the same as next relay entry.");

await keepRandomBeacon.relayEntry(requestId, bls.groupSignature, bls.groupPubKey, bls.previousEntry, bls.seed);

result = await callbackContract.lastEntry();
assert.isTrue(result.eq(bls.groupSignature), "Value updated by the callback should be the same as relay entry.");
});

});
Loading

0 comments on commit 22d3089

Please sign in to comment.