Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add random oracle #32

Merged
merged 39 commits into from
Sep 28, 2023
Merged

Add random oracle #32

merged 39 commits into from
Sep 28, 2023

Conversation

nnn-gif
Copy link
Contributor

@nnn-gif nnn-gif commented Sep 25, 2023

RandomOracle contract for storing random values associated with different rounds, which can be updated by the owner of the contract.

this oracles used RandomOracleSetter and RandomOracleGetter traits which has common methods with Price oracle Setter and Getter traits. @deuszx what do you suggest, creating a separate trait or splitting Price oracle traits so that same can be used for this Random oracle

@deuszx
Copy link
Collaborator

deuszx commented Sep 25, 2023

I think it's fine to keep them separate but I'd put these two traits in independent subfolders - similar to the ones for the "main" oracle - so that people wanting to depend on only one side of it can add the single dependency (like here).

@deuszx
Copy link
Collaborator

deuszx commented Sep 25, 2023

Thanks for the changes!

What do you think about renaming Random -> Randomness?

Copy link
Collaborator

@deuszx deuszx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple of comments.

Comment on lines 146 to 153
Self::env().emit_event(OwnershipTransferred {
previous_owner: None,
new_owner: caller,
});
Self::env().emit_event(UpdaterChanged {
old: None,
new: caller,
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI - these events will be difficult to catch with any of the existing indexers (Subsquid or Subquery) as these indexers "subscribe" to AccountId of the contract while this new constructor will emit events for which address? The new one (most probably) but no one yet knows its address as it's just being created.

We can leave it, maybe someone will find a way to use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense if we keep previous_owner and old same as caller ?

Comment on lines 21 to 25
)] pub struct RandomData {
randomness: Vec<u8>,
signature: Vec<u8>,
previous_signature: Vec<u8>,
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you answer these questions from my previous comment?

  1. How big can the data/signature be? I.e. how many bytes?
  2. Why do we need prev_signature?
  3. Do you expect users of the oracle to do something with signature/prev_signature? If yes, what would that be?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 signature size is around 192 bytes
2 prev_signature is not required, I am removing it.
3 signature will be used for auditing purpose to make sure the randomness value is coming from drand only.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not posting signature in the (previous) Oracle, won't those price points not be "audited"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I added one getter to retrieve signature if required

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the data AND signature will be both 192 bytes each?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

@deuszx deuszx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please run cargo fmt on the project.

}

#[ink(message)]
fn set_random_value(&mut self, round: u64, data: RandomData) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your docs it says that if the new randomness is for a round that is older than self.latest_round then such update will be rejected. Why did you decide to change the behavior here?

[req]
)

const txnHash = result.result?.toHex()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if this fails? i.e. the transaction isn't finalized/included in a block? Would the whole function return w/ an error and some upper layers retry it?

@nnn-gif
Copy link
Contributor Author

nnn-gif commented Sep 28, 2023

What happens if this fails? i.e. the transaction isn't finalized/included in a block? Would the whole function return w/ an error and some upper layers retry it?

If tx fail next round will update all pending rounds

Why these two ink(message)s are in a separate impl ? I like the idea of separating ink-related functions (like contructors and messages) from some internal details (_set_random_value) that you're doing here but let's make it consistent - i.e. move code_hash, set_code_hash and new to the previous impl ....

previous impl is for Default, do you want me to add code_hash and set_code in getter setter as this cannot be moved in default and aprt from those there are no impl

**In the docs, the Solidity contract rejects updates that are for "old rounds":

  function setRandomValue(uint256 _round, string memory _randomness, string memory _signature, string memory _previousSignature) public {
    ...
    require(lastRound<_round, "old round");
    ...
}

Why are you not doing it here?**

In our next version we are going to remove that check, as if somehow feeder updates newer round than that condition will restrict update of older round if it is skipped by any chance.

Copy link
Collaborator

@deuszx deuszx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one last comment and we're good to go.

Copy link
Collaborator

@deuszx deuszx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Let's make sure all e2e tests pass as well.

@kaythxbye kaythxbye merged commit b21e5a3 into main Sep 28, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants