Skip to content

Commit 021d039

Browse files
authored
Merge pull request #10 from edgeandnode/tmigone/thaw-requests
feat: provision thaw requests
2 parents b15d665 + 9467e19 commit 021d039

9 files changed

Lines changed: 643 additions & 13 deletions

File tree

packages/subgraph/schema.graphql

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ type ServiceProvider @entity(immutable: false) {
4141
"Service provider address"
4242
id: Bytes!
4343

44+
# Relationships
45+
"Provisions created by this service provider"
46+
provisions: [Provision!]! @derivedFrom(field: "serviceProvider")
47+
"Delegation pools for this service provider"
48+
delegationPools: [DelegationPool!]! @derivedFrom(field: "serviceProvider")
49+
"Provision thaw requests for this service provider"
50+
provisionThawRequests: [ProvisionThawRequest!]! @derivedFrom(field: "serviceProvider")
51+
4452
# Counts
4553
"Number of active provisions"
4654
countProvisions: Int!
@@ -73,14 +81,6 @@ type ServiceProvider @entity(immutable: false) {
7381
"Tokens slashed from delegation pools"
7482
tokensSlashedFromDelegationPools: BigInt!
7583

76-
# Provisions
77-
"Provisions created by this service provider"
78-
provisions: [Provision!]! @derivedFrom(field: "serviceProvider")
79-
80-
# Delegation pools
81-
"Delegation pools for this service provider"
82-
delegationPools: [DelegationPool!]! @derivedFrom(field: "serviceProvider")
83-
8484
# Metadata
8585
"Block number when entity was created"
8686
createdAtBlock: BigInt!
@@ -101,6 +101,8 @@ type DataService @entity(immutable: false) {
101101
provisions: [Provision!]! @derivedFrom(field: "dataService")
102102
"Delegation pools for this data service"
103103
delegationPools: [DelegationPool!]! @derivedFrom(field: "dataService")
104+
"Provision thaw requests for this data service"
105+
provisionThawRequests: [ProvisionThawRequest!]! @derivedFrom(field: "dataService")
104106

105107
# Counts
106108
"Active service providers with provisions to this data service"
@@ -185,6 +187,8 @@ type Provision @entity(immutable: false) {
185187
serviceProvider: ServiceProvider!
186188
"Data service (verifier)"
187189
dataService: DataService!
190+
"Thaw requests for this provision"
191+
thawRequests: [ProvisionThawRequest!]! @derivedFrom(field: "provision")
188192

189193
# Tokens
190194
"Tokens currently provisioned"
@@ -216,3 +220,42 @@ type Provision @entity(immutable: false) {
216220
"Timestamp when entity was last updated"
217221
updatedAt: BigInt!
218222
}
223+
224+
type ProvisionThawRequest @entity(immutable: false) {
225+
"Thaw request ID (bytes32) emitted by ThawRequestCreated event"
226+
id: Bytes!
227+
228+
# Relationships
229+
"Provision being thawed"
230+
provision: Provision!
231+
"Service provider"
232+
serviceProvider: ServiceProvider!
233+
"Data service (verifier)"
234+
dataService: DataService!
235+
236+
# State
237+
"Shares being thawed"
238+
shares: BigInt!
239+
"Timestamp when thaw completes"
240+
thawingUntil: BigInt!
241+
"Thawing nonce at time of creation"
242+
thawingNonce: BigInt!
243+
"Tokens withdrawn (set on fulfillment, null while pending)"
244+
tokensWithdrawn: BigInt
245+
246+
# Status
247+
"False if invalidated by slashing"
248+
valid: Boolean!
249+
"True when tokens have been withdrawn"
250+
fulfilled: Boolean!
251+
252+
# Metadata
253+
"Block number when entity was created"
254+
createdAtBlock: BigInt!
255+
"Timestamp when entity was created"
256+
createdAt: BigInt!
257+
"Block number when entity was last updated"
258+
updatedAtBlock: BigInt!
259+
"Timestamp when entity was last updated"
260+
updatedAt: BigInt!
261+
}

packages/subgraph/src/entities/delegationPool.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"
22
import { DelegationPool } from "../../generated/schema"
33
import { BIGINT_ZERO } from "../common/constants"
4+
import { twoPartId } from "../common/ids"
45

56
export function getDelegationPoolId(serviceProvider: Bytes, dataService: Bytes): Bytes {
6-
return serviceProvider.concat(dataService)
7+
return twoPartId(serviceProvider, dataService)
78
}
89

910
export class DelegationPoolResult {

packages/subgraph/src/entities/provision.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"
22
import { Provision } from "../../generated/schema"
33
import { BIGINT_ZERO } from "../common/constants"
4+
import { twoPartId } from "../common/ids"
45

56
export function getProvisionId(serviceProvider: Bytes, dataService: Bytes): Bytes {
6-
return serviceProvider.concat(dataService)
7+
return twoPartId(serviceProvider, dataService)
78
}
89

910
export class ProvisionResult {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"
2+
import { ProvisionThawRequest } from "../../generated/schema"
3+
import { getProvisionId } from "./provision"
4+
5+
export class ProvisionThawRequestResult {
6+
entity: ProvisionThawRequest
7+
isNew: boolean
8+
9+
constructor(entity: ProvisionThawRequest, isNew: boolean) {
10+
this.entity = entity
11+
this.isNew = isNew
12+
}
13+
}
14+
15+
export function getOrCreateProvisionThawRequest(
16+
id: Bytes,
17+
serviceProvider: Bytes,
18+
dataService: Bytes,
19+
blockNumber: BigInt,
20+
timestamp: BigInt
21+
): ProvisionThawRequestResult {
22+
let entity = ProvisionThawRequest.load(id)
23+
let isNew = entity == null
24+
25+
if (entity == null) {
26+
entity = new ProvisionThawRequest(id)
27+
entity.provision = getProvisionId(serviceProvider, dataService)
28+
entity.serviceProvider = serviceProvider
29+
entity.dataService = dataService
30+
entity.shares = BigInt.zero()
31+
entity.thawingUntil = BigInt.zero()
32+
entity.thawingNonce = BigInt.zero()
33+
entity.tokensWithdrawn = null
34+
entity.valid = true
35+
entity.fulfilled = false
36+
entity.createdAtBlock = blockNumber
37+
entity.createdAt = timestamp
38+
entity.updatedAtBlock = blockNumber
39+
entity.updatedAt = timestamp
40+
}
41+
42+
return new ProvisionThawRequestResult(entity, isNew)
43+
}
44+
45+
export function saveProvisionThawRequest(
46+
thawRequest: ProvisionThawRequest,
47+
block: ethereum.Block
48+
): void {
49+
thawRequest.updatedAtBlock = block.number
50+
thawRequest.updatedAt = block.timestamp
51+
thawRequest.save()
52+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Bytes, log } from "@graphprotocol/graph-ts"
2+
import {
3+
ThawRequestCreated,
4+
ThawRequestFulfilled,
5+
} from "../../generated/HorizonStaking/HorizonStaking"
6+
import { ProvisionThawRequest } from "../../generated/schema"
7+
import {
8+
getOrCreateProvisionThawRequest,
9+
saveProvisionThawRequest,
10+
} from "../entities/provisionThawRequest"
11+
12+
// ThawRequestType enum values from the contract
13+
// 0 = Provision
14+
// 1 = Delegation
15+
const THAW_REQUEST_TYPE_PROVISION = 0
16+
17+
/**
18+
* Handles ThawRequestCreated event.
19+
* Creates a ProvisionThawRequest entity when a service provider initiates thawing.
20+
* Only handles provision thaw requests (type 0), ignores delegation thaw requests.
21+
*/
22+
export function handleThawRequestCreated(event: ThawRequestCreated): void {
23+
if (event.params.requestType != THAW_REQUEST_TYPE_PROVISION) {
24+
return
25+
}
26+
27+
let serviceProviderBytes = Bytes.fromHexString(
28+
event.params.serviceProvider.toHexString()
29+
) as Bytes
30+
let dataServiceBytes = Bytes.fromHexString(
31+
event.params.verifier.toHexString()
32+
) as Bytes
33+
34+
let thawRequest = getOrCreateProvisionThawRequest(
35+
event.params.thawRequestId,
36+
serviceProviderBytes,
37+
dataServiceBytes,
38+
event.block.number,
39+
event.block.timestamp
40+
)
41+
42+
assert(thawRequest.isNew, "Thaw request already exists.")
43+
thawRequest.entity.shares = event.params.shares
44+
thawRequest.entity.thawingUntil = event.params.thawingUntil
45+
thawRequest.entity.thawingNonce = event.params.nonce
46+
47+
saveProvisionThawRequest(thawRequest.entity, event.block)
48+
}
49+
50+
/**
51+
* Handles ThawRequestFulfilled event.
52+
* Updates a ProvisionThawRequest entity when thawed tokens are withdrawn.
53+
* Only handles provision thaw requests (type 0), ignores delegation thaw requests.
54+
*/
55+
export function handleThawRequestFulfilled(event: ThawRequestFulfilled): void {
56+
if (event.params.requestType != THAW_REQUEST_TYPE_PROVISION) {
57+
return
58+
}
59+
60+
// Load directly since ThawRequestFulfilled doesn't include serviceProvider/dataService
61+
let thawRequest = ProvisionThawRequest.load(event.params.thawRequestId)
62+
if (thawRequest == null) {
63+
log.critical("Could not find thaw request: {}.", [event.params.thawRequestId.toHexString()])
64+
return
65+
}
66+
67+
thawRequest.tokensWithdrawn = event.params.tokens
68+
thawRequest.valid = event.params.valid
69+
thawRequest.fulfilled = true
70+
71+
saveProvisionThawRequest(thawRequest, event.block)
72+
}

packages/subgraph/src/mapping.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ export {
2121
handleRebateCollected,
2222
handleAllocationClosed
2323
} from "./handlers/legacy"
24+
export {
25+
handleThawRequestCreated,
26+
handleThawRequestFulfilled
27+
} from "./handlers/thawRequest"

packages/subgraph/subgraph.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ dataSources:
1818
entities:
1919
- GraphNetwork
2020
- ServiceProvider
21+
- DataService
2122
- Provision
2223
- DelegationPool
23-
- Delegator
24-
- Delegation
24+
- ProvisionThawRequest
2525
abis:
2626
- name: HorizonStaking
2727
file: ./abis/HorizonStaking.json
@@ -59,6 +59,11 @@ dataSources:
5959
handler: handleDelegatedTokensWithdrawn
6060
- event: DelegationSlashed(indexed address,indexed address,uint256)
6161
handler: handleDelegationSlashed
62+
# Thaw request events
63+
- event: ThawRequestCreated(indexed uint8,indexed address,indexed address,address,uint256,uint64,bytes32,uint256)
64+
handler: handleThawRequestCreated
65+
- event: ThawRequestFulfilled(indexed uint8,indexed bytes32,uint256,uint256,uint64,bool)
66+
handler: handleThawRequestFulfilled
6267
# Legacy delegation reward events (HorizonStakingExtension)
6368
- event: RebateCollected(address,indexed address,indexed bytes32,indexed address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)
6469
handler: handleRebateCollected

0 commit comments

Comments
 (0)