-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prepare to pull request to deploy branch
- Loading branch information
1 parent
b2b6d70
commit 2af4ad5
Showing
72 changed files
with
6,798 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
version: '3' | ||
|
||
services: | ||
postgres: | ||
image: postgres:12-alpine | ||
ports: | ||
- 5432:5432 | ||
volumes: | ||
- .data/postgres:/var/lib/postgresql/data | ||
healthcheck: | ||
test: ["CMD-SHELL", "pg_isready -U postgres"] | ||
interval: 5s | ||
timeout: 5s | ||
retries: 5 | ||
environment: | ||
POSTGRES_PASSWORD: postgres | ||
|
||
subquery-node: | ||
image: onfinality/subql-node:latest | ||
depends_on: | ||
postgres: | ||
condition: service_healthy | ||
restart: always | ||
environment: | ||
DB_USER: postgres | ||
DB_PASS: postgres | ||
DB_DATABASE: postgres | ||
DB_HOST: postgres | ||
DB_POST: 5432 | ||
volumes: | ||
- ./:/app | ||
command: | ||
- -f=/app | ||
# - --local #remove | ||
# - --batch-size=50 | ||
|
||
graphql-engine: | ||
image: onfinality/subql-query:latest | ||
ports: | ||
- 3000:3000 | ||
depends_on: | ||
- subquery-node | ||
restart: always | ||
environment: | ||
DB_USER: postgres | ||
DB_PASS: postgres | ||
DB_DATABASE: postgres | ||
DB_HOST: postgres | ||
DB_PORT: 5432 | ||
command: | ||
- --name=app | ||
- --playground | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
SCRIPT_PATH=$(dirname "$0") | ||
|
||
cd ${SCRIPT_PATH} | ||
|
||
docker rm -f $(docker-compose ps -a -q) | ||
sudo rm -rf .data/ | ||
sudo rm -rf dist/ | ||
yarn | ||
yarn codegen | ||
yarn build | ||
yarn start:docker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
type Transfer @jsonField { | ||
assetId: String, | ||
amount: String! | ||
to: String! | ||
from: String! | ||
fee: String! | ||
eventIdx: Int! | ||
success: Boolean! | ||
} | ||
|
||
type Reward @jsonField { | ||
eventIdx: Int! | ||
amount: String! | ||
isReward: Boolean!, | ||
era: Int, | ||
stash: String, | ||
validator: String | ||
} | ||
|
||
type AccumulatedReward @entity { | ||
id: ID! #address | ||
amount: BigInt! | ||
} | ||
|
||
type Extrinsic @jsonField { | ||
hash: String! | ||
module: String! | ||
call: String! | ||
fee: String! | ||
success: Boolean! | ||
} | ||
|
||
type HistoryElement @entity { | ||
id: ID! | ||
blockNumber: Int! | ||
extrinsicIdx: Int | ||
extrinsicHash: String | ||
timestamp: BigInt! @index | ||
address: String! @index | ||
reward: Reward | ||
extrinsic: Extrinsic | ||
transfer: Transfer | ||
} | ||
|
||
type EraValidatorInfo @entity { | ||
id: ID! | ||
address: String! @index | ||
era: Int! @index | ||
total: BigInt! | ||
own: BigInt! | ||
others: [IndividualExposure]! | ||
} | ||
|
||
type IndividualExposure @jsonField { | ||
who: String! | ||
value: String! | ||
} | ||
|
||
#enum StakeChangeType { | ||
# bonded | ||
# unbonded | ||
# slashed | ||
# rewarded | ||
#} | ||
|
||
type StakeChange @entity { | ||
id: ID! | ||
blockNumber: Int! | ||
extrinsicHash: String | ||
eventIdx: Int! | ||
timestamp: BigInt! @index | ||
address: String! @index | ||
amount: BigInt! | ||
accumulatedAmount: BigInt! | ||
type: String! | ||
} | ||
|
||
type AccumulatedStake @entity { | ||
id: ID! | ||
amount: BigInt! | ||
} | ||
|
||
type ErrorEvent @entity { | ||
id: ID! | ||
description: String! | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//Exports all handler functions | ||
export * from './mappings/HistoryElements' | ||
export * from './mappings/Rewards' | ||
export * from './mappings/Transfers' | ||
export * from './mappings/NewEra' | ||
export * from './mappings/StakeChanged' | ||
import "@polkadot/api-augment" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import {SubstrateEvent} from "@subql/types"; | ||
import {blockNumber, eventId, timestamp} from "./common"; | ||
import {Balance, AccountId} from "@polkadot/types/interfaces"; | ||
import {RewardDestination} from "@polkadot/types/interfaces/staking"; | ||
|
||
// Due to memory consumption optimization `rewardDestinationByAddress` contains only one key | ||
let rewardDestinationByAddress: {[blockId: string]: {[address: string]: RewardDestination}} = {} | ||
let controllersByStash: {[blockId: string]: {[address: string]: string}} = {} | ||
|
||
export async function cachedRewardDestination(accountAddress: string, event: SubstrateEvent): Promise<RewardDestination> { | ||
const blockId = blockNumber(event) | ||
let cachedBlock = rewardDestinationByAddress[blockId] | ||
|
||
if (cachedBlock !== undefined) { | ||
return cachedBlock[accountAddress] | ||
} else { | ||
rewardDestinationByAddress = {} | ||
|
||
let method = event.event.method | ||
let section = event.event.section | ||
|
||
const allAccountsInBlock = event.block.events | ||
.filter(blockEvent => { | ||
return blockEvent.event.method == method && blockEvent.event.section == section | ||
}) | ||
.map(event => { | ||
let {event: {data: [accountId, ]}} = event | ||
return accountId | ||
}); | ||
|
||
// looks like accountAddress not related to events so just try to query payee directly | ||
if (allAccountsInBlock.length === 0) { | ||
rewardDestinationByAddress[blockId] = {} | ||
return await api.query.staking.payee(accountAddress) | ||
} | ||
|
||
// TODO: Commented code doesn't work now, may be fixed later | ||
// const payees = await api.query.staking.payee.multi(allAccountsInBlock); | ||
const payees = await api.queryMulti(allAccountsInBlock.map(account => ([api.query.staking.payee, account]))); | ||
|
||
const rewardDestinations = payees.map(payee => { return payee as RewardDestination }); | ||
|
||
let destinationByAddress: {[address: string]: RewardDestination} = {} | ||
|
||
// something went wrong, so just query for single accountAddress | ||
if (rewardDestinations.length !== allAccountsInBlock.length) { | ||
const payee = await api.query.staking.payee(accountAddress) | ||
destinationByAddress[accountAddress] = payee | ||
rewardDestinationByAddress[blockId] = destinationByAddress | ||
return payee | ||
} | ||
allAccountsInBlock.forEach((account, index) => { | ||
let accountAddress = account.toString() | ||
let rewardDestination = rewardDestinations[index] | ||
destinationByAddress[accountAddress] = rewardDestination | ||
}) | ||
rewardDestinationByAddress[blockId] = destinationByAddress | ||
return destinationByAddress[accountAddress] | ||
} | ||
} | ||
|
||
export async function cachedController(accountAddress: string, event: SubstrateEvent): Promise<string> { | ||
const blockId = blockNumber(event) | ||
let cachedBlock = controllersByStash[blockId] | ||
|
||
if (cachedBlock !== undefined) { | ||
return cachedBlock[accountAddress] | ||
} else { | ||
controllersByStash = {} | ||
|
||
let method = event.event.method | ||
let section = event.event.section | ||
|
||
const allAccountsInBlock = event.block.events | ||
.filter(blockEvent => { | ||
return blockEvent.event.method == method && blockEvent.event.section == section | ||
}) | ||
.map(event => { | ||
let {event: {data: [accountId, ]}} = event | ||
return accountId | ||
}); | ||
|
||
var controllerNeedAccounts: AccountId[] = [] | ||
|
||
for (let accountId of allAccountsInBlock) { | ||
const rewardDestination = await cachedRewardDestination(accountId.toString(), event) | ||
|
||
if (rewardDestination.isController) { | ||
controllerNeedAccounts.push(accountId as AccountId) | ||
} | ||
} | ||
|
||
// looks like accountAddress not related to events so just try to query controller directly | ||
if (controllerNeedAccounts.length === 0) { | ||
controllersByStash[blockId] = {} | ||
let accountId = await api.query.staking.bonded(accountAddress) | ||
return accountId.toString() | ||
} | ||
|
||
// TODO: Commented code doesn't work now, may be fixed later | ||
// const bonded = await api.query.staking.bonded.multi(controllerNeedAccounts); | ||
const bonded = await api.queryMulti(controllerNeedAccounts.map(account => ([api.query.staking.bonded, account]))); | ||
const controllers = bonded.map(bonded => { return bonded.toString() }); | ||
|
||
let bondedByAddress: {[address: string]: string} = {} | ||
|
||
// something went wrong, so just query for single accountAddress | ||
if (controllers.length !== controllerNeedAccounts.length) { | ||
const controller = await api.query.staking.bonded(accountAddress) | ||
let controllerAddress = controller.toString() | ||
bondedByAddress[accountAddress] = controllerAddress | ||
controllersByStash[blockId] = bondedByAddress | ||
return controllerAddress | ||
} | ||
controllerNeedAccounts.forEach((account, index) => { | ||
let accountAddress = account.toString() | ||
bondedByAddress[accountAddress] = controllers[index] | ||
}) | ||
controllersByStash[blockId] = bondedByAddress | ||
return bondedByAddress[accountAddress] | ||
} | ||
} |
Oops, something went wrong.