-
Notifications
You must be signed in to change notification settings - Fork 87
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
Oracle V2 implementation #1629
Oracle V2 implementation #1629
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Highlighting the most important things:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round. Sorry for stalling. Looks goood, but need to look at the details again.
@mustermeiszer here is the root support: 29bfc7d I've needed to propagate that to |
@mustermeiszer when you say #[pallet::origin]
pub type Origin = FeederOrigin; ? |
Ok, I think we do not want that, just reuse the current |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round with a lot of nits and some questions from my side. Feel free to ignore all the nits. Looks really good!
impl pallet_oracle_feed::Config for Runtime { | ||
type FirstValuePayFee = FeeToTreasury<Fees, FirstValueFee>; | ||
type OracleKey = OracleKey; | ||
type OracleValue = Quantity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really Quantity
? I would have imagined Rate
for loans or Ratio
for the orderbook
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rate
sure not because it has 27 decimals with a few integer parts. It could be a Ratio
which is exactly the same type as Quantity
(both alias the same exact type). We should probably unify these types to avoid confusion.
Regarding the name, I think you're right, and Ratio
fits better to specify a "price"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lemunozm can you make this an enum already? I think we will have non ratio types in the future. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense to avoid future migrations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mustermeiszer thinking about this. Do you think it would be interesting to have different pallet instances for pallet-oracle-feed
in case of different values instead of an OracleValue
enum?
I say this to avoid, for example, a feeder feeding with a Key as Isin
and a Value as a non-ratio type, mixing keys with non-related values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After another thought, definitely I think it's better to use different pallet instances to maintain always well-formed key-value correlations on-chain. If some consumer needs different value types, we can always compound them into an enum using a runtime type that implements ValueProvider
in the runtime. Similar to what we already do with OracleConverterBridge
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am really undecided here.
PRO:
- strong typed relationship
- cleaner from a technical perspective
CON:
- We have 70 pallets right now, the limit is 255 - not really close, but we are already having more pallets than most parachains IIRC
- External integrations - It is just harder to look at the right place but I might over-value that
I have even thought about allowing this API
pub fn feed(
lemunozm marked this conversation as resolved.
origin: OriginFor<T>,
key: BoundedVec<T::MaxScaleSizeKey>,
value: BoundedVec<T::MaxScaleSizeValue>,
) -> DispatchResultWithPostInfo {
and upon fetching/aggregating we decode into the needed type and fail if it is not correct. That would be the most flexible.
For example with currently we have needs for
ISIN
->Price
(Currency, Currency)
->Price
Should we really have an instance of this pallet for each combination that we need on-chain? There will be more, I can promise that ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
Should we really have an instance of this pallet for each combination that we need on-chain?
I think both relations above can be in the same pallet instance. The pallet instance can have the Key as an enum but the Value as Price
. That way, any Key enum variant will map always to a correct Value type.
The number of instances will depend only on the number of different kinds of values, not keys. Mostly, I can see Price,
Balance
, and maybe some id or similar (?).
The API with encoding values seems pretty scary to me 😅
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The encoding is always ensured when fetching the keys. Basically anywas what we are already doing when accceotinbg an extrinsic, but just during a runtime call. It is then an invalid key.
But lets go with instances if you think it is better. Should we already make the current key
then an enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we already make the current key then an enum?
It currently is!
Thanks for your deep review @wischli, I'll go into detail with your comments once I give the support for RuntimeOrigin to the PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mustermeiszer latest changes for the RuntimeOrigin support: 72f3e09
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adhering to many of my nits and arguing against the other. AFAICS, the last open discussion is about instantiation vs. OracleValue
enum. As I am voting for the former, I am approving this PR already. We must not merge before Frederik's approval though.
impl pallet_oracle_feed::Config for Runtime { | ||
type FirstValuePayFee = FeeToTreasury<Fees, FirstValueFee>; | ||
type OracleKey = OracleKey; | ||
type OracleValue = Quantity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think instantiating the pallet-oracle-feed
makes more sense for the mentioned reason. That can be done in a follow up PR. But @mustermeiszer should have the stronger say here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look great, just need to decide on the instance vs. enum vs. generic scale for key-value in oracle.
impl pallet_oracle_feed::Config for Runtime { | ||
type FirstValuePayFee = FeeToTreasury<Fees, FirstValueFee>; | ||
type OracleKey = OracleKey; | ||
type OracleValue = Quantity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am really undecided here.
PRO:
- strong typed relationship
- cleaner from a technical perspective
CON:
- We have 70 pallets right now, the limit is 255 - not really close, but we are already having more pallets than most parachains IIRC
- External integrations - It is just harder to look at the right place but I might over-value that
I have even thought about allowing this API
pub fn feed(
lemunozm marked this conversation as resolved.
origin: OriginFor<T>,
key: BoundedVec<T::MaxScaleSizeKey>,
value: BoundedVec<T::MaxScaleSizeValue>,
) -> DispatchResultWithPostInfo {
and upon fetching/aggregating we decode into the needed type and fail if it is not correct. That would be the most flexible.
For example with currently we have needs for
ISIN
->Price
(Currency, Currency)
->Price
Should we really have an instance of this pallet for each combination that we need on-chain? There will be more, I can promise that ^^
pub struct OracleConverterBridge<Origin, Provider, Pools, AssetRegistry>( | ||
PhantomData<(Origin, Provider, Pools, AssetRegistry)>, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we also need a converter for the CachedCollection
, or is it implicitly using this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes it is implicitly using this one
parameter_types! { | ||
#[derive(Clone, PartialEq, Eq, Debug, TypeInfo, Encode, Decode, MaxEncodedLen)] | ||
pub const MaxFeedersPerKey: u32 = 10; | ||
pub const FirstValueFee: Fee = Fee::Balance(deposit(1, pallet_oracle_feed::util::size_of_feed::<Runtime>())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means 1 CFG
per value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1.65 CFG
for each first value, yes. See here for context: #1629 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! All thinks sort out from my side.
Description
Main new requirements:
See the specs here
Changes and Descriptions
ValueProvider
trait to pass values through the oracle structure.OracleConverterBridge
to convert fromQuantity
toBalance
PoolAdminCheck
type implementingPreConditions
to carry the evaluation of a pool admin easily.pallet-oracle-feed
: a pallet that just store feeding valuespallet-oracle-data-collection
: a pallet that compose collections aggregating values.This PR not:
pallet-loans
logic to these new pallets