Skip to content

Commit a10c624

Browse files
idiom-bytesalexcos20mihaisctrizin
authored
Implementing first pass of veAllocate schema, handlers, and test cove… (#490)
* Implementing first pass of veAllocate schema, handlers, and test coverage. * Fixed compiling issues, wrote compiling & testing outline inside of veAllocate.test. More to come. * Created documentation. Moving tests away from subgraph and into df-py. * Expanding documentation to be thorough and cover more of the work involved. * use barge artifacts * use proper contracts in ci * use barge artifacts folder * fix replace * use npm contracts dep * use latest contracts for barge * fix some lint * Fix linter errors * Update schema * Finished basic integration of setAllocation event and verified queries/schema is working as intended. * Fixing amount getter. * Fixed remaining implementation, verified SimpleSubgraph.test is working, and fixed lint errors. * Fixing import. * Use .zero() * Improve readability * Add allocated to schema * Update abi * Update event handlers in the template * Update veREADME * Remove `AllocationRemoved` handler * Hooking data for tx, firstContact, lastUpdate, block * Update event abi * Add chainId and nftAddress to schema * Update `handleAllocationSet` * Update abi * Update readme * Set initial values * Fix math * Missing event param * set initial value of `lastContact` * veOcean template * VeOcean entity * Handler functions - wip * rename file * Delegation schema * veDelegate mapping file * Rename * Update template * Update schema * Update replaces * Add handler for delegation * Update schema * getveDelegation * Update naming * Add deposit entity * Update template * Make delegation an array * Add `handleDelegation` * Add `handleDeposit` for veOCEAN * Add `getveOCEAN` util function * Add `getDeposit` util function * Add `handleBurnBoost` * Add `handleExtendBoost` * Add `handleTransferBoost` * Set default veOCEAN * Remove unused import * Rename Deposit to VeDeposit * Include block number * Remove `allocatedTotal` * Updating schema and fixing errors due to naming changes. Let's keep the user current allocation, maybe we need to create a feature to more easily let them know whether they are fully allocated, or not.. * bump contracts to v1.1.1 * bump contracts * bump to contracts 1.1.2 * fix script for networks without ve * add veAllocation.sol's AllocationSetMultiple * copy artfacts from barge for npm quickstart:barge * fix using barge artifacts * temp debug * use barge artifacts * use contracts 1.1.3 * use same approach for 'development' * bump ocean-contracts Co-authored-by: alexcos20 <[email protected]> Co-authored-by: mihaisc <[email protected]> Co-authored-by: trizin <[email protected]>
1 parent dbb2960 commit a10c624

14 files changed

+884
-73
lines changed

.github/workflows/tests.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
run: |
5353
bash -x start_ocean.sh --with-thegraph --skip-subgraph-deploy --no-dashboard 2>&1 > start_ocean.log &
5454
env:
55-
CONTRACTS_VERSION: v1.0.0-alpha.28
55+
CONTRACTS_VERSION: v1.1.3
5656

5757
- run: npm ci
5858

@@ -69,6 +69,8 @@ jobs:
6969
sleep 20
7070
env:
7171
ADDRESS_FILE: /home/runner/.ocean/ocean-contracts/artifacts/address.json
72+
BARGE_FOLDER: /home/runner/.ocean/
7273
- run: npm run test-integration
7374
env:
7475
ADDRESS_FILE: /home/runner/.ocean/ocean-contracts/artifacts/address.json
76+
BARGE_FOLDER: /home/runner/.ocean/

docs/README-local-veSubgraph.md

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Add contract as dataSource and use local Subgraph + Ganache + Brownie
2+
To develop new features on top of `ocean-subgraph`, it pays to deploy a local Subgraph that consumes from Ganache, so you can deploy your Contracts, execute their functionality, and query the Subgraph to verify Events are being Handled correctly, w/ the right Schema being yielded.
3+
4+
The following doc takes you through:
5+
1. Configuring `docker-compose.yml` to run an internal Subgraph that consumes from a local Ganache.
6+
2. Configuring `df-py` + Brownie to connect to the `ocean-subgraph` Ganache so we can deploy our local contracts.
7+
3. Adding our smart contract as a dataSource for our internal Subgraph. We can then handle contract events, and transform that data into queryable entities using GQL.
8+
4. Finally, we can hook our contracts into Testing & verifying that your subgraph is working as intended.
9+
10+
Note 1: For this tutorial, you should be using multiple terminal windows. These will be referred to at the top of each section.
11+
12+
Note 2: For this example, we're going to use the `df-py` repository and integrate `veAllocate` contract into `ocean-subgraph`
13+
14+
Note 3: For the sake of versatility, the example below is being executed using `df-py` while verification is being done by hand by viewing & querying GQL on the browser.
15+
16+
### 1. ocean-subgraph - Add & Connect Ganache
17+
Section 1 takes place inside `ocean-subgraph` terminal window.
18+
19+
You should have this repository configured and working on your machine.
20+
21+
We now need to update `./docker/docker-compose.yml` to implement a local instance of Ganache. Our `graph-node` needs to listen to Ganache for events, so we update the ethereum url.
22+
```
23+
services:
24+
ganache:
25+
image: trufflesuite/ganache-cli:latest
26+
ports:
27+
- 8545:8545
28+
entrypoint: ["node", "/app/ganache-core.docker.cli.js", "--db", "./ganache_cache","--chainId","0x2324","--networkId","0x2324","--gasLimit","10000000000","--gasPrice","1","---hardfork","istanbul","--mnemonic","${GANACHE_MNEMONIC}", "-e", "100", "-a", "20"]
29+
graph-node:
30+
environment:
31+
ethereum: 'development:http://ganache:8545'
32+
```
33+
34+
Great, our docker environment is now setup. We can finally deploy it by typing `docker-compose up` inside of `./docker/`.
35+
36+
### 2a. df-py - Configure to connect to Subgraph
37+
Section 2 takes place inside `df-py` terminal window.
38+
39+
You should have this repository configured and working on your machine.
40+
41+
First, we make sure that we're inside our venv by typing `source venv/bin/activate/`. Again, we're assuming your requirements.txt, and other dependencies have been properly initialized.
42+
43+
We now `df-py` connect to Ganache via Brownie. To do this, we're going to add a network so Brownie can listen to our Ganache service.
44+
```
45+
brownie networks add Ethereum subgraph-ganache host=http://127.0.0.1:8545, chainid=8996
46+
```
47+
48+
We then update our `brownie-config.yaml` so that it uses the network above by default.
49+
```
50+
networks:
51+
default: subgraph-ganache
52+
```
53+
54+
You should now be able to verify that the accounts from `subgraph-ganache` are working from inside `df-py` brownie.
55+
```
56+
brownie console --network subgraph-ganache
57+
>>> accounts[0].balance()
58+
100000000000000000000
59+
```
60+
61+
### 2b. df-py - Configure dftools and deploy contracts
62+
This section continues from Section 2.
63+
64+
We can now, also configure dftools to use accounts from Ganache, and deploy contracts into `ocean-subgraph`.
65+
66+
Look inside the `ocean-subgraph` terminal for the private accounts that were generated for you inside of Ganache. Copy one of their private keys, and do the following inside of `df-py/(venv)/`
67+
```
68+
export DFTOOL_KEY=0xYourUserPrivateKeyFromGanache
69+
export WEB3_INFURA_PROJECT_ID=YourInfuraKey
70+
```
71+
72+
You should now be able to deploy a newToken + veOCEAN + veAllocate contracts.
73+
```
74+
// deploy a new token
75+
dftool newToken 8996
76+
77+
// use the token address from above to deploy veOcean
78+
dftool newVeOcean 8996 token_address
79+
80+
// deploy veAllocate
81+
dftool newVeAllocate 8996
82+
```
83+
84+
You will need the address from the new `veAllocate` contract you just deployed for the next section. This contract will be used in the future so our subgraph can listen for events.
85+
86+
### 3a. ocean-subgraph - Initialize the project
87+
Section 3 takes place inside `ocean-subgraph` terminal.
88+
89+
We're going to now generate `subgraph.yaml` so we can start connecting the veOCEAN contract into the logic of `ocean-subpgrah`.
90+
91+
We begin by running the following node script from the root folder.
92+
```
93+
node ./scripts/generatenetworkssubgraphs.js
94+
```
95+
96+
Here, we're going to configure our local `subgraph.yaml` file so we can serve our local ganache, contracts, and everything that `df-py` depends on.
97+
98+
Use this file for all of your development until you have things sorted out. If you make any mistakes, you can just recreate the file. You should make your final changes inside of `subgraph.template.yaml` before submitting a PR.
99+
100+
### 3b. ocean-subgraph - Configure dataSources
101+
102+
We now configure our `subgraph.yaml` to talk to ganache and add our veAllocate Contract as a dataSource.
103+
104+
Our first step is to reset our `subgraph.yaml` so that it can consume all the events. Do a search for `startBlock` and make sure all params are initialized to 0.
105+
```
106+
- kind: ethereum/contract
107+
source:
108+
startBlock: 0
109+
```
110+
111+
We then add our contract as a dataSource. We get our address from Section 2b `dftool newVeAllocate 8996` and enter it in the `dataSources` section of the `subgraph.yaml` file.
112+
```
113+
dataSources:
114+
- kind: ethereum/contract
115+
name: veAllocate
116+
network: development
117+
source:
118+
address: 0x0000000000000000000000000000000
119+
abi: veAllocate
120+
startBlock: 0
121+
mapping:
122+
kind: ethereum/events
123+
apiVersion: 0.0.6
124+
language: wasm/assemblyscript
125+
file: ./src/mappings/veAllocate.ts
126+
entities:
127+
- veAllocate
128+
abis:
129+
- name: veAllocate
130+
file: ./abis/veAllocate.json
131+
eventHandlers:
132+
- event: AllocationSet(indexed address,indexed address,indexed uint256,uint256)
133+
handler: handleAllocationSet
134+
```
135+
136+
As you can see, we have also imported our `veAllocate.json ABI` file into the project, added the contract events we want to handle, and created a mapping script `./src/mappings/veAllocate.ts` so we can handle all the vents for the Subgraph.
137+
138+
Note: This tutorial will not go into details of how to do this work. Someone can create a separate guide on how to handle internal logic, define GraphQL entities, and save records into GraphQL.
139+
140+
_Please review the PR associated with this README for more intuition on this_
141+
142+
### 4a. ocean-subgraph - run: `npm run codegen`
143+
From the root folder run this command.
144+
145+
You'll have to do this again every time you change `schema.graphql`
146+
147+
### 4b. ocean-subgraph - run: `npm run create:local`
148+
From the root folder run this command.
149+
150+
You'll have to do this again every time you run step 5a.
151+
152+
### 4c. ocean-subgraph - run: `npm run deploy:local`
153+
From the root folder run this command.
154+
155+
You'll have to do this again when you write any new subgraph code (mappings, utils, etc...).
156+
157+
### 5. ocean-subgraph - restart docker
158+
Restart docker containers via `docker-compose up`
159+
160+
### 6. df-py - Execute onchain events + query subgraph
161+
You can now start performing your onchain + contract tests and see records inside of your local subgraph.
162+
163+
As an example, you may use the following command inside `dftools` to generate many onchain events for Ganache.
164+
```
165+
dftool manyrandom 8996
166+
```

package-lock.json

+8-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"typescript": "^4.8.2"
6565
},
6666
"dependencies": {
67+
"@oceanprotocol/contracts": "^1.1.3",
6768
"@oceanprotocol/lib": "^1.1.8",
6869
"cross-fetch": "^3.1.4"
6970
},

schema.graphql

+94-1
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,105 @@ type NftUpdate @entity {
360360
tx: String!
361361
}
362362

363-
364363
type Template @entity{
365364
id: ID!
366365
fixedRateTemplates: [String!]
367366
dispenserTemplates: [String!]
368367
ssTemplates: [String!]
369368
}
370369

370+
# Not tracking allocationToId or idToAllocation
371+
type VeAllocateUser @entity{
372+
"id = {user}"
373+
id: ID!
374+
375+
veAllocation: [VeAllocation!] @derivedFrom(field: "allocationUser")
376+
allocatedTotal: BigDecimal!
377+
378+
block: Int!
379+
firstContact: Int!
380+
lastContact: Int!
381+
tx: String!
382+
}
383+
384+
type VeAllocateId @entity{
385+
"id = {DataNFT Address}-{chain id}"
386+
id: ID!
387+
388+
veAllocation: [VeAllocation!] @derivedFrom(field: "allocationId")
389+
allocatedTotal: BigDecimal!
390+
391+
block: Int!
392+
firstContact: Int!
393+
lastContact: Int!
394+
tx: String!
395+
}
396+
397+
# we need to track allocation of user to id
398+
type VeAllocation @entity {
399+
"id = {user}-{DataNFT Address}-{chain id}"
400+
id: ID!
401+
402+
allocationUser: VeAllocateUser!
403+
allocationId: VeAllocateId!
404+
405+
updates: [VeAllocationUpdate!] @derivedFrom(field: "veAllocation")
406+
allocated: BigDecimal!
407+
chainId: BigInt!
408+
nftAddress: String!
409+
410+
block: Int!
411+
firstContact: Int!
412+
lastContact: Int!
413+
tx: String!
414+
}
415+
416+
enum veAllocationUpdateType {
417+
SET,
418+
REMOVED
419+
}
420+
421+
type VeAllocationUpdate @entity {
422+
"{tx}-{VeAllocation id}"
423+
id: ID!
424+
425+
veAllocation: VeAllocation!
426+
type: veAllocationUpdateType!
427+
allocatedTotal: BigDecimal!
428+
429+
block: Int!
430+
timestamp: Int!
431+
tx: String!
432+
}
433+
434+
type VeDelegation @entity {
435+
"id = tokenId"
436+
id: ID!
437+
delegator: VeOCEAN!
438+
receiver: VeOCEAN!
439+
tokenId: BigInt!
440+
amount: BigInt!
441+
cancelTime: BigInt!
442+
expireTime: BigInt!
443+
block: Int!
444+
}
445+
446+
type VeOCEAN @entity {
447+
"id = {user address}"
448+
id: ID!
449+
lockedAmount: BigDecimal!
450+
unlockTime: BigInt!
451+
delegation: [VeDelegation!] @derivedFrom(field: "delegator")
452+
delegates: [VeDelegation!] @derivedFrom(field: "receiver")
453+
block: Int!
454+
}
371455

