Skip to content

Commit

Permalink
Add additional event handlers for bounties. (#61)
Browse files Browse the repository at this point in the history
* Handle additional bounty events

* Add handling for bounty awarded

* Add handling for became active

* Fix package

* Add remark and description for bounties.

* Fix unit tests.

* Fix storageFetcher emitting Claimed event before payout has occured

* Fix storageFetcher logic.

* Fix unit tests and use derive description.

* Ignore unused bounty extrinsics and events.

Co-authored-by: Raymond Zhong <raykyri@gmail.com>
  • Loading branch information
jnaviask and raykyri authored May 24, 2021
1 parent 6fe3063 commit ca9097d
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 53 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ yarn-error.log
coverage/
.env
dist/
*.tgz
*.tgz

.yalc/
yalc.lock
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ Please submit any enhancements or bug fixes as a Pull Request on the [project's

## Development

```
npm install -g npm-install-peers
```

For using a local version of Chain Events in other projects, we recommend you use `yalc`, which functions as a local package repository for your `npm` libraries in development.

To install `yalc`, run:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"prepare": "npx install-peers",
"unit-test": "nyc ts-mocha --config ./.mocharc.json ./test/unit/**/*.spec.ts",
"marlin-test": "nyc ts-mocha --config ./.mocharc.json ./test/integration/marlin.spec.ts",
"integration-test": "nyc ts-mocha --config ./.mocharc.json ./test/integration/*.spec.ts",
"test": "nyc ts-mocha --config ./.mocharc.json ./test/integration/*.spec.ts ./test/unit/**/*.spec.ts",
"prepare": "install-peers",
"lint": "eslint src/ test/",
"listen": "ts-node -T ./scripts/listener.ts",
"listen-archival": "ts-node -T ./scripts/listener.ts -n edgeware-local -a true",
Expand Down
30 changes: 20 additions & 10 deletions src/substrate/filters/enricher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ import {
u64,
Compact,
StorageKey,
Bytes,
} from '@polkadot/types';
import { Codec, AnyTuple } from '@polkadot/types/types';
import { hexToString } from '@polkadot/util';
import { filter } from 'lodash';
import {
Kind,
Expand Down Expand Up @@ -686,6 +688,9 @@ export async function Enrich(
if (!bounty) {
throw new Error(`could not fetch bounty`);
}
const description = await api.query.bounties.bountyDescriptions(
bountyIndex
);
return {
data: {
kind,
Expand All @@ -695,6 +700,9 @@ export async function Enrich(
fee: bounty.bounty.fee.toString(),
curatorDeposit: bounty.bounty.curatorDeposit.toString(),
bond: bounty.bounty.bond.toString(),
description: description?.isSome
? hexToString(description.unwrap().toString())
: undefined,
},
};
}
Expand Down Expand Up @@ -729,16 +737,6 @@ export async function Enrich(
};
}

case EventKind.TreasuryBountyExtended: {
const [bountyIndex] = (event.data as unknown) as [BountyIndex] & Codec;
return {
data: {
kind,
bountyIndex: +bountyIndex,
},
};
}

case EventKind.TreasuryBountyClaimed: {
const [bountyIndex, payout, beneficiary] = (event.data as unknown) as [
BountyIndex,
Expand Down Expand Up @@ -1177,6 +1175,18 @@ export async function Enrich(
},
};
}

case EventKind.TreasuryBountyExtended: {
const [idx, remark] = extrinsic.args as [BountyIndex, Bytes];
return {
data: {
kind,
bountyIndex: +idx,
remark: hexToString(remark.toString()),
},
};
}

default: {
throw new Error(`unknown event type: ${kind}`);
}
Expand Down
4 changes: 2 additions & 2 deletions src/substrate/filters/type_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,10 @@ export function ParseType(
return EventKind.TreasuryBountyClaimed;
case 'BountyCanceled':
return EventKind.TreasuryBountyCanceled;
case 'BountyExtended':
case 'extendBountyExpiry':
return EventKind.TreasuryBountyExtended;
default:
throw new Error('invalid case');
return null;
}
}
default:
Expand Down
45 changes: 18 additions & 27 deletions src/substrate/storageFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from '@polkadot/types/interfaces';
import { Codec } from '@polkadot/types/types';
import { DeriveProposalImage } from '@polkadot/api-derive/types';
import { isFunction } from '@polkadot/util';
import { hexToString, isFunction } from '@polkadot/util';

import { CWEvent, IStorageFetcher } from '../interfaces';
import { factory, formatFilename } from '../logging';
Expand Down Expand Up @@ -350,7 +350,7 @@ export class StorageFetcher extends IStorageFetcher<ApiPromise> {
log.info('Migrating treasury bounties...');
const bounties = await this._api.derive.bounties.bounties();
const events = [];
bounties.forEach((b) => {
for (const b of bounties) {
events.push({
kind: EventKind.TreasuryBountyProposed,
bountyIndex: +b.index,
Expand All @@ -359,36 +359,27 @@ export class StorageFetcher extends IStorageFetcher<ApiPromise> {
fee: b.bounty.fee.toString(),
curatorDeposit: b.bounty.curatorDeposit.toString(),
bond: b.bounty.bond.toString(),
description: b.description,
} as ITreasuryBountyProposed);

if (
b.bounty.status.isProposed ||
b.bounty.status.isNone ||
b.bounty.status.isCuratorProposed
)
return; // Return here, not progressed

events.push({
kind: EventKind.TreasuryBountyBecameActive,
bountyIndex: +b.index,
} as ITreasuryBountyBecameActive);
if (b.bounty.status.isActive) return;
if (b.bounty.status.isPendingPayout) {
if (b.bounty.status.isActive || b.bounty.status.isPendingPayout) {
events.push({
kind: EventKind.TreasuryBountyAwarded,
kind: EventKind.TreasuryBountyBecameActive,
bountyIndex: +b.index,
value: b.bounty.value.toString(),
beneficiary: b.bounty.status.asPendingPayout.beneficiary.toString(),
} as ITreasuryBountyAwarded);
events.push({
kind: EventKind.TreasuryBountyClaimed,
bountyIndex: +b.index,
payout: b.bounty.value.toString(),
beneficiary: b.bounty.status.asPendingPayout.beneficiary.toString(),
} as ITreasuryBountyClaimed);
} as ITreasuryBountyBecameActive);

if (b.bounty.status.isPendingPayout) {
events.push({
kind: EventKind.TreasuryBountyAwarded,
bountyIndex: +b.index,
value: b.bounty.value.toString(),
beneficiary: b.bounty.status.asPendingPayout.beneficiary.toString(),
} as ITreasuryBountyAwarded);
}
}
// No other events can be extracted from a derivable bounty itself
});
// We don't belive any other events can be extracted from a
// derivable bounty itself, but we might be wrong
}

log.info(`Found ${bounties.length} bounties!`);
return events.map((data) => ({ blockNumber, data }));
Expand Down
4 changes: 3 additions & 1 deletion src/substrate/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ export interface ITreasuryBountyProposed extends IEvent {
fee: BalanceString;
curatorDeposit: BalanceString;
bond: BalanceString;
description?: string;
}

export interface ITreasuryBountyAwarded extends IEvent {
Expand Down Expand Up @@ -482,9 +483,10 @@ export interface ITreasuryBountyCanceled extends IEvent {
}

export interface ITreasuryBountyExtended extends IEvent {
// A bounty expiry is extended. [index]
// A bounty expiry is extended. [index, remark]
kind: EventKind.TreasuryBountyExtended;
bountyIndex: number;
remark: string;
}

/**
Expand Down
8 changes: 6 additions & 2 deletions test/unit/edgeware/enricher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
DeriveProposalImage,
DeriveBounties,
} from '@polkadot/api-derive/types';
import { Vec, bool, Data, TypeRegistry, Option } from '@polkadot/types';
import { Vec, bool, Data, TypeRegistry, Option, Bytes } from '@polkadot/types';
import { Codec, ITuple, TypeDef } from '@polkadot/types/types';
import { stringToHex } from '@polkadot/util';
import {
Expand Down Expand Up @@ -504,6 +504,8 @@ const api = constructFakeApi({
proposals: [],
},
] as unknown) as DeriveBounties,
bountyDescriptions: async () =>
constructOption((stringToHex('hello') as unknown) as Bytes),
voting: async (hash) =>
hash.toString() !== 'hash'
? constructOption()
Expand Down Expand Up @@ -1101,6 +1103,7 @@ describe('Edgeware Event Enricher Filter Tests', () => {
fee: '10',
proposer: 'alice',
value: '50',
description: 'hello',
},
});
});
Expand Down Expand Up @@ -1177,13 +1180,14 @@ describe('Edgeware Event Enricher Filter Tests', () => {

it('should enrich bounty-extended event', async () => {
const kind = EventKind.TreasuryBountyExtended;
const event = constructEvent(['1']);
const event = constructExtrinsic('alice', ['1', stringToHex('remark')]);
const result = await Enrich(api, blockNumber, kind, event);
assert.deepEqual(result, {
blockNumber,
data: {
kind,
bountyIndex: 1,
remark: 'remark',
},
});
});
Expand Down
12 changes: 3 additions & 9 deletions test/unit/edgeware/storageFetcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Votes,
Bounty,
} from '@polkadot/types/interfaces';
import { Vec, Data, TypeRegistry } from '@polkadot/types';
import { Vec, Data, TypeRegistry, Bytes } from '@polkadot/types';
import { Codec } from '@polkadot/types/types';
import { stringToHex } from '@polkadot/util';
import { DeriveReferendum } from '@polkadot/api-derive/democracy/types';
Expand Down Expand Up @@ -180,7 +180,7 @@ const api = constructFakeApi({
bond: 10,
status: 'Proposed',
},
description: 'test bounty description',
description: 'hello',
index: 0,
proposals: [{}],
} as unknown) as DeriveBounty,
Expand Down Expand Up @@ -479,15 +479,9 @@ describe('Edgeware Event Migration Tests', () => {
fee: '10',
curatorDeposit: '10',
bond: '10',
description: 'hello',
} as ITreasuryBountyProposed,
},
{
blockNumber,
data: {
kind: 'treasury-bounty-became-active',
bountyIndex: 0,
} as ITreasuryBountyBecameActive,
},
]);
});

Expand Down
1 change: 1 addition & 0 deletions test/unit/edgeware/testUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export function constructFakeApi(callOverrides: {
},
bounties: {
bountyCount: callOverrides['bountyCount'],
bountyDescriptions: callOverrides['bountyDescriptions'],
},
democracy: {
referendumInfoOf: callOverrides['referendumInfoOf'],
Expand Down

0 comments on commit ca9097d

Please sign in to comment.