-
Notifications
You must be signed in to change notification settings - Fork 1
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
Modify PRE operator schema's entity #11
Conversation
e22be4b
to
eeeac19
Compare
a79ad0b
to
c2834fa
Compare
eeeac19
to
0ef1044
Compare
c2834fa
to
ae02310
Compare
0ef1044
to
44c51a1
Compare
ae02310
to
a0ae207
Compare
44c51a1
to
1600fac
Compare
A stake can have different stake types at the same time (T, NuInTStake and KeepInTStake), so the StakeType's field can be misleading.
- Entity name changed to PREOperator, which is more descriptive. - Added OperatorBonded event handler, so PREOperator instance is created when a new operator is bonded. - Added confirmationTimestamp field, which will store the time in which the operator is confirmed. - Update getEpochStakeId function to accept epoch ID. If no argument passed, the function takes the current epoch count.
a0ae207
to
e4a63ea
Compare
@@ -78,10 +78,11 @@ type TokenholderDelegation implements Delegation @entity { | |||
delegators: [Account!] @derivedFrom(field: "delegatee") | |||
} | |||
|
|||
type ConfirmedOperator @entity { | |||
type PREOperator @entity { | |||
# ID is the staking provider address | |||
id: ID! |
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 ID should be the operator address, not the staking provider because we are in the PREOperator entity and we should add a relationship between PREOperator
and StakeData
entity.
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.
That's a good point. I agree with ID being the operator's address.
But I don't see clearly how to add a relationship between PREOperator and StakeData. Do you mean a Reverse Lookup? This will imply to add a new field in StakeData (probably called preoperator), and in my opinion, we shouldn't mix Threshold Network Staking (StakeData) with an Threshold application of the network (PRE).
Or maybe you mean to use One-To-Many relationship? In that case, do you agree with this schema?
type PREOperator @entity {
# ID is the operator address
id: ID!
confirmationTimestamp: BigInt
stakes: [StakeData!]!
}
The PREOperator entity will include an array of all stakeDatas that use this operator.
What do you think?
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.
Yep makes sense. But it should probably be a one-to-one relationship because of this requirement https://github.com/nucypher/nucypher-contracts/blob/main/contracts/contracts/SimplePREApplication.sol#L193 cc @cygnusv.
Another solution could be a schema like this:
type StakeData @entity {
...
applications: [Application!] @derivedFrom(field: "stake")
}
interface Application {
id: ID!
stake: StakeData!
authorizedStakeAmount: BigInt!
}
type PREApplication implements Application @entity {
id: ID! // id = "operatorAddress-preapplication"
stake: StakeData!
authorizedStakeAmount: BigInt!
confirmationTimestamp: BigInt!
... // other fields related to the pre app
}
// other applications in the future eg. RandomBeaconApplication
type RandomBeaconApplication implement Application @entity {
...
}
So in that case we are ready for multi-staking app authorization and the applications
field makes sense in the StakeData
entity because we authorize applications to use a given stake. What do you think? @manumonti @cygnusv ofc we can address it in a separate PR just a thought.
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 find your proposal very reasonable and I mostly agree with that.
Only one comment about this:
type PREApplication implements Application @entity {
id: ID! // id = "operatorAddress-preapplication"
[...]
I think it could be easier to implement this if id
is stakingProviderAdress-preapplication
. I understand that this entity is PREApplication
so ID should include operator address
, but there is a case which makes hard to implement this:
Check this line: https://github.com/nucypher/nucypher-contracts/blob/710b68713b5b8fece0d0b1c5de376dba1d7d68e7/contracts/contracts/SimplePREApplication.sol#L206
If I am not wrong, this means that when an operator is unbonded, an operatorBonded
event is emitted with these parameters:
stakingProvider
= staking provider addressoperator
= 0x00000000000000000
(please @cygnusv , @vzotova can you confirm?)
So, if the ID is composed of the operator
address, we can't easily find the PREOperator
entity in order to modify or delete it when this type of event is received.
What do you think, @r-czajkowski ?
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.
Yeah, that's right and it works for me. I'm curious about David's opinion.
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.
Unbonding operator will lead to operator = 0x00000000000000000
in an event
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.
So, if the ID is composed of the operator address, we can't easily find the PREOperator entity in order to modify or delete it when this type of event is received.
On the other hand, this is probably a rare scenario (but I'm not sure) and there will be 3 apps (at least for now: tbtc, random beacon, and pre) so I don't mind iterating through applications
from the StakeData
entity and finding the app which contains -preapplication
in the ID and then removing it from the store. Just a thought. Both solutions work for me 👍.
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.
Hi @r-czajkowski. Although I think your proposal scheme fits for Threshold Applications (PREApplication, RandomBeacon, TBTC...), IMHO it can't be applied to SimplePREApplication
because:
It doesn't make sense to have an authorizedStakeAmount
field in SimplePREApplication
since events for authorized stake are not emitted yet.
There is a discussion in progress about these events: threshold-network/solidity-contracts#88 (comment).
I have thought about calling the authorizedStake
function from SimplePREApplication contract (https://github.com/nucypher/nucypher-contracts/blob/710b68713b5b8fece0d0b1c5de376dba1d7d68e7/contracts/contracts/SimplePREApplication.sol#L95-L101), but the state of this field won't be synced since no new events are emitted if stake amounts are modified.
In any case, about this:
On the other hand, this is probably a rare scenario (but I'm not sure) and there will be 3 apps (at least for now: tbtc, random beacon, and pre) so I don't mind iterating through applications from the StakeData entity and finding the app which contains -preapplication in the ID and then removing it from the store.
As I understand, this can't work in your proposal schema since the applications field is a derived field. And it is not possible to fetch derived fields in the mappings.ts, since these are built at query time. See https://github.com/graphprotocol/graph-ts/issues/219.
In my opinion, we should create a new issue or PR with your proposed schema and address it when a definitive version of some Threshold application (PREApplication, TBTC, RandomBeacon) is deployed.
Please, let me know your opinion about this.
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 finally created a issue addressing this. So if @r-czajkowski agree, we can continue the conversation there.
src/mapping.ts
Outdated
const timestamp = event.params.startTimestamp | ||
|
||
const preApplication = getOrCreatePreApplication(stakingProvider) | ||
if (operator == Address.zero()) { |
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.
It is always safer to use ===
instead of ==
, unless there is a really good reason to use ==
.
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.
Done! thank you for the tip
subgraph.yaml
Outdated
@@ -71,11 +71,13 @@ dataSources: | |||
apiVersion: 0.0.5 | |||
language: wasm/assemblyscript | |||
entities: | |||
- Operator | |||
- PREOperator |
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.
We renamed the entity to SimplePREApplication
. Let's update here as well.
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.
Good catch! Done.
The contract used for PRE application is 'SimplePREApplication' instead of 'PREApplication' since the current version of the app is not the definitive one. Also, this GraphQL entity includes a field for 'StakeData', and two timestamps fields, one for when the operator is bonded and another for when the operator is confirmed.
2aaf504
to
88380ab
Compare
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.
Note: This PR must be merged after graphprotocol/graph-tooling#1108.
Schema's changes:
Other changes: