Skip to content

Commit c49bc90

Browse files
feat(RNG): add limit for blocks to pass
1 parent eaa70dc commit c49bc90

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

contracts/standard/rng/BeaconRNG.sol

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import "./RNG.sol";
1616
contract BeaconRNG is RNG {
1717

1818
uint public constant LOOKAHEAD = 132; // Number of blocks that has to pass before obtaining the random number. 4 epochs + 4 slots, according to EIP-4399.
19+
uint public constant ERROR = 20; // Number of blocks after which the lookahead gets reset, so eligible blocks after lookahead don't go long distance, to avoid a possiblity for manipulation.
1920

2021
RNG public blockhashRNG; // Address of blockhashRNG to fall back on.
21-
mapping (uint => uint) public randomNumber; // randomNumber[block] is the random number for this requested block, 0 otherwise.
22+
mapping (uint => uint) public randomNumber; // randomNumber[_requestedBlock] is the random number for this requested block, 0 otherwise.
23+
mapping (uint => uint) public startingBlock; // The starting block number for lookahead countdown. startingBlock[_requestedBlock].
2224

2325
/** @dev Constructor.
2426
* @param _blockhashRNG The blockhash RNG deployed contract address.
@@ -48,6 +50,9 @@ contract BeaconRNG is RNG {
4850
if (block.difficulty <= 2**64) {
4951
blockhashRNG.contribute(_block);
5052
} else {
53+
if (startingBlock[_block] == 0) {
54+
startingBlock[_block] = _block; // Starting block is equal to requested by default.
55+
}
5156
contribute(_block);
5257
}
5358
}
@@ -62,11 +67,17 @@ contract BeaconRNG is RNG {
6267
// fallback to blockhash RNG
6368
if (block.difficulty <= 2**64) {
6469
return blockhashRNG.getRN(_block);
65-
} else if (block.number < _block + LOOKAHEAD) {
66-
// Beacon chain returns the random number, but sufficient number of blocks hasn't been mined yet.
67-
// In this case signal to the court that RN isn't ready.
68-
return 0;
6970
} else {
71+
// Reset the starting block if too many blocks passed since lookahead.
72+
if (block.number > startingBlock[_block] + LOOKAHEAD + ERROR) {
73+
startingBlock[_block] = block.number;
74+
}
75+
if (block.number < startingBlock[_block] + LOOKAHEAD) {
76+
// Beacon chain returns the random number, but sufficient number of blocks hasn't been mined yet.
77+
// In this case signal to the court that RN isn't ready.
78+
return 0;
79+
}
80+
7081
if (randomNumber[_block] == 0) {
7182
randomNumber[_block] = block.difficulty;
7283
}

0 commit comments

Comments
 (0)