|
@@ -10,7 +10,7 @@ import {
|
|
|
Channel,
|
|
|
Council,
|
|
|
Consul,
|
|
|
- ConsulStake,
|
|
|
+ Commitment,
|
|
|
Era,
|
|
|
Event,
|
|
|
Member,
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
// library
|
|
|
import {
|
|
|
getBlockHash,
|
|
|
+ getHead,
|
|
|
getTimestamp,
|
|
|
getEra,
|
|
|
getEraStake,
|
|
@@ -34,6 +35,8 @@ import {
|
|
|
getCouncilRound,
|
|
|
getCouncilElectionStatus,
|
|
|
getCouncilElectionDurations,
|
|
|
+ getCommitment,
|
|
|
+ getCommitments,
|
|
|
getProposalCount,
|
|
|
getProposal,
|
|
|
getProposalVotes,
|
|
@@ -61,7 +64,7 @@ import moment from 'moment'
|
|
|
import chalk from 'chalk'
|
|
|
|
|
|
// types
|
|
|
-import { AccountBalance, Round, ProposalDetail } from './lib/types'
|
|
|
+import { AccountBalance, Round, Vote, ProposalDetail } from './lib/types'
|
|
|
import {
|
|
|
AccountId,
|
|
|
BlockNumber,
|
|
@@ -72,7 +75,7 @@ import {
|
|
|
} from '@polkadot/types/interfaces'
|
|
|
import { HeaderExtended } from '@polkadot/api-derive/types'
|
|
|
//import { AccountInfo } from '@polkadot/types/interfaces/system'
|
|
|
-import { Seat } from '@joystream/types/council'
|
|
|
+import { SealedVote, Seat } from '@joystream/types/council'
|
|
|
import { MemberId, Membership } from '@joystream/types/members'
|
|
|
import {
|
|
|
ProposalId,
|
|
@@ -86,6 +89,7 @@ import {
|
|
|
MemberType,
|
|
|
CategoryType,
|
|
|
ChannelType,
|
|
|
+ CommitmentType,
|
|
|
PostType,
|
|
|
ThreadType,
|
|
|
CouncilType,
|
|
@@ -231,7 +235,7 @@ const updateStatus = async (
|
|
|
}
|
|
|
|
|
|
const fetchAll = async (api: ApiPromise, status: Status) => {
|
|
|
- getCouncils(api, status.block).then((rounds: Round[]) =>
|
|
|
+ await getCouncils(api, status.block).then((rounds: Round[]) =>
|
|
|
rounds.forEach((round) => fetchCouncil(api, round))
|
|
|
)
|
|
|
queue.push(() => fetchAccounts(api))
|
|
@@ -411,6 +415,7 @@ const createModeration = async (
|
|
|
const key = accountId.toHuman()
|
|
|
await Account.findOrCreate({ where: { key } })
|
|
|
const where = { ...association, moderatorKey: key }
|
|
|
+ return // TODO
|
|
|
const [moderation] = await Moderation.findOrCreate({ where })
|
|
|
if (moderation) object.setModeration(moderation.id)
|
|
|
}
|
|
@@ -454,50 +459,108 @@ const fetchThread = async (api: ApiPromise, id: number) => {
|
|
|
return thread
|
|
|
}
|
|
|
|
|
|
+// council
|
|
|
+interface Council {
|
|
|
+ round: number
|
|
|
+ start: number
|
|
|
+ startDate?: number
|
|
|
+ end: number
|
|
|
+ endDate?: number
|
|
|
+}
|
|
|
+
|
|
|
const fetchCouncil = async (api: ApiPromise, term: Round) => {
|
|
|
const { round, start, end } = term
|
|
|
const exists = await Council.findByPk(round)
|
|
|
- if (exists) return exists
|
|
|
+ //if (exists) return exists
|
|
|
processing = `council ${round}`
|
|
|
+ let council: Council = { start, end, round }
|
|
|
const startHash = await getBlockHash(api, start)
|
|
|
- const startDate = await getTimestamp(api, startHash)
|
|
|
+ council.startDate = await getTimestamp(api, startHash)
|
|
|
const seats: Seat[] = await getCouncil(api, startHash)
|
|
|
- let council: { [key: string]: number | string } = {
|
|
|
- start,
|
|
|
- end,
|
|
|
- round,
|
|
|
- startDate,
|
|
|
- }
|
|
|
- try {
|
|
|
+ const head = Number(await getHead(api))
|
|
|
+ if (end < head) {
|
|
|
const endHash = await getBlockHash(api, end)
|
|
|
if (endHash) council.endDate = await getTimestamp(api, endHash)
|
|
|
- } catch (e) {}
|
|
|
+ } else console.log(`fetchCouncil: round ${round} is ongoing.`)
|
|
|
+
|
|
|
// TODO import report generator and save tokenomics
|
|
|
- Council.create(council)
|
|
|
- .then(({ round }: any) =>
|
|
|
- seats.map(({ member, stake, backers }) =>
|
|
|
- fetchMemberByAccount(api, member).then(({ id }: any) =>
|
|
|
- Consul.create({
|
|
|
- stake: Number(stake),
|
|
|
- councilRound: round,
|
|
|
- memberId: id,
|
|
|
- }).then((consul: any) =>
|
|
|
- backers.map(async ({ member, stake }) =>
|
|
|
- fetchMemberByAccount(api, member).then(({ id }: any) =>
|
|
|
- ConsulStake.create({
|
|
|
- stake: Number(stake),
|
|
|
- consulId: consul.id,
|
|
|
- memberId: id,
|
|
|
- })
|
|
|
- )
|
|
|
- )
|
|
|
- )
|
|
|
+ saveCouncil(api, council, seats)
|
|
|
+ saveCommitments(api, round, start - 2)
|
|
|
+}
|
|
|
+
|
|
|
+const saveCommitments = async (
|
|
|
+ api: ApiPromise,
|
|
|
+ round: number,
|
|
|
+ block: number
|
|
|
+) => {
|
|
|
+ console.log(round, block)
|
|
|
+ const hash = await getBlockHash(api, block)
|
|
|
+ const commitments: Hash[] = await getCommitments(api, hash)
|
|
|
+ Promise.all(
|
|
|
+ commitments.map((voteHash: Hash) => getCommitment(api, hash, voteHash))
|
|
|
+ ).then((votes: SealedVote[]) =>
|
|
|
+ votes.map(async (v) => {
|
|
|
+ const voter: AccountId = v.voter
|
|
|
+ const stake = v.stake.new.toNumber()
|
|
|
+ const vote = String(v.vote)
|
|
|
+ const member = await fetchMemberByAccount(api, voter)
|
|
|
+ const memberId = member?.id
|
|
|
+ Commitment.findOrCreate({
|
|
|
+ where: { councilRound: round, stake, memberId },
|
|
|
+ }).then(([c]: [CommitmentType]) => vote && c.update({ vote }))
|
|
|
+ })
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const saveCouncil = async (
|
|
|
+ api: ApiPromise,
|
|
|
+ council: Council,
|
|
|
+ seats: Seat[]
|
|
|
+) => {
|
|
|
+ const { round } = council
|
|
|
+ //console.log(`council`, council)
|
|
|
+ Council.findOrCreate({ where: { round } })
|
|
|
+ .then(([council]: [CouncilType]) => {
|
|
|
+ council.update(council)
|
|
|
+ seats.map((seat) =>
|
|
|
+ fetchMemberByAccount(api, seat.member).then(
|
|
|
+ (member: MemberType | undefined) =>
|
|
|
+ member && saveConsul(api, round, member.id, seat)
|
|
|
)
|
|
|
)
|
|
|
- )
|
|
|
+ })
|
|
|
.catch((e: any) => console.error(`Failed to save council ${round}`, e))
|
|
|
}
|
|
|
|
|
|
+const saveConsul = async (
|
|
|
+ api: ApiPromise,
|
|
|
+ councilRound: number,
|
|
|
+ memberId: number,
|
|
|
+ seat?: Seat
|
|
|
+) =>
|
|
|
+ Consul.findOrCreate({ where: { councilRound, memberId } }).then(
|
|
|
+ ([consul]: any) => {
|
|
|
+ if (!seat) return
|
|
|
+ const stake = Number(seat.stake)
|
|
|
+ consul.update({ stake })
|
|
|
+ seat.backers.map(async ({ member, stake }) =>
|
|
|
+ fetchMemberByAccount(api, member).then(({ id }: any) =>
|
|
|
+ saveCommitment(Number(stake), consul.id, id)
|
|
|
+ )
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+const saveCommitment = async (
|
|
|
+ stake: number,
|
|
|
+ consulId: number,
|
|
|
+ memberId: number,
|
|
|
+ vote?: string
|
|
|
+) =>
|
|
|
+ Commitment.findOrCreate({ where: { stake, consulId, memberId } }).then(
|
|
|
+ ([c]: [CommitmentType]) => vote && c.update({ vote })
|
|
|
+ )
|
|
|
+
|
|
|
const fetchProposal = async (api: ApiPromise, id: number) => {
|
|
|
if (id <= 0) return
|
|
|
queue.push(() => fetchProposal(api, id - 1))
|