456+
type VeDeposit @entity {
457+
"id = {user address}-{timestamp}"
458+
id: ID!
459+
provider:String!
460+
value: BigDecimal!
461+
unlockTime: BigInt!
462+
type:BigInt!
463+
timestamp: BigInt!
464+
}

scripts/generatenetworkssubgraphs.js

+28
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ async function replaceContractAddresses() {
2020
}
2121
console.log('Creating subgraph.yaml for ' + network)
2222
let subgraph = fs.readFileSync('./subgraph.template.yaml', 'utf8')
23+
const subgraphVe = fs.readFileSync('./subgraph_ve.template.yaml', 'utf8')
24+
if (addresses[network].veOCEAN) {
25+
// fix identation , due to vs auto format (subgraph_ve.template is moved to left)
26+
const lines = subgraphVe.split('\n')
27+
for (let line = 0; line < lines.length; line++) {
28+
subgraph += ' ' + lines[line] + '\n'
29+
}
30+
}
2331

2432
subgraph = subgraph.replace(/__NETWORK__/g, network)
2533
subgraph = subgraph.replace(
@@ -34,6 +42,26 @@ async function replaceContractAddresses() {
3442
/__FACTORYROUTERADDRESS__/g,
3543
"'" + addresses[network].Router + "'"
3644
)
45+
46+
subgraph = subgraph.replace(
47+
/__VEALLOCATEADDRESS__/g,
48+
"'" + addresses[network].veAllocate + "'"
49+
)
50+
51+
subgraph = subgraph.replace(
52+
/__VEOCEANADDRESS__/g,
53+
"'" + addresses[network].veOCEAN + "'"
54+
)
55+
56+
subgraph = subgraph.replace(
57+
/__VEDELEGATIONADDRESS__/g,
58+
"'" + addresses[network].veDelegation + "'"
59+
)
60+
61+
subgraph = subgraph.replace(
62+
/__DFREWARDSADDRESS__/g,
63+
"'" + addresses[network].DFRewards + "'"
64+
)
3765
fs.writeFileSync('subgraph.yaml', subgraph, 'utf8')
3866
}
3967
}

src/mappings/utils/constants.ts

+5
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,8 @@ export namespace NftUpdateType {
2828
export const STATE_UPDATED = 'STATE_UPDATED'
2929
export const TOKENURI_UPDATED = 'TOKENURI_UPDATED'
3030
}
31+
32+
export namespace veAllocationUpdateType {
33+
export const SET = 'SET'
34+
export const REMOVED = 'REMOVED'
35+
}

0 commit comments

Comments
 (0)