Skip to content

Commit f9f8dd9

Browse files
authored
feat(entropy): Minor items to prep for testnet deployments (#2673)
* rename stuff * fix test
1 parent dd73357 commit f9f8dd9

File tree

7 files changed

+193
-170
lines changed

7 files changed

+193
-170
lines changed

target_chains/ethereum/contracts/contracts/entropy/Entropy.sol

Lines changed: 55 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ import "./EntropyStructConverter.sol";
1616
// Entropy implements a secure 2-party random number generation procedure. The protocol
1717
// is an extension of a simple commit/reveal protocol. The original version has the following steps:
1818
//
19-
// 1. Two parties A and B each draw a random number x_{A,B}
20-
// 2. A and B then share h_{A,B} = hash(x_{A,B})
21-
// 3. A and B reveal x_{A,B}
22-
// 4. Both parties verify that hash(x_{A, B}) == h_{A,B}
23-
// 5. The random number r = hash(x_A, x_B)
19+
// 1. Two parties A and B each randomly sample a contribution x_{A,B} to the random number
20+
// 2. A commits to their number by sharing h_A = hash(x_A)
21+
// 3. B reveals x_B
22+
// 4. A reveals x_A
23+
// 5. B verifies that hash(x_{A}) == h_A
24+
// 6. The random number r = hash(x_A, x_B)
2425
//
2526
// This protocol has the property that the result is random as long as either A or B are honest.
26-
// Thus, neither party needs to trust the other -- as long as they are themselves honest, they can
27+
// Honesty means that (1) they draw their value at random, and (2) for A, they keep x_A a secret until
28+
// step 4. Thus, neither party needs to trust the other -- as long as they are themselves honest, they can
2729
// ensure that the result r is random.
2830
//
2931
// Entropy implements a version of this protocol that is optimized for on-chain usage. The
@@ -37,26 +39,19 @@ import "./EntropyStructConverter.sol";
3739
// verified against the previous one in the sequence by hashing it, i.e., hash(x_i) == x_{i - 1}
3840
//
3941
// Request: To produce a random number, the following steps occur.
40-
// 1. The user draws a random number x_U, and submits h_U = hash(x_U) to this contract
41-
// 2. The contract remembers h_U and assigns it an incrementing sequence number i, representing which
42+
// 1. The user randomly samples their contribution x_U and submits it to the contract
43+
// 2. The contract remembers x_U and assigns it an incrementing sequence number i, representing which
4244
// of the provider's random numbers the user will receive.
43-
// 3. The user submits an off-chain request (e.g. via HTTP) to the provider to reveal the i'th random number.
44-
// 4. The provider checks the on-chain sequence number and ensures it is > i. If it is not, the provider
45-
// refuses to reveal the ith random number. The provider should wait for a sufficient number of block confirmations
46-
// to ensure that the request does not get re-orged out of the blockchain.
47-
// 5. The provider reveals x_i to the user.
48-
// 6. The user submits both the provider's revealed number x_i and their own x_U to the contract.
49-
// 7. The contract verifies hash(x_i) == x_{i-1} to prove that x_i is the i'th random number. The contract also checks that hash(x_U) == h_U.
45+
// 3. The provider submits a transaction to the contract revealing their contribution x_i to the contract.
46+
// 4. The contract verifies hash(x_i) == x_{i-1} to prove that x_i is the i'th random number.
5047
// The contract stores x_i as the i'th random number to reuse for future verifications.
51-
// 8. If both of the above conditions are satisfied, the random number r = hash(x_i, x_U).
52-
// (Optional) as an added security mechanism, this step can further incorporate the blockhash of the block that the
53-
// request transaction landed in: r = hash(x_i, x_U, blockhash).
48+
// 5. If the condition above is satisfied, the random number r = hash(x_i, x_U).
49+
// 6. The contract submits a callback to the calling contract with the random number `r`.
5450
//
5551
// This protocol has the same security properties as the 2-party randomness protocol above: as long as either
56-
// the provider or user is honest, the number r is random. Honesty here means that the participant keeps their
57-
// random number x a secret until the revelation phase (step 5) of the protocol. Note that providers need to
58-
// be careful to ensure their off-chain service isn't compromised to reveal the random numbers -- if this occurs,
59-
// then users will be able to influence the random number r.
52+
// the provider or user is honest, the number r is random. Note that this analysis assumes that
53+
// providers cannot frontrun user transactions -- a dishonest provider who frontruns user transaction can
54+
// manipulate the result.
6055
//
6156
// The Entropy implementation of the above protocol allows anyone to permissionlessly register to be a
6257
// randomness provider. Users then choose which provider to request randomness from. Each provider can set
@@ -71,13 +66,6 @@ import "./EntropyStructConverter.sol";
7166
// a compromised sequence. On rotation, any in-flight requests continue to use the pre-rotation commitment.
7267
// Providers can use the sequence number of the request along with the event log of their registrations to determine
7368
// which hash chain contains the requested random number.
74-
//
75-
// Warning to integrators:
76-
// An important caveat of this protocol is that the user can compute the random number r before
77-
// revealing their own number to the contract. This property means that the user can choose to halt the
78-
// protocol prior to the random number being revealed (i.e., prior to step (6) above). Integrators should ensure that
79-
// the user is always incentivized to reveal their random number, and that the protocol has an escape hatch for
80-
// cases where the user chooses not to reveal.
8169
abstract contract Entropy is IEntropy, EntropyState {
8270
using ExcessivelySafeCall for address;
8371

@@ -357,24 +345,24 @@ abstract contract Entropy is IEntropy, EntropyState {
357345
// Note that excess value is *not* refunded to the caller.
358346
function requestWithCallback(
359347
address provider,
360-
bytes32 userRandomNumber
348+
bytes32 userContribution
361349
) public payable override returns (uint64) {
362350
return
363351
requestV2(
364352
provider,
365-
userRandomNumber,
353+
userContribution,
366354
0 // Passing 0 will assign the request the provider's default gas limit
367355
);
368356
}
369357

370358
function requestV2(
371359
address provider,
372-
bytes32 userRandomNumber,
360+
bytes32 userContribution,
373361
uint32 gasLimit
374362
) public payable override returns (uint64) {
375363
EntropyStructsV2.Request storage req = requestHelper(
376364
provider,
377-
constructUserCommitment(userRandomNumber),
365+
constructUserCommitment(userContribution),
378366
// If useBlockHash is set to true, it allows a scenario in which the provider and miner can collude.
379367
// If we remove the blockHash from this, the provider would have no choice but to provide its committed
380368
// random number. Hence, useBlockHash is set to false.
@@ -387,14 +375,14 @@ abstract contract Entropy is IEntropy, EntropyState {
387375
provider,
388376
req.requester,
389377
req.sequenceNumber,
390-
userRandomNumber,
378+
userContribution,
391379
EntropyStructConverter.toV1Request(req)
392380
);
393381
emit EntropyEventsV2.Requested(
394382
provider,
395383
req.requester,
396384
req.sequenceNumber,
397-
userRandomNumber,
385+
userContribution,
398386
uint32(req.gasLimit10k) * TEN_THOUSAND,
399387
bytes("")
400388
);
@@ -406,14 +394,14 @@ abstract contract Entropy is IEntropy, EntropyState {
406394
// current commitment and returns the generated random number.
407395
function revealHelper(
408396
EntropyStructsV2.Request storage req,
409-
bytes32 userRevelation,
410-
bytes32 providerRevelation
397+
bytes32 userContribution,
398+
bytes32 providerContribution
411399
) internal returns (bytes32 randomNumber, bytes32 blockHash) {
412400
bytes32 providerCommitment = constructProviderCommitment(
413401
req.numHashes,
414-
providerRevelation
402+
providerContribution
415403
);
416-
bytes32 userCommitment = constructUserCommitment(userRevelation);
404+
bytes32 userCommitment = constructUserCommitment(userContribution);
417405
if (
418406
keccak256(bytes.concat(userCommitment, providerCommitment)) !=
419407
req.commitment
@@ -436,8 +424,8 @@ abstract contract Entropy is IEntropy, EntropyState {
436424
}
437425

438426
randomNumber = combineRandomValues(
439-
userRevelation,
440-
providerRevelation,
427+
userContribution,
428+
providerContribution,
441429
blockHash
442430
);
443431

@@ -446,7 +434,7 @@ abstract contract Entropy is IEntropy, EntropyState {
446434
];
447435
if (providerInfo.currentCommitmentSequenceNumber < req.sequenceNumber) {
448436
providerInfo.currentCommitmentSequenceNumber = req.sequenceNumber;
449-
providerInfo.currentCommitment = providerRevelation;
437+
providerInfo.currentCommitment = providerContribution;
450438
}
451439
}
452440

@@ -455,7 +443,7 @@ abstract contract Entropy is IEntropy, EntropyState {
455443
function advanceProviderCommitment(
456444
address provider,
457445
uint64 advancedSequenceNumber,
458-
bytes32 providerRevelation
446+
bytes32 providerContribution
459447
) public override {
460448
EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[
461449
provider
@@ -473,14 +461,14 @@ abstract contract Entropy is IEntropy, EntropyState {
473461
);
474462
bytes32 providerCommitment = constructProviderCommitment(
475463
numHashes,
476-
providerRevelation
464+
providerContribution
477465
);
478466

479467
if (providerCommitment != providerInfo.currentCommitment)
480468
revert EntropyErrors.IncorrectRevelation();
481469

482470
providerInfo.currentCommitmentSequenceNumber = advancedSequenceNumber;
483-
providerInfo.currentCommitment = providerRevelation;
471+
providerInfo.currentCommitment = providerContribution;
484472
if (
485473
providerInfo.currentCommitmentSequenceNumber >=
486474
providerInfo.sequenceNumber
@@ -508,8 +496,8 @@ abstract contract Entropy is IEntropy, EntropyState {
508496
function reveal(
509497
address provider,
510498
uint64 sequenceNumber,
511-
bytes32 userRevelation,
512-
bytes32 providerRevelation
499+
bytes32 userContribution,
500+
bytes32 providerContribution
513501
) public override returns (bytes32 randomNumber) {
514502
EntropyStructsV2.Request storage req = findActiveRequest(
515503
provider,
@@ -528,13 +516,13 @@ abstract contract Entropy is IEntropy, EntropyState {
528516
bytes32 blockHash;
529517
(randomNumber, blockHash) = revealHelper(
530518
req,
531-
userRevelation,
532-
providerRevelation
519+
userContribution,
520+
providerContribution
533521
);
534522
emit Revealed(
535523
EntropyStructConverter.toV1Request(req),
536-
userRevelation,
537-
providerRevelation,
524+
userContribution,
525+
providerContribution,
538526
blockHash,
539527
randomNumber
540528
);
@@ -554,8 +542,8 @@ abstract contract Entropy is IEntropy, EntropyState {
554542
function revealWithCallback(
555543
address provider,
556544
uint64 sequenceNumber,
557-
bytes32 userRandomNumber,
558-
bytes32 providerRevelation
545+
bytes32 userContribution,
546+
bytes32 providerContribution
559547
) public override {
560548
EntropyStructsV2.Request storage req = findActiveRequest(
561549
provider,
@@ -573,8 +561,8 @@ abstract contract Entropy is IEntropy, EntropyState {
573561
bytes32 randomNumber;
574562
(randomNumber, ) = revealHelper(
575563
req,
576-
userRandomNumber,
577-
providerRevelation
564+
userContribution,
565+
providerContribution
578566
);
579567

580568
// If the request has an explicit gas limit, then run the new callback failure state flow.
@@ -613,15 +601,17 @@ abstract contract Entropy is IEntropy, EntropyState {
613601
if (success) {
614602
emit RevealedWithCallback(
615603
EntropyStructConverter.toV1Request(req),
616-
userRandomNumber,
617-
providerRevelation,
604+
userContribution,
605+
providerContribution,
618606
randomNumber
619607
);
620608
emit EntropyEventsV2.Revealed(
621609
provider,
622610
req.requester,
623611
req.sequenceNumber,
624612
randomNumber,
613+
userContribution,
614+
providerContribution,
625615
false,
626616
ret,
627617
SafeCast.toUint32(gasUsed),
@@ -642,8 +632,8 @@ abstract contract Entropy is IEntropy, EntropyState {
642632
provider,
643633
req.requester,
644634
sequenceNumber,
645-
userRandomNumber,
646-
providerRevelation,
635+
userContribution,
636+
providerContribution,
647637
randomNumber,
648638
ret
649639
);
@@ -652,6 +642,8 @@ abstract contract Entropy is IEntropy, EntropyState {
652642
req.requester,
653643
sequenceNumber,
654644
randomNumber,
645+
userContribution,
646+
providerContribution,
655647
true,
656648
ret,
657649
SafeCast.toUint32(gasUsed),
@@ -692,15 +684,17 @@ abstract contract Entropy is IEntropy, EntropyState {
692684

693685
emit RevealedWithCallback(
694686
reqV1,
695-
userRandomNumber,
696-
providerRevelation,
687+
userContribution,
688+
providerContribution,
697689
randomNumber
698690
);
699691
emit EntropyEventsV2.Revealed(
700692
provider,
701693
callAddress,
702694
sequenceNumber,
703695
randomNumber,
696+
userContribution,
697+
providerContribution,
704698
false,
705699
bytes(""),
706700
gasUsed,

0 commit comments

Comments
 (0)