From 1518830bc2e46c8738bc963c7d0f9d148881b410 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 29 Oct 2019 18:36:11 +0400 Subject: [PATCH 01/38] init --- package-lock.json | 24 ++++++++---------------- plan.md | 4 ++++ src/mappings/DAOTracker/datasource.yaml | 9 +++++++++ src/mappings/DAOTracker/mapping.ts | 1 + src/mappings/DAOTracker/schema.graphql | 5 +++++ 5 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 plan.md create mode 100644 src/mappings/DAOTracker/datasource.yaml create mode 100644 src/mappings/DAOTracker/mapping.ts create mode 100644 src/mappings/DAOTracker/schema.graphql diff --git a/package-lock.json b/package-lock.json index 39724724..c107a5a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -281,7 +281,7 @@ "bs58": "^4.0.1", "buffer": "^5.4.2", "cids": "~0.7.1", - "concat-stream": "github:hugomrdias/concat-stream#feat/smaller", + "concat-stream": "github:hugomrdias/concat-stream#057bc7b5d6d8df26c8cf00a3f151b6721a0a8034", "debug": "^4.1.0", "detect-node": "^2.0.4", "end-of-stream": "^1.4.1", @@ -310,7 +310,7 @@ "multibase": "~0.6.0", "multicodec": "~0.5.1", "multihashes": "~0.4.14", - "ndjson": "github:hugomrdias/ndjson#feat/readable-stream3", + "ndjson": "github:hugomrdias/ndjson#4db16da6b42e5b39bf300c3a7cde62abb3fa3a11", "once": "^1.4.0", "peer-id": "~0.12.3", "peer-info": "~0.15.1", @@ -1217,8 +1217,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "string_decoder": { "version": "1.1.1", @@ -2263,8 +2262,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "optional": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "contains-path": { "version": "0.1.0", @@ -4650,8 +4648,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "optional": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -4677,7 +4674,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -10625,7 +10621,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -10639,8 +10634,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -10648,7 +10642,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, "requires": { "safe-buffer": "~5.1.0" }, @@ -10656,8 +10649,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -11665,7 +11657,7 @@ "requires": { "underscore": "1.8.3", "web3-core-helpers": "1.0.0-beta.37", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" + "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" } }, "web3-shh": { diff --git a/plan.md b/plan.md new file mode 100644 index 00000000..80235f2f --- /dev/null +++ b/plan.md @@ -0,0 +1,4 @@ +# New DAO Indexing +- DAOTracker (avatar, controller, token, reputation) +- - Blacklist +- - Ensure new schemes that aren't universal are added diff --git a/src/mappings/DAOTracker/datasource.yaml b/src/mappings/DAOTracker/datasource.yaml new file mode 100644 index 00000000..c6628fbb --- /dev/null +++ b/src/mappings/DAOTracker/datasource.yaml @@ -0,0 +1,9 @@ +entities: + - DAOTrackerContract +eventHandlers: + - event: TrackDAO(indexed address,address,address) + handler: handleTrackDAO + - event: BlacklistDAO(indexed address,string) + handler: handleBlacklistDAO + - event: ResetDAO(indexed address,string) + handler: handleResetDAO(indexed address,string) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts new file mode 100644 index 00000000..337f84e7 --- /dev/null +++ b/src/mappings/DAOTracker/mapping.ts @@ -0,0 +1 @@ +TODO: handle events + create entity \ No newline at end of file diff --git a/src/mappings/DAOTracker/schema.graphql b/src/mappings/DAOTracker/schema.graphql new file mode 100644 index 00000000..0110c20f --- /dev/null +++ b/src/mappings/DAOTracker/schema.graphql @@ -0,0 +1,5 @@ +type DAOTrackerContract @entity { + id: ID! + address: Bytes! + owner: Bytes! +} From 4324736e1c2d2c06621a49632c777eba2790a74b Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 19:05:12 +0400 Subject: [PATCH 02/38] testing next --- README.md | 7 +- ops/generate-subgraph.js | 48 +++++++--- ops/mappings.json | 21 +++++ src/mappings/DAOTracker/datasource.yaml | 13 ++- src/mappings/DAOTracker/mapping.ts | 117 +++++++++++++++++++++++- src/mappings/DAOTracker/schema.graphql | 16 ++++ 6 files changed, 204 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3eab61b8..a59a736d 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,12 @@ In order to add support for a new contract follow these steps: list of entities that are written by the the mapping. 3. [`eventHandlers`](https://github.com/graphprotocol/graph-node/blob/master/docs/subgraph-manifest.md#1522-eventhandler) - map of solidity event signatures to event handlers in mapping code. - 4. [`templates`]([https://](https://github.com/graphprotocol/graph-node/blob/master/docs/subgraph-manifest.md#17-dynamicdatasource)) - list of datasource mappings that are created by the mapping. + 4. [`templates`]([https://](https://github.com/graphprotocol/graph-node/blob/master/docs/subgraph-manifest.md#17-dynamicdatasource)) - list of datasource mappings that are created by the mapping. Each template entry refers to a mapping name, and a version to be used with that mapping. Example: + ```yaml + templates: + - mapping: Avatar + version: 0.0.1-rc.31 + ``` 4. `test/integration/.spec.ts` 3. Add your contract to `ops/mappings.json`. Under the JSON object for the network your contract is located at, under the `"mappings"` JSON array, add the following. diff --git a/ops/generate-subgraph.js b/ops/generate-subgraph.js index 08a50451..fd255689 100644 --- a/ops/generate-subgraph.js +++ b/ops/generate-subgraph.js @@ -16,6 +16,7 @@ async function generateSubgraph(opts={}) { opts.subgraphLocation = opts.subgraphLocation || defaultSubgraphLocation; const addresses = JSON.parse(fs.readFileSync(migrationFile, "utf-8")); const missingAddresses = {}; + const templateDefinitions = {}; // Filter out 0.0.1-rc.18 & 0.0.1-rc.17 const latestMappings = mappings.filter(mapping => @@ -25,7 +26,7 @@ async function generateSubgraph(opts={}) { // Build our subgraph's datasources from the mapping fragments const dataSources = combineFragments( - latestMappings, false, addresses, missingAddresses + latestMappings, false, addresses, missingAddresses, templateDefinitions ).filter(el => el != null); // Throw an error if there are contracts that're missing an address @@ -41,7 +42,8 @@ async function generateSubgraph(opts={}) { const subgraph = { specVersion: "0.0.1", schema: { file: "./schema.graphql" }, - dataSources + dataSources, + templates: Object.values(templateDefinitions) }; fs.writeFileSync( @@ -51,10 +53,11 @@ async function generateSubgraph(opts={}) { ); } -function combineFragments(fragments, isTemplate, addresses, missingAddresses) { +function combineFragments(fragments, isTemplate, addresses, missingAddresses, templateDefinitions) { let ids = []; return fragments.map(mapping => { const contract = mapping.name; + const version = mapping.arcVersion; const fragment = `${__dirname}/../src/mappings/${mapping.mapping}/datasource.yaml`; var abis, entities, eventHandlers, templates, file, yamlLoad, abi; @@ -65,7 +68,6 @@ function combineFragments(fragments, isTemplate, addresses, missingAddresses) { entities = yamlLoad.entities; templates = yamlLoad.templates; abis = (yamlLoad.abis || [contract]).map(contractName => { - const version = mapping.arcVersion; const strlen = version.length const versionNum = Number(version.slice(strlen - 2, strlen)); @@ -95,9 +97,9 @@ function combineFragments(fragments, isTemplate, addresses, missingAddresses) { if (mapping.dao === 'address') { contractAddress = mapping.address; } else if (mapping.dao === 'organs') { - contractAddress = addresses[network].test[mapping.arcVersion][mapping.dao][mapping.contractName]; + contractAddress = addresses[network].test[version][mapping.dao][mapping.contractName]; } else { - contractAddress = addresses[network][mapping.dao][mapping.arcVersion][mapping.contractName]; + contractAddress = addresses[network][mapping.dao][version][mapping.contractName]; } // If the contract isn't predeployed @@ -105,7 +107,7 @@ function combineFragments(fragments, isTemplate, addresses, missingAddresses) { // Keep track of contracts that're missing addresses. // These contracts should have addresses because they're not // templated contracts aren't used as templates - const daoContract = `${network}-${mapping.arcVersion}-${mapping.contractName}-${mapping.dao}`; + const daoContract = `${network}-${version}-${mapping.contractName}-${mapping.dao}`; if (missingAddresses[daoContract] === undefined) { missingAddresses[daoContract] = true; } @@ -130,6 +132,12 @@ function combineFragments(fragments, isTemplate, addresses, missingAddresses) { return; } + if (isTemplate) { + // convert name to be version specific + const classVersion = version.replace(/\.|-/g, '_'); + name = `${name}_${classVersion}` + } + var result = { kind: 'ethereum/contract', name: `${name}`, @@ -146,15 +154,25 @@ function combineFragments(fragments, isTemplate, addresses, missingAddresses) { } }; + // If this datasource is requesting templates, + // build their definition if we haven't already if (templates && templates.length) { - result.templates = combineFragments( - templates.map(template => ({ - name: template, - mapping: template, - arcVersion: mapping.arcVersion - })), - true, addresses, missingAddresses - ); + templates.forEach((template) => { + const { mapping, version } = template; + const name = `${mapping}${version}` + + // If we haven't processed it already + if (templateDefinitions[name] === undefined) { + // Avoid infinite recursion + templateDefinitions[name] = {}; + // Reuse this logic with the template requested + templateDefinitions[name] = combineFragments([{ + name: mapping, + mapping: mapping, + arcVersion: version + }], true, addresses, missingAddresses)[0]; + } + }); } return result; diff --git a/ops/mappings.json b/ops/mappings.json index ff4c4383..eae7dc2e 100644 --- a/ops/mappings.json +++ b/ops/mappings.json @@ -610,6 +610,13 @@ "dao": "base", "mapping": "Redeemer", "arcVersion": "0.0.1-rc.31" + }, + { + "name": "DAOTracker", + "contractName": "DAOTracker", + "dao": "base", + "mapping": "DAOTracker", + "arcVersion": "0.0.1-rc.29" } ] }, @@ -824,6 +831,13 @@ "dao": "base", "mapping": "GenesisProtocol", "arcVersion": "0.0.1-rc.24" + }, + { + "name": "DAOTracker", + "contractName": "DAOTracker", + "dao": "base", + "mapping": "DAOTracker", + "arcVersion": "0.0.1-rc.29" } ] }, @@ -927,6 +941,13 @@ "dao": "base", "mapping": "UGenericScheme", "arcVersion": "0.0.1-rc.27" + }, + { + "name": "DAOTracker", + "contractName": "DAOTracker", + "dao": "base", + "mapping": "DAOTracker", + "arcVersion": "0.0.1-rc.29" } ] } diff --git a/src/mappings/DAOTracker/datasource.yaml b/src/mappings/DAOTracker/datasource.yaml index c6628fbb..7370d4f3 100644 --- a/src/mappings/DAOTracker/datasource.yaml +++ b/src/mappings/DAOTracker/datasource.yaml @@ -1,7 +1,18 @@ +abis: + - DAOTracker entities: - DAOTrackerContract +templates: + - mapping: Avatar + version: 0.0.1-rc.31 + - mapping: Controller + version: 0.0.1-rc.31 + - mapping: DAOToken + version: 0.0.1-rc.31 + - mapping: Reputation + version: 0.0.1-rc.31 eventHandlers: - - event: TrackDAO(indexed address,address,address) + - event: TrackDAO(indexed address,address,address,address) handler: handleTrackDAO - event: BlacklistDAO(indexed address,string) handler: handleBlacklistDAO diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 337f84e7..74f06335 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -1 +1,116 @@ -TODO: handle events + create entity \ No newline at end of file +import { Address, store, ipfs } from '@graphprotocol/graph-ts' +import { + DAOTracker, + TrackDAO, + BlacklistDAO, + ResetDAO +} from '../../types/DAOTracker/DAOTracker'; +import { + Avatar_0_0_1_rc_31, + Controller_0_0_1_rc_31, + DAOToken_0_0_1_rc_31, + Reputation_0_0_1_rc_31 +} from '../../types/templates'; +import { + DAOTrackerContract, + BlacklistedDAO, + ResetDAO as ResetDAOEntity +} from '../../types/schema'; +import { equalStrings } from '../../utils'; + +export function getDAOTrackerContract(address: Address): DAOTrackerContract { + let daoTracker = DAOTrackerContract.load(address.toHex()); + if (daoTracker == null) { + daoTracker = new DAOTrackerContract(address.toHex()); + daoTracker.address = address; + let daoTrackerSC = DAOTracker.bind(address); + daoTracker.owner = daoTrackerSC.owner(); + store.set('DAOTrackerContract', daoTracker.id, daoTracker); + } + return daoTracker; +} + +export function handleTrackDAO(event: TrackDAO): void { + // Ensure the DAOTrackerContract has been added to the store + getDAOTrackerContract(event.address); + + const { _avatar, _controller, _reputation, _daoToken } = event.params; + + /* TODO: uncomment when this issue is resolved https://github.com/graphprotocol/graph-node/issues/1333 + // If the avatar hasn't been blacklisted + const daoTrackerSC = DAOTracker.bind(event.address); + if (daoTrackerSC.blacklisted(_avatar), "latest") { + return; + } + */ + + // If the avatar already exists, early out + if (store.get("AvatarContract", _avatar.toHex()) != null) { + return; + } + + // Tell the subgraph to start indexing events from the: + // Avatar, Controller, DAOToken, and Reputation contracts + Avatar_0_0_1_rc_31.create(_avatar); + Reputation_0_0_1_rc_31.create(_reputation); + DAOToken_0_0_1_rc_31.create(_daoToken); + + // Track the Controller if it isn't a UController we're already tracking + if (store.get("UControllerOrganization", _controller.toHex()) == null) { + Controller_0_0_1_rc_31.create(_controller); + } + + // Note, no additional work is needed here because... + // * AvatarContract is added to the store by the 'OwnershipTransfered' event + // * ControllerOrganization is added to the store by the 'RegisterScheme' event + // * ReputationContract is added to the store by the 'RegisterScheme' event + // * TokenContract is added to the store by the 'RegisterScheme' event +} + +export function handleBlacklistDAO(event: BlacklistDAO): void { + // Ensure the DAOTrackerContract has been added to the store + const daoTracker = getDAOTrackerContract(event.address); + + const { _avatar, _explanationHash } = event.params; + + // Add the BlacklistedDAO to the store + const blacklistedDAO = new BlacklistedDAO(_avatar.toHex()); + blacklistedDAO.address = _avatar; + blacklistedDAO.tracker = daoTracker.id; + blacklistedDAO.explanationHash = _explanationHash; + + if (!equalStrings(_explanationHash, '')) { + const explanation = ipfs.cat('/ipfs/' + _explanationHash); + + if (explanation != null) { + blacklistedDAO.explanation = explanation.toString(); + } + } + + store.set("BlacklistedDAO", blacklistedDAO.id, blacklistedDAO); +} + +export function handleResetDAO(event: ResetDAO): void { + // Ensure the DAOTrackerContract has been added to the store + getDAOTrackerContract(event.address); + + const { _avatar, _explanationHash } = event.params; + + // Remove the BlacklistedDAO from the store + store.remove("BlacklistedDAO", _avatar.toHex()); + + // Add the ResetDAO entity to the store + const resetDAO = new ResetDAOEntity(_avatar.toHex()); + resetDAO.address = _avatar; + resetDAO.explanationHash = _explanationHash; + + if (!equalStrings(_explanationHash, '')) { + const explanation = ipfs.cat('/ipfs/' + _explanationHash); + + if (explanation != null) { + resetDAO.explanation = explanation.toString(); + } + } + + store.set("ResetDAO", resetDAO.id, resetDAO); +} diff --git a/src/mappings/DAOTracker/schema.graphql b/src/mappings/DAOTracker/schema.graphql index 0110c20f..39a9301a 100644 --- a/src/mappings/DAOTracker/schema.graphql +++ b/src/mappings/DAOTracker/schema.graphql @@ -2,4 +2,20 @@ type DAOTrackerContract @entity { id: ID! address: Bytes! owner: Bytes! + blacklisted: [BlacklistedDAO!] @derivedFrom(field: "tracker") +} + +type BlacklistedDAO @entity { + id: ID! + address: Bytes! + tracker: DAOTrackerContract! + explanationHash: String! + explanation: String +} + +type ResetDAO @entity { + id: ID! + address: Bytes! + explanationHash: String! + explanation: String } From 3ab8fbeecd0f3ca928b0893ee0bd59d8ab70943a Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 21:21:51 +0400 Subject: [PATCH 03/38] tests --- src/mappings/DAOTracker/mapping.ts | 24 ++- src/mappings/Reputation/datasource.yaml | 2 + src/mappings/Reputation/mapping.ts | 5 + test/0.0.1-rc.29/DAOTracker.spec.ts | 209 ++++++++++++++++++++++++ test/0.0.1-rc.29/util.ts | 170 +++++++++++++++++++ 5 files changed, 401 insertions(+), 9 deletions(-) create mode 100644 test/0.0.1-rc.29/DAOTracker.spec.ts create mode 100644 test/0.0.1-rc.29/util.ts diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 74f06335..5e23dbb3 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -39,13 +39,13 @@ export function handleTrackDAO(event: TrackDAO): void { /* TODO: uncomment when this issue is resolved https://github.com/graphprotocol/graph-node/issues/1333 // If the avatar hasn't been blacklisted const daoTrackerSC = DAOTracker.bind(event.address); - if (daoTrackerSC.blacklisted(_avatar), "latest") { + if (daoTrackerSC.blacklisted(_avatar), 'latest') { return; } */ // If the avatar already exists, early out - if (store.get("AvatarContract", _avatar.toHex()) != null) { + if (store.get('AvatarContract', _avatar.toHex()) != null) { return; } @@ -56,15 +56,14 @@ export function handleTrackDAO(event: TrackDAO): void { DAOToken_0_0_1_rc_31.create(_daoToken); // Track the Controller if it isn't a UController we're already tracking - if (store.get("UControllerOrganization", _controller.toHex()) == null) { + if (store.get('UControllerOrganization', _controller.toHex()) == null) { Controller_0_0_1_rc_31.create(_controller); } // Note, no additional work is needed here because... - // * AvatarContract is added to the store by the 'OwnershipTransfered' event // * ControllerOrganization is added to the store by the 'RegisterScheme' event - // * ReputationContract is added to the store by the 'RegisterScheme' event - // * TokenContract is added to the store by the 'RegisterScheme' event + // * AvatarContract, ReputationContract, and TokenContract are added to the store + // by the 'RegisterScheme' or 'OwnershipTransfered' events } export function handleBlacklistDAO(event: BlacklistDAO): void { @@ -87,7 +86,12 @@ export function handleBlacklistDAO(event: BlacklistDAO): void { } } - store.set("BlacklistedDAO", blacklistedDAO.id, blacklistedDAO); + store.set('BlacklistedDAO', blacklistedDAO.id, blacklistedDAO); + + // If the DAO has been previously reset, remove that entity from the store + if (store.get('ResetDAO', _avatar.toHex())) { + store.remove('ResetDAO', _avatar.toHex()); + } } export function handleResetDAO(event: ResetDAO): void { @@ -97,7 +101,9 @@ export function handleResetDAO(event: ResetDAO): void { const { _avatar, _explanationHash } = event.params; // Remove the BlacklistedDAO from the store - store.remove("BlacklistedDAO", _avatar.toHex()); + if (store.get('BlacklistedDAO', _avatar.toHex())) { + store.remove('BlacklistedDAO', _avatar.toHex()); + } // Add the ResetDAO entity to the store const resetDAO = new ResetDAOEntity(_avatar.toHex()); @@ -112,5 +118,5 @@ export function handleResetDAO(event: ResetDAO): void { } } - store.set("ResetDAO", resetDAO.id, resetDAO); + store.set('ResetDAO', resetDAO.id, resetDAO); } diff --git a/src/mappings/Reputation/datasource.yaml b/src/mappings/Reputation/datasource.yaml index d0a31df7..9fccb5b7 100644 --- a/src/mappings/Reputation/datasource.yaml +++ b/src/mappings/Reputation/datasource.yaml @@ -10,3 +10,5 @@ eventHandlers: handler: handleMint - event: Burn(indexed address,uint256) handler: handleBurn + - event: OwnershipTransferred(indexed address,indexed address) + handler: handleOwnershipTransferred diff --git a/src/mappings/Reputation/mapping.ts b/src/mappings/Reputation/mapping.ts index 2c5fe54c..687e9584 100644 --- a/src/mappings/Reputation/mapping.ts +++ b/src/mappings/Reputation/mapping.ts @@ -4,6 +4,7 @@ import { Address, BigInt, crypto, store } from '@graphprotocol/graph-ts'; import { Burn, Mint, + OwnershipTransferred, Reputation, } from '../../types/Reputation/Reputation'; import { concat, eventId } from '../../utils'; @@ -90,3 +91,7 @@ export function handleBurn(event: Burn): void { store.set('ReputationBurn', ent.id, ent); } + +export function handleOwnershipTransferred(event: OwnershipTransferred): void { + update(event.address, event.params.newOwner as Address, event.block.timestamp); +} diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts new file mode 100644 index 00000000..26d1fb11 --- /dev/null +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -0,0 +1,209 @@ +import { getContractAddresses, getOptions, getWeb3, sendQuery } from './util'; + +const DAOTracker = require('@daostack/arc/build/contracts/DAOTracker.json'); +const Avatar = require('@daostack/arc/build/contracts/Avatar.json'); +const Controller = require('@daostack/arc/build/contracts/Controller.json'); +const UController = require('@daostack/ar/build/contracts/UController.json'); +const DAOToken = require('@daostack/arc/contracts/build/DAOToken.json'); +const Reputation = require('@daostack/arc/contracts/build/Reputation.json'); +const ContributionReward = require('@daostack/arc/contracts/build/ContributionReward.json'); +const AbsoluteVote = require('@daostack/arc/contracts/build/AbsoluteVote.json'); + +describe('DAOTracker', () => { + let web3; + let addresses; + let opts; + let daoTracker; + let uController; + let contributionReward; + let absVote; + let vmParamsHash; + let schemeParamsHash; + + beforeAll(async () => { + web3 = await getWeb3(); + addresses = getContractAddresses(); + opts = await getOptions(web3); + daoTracker = new web3.eth.Contract(DAOTracker.abi, addresses.DAOTracker, opts); + uController = new web3.eth.Contract(UController.abi, addresses.UController, opts); + contributionReward = new web3.eth.Contract(ContributionReward.abi, addresses.ContributionReward, opts); + absVote = new web3.eth.Contract(AbsoluteVote.abi, undefined, opts) + .deploy({ data: AbsoluteVote.bytecode, arguments: [] }) + .send(); + + const vmSetParams = absVote.methods.setParameters(20, '0x0000000000000000000000000000000000000000'); + vmParamsHash = await vmSetParams.call(); + await vmSetParams.send(); + + const schemeSetParams = contributionReward.methods.setParameters(vmParamsHash, absVote.options.address); + schemeParamsHash = schemeSetParams.call(); + schemeSetParams.send(); + }); + + const e2eControllerTest = async (uController: boolean) => { + // Start deploying a new DAO + const nativeToken = await new web3.eth.Contract(DAOToken.abi, undefined, opts) + .deploy({ data: DAOToken.bytecode, arguments: [ 'Test Token', 'TST', '10000000000' ] }) + .send(); + + const reputation = await new web3.eth.Contract(Reputation.abi, undefined, opts) + .deploy({ data: Reputation.bytecode, arguments: [] }) + .send(); + + const avatar = await new web3.eth.Contract(Avatar.abi, undefined, opts) + .deploy({ data: Avatar.bytecode, arguments: [ 'Test DAO', nativeToken.options.address, reputation.options.address ] }) + .send(); + + let controller; + + if (!uController) { + controller = await new web3.eth.Contracts(Controller.abi, undefined, opts) + .deploy({ data: Controller.bytecode, arguments: [ avatar.options.address ] }); + } else { + controller = uController; + } + + // Add the new DAO to the DAOTracker + await daoTracker.methods.track(avatar.options.address, controller.options.address) + .send(); + + // Finish setting up the new DAO + await reputation.methods.transferOwnership(controller.options.address).send(); + await nativeToken.methods.transferOwnership(controller.options.address).send(); + await avatar.methods.transferOwnership(controller.options.address).send(); + + // Ensure the new DAO is in the subgraph + const { dao } = await sendQuery(`{ + dao(id: "${avatar.options.address}") { + id + name + nativeToken { + id + dao { + id + } + } + nativeReputation { + id + dao { + id + } + } + reputationHoldersCount + } + }`, 5000); + + expect(dao).toMatchObject({ + id: avatar.options.address, + name: 'Test DAO', + nativeToken: { + id: nativeToken.options.address, + dao: { + id: avatar.options.address + } + }, + nativeReputation: { + id: reputation.options.address, + dao: { + id: avatar.options.address + } + }, + reputationHoldersCount: '0' + }); + + // Add a scheme + await controller.methods.registerScheme( + contributionReward.options.address, + schemeParamsHash, + '0x0000001F', + avatar.options.address + ).send(); + + // Ensure the scheme is in the subgraph + const { controllerSchemes } = await sendQuery(`{ + controllerSchemes { + dao { + id + } + address + } + }`, 5000); + + expect(controllerSchemes).toContainEqual({ + dao: { + id: avatar.options.address + }, + address: contributionReward.options.address + }); + + return { + avatar + } + } + + it('Controller e2e', async () => { + await e2eControllerTest(false); + }); + + it('UController e2e', async () => { + await e2eControllerTest(true); + }); + + it('Blacklist & Reset DAO', async () => { + const { avatar } = await e2eControllerTest(false); + + // Blacklist the deployed DAO + await daoTracker.methods.blacklist(avatar.options.address, '').send(); + + // Ensure the blacklisted DAO is in the subgraph + { + const { blacklistedDAO } = await sendQuery(`{ + blacklistedDAO(id: "${avatar.options.address}") { + id + address + tracker + explanationHash + } + }`, 5000); + + expect(blacklistedDAO).toMatchObject({ + id: avatar.options.address, + address: avatar.options.address, + tracker: daoTracker.options.address, + explanationHash: '' + }); + } + + // Reset the DAO + await daoTracker.methods.reset(avatar.options.address, '').send(); + + // Ensure the blacklisted DAO is no longer in the subgraph + { + const { blacklistedDAO } = await sendQuery(`{ + blacklistedDAO(id: "${avatar.options.address}") { + id + address + tracker + explanationHash + } + }`, 5000); + + expect(blacklistedDAO).toBeFalsy(); + } + + // Ensure the reset DAO is in the subgraph + const { resetDAO } = await sendQuery(`{ + resetDAO(id: "${avatar.options.address}') { + id + address + explanationHash + } + }`); + + expect(resetDAO).toMatchObject({ + id: avatar.options.address, + address: avatar.options.address, + explanationHash: '' + }); + }); +}); diff --git a/test/0.0.1-rc.29/util.ts b/test/0.0.1-rc.29/util.ts new file mode 100644 index 00000000..80c14efa --- /dev/null +++ b/test/0.0.1-rc.29/util.ts @@ -0,0 +1,170 @@ +require('dotenv').config(); +const IPFSClient = require('ipfs-http-client'); + +process.env = { + ethereum: 'http://127.0.0.1:8545', + ipfs: '/ip4/127.0.0.1/tcp/5001', + node_http: 'http://127.0.0.1:8000/subgraphs/name/daostack', + node_ws: 'http://127.0.0.1:8001/subgraphs/name/daostack', + test_mnemonic: + 'myth like bonus scare over problem client lizard pioneer submit female collect', + ...process.env, +}; + +const { execute } = require('apollo-link'); +const { WebSocketLink } = require('apollo-link-ws'); +const { SubscriptionClient } = require('subscriptions-transport-ws'); +const ws = require('ws'); +import axios from 'axios'; +import * as HDWallet from 'hdwallet-accounts'; +const Web3 = require('web3'); + +const { node_ws, node_http, ethereum, ipfs, test_mnemonic } = process.env; + +export async function sendQuery(q: string, maxDelay = 1000, url = node_http) { + await new Promise((res, rej) => setTimeout(res, maxDelay)); + const { + data: { data }, + } = await axios.post(url, { + query: q, + }); + + return data; +} + +export const addressLength = 40; +export const hashLength = 64; +export const nullAddress = '0x0000000000000000000000000000000000000000'; +export const nullParamsHash = '0x' + padZeros('', 64); + +export async function getWeb3() { + const web3 = new Web3(ethereum); + const hdwallet = HDWallet(10, test_mnemonic); + Array(10) + .fill(10) + .map((_, i) => i) + .forEach((i) => { + const pk = hdwallet.accounts[i].privateKey; + const account = web3.eth.accounts.privateKeyToAccount(pk); + web3.eth.accounts.wallet.add(account); + }); + web3.eth.defaultAccount = web3.eth.accounts.wallet[0].address; + return web3; +} + +export function getContractAddresses() { + const addresses = require(`@daostack/migration/migration.json`); + let arcVersion = '0.0.1-rc.29'; + return { + ...addresses.private.test[arcVersion], + ...addresses.private.dao[arcVersion], + ...addresses.private.base[arcVersion], + ...addresses.private.test[arcVersion].organs, + TestAvatar: addresses.private.test[arcVersion].Avatar, + NativeToken: addresses.private.dao[arcVersion].DAOToken, + NativeReputation: addresses.private.dao[arcVersion].Reputation, + }; +} + +export function getOrgName() { + return require(`@daostack/migration/migration.json`).private.dao['0.0.1-rc.29'].name; +} + +export async function getOptions(web3) { + const block = await web3.eth.getBlock('latest'); + return { + from: web3.eth.defaultAccount, + gas: block.gasLimit - 100000, + }; +} + +export async function writeProposalIPFS(data: any) { + const ipfsClient = IPFSClient(ipfs); + const ipfsResponse = await ipfsClient.add(new Buffer(JSON.stringify(data))); + + return ipfsResponse[0].path; +} + +export function padZeros(str: string, max = 36) { + str = str.toString(); + return str.length < max ? padZeros('0' + str, max) : str; +} + +export const createSubscriptionObservable = ( + query: string, + variables = 0, + wsurl = node_ws, +) => { + const client = new SubscriptionClient(wsurl, { reconnect: true }, ws); + const link = new WebSocketLink(client); + return execute(link, { query, variables }); +}; + +export async function waitUntilTrue(test: () => Promise | boolean) { + return new Promise((resolve, reject) => { + (async function waitForIt(): Promise { + if (await test()) { return resolve(); } + setTimeout(waitForIt, 30); + })(); + }); +} + +export async function waitUntilSynced() { + const getGraphsSynced = `{ + subgraphDeployments { + synced + } + }`; + const graphIsSynced = async () => { + let result = await sendQuery( + getGraphsSynced, + 1000, + 'http://127.0.0.1:8000/subgraphs'); + return ((result.subgraphDeployments.length > 0) && result.subgraphDeployments[0].synced); + }; + await waitUntilTrue(graphIsSynced); +} + +export const increaseTime = async function(duration, web3) { + const id = await Date.now(); + web3.providers.HttpProvider.prototype.sendAsync = web3.providers.HttpProvider.prototype.send; + + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync({ + jsonrpc: '2.0', + method: 'evm_increaseTime', + params: [duration], + id, + }, (err1) => { + if (err1) { return reject(err1); } + + web3.currentProvider.sendAsync({ + jsonrpc: '2.0', + method: 'evm_mine', + id: id + 1, + }, (err2, res) => { + return err2 ? reject(err2) : resolve(res); + }); + }); + }); +}; + +export function toFixed(x) { + if (Math.abs(x) < 1.0) { + // tslint:disable-next-line: radix + let e = parseInt(x.toString().split('e-')[1]); + if (e) { + x *= Math.pow(10, e - 1); + x = '0.' + (new Array(e)).join('0') + x.toString().substring(2); + } + } else { + // tslint:disable-next-line: radix + let e = parseInt(x.toString().split('+')[1]); + if (e > 20) { + e -= 20; + x /= Math.pow(10, e); + x += (new Array(e + 1)).join('0'); + } + } + return x; +} From 6f8a3cae19919555ead035c4e7fa0eb677b07c57 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 21:24:07 +0400 Subject: [PATCH 04/38] remove brainstorming doc --- plan.md | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 plan.md diff --git a/plan.md b/plan.md deleted file mode 100644 index 80235f2f..00000000 --- a/plan.md +++ /dev/null @@ -1,4 +0,0 @@ -# New DAO Indexing -- DAOTracker (avatar, controller, token, reputation) -- - Blacklist -- - Ensure new schemes that aren't universal are added From c1f285571838fc228b0d5022c9c9e87300352381 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 21:33:51 +0400 Subject: [PATCH 05/38] fix --- src/mappings/DAOTracker/mapping.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 5e23dbb3..70505905 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -34,11 +34,11 @@ export function handleTrackDAO(event: TrackDAO): void { // Ensure the DAOTrackerContract has been added to the store getDAOTrackerContract(event.address); - const { _avatar, _controller, _reputation, _daoToken } = event.params; + let { _avatar, _controller, _reputation, _daoToken } = event.params; /* TODO: uncomment when this issue is resolved https://github.com/graphprotocol/graph-node/issues/1333 // If the avatar hasn't been blacklisted - const daoTrackerSC = DAOTracker.bind(event.address); + let daoTrackerSC = DAOTracker.bind(event.address); if (daoTrackerSC.blacklisted(_avatar), 'latest') { return; } @@ -68,18 +68,18 @@ export function handleTrackDAO(event: TrackDAO): void { export function handleBlacklistDAO(event: BlacklistDAO): void { // Ensure the DAOTrackerContract has been added to the store - const daoTracker = getDAOTrackerContract(event.address); + let daoTracker = getDAOTrackerContract(event.address); - const { _avatar, _explanationHash } = event.params; + let { _avatar, _explanationHash } = event.params; // Add the BlacklistedDAO to the store - const blacklistedDAO = new BlacklistedDAO(_avatar.toHex()); + let blacklistedDAO = new BlacklistedDAO(_avatar.toHex()); blacklistedDAO.address = _avatar; blacklistedDAO.tracker = daoTracker.id; blacklistedDAO.explanationHash = _explanationHash; if (!equalStrings(_explanationHash, '')) { - const explanation = ipfs.cat('/ipfs/' + _explanationHash); + let explanation = ipfs.cat('/ipfs/' + _explanationHash); if (explanation != null) { blacklistedDAO.explanation = explanation.toString(); @@ -98,7 +98,7 @@ export function handleResetDAO(event: ResetDAO): void { // Ensure the DAOTrackerContract has been added to the store getDAOTrackerContract(event.address); - const { _avatar, _explanationHash } = event.params; + let { _avatar, _explanationHash } = event.params; // Remove the BlacklistedDAO from the store if (store.get('BlacklistedDAO', _avatar.toHex())) { @@ -106,12 +106,12 @@ export function handleResetDAO(event: ResetDAO): void { } // Add the ResetDAO entity to the store - const resetDAO = new ResetDAOEntity(_avatar.toHex()); + let resetDAO = new ResetDAOEntity(_avatar.toHex()); resetDAO.address = _avatar; resetDAO.explanationHash = _explanationHash; if (!equalStrings(_explanationHash, '')) { - const explanation = ipfs.cat('/ipfs/' + _explanationHash); + let explanation = ipfs.cat('/ipfs/' + _explanationHash); if (explanation != null) { resetDAO.explanation = explanation.toString(); From 07481362266765fc1b83f155136b5e632c080679 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 21:45:11 +0400 Subject: [PATCH 06/38] fix --- src/mappings/DAOTracker/mapping.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 70505905..3e5652e4 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -34,7 +34,10 @@ export function handleTrackDAO(event: TrackDAO): void { // Ensure the DAOTrackerContract has been added to the store getDAOTrackerContract(event.address); - let { _avatar, _controller, _reputation, _daoToken } = event.params; + let _avatar = event.params._avatar; + let _controller = event.params._controller; + let _reputation = event.params._reputation; + let _daoToken = event.params._daoToken; /* TODO: uncomment when this issue is resolved https://github.com/graphprotocol/graph-node/issues/1333 // If the avatar hasn't been blacklisted @@ -70,7 +73,8 @@ export function handleBlacklistDAO(event: BlacklistDAO): void { // Ensure the DAOTrackerContract has been added to the store let daoTracker = getDAOTrackerContract(event.address); - let { _avatar, _explanationHash } = event.params; + let _avatar = event.params._avatar; + let _explanationHash = event.params._explanationHash; // Add the BlacklistedDAO to the store let blacklistedDAO = new BlacklistedDAO(_avatar.toHex()); @@ -98,7 +102,8 @@ export function handleResetDAO(event: ResetDAO): void { // Ensure the DAOTrackerContract has been added to the store getDAOTrackerContract(event.address); - let { _avatar, _explanationHash } = event.params; + let _avatar = event.params._avatar; + let _explanationHash = event.params._explanationHash; // Remove the BlacklistedDAO from the store if (store.get('BlacklistedDAO', _avatar.toHex())) { From 26bb9e5d9cf59e4241f3c100abb204aa1f945789 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 21:53:57 +0400 Subject: [PATCH 07/38] fix --- src/mappings/DAOTracker/mapping.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 3e5652e4..c4a076d1 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -19,7 +19,7 @@ import { import { equalStrings } from '../../utils'; export function getDAOTrackerContract(address: Address): DAOTrackerContract { - let daoTracker = DAOTrackerContract.load(address.toHex()); + let daoTracker = DAOTrackerContract.load(address.toHex()) as DAOTrackerContract; if (daoTracker == null) { daoTracker = new DAOTrackerContract(address.toHex()); daoTracker.address = address; From 01c335bb5b312cbd702e69f8ebb505e1193d09fe Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 22:09:56 +0400 Subject: [PATCH 08/38] fixes --- src/mappings/DAOTracker/mapping.ts | 18 +++++++-------- test/0.0.1-rc.29/DAOTracker.spec.ts | 36 +++++++++++++++-------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index c4a076d1..5e357d43 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -1,21 +1,21 @@ -import { Address, store, ipfs } from '@graphprotocol/graph-ts' +import { Address, ipfs, store } from '@graphprotocol/graph-ts'; import { + BlacklistDAO, DAOTracker, + ResetDAO, TrackDAO, - BlacklistDAO, - ResetDAO } from '../../types/DAOTracker/DAOTracker'; +import { + BlacklistedDAO, + DAOTrackerContract, + ResetDAO as ResetDAOEntity, +} from '../../types/schema'; import { Avatar_0_0_1_rc_31, Controller_0_0_1_rc_31, DAOToken_0_0_1_rc_31, - Reputation_0_0_1_rc_31 + Reputation_0_0_1_rc_31, } from '../../types/templates'; -import { - DAOTrackerContract, - BlacklistedDAO, - ResetDAO as ResetDAOEntity -} from '../../types/schema'; import { equalStrings } from '../../utils'; export function getDAOTrackerContract(address: Address): DAOTrackerContract { diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index 26d1fb11..dfa9e09d 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -3,7 +3,7 @@ import { getContractAddresses, getOptions, getWeb3, sendQuery } from './util'; const DAOTracker = require('@daostack/arc/build/contracts/DAOTracker.json'); const Avatar = require('@daostack/arc/build/contracts/Avatar.json'); const Controller = require('@daostack/arc/build/contracts/Controller.json'); -const UController = require('@daostack/ar/build/contracts/UController.json'); +const UController = require('@daostack/arc/build/contracts/UController.json'); const DAOToken = require('@daostack/arc/contracts/build/DAOToken.json'); const Reputation = require('@daostack/arc/contracts/build/Reputation.json'); const ContributionReward = require('@daostack/arc/contracts/build/ContributionReward.json'); @@ -40,7 +40,7 @@ describe('DAOTracker', () => { schemeSetParams.send(); }); - const e2eControllerTest = async (uController: boolean) => { + const e2eControllerTest = async (isUController: boolean) => { // Start deploying a new DAO const nativeToken = await new web3.eth.Contract(DAOToken.abi, undefined, opts) .deploy({ data: DAOToken.bytecode, arguments: [ 'Test Token', 'TST', '10000000000' ] }) @@ -51,12 +51,14 @@ describe('DAOTracker', () => { .send(); const avatar = await new web3.eth.Contract(Avatar.abi, undefined, opts) - .deploy({ data: Avatar.bytecode, arguments: [ 'Test DAO', nativeToken.options.address, reputation.options.address ] }) + .deploy({ + data: Avatar.bytecode, + arguments: [ 'Test DAO', nativeToken.options.address, reputation.options.address ] }) .send(); let controller; - if (!uController) { + if (!isUController) { controller = await new web3.eth.Contracts(Controller.abi, undefined, opts) .deploy({ data: Controller.bytecode, arguments: [ avatar.options.address ] }); } else { @@ -99,16 +101,16 @@ describe('DAOTracker', () => { nativeToken: { id: nativeToken.options.address, dao: { - id: avatar.options.address - } + id: avatar.options.address, + }, }, nativeReputation: { id: reputation.options.address, dao: { - id: avatar.options.address - } + id: avatar.options.address, + }, }, - reputationHoldersCount: '0' + reputationHoldersCount: '0', }); // Add a scheme @@ -116,7 +118,7 @@ describe('DAOTracker', () => { contributionReward.options.address, schemeParamsHash, '0x0000001F', - avatar.options.address + avatar.options.address, ).send(); // Ensure the scheme is in the subgraph @@ -131,15 +133,15 @@ describe('DAOTracker', () => { expect(controllerSchemes).toContainEqual({ dao: { - id: avatar.options.address + id: avatar.options.address, }, - address: contributionReward.options.address + address: contributionReward.options.address, }); return { - avatar - } - } + avatar, + }; + }; it('Controller e2e', async () => { await e2eControllerTest(false); @@ -170,7 +172,7 @@ describe('DAOTracker', () => { id: avatar.options.address, address: avatar.options.address, tracker: daoTracker.options.address, - explanationHash: '' + explanationHash: '', }); } @@ -203,7 +205,7 @@ describe('DAOTracker', () => { expect(resetDAO).toMatchObject({ id: avatar.options.address, address: avatar.options.address, - explanationHash: '' + explanationHash: '', }); }); }); From b27bde50c984ed0884c51fa3610e8e9e4d5996de Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 22:24:50 +0400 Subject: [PATCH 09/38] fix --- test/0.0.1-rc.29/DAOTracker.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index dfa9e09d..ceab24de 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -4,7 +4,7 @@ const DAOTracker = require('@daostack/arc/build/contracts/DAOTracker.json'); const Avatar = require('@daostack/arc/build/contracts/Avatar.json'); const Controller = require('@daostack/arc/build/contracts/Controller.json'); const UController = require('@daostack/arc/build/contracts/UController.json'); -const DAOToken = require('@daostack/arc/contracts/build/DAOToken.json'); +const DAOToken = require('@daostack/arc/build/contracts/DAOToken.json'); const Reputation = require('@daostack/arc/contracts/build/Reputation.json'); const ContributionReward = require('@daostack/arc/contracts/build/ContributionReward.json'); const AbsoluteVote = require('@daostack/arc/contracts/build/AbsoluteVote.json'); From 1a1468791e0900c22aa1ea4f12c171be47780a53 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 22:50:09 +0400 Subject: [PATCH 10/38] :face_palm: --- test/0.0.1-rc.29/DAOTracker.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index ceab24de..b47d6535 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -5,9 +5,9 @@ const Avatar = require('@daostack/arc/build/contracts/Avatar.json'); const Controller = require('@daostack/arc/build/contracts/Controller.json'); const UController = require('@daostack/arc/build/contracts/UController.json'); const DAOToken = require('@daostack/arc/build/contracts/DAOToken.json'); -const Reputation = require('@daostack/arc/contracts/build/Reputation.json'); -const ContributionReward = require('@daostack/arc/contracts/build/ContributionReward.json'); -const AbsoluteVote = require('@daostack/arc/contracts/build/AbsoluteVote.json'); +const Reputation = require('@daostack/arc/build/contracts/Reputation.json'); +const ContributionReward = require('@daostack/arc/build/contracts/ContributionReward.json'); +const AbsoluteVote = require('@daostack/arc/build/contracts/AbsoluteVote.json'); describe('DAOTracker', () => { let web3; From c655571b76b1c30cd9971ebadd1d06cffcdb09e0 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 23:06:43 +0400 Subject: [PATCH 11/38] fix --- test/0.0.1-rc.29/DAOTracker.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index b47d6535..edda7dfb 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -27,7 +27,7 @@ describe('DAOTracker', () => { daoTracker = new web3.eth.Contract(DAOTracker.abi, addresses.DAOTracker, opts); uController = new web3.eth.Contract(UController.abi, addresses.UController, opts); contributionReward = new web3.eth.Contract(ContributionReward.abi, addresses.ContributionReward, opts); - absVote = new web3.eth.Contract(AbsoluteVote.abi, undefined, opts) + absVote = await new web3.eth.Contract(AbsoluteVote.abi, undefined, opts) .deploy({ data: AbsoluteVote.bytecode, arguments: [] }) .send(); From a3635e1c090fff06d119c64aee6a0bc48c807518 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 23:24:53 +0400 Subject: [PATCH 12/38] fix --- test/0.0.1-rc.29/DAOTracker.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index edda7dfb..128410fe 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -59,7 +59,7 @@ describe('DAOTracker', () => { let controller; if (!isUController) { - controller = await new web3.eth.Contracts(Controller.abi, undefined, opts) + controller = await new web3.eth.Contract(Controller.abi, undefined, opts) .deploy({ data: Controller.bytecode, arguments: [ avatar.options.address ] }); } else { controller = uController; From 7dc18a21c14eac34b17ba582835eabfd3057c16d Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 1 Nov 2019 23:44:12 +0400 Subject: [PATCH 13/38] timeout --- test/0.0.1-rc.29/DAOTracker.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index 128410fe..5ea9d15d 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -145,11 +145,11 @@ describe('DAOTracker', () => { it('Controller e2e', async () => { await e2eControllerTest(false); - }); + }, 120000); it('UController e2e', async () => { await e2eControllerTest(true); - }); + }, 120000); it('Blacklist & Reset DAO', async () => { const { avatar } = await e2eControllerTest(false); @@ -207,5 +207,5 @@ describe('DAOTracker', () => { address: avatar.options.address, explanationHash: '', }); - }); + }, 120000); }); From 1da76e87405cf106dbd339fb801731cb1f3699ea Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 00:03:41 +0400 Subject: [PATCH 14/38] found it --- test/0.0.1-rc.29/DAOTracker.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index 5ea9d15d..c43c92fb 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -37,7 +37,7 @@ describe('DAOTracker', () => { const schemeSetParams = contributionReward.methods.setParameters(vmParamsHash, absVote.options.address); schemeParamsHash = schemeSetParams.call(); - schemeSetParams.send(); + await schemeSetParams.send(); }); const e2eControllerTest = async (isUController: boolean) => { From 7703a4ac091b908cd48e46cbe36998bf1772fc15 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 00:19:38 +0400 Subject: [PATCH 15/38] fix --- test/0.0.1-rc.29/DAOTracker.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index c43c92fb..e3af49ff 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -60,7 +60,8 @@ describe('DAOTracker', () => { if (!isUController) { controller = await new web3.eth.Contract(Controller.abi, undefined, opts) - .deploy({ data: Controller.bytecode, arguments: [ avatar.options.address ] }); + .deploy({ data: Controller.bytecode, arguments: [ avatar.options.address ] }) + .send(); } else { controller = uController; } From a3acb0b5c35564232a243b6068ad2d658e34294d Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 00:49:17 +0400 Subject: [PATCH 16/38] checking correct things --- test/0.0.1-rc.29/DAOTracker.spec.ts | 66 +++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index e3af49ff..816c614d 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -70,11 +70,67 @@ describe('DAOTracker', () => { await daoTracker.methods.track(avatar.options.address, controller.options.address) .send(); - // Finish setting up the new DAO + // Finish setting up the new DAO, and verify the contract entities are added await reputation.methods.transferOwnership(controller.options.address).send(); + + const { reputationContract } = await sendQuery(`{ + reputationContract(id: "${reputation.options.address}") { + id + address + } + }`, 5000); + + expect(reputationContract).toMatchObject({ + id: reputation.options.address, + address: reputation.options.address, + }); + await nativeToken.methods.transferOwnership(controller.options.address).send(); + + const { tokenContract } = await sendQuery(`{ + tokenContract(id: "${nativeToken.options.address}") { + id + address + owner + } + }`, 5000); + + expect(tokenContract).toMatchObject({ + id: nativeToken.options.address, + address: nativeToken.options.address, + owner: controller.options.address, + }); + await avatar.methods.transferOwnership(controller.options.address).send(); + const { avatarContract } = await sendQuery(`{ + avatarContract(id: "${avatar.options.address}") { + id + address + name + nativeToken + nativeReputation + owner + } + }`, 5000); + + expect(avatarContract).toMatchObject({ + id: avatar.options.address, + address: avatar.options.address, + name: 'Test DAO', + nativeToken: nativeToken.options.address, + nativeReputation: reputation.options.address, + owner: controller.options.address, + }); + + // Add a scheme + await controller.methods.registerScheme( + contributionReward.options.address, + schemeParamsHash, + '0x0000001F', + avatar.options.address, + ).send(); + // Ensure the new DAO is in the subgraph const { dao } = await sendQuery(`{ dao(id: "${avatar.options.address}") { @@ -114,14 +170,6 @@ describe('DAOTracker', () => { reputationHoldersCount: '0', }); - // Add a scheme - await controller.methods.registerScheme( - contributionReward.options.address, - schemeParamsHash, - '0x0000001F', - avatar.options.address, - ).send(); - // Ensure the scheme is in the subgraph const { controllerSchemes } = await sendQuery(`{ controllerSchemes { From 8771ada277f21906eb43a11cffa91673858666a7 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 01:14:30 +0400 Subject: [PATCH 17/38] see if dao tracker is even a thing --- test/0.0.1-rc.29/DAOTracker.spec.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index 816c614d..4bae09d4 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -70,6 +70,20 @@ describe('DAOTracker', () => { await daoTracker.methods.track(avatar.options.address, controller.options.address) .send(); + const { daoTrackerContract } = await sendQuery(`{ + daoTrackerContract(id: "${daoTracker.options.address}") { + id + address + owner + } + }`, 5000); + + expect(daoTrackerContract).toMatchObject({ + id: daoTracker.options.address, + address: daoTracker.options.address, + owner: web3.eth.defaultAccount.toLowerCase(), + }); + // Finish setting up the new DAO, and verify the contract entities are added await reputation.methods.transferOwnership(controller.options.address).send(); From 35c62d816156b16744eee50fcf8b93a0b46e42bd Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 01:47:11 +0400 Subject: [PATCH 18/38] fix datasource.yaml --- src/mappings/DAOTracker/datasource.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mappings/DAOTracker/datasource.yaml b/src/mappings/DAOTracker/datasource.yaml index 7370d4f3..d95b03a3 100644 --- a/src/mappings/DAOTracker/datasource.yaml +++ b/src/mappings/DAOTracker/datasource.yaml @@ -17,4 +17,4 @@ eventHandlers: - event: BlacklistDAO(indexed address,string) handler: handleBlacklistDAO - event: ResetDAO(indexed address,string) - handler: handleResetDAO(indexed address,string) + handler: handleResetDAO From 730907bfdf5d8f7e0312552ce99eaf92773af6eb Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 02:17:07 +0400 Subject: [PATCH 19/38] .toLowerCase() --- test/0.0.1-rc.29/DAOTracker.spec.ts | 64 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index 4bae09d4..5b292a1b 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -71,7 +71,7 @@ describe('DAOTracker', () => { .send(); const { daoTrackerContract } = await sendQuery(`{ - daoTrackerContract(id: "${daoTracker.options.address}") { + daoTrackerContract(id: "${daoTracker.options.address.toLowerCase()}") { id address owner @@ -79,8 +79,8 @@ describe('DAOTracker', () => { }`, 5000); expect(daoTrackerContract).toMatchObject({ - id: daoTracker.options.address, - address: daoTracker.options.address, + id: daoTracker.options.address.toLowerCase(), + address: daoTracker.options.address.toLowerCase(), owner: web3.eth.defaultAccount.toLowerCase(), }); @@ -88,21 +88,21 @@ describe('DAOTracker', () => { await reputation.methods.transferOwnership(controller.options.address).send(); const { reputationContract } = await sendQuery(`{ - reputationContract(id: "${reputation.options.address}") { + reputationContract(id: "${reputation.options.address.toLowerCase()}") { id address } }`, 5000); expect(reputationContract).toMatchObject({ - id: reputation.options.address, - address: reputation.options.address, + id: reputation.options.address.toLowerCase(), + address: reputation.options.address.toLowerCase(), }); await nativeToken.methods.transferOwnership(controller.options.address).send(); const { tokenContract } = await sendQuery(`{ - tokenContract(id: "${nativeToken.options.address}") { + tokenContract(id: "${nativeToken.options.address.toLowerCase()}") { id address owner @@ -110,15 +110,15 @@ describe('DAOTracker', () => { }`, 5000); expect(tokenContract).toMatchObject({ - id: nativeToken.options.address, - address: nativeToken.options.address, - owner: controller.options.address, + id: nativeToken.options.address.toLowerCase(), + address: nativeToken.options.address.toLowerCase(), + owner: controller.options.address.toLowerCase(), }); await avatar.methods.transferOwnership(controller.options.address).send(); const { avatarContract } = await sendQuery(`{ - avatarContract(id: "${avatar.options.address}") { + avatarContract(id: "${avatar.options.address.toLowerCase()}") { id address name @@ -129,12 +129,12 @@ describe('DAOTracker', () => { }`, 5000); expect(avatarContract).toMatchObject({ - id: avatar.options.address, - address: avatar.options.address, + id: avatar.options.address.toLowerCase(), + address: avatar.options.address.toLowerCase(), name: 'Test DAO', - nativeToken: nativeToken.options.address, - nativeReputation: reputation.options.address, - owner: controller.options.address, + nativeToken: nativeToken.options.address.toLowerCase(), + nativeReputation: reputation.options.address.toLowerCase(), + owner: controller.options.address.toLowerCase(), }); // Add a scheme @@ -147,7 +147,7 @@ describe('DAOTracker', () => { // Ensure the new DAO is in the subgraph const { dao } = await sendQuery(`{ - dao(id: "${avatar.options.address}") { + dao(id: "${avatar.options.address.toLowerCase()}") { id name nativeToken { @@ -167,18 +167,18 @@ describe('DAOTracker', () => { }`, 5000); expect(dao).toMatchObject({ - id: avatar.options.address, + id: avatar.options.address.toLowerCase(), name: 'Test DAO', nativeToken: { - id: nativeToken.options.address, + id: nativeToken.options.address.toLowerCase(), dao: { - id: avatar.options.address, + id: avatar.options.address.toLowerCase(), }, }, nativeReputation: { - id: reputation.options.address, + id: reputation.options.address.toLowerCase(), dao: { - id: avatar.options.address, + id: avatar.options.address.toLowerCase(), }, }, reputationHoldersCount: '0', @@ -196,9 +196,9 @@ describe('DAOTracker', () => { expect(controllerSchemes).toContainEqual({ dao: { - id: avatar.options.address, + id: avatar.options.address.toLowerCase(), }, - address: contributionReward.options.address, + address: contributionReward.options.address.toLowerCase(), }); return { @@ -223,7 +223,7 @@ describe('DAOTracker', () => { // Ensure the blacklisted DAO is in the subgraph { const { blacklistedDAO } = await sendQuery(`{ - blacklistedDAO(id: "${avatar.options.address}") { + blacklistedDAO(id: "${avatar.options.address.toLowerCase()}") { id address tracker @@ -232,9 +232,9 @@ describe('DAOTracker', () => { }`, 5000); expect(blacklistedDAO).toMatchObject({ - id: avatar.options.address, - address: avatar.options.address, - tracker: daoTracker.options.address, + id: avatar.options.address.toLowerCase(), + address: avatar.options.address.toLowerCase(), + tracker: daoTracker.options.address.toLowerCase(), explanationHash: '', }); } @@ -245,7 +245,7 @@ describe('DAOTracker', () => { // Ensure the blacklisted DAO is no longer in the subgraph { const { blacklistedDAO } = await sendQuery(`{ - blacklistedDAO(id: "${avatar.options.address}") { + blacklistedDAO(id: "${avatar.options.address.toLowerCase()}") { id address tracker @@ -258,7 +258,7 @@ describe('DAOTracker', () => { // Ensure the reset DAO is in the subgraph const { resetDAO } = await sendQuery(`{ - resetDAO(id: "${avatar.options.address}') { + resetDAO(id: "${avatar.options.address.toLowerCase()}") { id address explanationHash @@ -266,8 +266,8 @@ describe('DAOTracker', () => { }`); expect(resetDAO).toMatchObject({ - id: avatar.options.address, - address: avatar.options.address, + id: avatar.options.address.toLowerCase(), + address: avatar.options.address.toLowerCase(), explanationHash: '', }); }, 120000); From 0b826d5fb144055eddc7214c631820d55e689db5 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 02:40:00 +0400 Subject: [PATCH 20/38] fix --- test/0.0.1-rc.29/DAOTracker.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index 5b292a1b..b94790ed 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -70,15 +70,15 @@ describe('DAOTracker', () => { await daoTracker.methods.track(avatar.options.address, controller.options.address) .send(); - const { daoTrackerContract } = await sendQuery(`{ - daoTrackerContract(id: "${daoTracker.options.address.toLowerCase()}") { + const { daotrackerContract } = await sendQuery(`{ + daotrackerContract(id: "${daoTracker.options.address.toLowerCase()}") { id address owner } }`, 5000); - expect(daoTrackerContract).toMatchObject({ + expect(daotrackerContract).toMatchObject({ id: daoTracker.options.address.toLowerCase(), address: daoTracker.options.address.toLowerCase(), owner: web3.eth.defaultAccount.toLowerCase(), From 21c7d3bd92c742dc87852158cae154f0c4c6e4d1 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 02:57:34 +0400 Subject: [PATCH 21/38] fix --- test/0.0.1-rc.29/DAOTracker.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index b94790ed..d49992e1 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -36,7 +36,7 @@ describe('DAOTracker', () => { await vmSetParams.send(); const schemeSetParams = contributionReward.methods.setParameters(vmParamsHash, absVote.options.address); - schemeParamsHash = schemeSetParams.call(); + schemeParamsHash = await schemeSetParams.call(); await schemeSetParams.send(); }); From ab7135abeb86ad27997b1d92acb7811ba8fc6ef9 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Sat, 2 Nov 2019 03:26:08 +0400 Subject: [PATCH 22/38] wait longer? --- test/0.0.1-rc.29/DAOTracker.spec.ts | 38 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index d49992e1..e3104220 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -145,6 +145,23 @@ describe('DAOTracker', () => { avatar.options.address, ).send(); + // Ensure the scheme is in the subgraph + const { controllerSchemes } = await sendQuery(`{ + controllerSchemes { + dao { + id + } + address + } + }`, 15000); + + expect(controllerSchemes).toContainEqual({ + dao: { + id: avatar.options.address.toLowerCase(), + }, + address: contributionReward.options.address.toLowerCase(), + }); + // Ensure the new DAO is in the subgraph const { dao } = await sendQuery(`{ dao(id: "${avatar.options.address.toLowerCase()}") { @@ -162,9 +179,8 @@ describe('DAOTracker', () => { id } } - reputationHoldersCount } - }`, 5000); + }`, 15000); expect(dao).toMatchObject({ id: avatar.options.address.toLowerCase(), @@ -181,24 +197,6 @@ describe('DAOTracker', () => { id: avatar.options.address.toLowerCase(), }, }, - reputationHoldersCount: '0', - }); - - // Ensure the scheme is in the subgraph - const { controllerSchemes } = await sendQuery(`{ - controllerSchemes { - dao { - id - } - address - } - }`, 5000); - - expect(controllerSchemes).toContainEqual({ - dao: { - id: avatar.options.address.toLowerCase(), - }, - address: contributionReward.options.address.toLowerCase(), }); return { From 9bed19a5fe611f63c7e2d700627b4535dd142fdb Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 4 Nov 2019 13:47:47 +0100 Subject: [PATCH 23/38] feedback changes --- src/mappings/DAOTracker/mapping.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 5e357d43..48338e9f 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -6,6 +6,7 @@ import { TrackDAO, } from '../../types/DAOTracker/DAOTracker'; import { + AvatarContract, BlacklistedDAO, DAOTrackerContract, ResetDAO as ResetDAOEntity, @@ -39,16 +40,8 @@ export function handleTrackDAO(event: TrackDAO): void { let _reputation = event.params._reputation; let _daoToken = event.params._daoToken; - /* TODO: uncomment when this issue is resolved https://github.com/graphprotocol/graph-node/issues/1333 - // If the avatar hasn't been blacklisted - let daoTrackerSC = DAOTracker.bind(event.address); - if (daoTrackerSC.blacklisted(_avatar), 'latest') { - return; - } - */ - // If the avatar already exists, early out - if (store.get('AvatarContract', _avatar.toHex()) != null) { + if (AvatarContract.load(_avatar.toHex()) != null) { return; } From 1fc11a8eeef5aca33a753dbc23b5d16b144ef485 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 4 Nov 2019 13:56:33 +0100 Subject: [PATCH 24/38] updates based on feedback --- src/mappings/DAOTracker/mapping.ts | 63 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 48338e9f..ed999215 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -10,6 +10,7 @@ import { BlacklistedDAO, DAOTrackerContract, ResetDAO as ResetDAOEntity, + UControllerOrganization } from '../../types/schema'; import { Avatar_0_0_1_rc_31, @@ -26,7 +27,7 @@ export function getDAOTrackerContract(address: Address): DAOTrackerContract { daoTracker.address = address; let daoTrackerSC = DAOTracker.bind(address); daoTracker.owner = daoTrackerSC.owner(); - store.set('DAOTrackerContract', daoTracker.id, daoTracker); + daoTracker.save(); } return daoTracker; } @@ -35,25 +36,25 @@ export function handleTrackDAO(event: TrackDAO): void { // Ensure the DAOTrackerContract has been added to the store getDAOTrackerContract(event.address); - let _avatar = event.params._avatar; - let _controller = event.params._controller; - let _reputation = event.params._reputation; - let _daoToken = event.params._daoToken; + let avatar = event.params._avatar; + let controller = event.params._controller; + let reputation = event.params._reputation; + let daoToken = event.params._daoToken; // If the avatar already exists, early out - if (AvatarContract.load(_avatar.toHex()) != null) { + if (AvatarContract.load(avatar.toHex()) != null) { return; } // Tell the subgraph to start indexing events from the: // Avatar, Controller, DAOToken, and Reputation contracts - Avatar_0_0_1_rc_31.create(_avatar); - Reputation_0_0_1_rc_31.create(_reputation); - DAOToken_0_0_1_rc_31.create(_daoToken); + Avatar_0_0_1_rc_31.create(avatar); + Reputation_0_0_1_rc_31.create(reputation); + DAOToken_0_0_1_rc_31.create(daoToken); // Track the Controller if it isn't a UController we're already tracking - if (store.get('UControllerOrganization', _controller.toHex()) == null) { - Controller_0_0_1_rc_31.create(_controller); + if (UControllerOrganization.load(controller.toHex()) == null) { + Controller_0_0_1_rc_31.create(controller); } // Note, no additional work is needed here because... @@ -66,28 +67,28 @@ export function handleBlacklistDAO(event: BlacklistDAO): void { // Ensure the DAOTrackerContract has been added to the store let daoTracker = getDAOTrackerContract(event.address); - let _avatar = event.params._avatar; - let _explanationHash = event.params._explanationHash; + let avatar = event.params._avatar; + let explanationHash = event.params._explanationHash; // Add the BlacklistedDAO to the store - let blacklistedDAO = new BlacklistedDAO(_avatar.toHex()); - blacklistedDAO.address = _avatar; + let blacklistedDAO = new BlacklistedDAO(avatar.toHex()); + blacklistedDAO.address = avatar; blacklistedDAO.tracker = daoTracker.id; - blacklistedDAO.explanationHash = _explanationHash; + blacklistedDAO.explanationHash = explanationHash; - if (!equalStrings(_explanationHash, '')) { - let explanation = ipfs.cat('/ipfs/' + _explanationHash); + if (!equalStrings(explanationHash, '')) { + let explanation = ipfs.cat('/ipfs/' + explanationHash); if (explanation != null) { blacklistedDAO.explanation = explanation.toString(); } } - store.set('BlacklistedDAO', blacklistedDAO.id, blacklistedDAO); + blacklistedDAO.save(); // If the DAO has been previously reset, remove that entity from the store - if (store.get('ResetDAO', _avatar.toHex())) { - store.remove('ResetDAO', _avatar.toHex()); + if (ResetDAOEntity.load(avatar.toHex())) { + store.remove('ResetDAO', avatar.toHex()); } } @@ -95,26 +96,26 @@ export function handleResetDAO(event: ResetDAO): void { // Ensure the DAOTrackerContract has been added to the store getDAOTrackerContract(event.address); - let _avatar = event.params._avatar; - let _explanationHash = event.params._explanationHash; + let avatar = event.params._avatar; + let explanationHash = event.params._explanationHash; // Remove the BlacklistedDAO from the store - if (store.get('BlacklistedDAO', _avatar.toHex())) { - store.remove('BlacklistedDAO', _avatar.toHex()); + if (BlacklistedDAO.load(avatar.toHex())) { + store.remove('BlacklistedDAO', avatar.toHex()); } // Add the ResetDAO entity to the store - let resetDAO = new ResetDAOEntity(_avatar.toHex()); - resetDAO.address = _avatar; - resetDAO.explanationHash = _explanationHash; + let resetDAO = new ResetDAOEntity(avatar.toHex()); + resetDAO.address = avatar; + resetDAO.explanationHash = explanationHash; - if (!equalStrings(_explanationHash, '')) { - let explanation = ipfs.cat('/ipfs/' + _explanationHash); + if (!equalStrings(explanationHash, '')) { + let explanation = ipfs.cat('/ipfs/' + explanationHash); if (explanation != null) { resetDAO.explanation = explanation.toString(); } } - store.set('ResetDAO', resetDAO.id, resetDAO); + resetDAO.save(); } From 76149667b15ec269ca8ab20c5ca43d565a8a68f1 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 4 Nov 2019 14:45:46 +0100 Subject: [PATCH 25/38] fixes --- package-lock.json | 618 +++++++++++++++------------- src/mappings/DAOTracker/mapping.ts | 2 +- test/0.0.1-rc.29/DAOTracker.spec.ts | 43 +- 3 files changed, 359 insertions(+), 304 deletions(-) diff --git a/package-lock.json b/package-lock.json index c107a5a4..0dc72841 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,17 +13,17 @@ } }, "@babel/core": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.0.tgz", - "integrity": "sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz", + "integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", - "@babel/helpers": "^7.6.0", - "@babel/parser": "^7.6.0", + "@babel/generator": "^7.6.4", + "@babel/helpers": "^7.6.2", + "@babel/parser": "^7.6.4", "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.0", - "@babel/types": "^7.6.0", + "@babel/traverse": "^7.6.3", + "@babel/types": "^7.6.3", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -46,15 +46,14 @@ } }, "@babel/generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz", - "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "source-map": "^0.5.0" }, "dependencies": { "source-map": { @@ -96,12 +95,12 @@ } }, "@babel/helpers": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.0.tgz", - "integrity": "sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", + "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", "requires": { "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.0", + "@babel/traverse": "^7.6.2", "@babel/types": "^7.6.0" } }, @@ -116,9 +115,9 @@ } }, "@babel/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==" + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==" }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.2.0", @@ -147,25 +146,25 @@ } }, "@babel/traverse": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz", - "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -269,6 +268,14 @@ "yaml": "^1.5.1" }, "dependencies": { + "concat-stream": { + "version": "github:hugomrdias/concat-stream#057bc7b5d6d8df26c8cf00a3f151b6721a0a8034", + "from": "github:hugomrdias/concat-stream#feat/smaller", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.0.2" + } + }, "ipfs-http-client": { "version": "34.0.0", "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-34.0.0.tgz", @@ -281,7 +288,7 @@ "bs58": "^4.0.1", "buffer": "^5.4.2", "cids": "~0.7.1", - "concat-stream": "github:hugomrdias/concat-stream#057bc7b5d6d8df26c8cf00a3f151b6721a0a8034", + "concat-stream": "github:hugomrdias/concat-stream#feat/smaller", "debug": "^4.1.0", "detect-node": "^2.0.4", "end-of-stream": "^1.4.1", @@ -310,7 +317,7 @@ "multibase": "~0.6.0", "multicodec": "~0.5.1", "multihashes": "~0.4.14", - "ndjson": "github:hugomrdias/ndjson#4db16da6b42e5b39bf300c3a7cde62abb3fa3a11", + "ndjson": "github:hugomrdias/ndjson#feat/readable-stream3", "once": "^1.4.0", "peer-id": "~0.12.3", "peer-info": "~0.15.1", @@ -331,6 +338,16 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "ndjson": { + "version": "github:hugomrdias/ndjson#4db16da6b42e5b39bf300c3a7cde62abb3fa3a11", + "from": "github:hugomrdias/ndjson#feat/readable-stream3", + "requires": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.0", + "split2": "^3.1.0", + "through2": "^3.0.0" + } } } }, @@ -626,9 +643,9 @@ } }, "@types/babel__generator": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.0.2.tgz", - "integrity": "sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz", + "integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==", "requires": { "@babel/types": "^7.0.0" } @@ -659,9 +676,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.16.10", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.10.tgz", - "integrity": "sha512-gM6evDj0OvTILTRKilh9T5dTaGpv1oYiFcJAfgSejuMJgGJUsD9hKEU2lB4aiTNy4WwChxRnjfYFuBQsULzsJw==", + "version": "4.16.11", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.11.tgz", + "integrity": "sha512-K8d2M5t3tBQimkyaYTXxtHYyoJPUEhy2/omVRnTAKw5FEdT+Ft6lTaTOpoJdHeG+mIwQXXtqiTcYZ6IR8LTzjQ==", "requires": { "@types/node": "*", "@types/range-parser": "*" @@ -707,9 +724,9 @@ "dev": true }, "@types/node": { - "version": "10.14.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.18.tgz", - "integrity": "sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ==" + "version": "10.17.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.3.tgz", + "integrity": "sha512-QZ9CjUB3QoA3f2afw3utKlfRPhpmufB7jC2+oDhLWnXqoyx333fhKSQDLQu2EK7OE0a15X67eYiRAaJsHXrpMA==" }, "@types/range-parser": { "version": "1.2.3", @@ -722,9 +739,9 @@ "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" }, "@types/yargs": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.2.tgz", - "integrity": "sha512-lwwgizwk/bIIU+3ELORkyuOgDjCh7zuWDFqRtPPhhVgq9N1F7CvLNKg1TX4f2duwtKQ0p044Au9r1PLIXHrIzQ==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz", + "integrity": "sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==", "requires": { "@types/yargs-parser": "*" } @@ -757,9 +774,9 @@ } }, "abab": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.1.tgz", - "integrity": "sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz", + "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==" }, "abort-controller": { "version": "3.0.0", @@ -800,9 +817,9 @@ } }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "acorn-walk": { @@ -1217,7 +1234,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true }, "string_decoder": { "version": "1.1.1", @@ -1614,9 +1632,9 @@ } }, "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==" }, "bn.js": { "version": "4.11.8", @@ -1814,9 +1832,9 @@ } }, "bser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", - "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "requires": { "node-int64": "^0.4.0" } @@ -1984,9 +2002,9 @@ } }, "chokidar": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.2.2.tgz", - "integrity": "sha512-bw3pm7kZ2Wa6+jQWYP/c7bAZy3i4GwiIiMO2EeRjrE48l8vBqC/WvFhSF0xyM8fQiPEGvwMY/5bqDG7sSEOuhg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -1999,9 +2017,9 @@ } }, "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" }, "ci-info": { "version": "2.0.0", @@ -2237,9 +2255,9 @@ } }, "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "component-emitter": { "version": "1.3.0", @@ -2252,8 +2270,9 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { - "version": "github:hugomrdias/concat-stream#057bc7b5d6d8df26c8cf00a3f151b6721a0a8034", - "from": "github:hugomrdias/concat-stream#feat/smaller", + "version": "2.0.0", + "resolved": "github:hugomrdias/concat-stream#057bc7b5d6d8df26c8cf00a3f151b6721a0a8034", + "dev": true, "requires": { "inherits": "^2.0.3", "readable-stream": "^3.0.2" @@ -2262,7 +2281,8 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true }, "contains-path": { "version": "0.1.0", @@ -2475,9 +2495,9 @@ }, "dependencies": { "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "requires": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -2953,9 +2973,9 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } @@ -2993,9 +3013,9 @@ "dev": true }, "es-abstract": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", - "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", @@ -3005,8 +3025,8 @@ "is-regex": "^1.0.4", "object-inspect": "^1.6.0", "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.0.0", - "string.prototype.trimright": "^2.0.0" + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" } }, "es-to-primitive": { @@ -3062,9 +3082,9 @@ } }, "eslint": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz", - "integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz", + "integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -3074,9 +3094,9 @@ "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.2", + "eslint-utils": "^1.4.3", "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.1", + "espree": "^6.1.2", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -3086,7 +3106,7 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", + "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -3106,12 +3126,45 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "ansi-escapes": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "dev": true, + "requires": { + "type-fest": "^0.5.2" + } + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "figures": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "import-fresh": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", @@ -3122,12 +3175,81 @@ "resolve-from": "^4.0.0" } }, + "inquirer": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", + "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -3464,12 +3586,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -3479,20 +3601,20 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" }, "dependencies": { "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true } } @@ -4648,7 +4770,8 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -4674,6 +4797,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4713,9 +4837,9 @@ "optional": true }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4814,9 +4938,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "graceful-readlink": { "version": "1.0.1", @@ -4824,9 +4948,9 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, "graphql": { - "version": "14.5.7", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.5.7.tgz", - "integrity": "sha512-as410RMJSUFqF8RcH2QWxZ5ioqHzsH9VWnWbaU+UnDXJ/6azMDIYPrtXCBPXd8rlunEVb7W8z6fuUnNHMbFu9A==", + "version": "14.5.8", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.5.8.tgz", + "integrity": "sha512-MMwmi0zlVLQKLdGiMfWkgQD7dY/TUKt4L+zgJ/aR0Howebod3aNgP5JkgvAULiR2HPVZaP2VEElqtdidHweLkg==", "requires": { "iterall": "^1.2.2" } @@ -4850,9 +4974,9 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, "handlebars": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.3.1.tgz", - "integrity": "sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.1.tgz", + "integrity": "sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA==", "requires": { "neo-async": "^2.6.0", "optimist": "^0.6.1", @@ -5043,9 +5167,9 @@ } }, "hosted-git-info": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", - "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==" + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" }, "html-encoding-sniffer": { "version": "1.0.2", @@ -5354,18 +5478,6 @@ "multihashes": "~0.4.14" } }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, "err-code": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", @@ -5460,93 +5572,6 @@ "nodeify": "^1.0.1" } }, - "ndjson": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-1.5.0.tgz", - "integrity": "sha1-rmA7NrE0vOw0e0UkIrC/mNWDLsg=", - "dev": true, - "requires": { - "json-stringify-safe": "^5.0.1", - "minimist": "^1.2.0", - "split2": "^2.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", - "dev": true, - "requires": { - "through2": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -5718,9 +5743,9 @@ } }, "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" }, "is-callable": { "version": "1.1.4", @@ -5944,9 +5969,13 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "iso-random-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/iso-random-stream/-/iso-random-stream-1.1.0.tgz", - "integrity": "sha512-ywSWt0KrWcsaK0jVoVJIR30rLyjg9Rw3k2Sm/qp+3tdtSV0SNH7L7KilKnENcENOSoJxDFvpt2idvuMMQohdCQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/iso-random-stream/-/iso-random-stream-1.1.1.tgz", + "integrity": "sha512-YEt/7xOwTdu4KXIgtdgGFkiLUsBaddbnkmHyaFdjJYIcD7V4gpQHPvYC5tyh3kA0PQ01y9lWm1ruVdf8Mqzovg==", + "requires": { + "buffer": "^5.4.3", + "readable-stream": "^3.4.0" + } }, "iso-stream-http": { "version": "0.1.2", @@ -6073,9 +6102,9 @@ }, "dependencies": { "@types/node": { - "version": "12.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.2.tgz", - "integrity": "sha512-dsfE4BHJkLQW+reOS6b17xhZ/6FB1rB8eRRvO08nn5o+voxf3i74tuyFWNH6djdfgX7Sm5s6LD8t6mJug4dpDw==" + "version": "12.12.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==" } } }, @@ -7172,9 +7201,9 @@ } }, "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", "requires": { "minimist": "^1.2.0" } @@ -7329,9 +7358,9 @@ } }, "libp2p-crypto": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/libp2p-crypto/-/libp2p-crypto-0.16.1.tgz", - "integrity": "sha512-+fxqy+cDjwOKK4KTj44WQmjPE5ep2eR5uAIQWHl/+RKvRSor3+RAY53VWkAecgAEvjX2AswxBsoCIJK1Qk5aIQ==", + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/libp2p-crypto/-/libp2p-crypto-0.16.3.tgz", + "integrity": "sha512-ro7/5Tu+f8p2+qDS1JrROnO++nNaAaBFs+VVXVHLuTMnbnMASu1eUtSlWPk1uOwikAlBFTvfqe5J1bK6Bpq6Pg==", "requires": { "asmcrypto.js": "^2.3.2", "asn1.js": "^5.0.1", @@ -7343,12 +7372,12 @@ "keypair": "^1.0.1", "libp2p-crypto-secp256k1": "~0.3.0", "multihashing-async": "~0.5.1", - "node-forge": "~0.7.6", + "node-forge": "~0.9.1", "pem-jwk": "^2.0.0", "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.10" + "ursa-optional": "~0.10.0" }, "dependencies": { "multihashing-async": { @@ -7908,20 +7937,20 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "minipass": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.7.0.tgz", - "integrity": "sha512-+CbZuJ4uEiuTL9s5Z/ULkuRg1O9AvVqVvceaBrhbYHIy1R3dPO7FMmG0nZLD0//ZzZq0MUOjwdBQvk+w1JHUqQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.2.tgz", - "integrity": "sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "requires": { - "minipass": "^2.2.1" + "minipass": "^2.9.0" } }, "mixin-deep": { @@ -7985,9 +8014,9 @@ } }, "mock-fs": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.10.1.tgz", - "integrity": "sha512-w22rOL5ZYu6HbUehB5deurghGM0hS/xBVyHMGKOuQctkk93J9z9VEOhDsiWrXOprVNQpP9uzGKdl8v9mFspKuw==" + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.10.2.tgz", + "integrity": "sha512-ewPQ83O4U8/Gd8I15WoB6vgTTmq5khxBskUWCRvswUqjCfOOTREmxllztQOm+PXMWUxATry+VBWXQJloAyxtbQ==" }, "moment": { "version": "2.24.0", @@ -8143,8 +8172,9 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "ndjson": { - "version": "github:hugomrdias/ndjson#4db16da6b42e5b39bf300c3a7cde62abb3fa3a11", - "from": "github:hugomrdias/ndjson#feat/readable-stream3", + "version": "1.5.0", + "resolved": "github:hugomrdias/ndjson#4db16da6b42e5b39bf300c3a7cde62abb3fa3a11", + "dev": true, "requires": { "json-stringify-safe": "^5.0.1", "minimist": "^1.2.0", @@ -8190,9 +8220,9 @@ "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "node-forge": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz", - "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==" + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", + "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" }, "node-int64": { "version": "0.4.0", @@ -8706,9 +8736,9 @@ } }, "peer-id": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/peer-id/-/peer-id-0.12.4.tgz", - "integrity": "sha512-AIAwL/6CmVc/VKbUhpA1rY3A/VJ3Z9ELvtvDQfl5cIi0A74L7lvsJ6LxQn5JSJVHM5Us2Ng9zMO523dO3FFnnw==", + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/peer-id/-/peer-id-0.12.5.tgz", + "integrity": "sha512-3xVWrtIvNm9/OPzaQBgXDrfWNx63AftgFQkvqO6YSZy7sP3Fuadwwbn54F/VO9AnpyW/26i0WRQz9FScivXrmw==", "requires": { "async": "^2.6.3", "class-is": "^1.1.0", @@ -8746,9 +8776,9 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.0.tgz", + "integrity": "sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw==" }, "pify": { "version": "3.0.0", @@ -9331,9 +9361,9 @@ } }, "react-is": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", - "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==" + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.11.0.tgz", + "integrity": "sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw==" }, "read-pkg": { "version": "3.0.0", @@ -9616,12 +9646,11 @@ } }, "rlp": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.3.tgz", - "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.4.tgz", + "integrity": "sha512-fdq2yYCWpAQBhwkZv+Z8o/Z4sPmYm1CUq6P7n6lVTOdb949CnqA0sndXal5C1NleSVSZm6q5F3iEbauyVln/iw==", "requires": { - "bn.js": "^4.11.1", - "safe-buffer": "^5.1.1" + "bn.js": "^4.11.1" } }, "rsa-pem-to-jwk": { @@ -10189,9 +10218,9 @@ } }, "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -10572,13 +10601,13 @@ } }, "tar": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.11.tgz", - "integrity": "sha512-iI4zh3ktLJKaDNZKZc+fUONiQrSn9HkCFzamtb7k8FFmVilHVob7QsLX/VySAW8lAviMzMbFw4QtFb4errwgYA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.6.4", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -10621,6 +10650,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -10634,7 +10664,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true } } }, @@ -10642,6 +10673,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, "requires": { "safe-buffer": "~5.1.0" }, @@ -10649,7 +10681,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true } } }, @@ -10925,11 +10958,6 @@ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", "dev": true }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, "triple-beam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", @@ -11104,6 +11132,12 @@ "prelude-ls": "~1.1.2" } }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -11113,12 +11147,6 @@ "mime-types": "~2.1.24" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -11128,17 +11156,17 @@ } }, "typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", - "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==" + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==" }, "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.7.tgz", + "integrity": "sha512-4sXQDzmdnoXiO+xvmTzQsfIiwrjUCSA95rSP4SEd8tDb51W2TiDOlL76Hl+Kw0Ie42PSItCW8/t6pBNCF2R48A==", "optional": true, "requires": { - "commander": "~2.20.0", + "commander": "~2.20.3", "source-map": "~0.6.1" } }, @@ -11260,12 +11288,12 @@ "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" }, "ursa-optional": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/ursa-optional/-/ursa-optional-0.9.10.tgz", - "integrity": "sha512-RvEbhnxlggX4MXon7KQulTFiJQtLJZpSb9ZSa7ZTkOW0AzqiVTaLjI4vxaSzJBDH9dwZ3ltZadFiBaZslp6haA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/ursa-optional/-/ursa-optional-0.10.1.tgz", + "integrity": "sha512-/pgpBXVJut57dHNrdGF+1/qXi+5B7JrlmZDWPSyoivEcbwFWRZJBJGkWb6ivknMBA3bnFA7lqsb6iHiFfp79QQ==", "requires": { - "bindings": "^1.3.0", - "nan": "^2.11.1" + "bindings": "^1.5.0", + "nan": "^2.14.0" } }, "use": { @@ -11657,7 +11685,7 @@ "requires": { "underscore": "1.8.3", "web3-core-helpers": "1.0.0-beta.37", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" + "websocket": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" } }, "web3-shh": { @@ -12057,9 +12085,9 @@ "integrity": "sha512-sc1JByruVRqL6GYdIKbcvYw8PRmYeuwtSd376fM13DNE+JjBh37qIlKjCtqg9mKV2N2+xCfyil3Hd6BXN9W1uQ==" }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yaml": { "version": "1.7.2", diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index ed999215..bb6dc43d 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -10,7 +10,7 @@ import { BlacklistedDAO, DAOTrackerContract, ResetDAO as ResetDAOEntity, - UControllerOrganization + UControllerOrganization, } from '../../types/schema'; import { Avatar_0_0_1_rc_31, diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.29/DAOTracker.spec.ts index e3104220..f1ba4383 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.29/DAOTracker.spec.ts @@ -7,7 +7,7 @@ const UController = require('@daostack/arc/build/contracts/UController.json'); const DAOToken = require('@daostack/arc/build/contracts/DAOToken.json'); const Reputation = require('@daostack/arc/build/contracts/Reputation.json'); const ContributionReward = require('@daostack/arc/build/contracts/ContributionReward.json'); -const AbsoluteVote = require('@daostack/arc/build/contracts/AbsoluteVote.json'); +const GenesisProtocol = require('@daostack/arc/build/contracts/GenesisProtocol.json'); describe('DAOTracker', () => { let web3; @@ -16,7 +16,7 @@ describe('DAOTracker', () => { let daoTracker; let uController; let contributionReward; - let absVote; + let genesisProtocol; let vmParamsHash; let schemeParamsHash; @@ -27,15 +27,42 @@ describe('DAOTracker', () => { daoTracker = new web3.eth.Contract(DAOTracker.abi, addresses.DAOTracker, opts); uController = new web3.eth.Contract(UController.abi, addresses.UController, opts); contributionReward = new web3.eth.Contract(ContributionReward.abi, addresses.ContributionReward, opts); - absVote = await new web3.eth.Contract(AbsoluteVote.abi, undefined, opts) - .deploy({ data: AbsoluteVote.bytecode, arguments: [] }) - .send(); - - const vmSetParams = absVote.methods.setParameters(20, '0x0000000000000000000000000000000000000000'); + genesisProtocol = await new web3.eth.Contract(GenesisProtocol.abi, addresses.GenesisProtocol, opts); + + const gpParams = { + queuedVoteRequiredPercentage: 50, + queuedVotePeriodLimit: 60, + boostedVotePeriodLimit: 5, + preBoostedVotePeriodLimit: 0, + thresholdConst: 2000, + quietEndingPeriod: 0, + proposingRepReward: 60, + votersReputationLossRatio: 10, + minimumDaoBounty: 15, + daoBountyConst: 10, + activationTime: 0, + voteOnBehalf: '0x0000000000000000000000000000000000000000', + }; + const vmSetParams = genesisProtocol.methods.setParameters( + [ + gpParams.queuedVoteRequiredPercentage, + gpParams.queuedVotePeriodLimit, + gpParams.boostedVotePeriodLimit, + gpParams.preBoostedVotePeriodLimit, + gpParams.thresholdConst, + gpParams.quietEndingPeriod, + gpParams.proposingRepReward, + gpParams.votersReputationLossRatio, + gpParams.minimumDaoBounty, + gpParams.daoBountyConst, + gpParams.activationTime, + ], + gpParams.voteOnBehalf, + ); vmParamsHash = await vmSetParams.call(); await vmSetParams.send(); - const schemeSetParams = contributionReward.methods.setParameters(vmParamsHash, absVote.options.address); + const schemeSetParams = contributionReward.methods.setParameters(vmParamsHash, genesisProtocol.options.address); schemeParamsHash = await schemeSetParams.call(); await schemeSetParams.send(); }); From 2e8621af152b1c427990a19cfafc00c4b663a18d Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 4 Nov 2019 16:52:50 +0100 Subject: [PATCH 26/38] change to 31 so tests pass --- ops/mappings.json | 2 +- test/{0.0.1-rc.29 => 0.0.1-rc.31}/DAOTracker.spec.ts | 5 +++++ test/{0.0.1-rc.29 => 0.0.1-rc.31}/util.ts | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) rename test/{0.0.1-rc.29 => 0.0.1-rc.31}/DAOTracker.spec.ts (98%) rename test/{0.0.1-rc.29 => 0.0.1-rc.31}/util.ts (98%) diff --git a/ops/mappings.json b/ops/mappings.json index eae7dc2e..66d5bf50 100644 --- a/ops/mappings.json +++ b/ops/mappings.json @@ -616,7 +616,7 @@ "contractName": "DAOTracker", "dao": "base", "mapping": "DAOTracker", - "arcVersion": "0.0.1-rc.29" + "arcVersion": "0.0.1-rc.31" } ] }, diff --git a/test/0.0.1-rc.29/DAOTracker.spec.ts b/test/0.0.1-rc.31/DAOTracker.spec.ts similarity index 98% rename from test/0.0.1-rc.29/DAOTracker.spec.ts rename to test/0.0.1-rc.31/DAOTracker.spec.ts index f1ba4383..097d340b 100644 --- a/test/0.0.1-rc.29/DAOTracker.spec.ts +++ b/test/0.0.1-rc.31/DAOTracker.spec.ts @@ -164,6 +164,11 @@ describe('DAOTracker', () => { owner: controller.options.address.toLowerCase(), }); + if (isUController) { + // Add the new organization to the UController + await controller.methods.newOrganization(avatar.options.address).send(); + } + // Add a scheme await controller.methods.registerScheme( contributionReward.options.address, diff --git a/test/0.0.1-rc.29/util.ts b/test/0.0.1-rc.31/util.ts similarity index 98% rename from test/0.0.1-rc.29/util.ts rename to test/0.0.1-rc.31/util.ts index 80c14efa..7c134dfd 100644 --- a/test/0.0.1-rc.29/util.ts +++ b/test/0.0.1-rc.31/util.ts @@ -54,7 +54,7 @@ export async function getWeb3() { export function getContractAddresses() { const addresses = require(`@daostack/migration/migration.json`); - let arcVersion = '0.0.1-rc.29'; + let arcVersion = '0.0.1-rc.31'; return { ...addresses.private.test[arcVersion], ...addresses.private.dao[arcVersion], @@ -67,7 +67,7 @@ export function getContractAddresses() { } export function getOrgName() { - return require(`@daostack/migration/migration.json`).private.dao['0.0.1-rc.29'].name; + return require(`@daostack/migration/migration.json`).private.dao['0.0.1-rc.31'].name; } export async function getOptions(web3) { From b2d371bdd1e82cccbace0188a12b85fdfad7ef93 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 4 Nov 2019 17:18:26 +0100 Subject: [PATCH 27/38] fixed --- src/mappings/DAOTracker/datasource.yaml | 2 ++ test/0.0.1-rc.31/DAOTracker.spec.ts | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/mappings/DAOTracker/datasource.yaml b/src/mappings/DAOTracker/datasource.yaml index d95b03a3..332a1e74 100644 --- a/src/mappings/DAOTracker/datasource.yaml +++ b/src/mappings/DAOTracker/datasource.yaml @@ -2,6 +2,8 @@ abis: - DAOTracker entities: - DAOTrackerContract + - BlacklistedDAO + - ResetDAO templates: - mapping: Avatar version: 0.0.1-rc.31 diff --git a/test/0.0.1-rc.31/DAOTracker.spec.ts b/test/0.0.1-rc.31/DAOTracker.spec.ts index 097d340b..4b15958f 100644 --- a/test/0.0.1-rc.31/DAOTracker.spec.ts +++ b/test/0.0.1-rc.31/DAOTracker.spec.ts @@ -256,7 +256,9 @@ describe('DAOTracker', () => { blacklistedDAO(id: "${avatar.options.address.toLowerCase()}") { id address - tracker + tracker { + id + } explanationHash } }`, 5000); @@ -264,7 +266,9 @@ describe('DAOTracker', () => { expect(blacklistedDAO).toMatchObject({ id: avatar.options.address.toLowerCase(), address: avatar.options.address.toLowerCase(), - tracker: daoTracker.options.address.toLowerCase(), + tracker: { + id: daoTracker.options.address.toLowerCase() + }, explanationHash: '', }); } @@ -278,7 +282,9 @@ describe('DAOTracker', () => { blacklistedDAO(id: "${avatar.options.address.toLowerCase()}") { id address - tracker + tracker { + id + } explanationHash } }`, 5000); From 4e053174d51e583a0ecccacbc1c4ef7e9bc8a1ce Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 4 Nov 2019 17:19:42 +0100 Subject: [PATCH 28/38] fix lint --- test/0.0.1-rc.31/DAOTracker.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/0.0.1-rc.31/DAOTracker.spec.ts b/test/0.0.1-rc.31/DAOTracker.spec.ts index 4b15958f..969e9375 100644 --- a/test/0.0.1-rc.31/DAOTracker.spec.ts +++ b/test/0.0.1-rc.31/DAOTracker.spec.ts @@ -267,7 +267,7 @@ describe('DAOTracker', () => { id: avatar.options.address.toLowerCase(), address: avatar.options.address.toLowerCase(), tracker: { - id: daoTracker.options.address.toLowerCase() + id: daoTracker.options.address.toLowerCase(), }, explanationHash: '', }); From 3350d4cdf6a8615effc60cf847ab89d074856eee Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 02:41:06 +0100 Subject: [PATCH 29/38] new DAOtracker --- README.md | 24 ++++++-- docker-compose.yml | 2 +- ops/generate-contractsinfo.js | 15 ++++- ops/generate-subgraph.js | 58 +++++++++---------- ops/mappings.json | 21 +++++++ ops/templates.json | 24 ++++++++ ops/utils.js | 36 ++++++++++++ package-lock.json | 20 +------ package.json | 2 +- src/domain/index.ts | 3 +- src/domain/schema.graphql | 5 ++ src/mappings/DAOTracker/datasource.yaml | 11 +--- src/mappings/DAOTracker/mapping.ts | 49 ++++++++++++---- src/utils.ts | 29 +++++++++- .../DAOTracker.spec.ts | 2 +- test/{0.0.1-rc.31 => 0.0.1-rc.32}/util.ts | 4 +- 16 files changed, 218 insertions(+), 87 deletions(-) create mode 100644 ops/templates.json create mode 100644 ops/utils.js rename test/{0.0.1-rc.31 => 0.0.1-rc.32}/DAOTracker.spec.ts (99%) rename test/{0.0.1-rc.31 => 0.0.1-rc.32}/util.ts (98%) diff --git a/README.md b/README.md index d8a763a5..b4990bdb 100644 --- a/README.md +++ b/README.md @@ -72,12 +72,6 @@ In order to add support for a new contract follow these steps: list of entities that are written by the the mapping. 3. [`eventHandlers`](https://github.com/graphprotocol/graph-node/blob/master/docs/subgraph-manifest.md#1522-eventhandler) - map of solidity event signatures to event handlers in mapping code. - 4. [`templates`]([https://](https://github.com/graphprotocol/graph-node/blob/master/docs/subgraph-manifest.md#17-dynamicdatasource)) - list of datasource mappings that are created by the mapping. Each template entry refers to a mapping name, and a version to be used with that mapping. Example: - ```yaml - templates: - - mapping: Avatar - version: 0.0.1-rc.31 - ``` 4. `test/integration/.spec.ts` 3. Add your contract to `ops/mappings.json`. Under the JSON object for the network your contract is located at, under the `"mappings"` JSON array, add the following. @@ -112,6 +106,24 @@ In order to add support for a new contract follow these steps: To index a DAO please follow the instructions here: [https://github.com/daostack/subgraph/blob/master/documentations/Deployment.md#indexing-a-new-dao](https://github.com/daostack/subgraph/blob/master/documentations/Deployment.md#indexing-a-new-dao) +## Add a new datasource template + +Datasource templates allow you to index blockchain data from addresses the subgraph finds out about at runtime. This is used to dynamically index newly deployed DAOs. To add a new contract ABI that can be used as a template within your mappings, modify the `ops/templates.json` file like so: + +```json +{ + "templates": [ + ..., + { + "name": "", + "mapping": "", + "start_arcVersion": "", + "end_arcVersion": "(optional) if not given, all future versions of this `name`'s contract ABI will be added as a template for this mapping" + } + ] +} +``` + ## Deploy Subgraph To deploy the subgraph, please follow the instructions below: diff --git a/docker-compose.yml b/docker-compose.yml index deb0e392..8577e362 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,7 @@ services: ipfs: 'ipfs:5001' ethereum: 'private:http://ganache:8545' GRAPH_IPFS_TIMEOUT: '2' - GRAPH_MAX_IPFS_FILE_BYTES: '120000' + GRAPH_MAX_IPFS_FILE_BYTES: '200000' GRAPH_GRAPHQL_MAX_FIRST: '1000' ipfs: build: docker/ipfs diff --git a/ops/generate-contractsinfo.js b/ops/generate-contractsinfo.js index c96cdb1a..66f9cffb 100644 --- a/ops/generate-contractsinfo.js +++ b/ops/generate-contractsinfo.js @@ -1,8 +1,8 @@ const fs = require("fs"); -const yaml = require("js-yaml"); const { migrationFileLocation: defaultMigrationFileLocation, network } = require("./settings"); +const { forEachTemplate } = require("./utils"); const path = require("path"); -const currentDir = path.resolve(`${__dirname}`) +const currentDir = path.resolve(`${__dirname}`); /** * Generate a `src/contractinfo.js` file from `migration.json` @@ -20,7 +20,7 @@ async function generateContractInfo(opts={}) { const migration = JSON.parse(fs.readFileSync(require.resolve(opts.migrationFile), "utf-8")); let versions = migration[network].base - let buffer = "import { setContractInfo } from './utils';\n"; + let buffer = "import { setContractInfo, setTemplateInfo } from './utils';\n"; buffer += "// this code was generated automatically . please not edit it -:)\n"; buffer += "/* tslint:disable:max-line-length */\n"; @@ -53,6 +53,15 @@ async function generateContractInfo(opts={}) { }); buffer += "}\n"; + buffer += "\nexport function setTemplatesInfo(): void {\n"; + + forEachTemplate((name, mapping, arcVersion) => { + const templateName = arcVersion.replace(/\.|-/g, '_'); + buffer += ` setTemplateInfo('${name}', '${arcVersion}', '${name}_${templateName}');\n`; + }); + + buffer += "}\n"; + fs.writeFileSync( `${currentDir}/../src/contractsInfo.ts`, buffer, diff --git a/ops/generate-subgraph.js b/ops/generate-subgraph.js index a9e10e56..9907a596 100644 --- a/ops/generate-subgraph.js +++ b/ops/generate-subgraph.js @@ -3,6 +3,7 @@ const path = require("path") const yaml = require("js-yaml"); const { migrationFileLocation: defaultMigrationFileLocation, network ,startBlock} = require("./settings"); +const { versionToNum, forEachTemplate } = require("./utils"); const mappings = require("./mappings.json")[network].mappings; const { subgraphLocation: defaultSubgraphLocation } = require('./graph-cli') @@ -16,7 +17,6 @@ async function generateSubgraph(opts={}) { opts.subgraphLocation = opts.subgraphLocation || defaultSubgraphLocation; const addresses = JSON.parse(fs.readFileSync(migrationFile, "utf-8")); const missingAddresses = {}; - const templateDefinitions = {}; // Filter out 0.0.1-rc.18 & 0.0.1-rc.17 const latestMappings = mappings.filter(mapping => @@ -26,7 +26,7 @@ async function generateSubgraph(opts={}) { // Build our subgraph's datasources from the mapping fragments const dataSources = combineFragments( - latestMappings, false, addresses, missingAddresses, templateDefinitions + latestMappings, false, addresses, missingAddresses ).filter(el => el != null); // Throw an error if there are contracts that're missing an address @@ -39,11 +39,13 @@ async function generateSubgraph(opts={}) { throw Error(`The following contracts are missing addresses: ${missing.toString()}`); } + const templates = buildTemplates(); + const subgraph = { specVersion: "0.0.1", schema: { file: "./schema.graphql" }, dataSources, - templates: Object.values(templateDefinitions) + templates }; fs.writeFileSync( @@ -53,23 +55,21 @@ async function generateSubgraph(opts={}) { ); } -function combineFragments(fragments, isTemplate, addresses, missingAddresses, templateDefinitions) { +function combineFragments(fragments, isTemplate, addresses, missingAddresses) { let ids = []; return fragments.map(mapping => { const contract = mapping.name; const version = mapping.arcVersion; const fragment = `${__dirname}/../src/mappings/${mapping.mapping}/datasource.yaml`; - var abis, entities, eventHandlers, templates, file, yamlLoad, abi; + var abis, entities, eventHandlers, file, yamlLoad, abi; if (fs.existsSync(fragment)) { yamlLoad = yaml.safeLoad(fs.readFileSync(fragment, "utf-8")); file = `${__dirname}/../src/mappings/${mapping.mapping}/mapping.ts`; eventHandlers = yamlLoad.eventHandlers; entities = yamlLoad.entities; - templates = yamlLoad.templates; abis = (yamlLoad.abis || [contract]).map(contractName => { - const strlen = version.length - const versionNum = Number(version.slice(strlen - 2, strlen)); + const versionNum = versionToNum(version); if ((versionNum < 24) && (contractName === "UGenericScheme")) { return { @@ -155,31 +155,31 @@ function combineFragments(fragments, isTemplate, addresses, missingAddresses, te } }; - // If this datasource is requesting templates, - // build their definition if we haven't already - if (templates && templates.length) { - templates.forEach((template) => { - const { mapping, version } = template; - const name = `${mapping}${version}` - - // If we haven't processed it already - if (templateDefinitions[name] === undefined) { - // Avoid infinite recursion - templateDefinitions[name] = {}; - // Reuse this logic with the template requested - templateDefinitions[name] = combineFragments([{ - name: mapping, - mapping: mapping, - arcVersion: version - }], true, addresses, missingAddresses)[0]; - } - }); - } - return result; }); } +function buildTemplates() { + let results = []; + + forEachTemplate((name, mapping, arcVersion) => { + results.push( + ...combineFragments( + [{ + name, + mapping, + arcVersion + }], + true, + undefined, + undefined + ) + ); + }); + + return results; +} + if (require.main === module) { generateSubgraph().catch(err => { console.log(err); diff --git a/ops/mappings.json b/ops/mappings.json index 0d9b1981..87f44316 100644 --- a/ops/mappings.json +++ b/ops/mappings.json @@ -610,6 +610,13 @@ "dao": "base", "mapping": "Redeemer", "arcVersion": "0.0.1-rc.32" + }, + { + "name": "DAOTracker", + "contractName": "DAOTracker", + "dao": "base", + "mapping": "DAOTracker", + "arcVersion": "0.0.1-rc.32" } ] }, @@ -824,6 +831,13 @@ "dao": "base", "mapping": "GenesisProtocol", "arcVersion": "0.0.1-rc.24" + }, + { + "name": "DAOTracker", + "contractName": "DAOTracker", + "dao": "base", + "mapping": "DAOTracker", + "arcVersion": "0.0.1-rc.32" } ] }, @@ -969,6 +983,13 @@ "dao": "base", "mapping": "DAORegistry", "arcVersion": "0.0.1-rc.30" + }, + { + "name": "DAOTracker", + "contractName": "DAOTracker", + "dao": "base", + "mapping": "DAOTracker", + "arcVersion": "0.0.1-rc.32" } ] } diff --git a/ops/templates.json b/ops/templates.json new file mode 100644 index 00000000..597104e9 --- /dev/null +++ b/ops/templates.json @@ -0,0 +1,24 @@ +{ + "templates": [ + { + "name": "Avatar", + "mapping": "Avatar", + "start_arcVersion": "0.0.1-rc.16" + }, + { + "name": "Controller", + "mapping": "Controller", + "start_arcVersion": "0.0.1-rc.16" + }, + { + "name": "DAOToken", + "mapping": "DAOToken", + "start_arcVersion": "0.0.1-rc.16" + }, + { + "name": "Reputation", + "mapping": "Reputation", + "start_arcVersion": "0.0.1-rc.16" + } + ] +} diff --git a/ops/utils.js b/ops/utils.js new file mode 100644 index 00000000..e296e25f --- /dev/null +++ b/ops/utils.js @@ -0,0 +1,36 @@ +const fs = require("fs"); +const path = require("path"); +const currentDir = path.resolve(`${__dirname}`); + +function versionToNum(version) { + const strlen = version.length; + return Number(version.slice(strlen - 2, strlen)); +} + +function forEachTemplate(callback) { + const templates = JSON.parse(fs.readFileSync(`${currentDir}/templates.json`, "utf-8")).templates; + const abiDirectories = fs.readdirSync(`${currentDir}/../abis/`, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name); + + for (var template of templates) { + const { name, mapping, start_arcVersion, end_arcVersion } = template; + const startNum = versionToNum(start_arcVersion); + const endNum = end_arcVersion ? versionToNum(end_arcVersion) : undefined; + + // for each ABI directory, if it falls within start & end + for (var abiDirectory of abiDirectories) { + const arcVersion = abiDirectory; + const arcNum = versionToNum(arcVersion); + + if (arcNum >= startNum && (endNum === undefined || arcNum <= endNum)) { + callback(name, mapping, arcVersion); + } + } + } +} + +module.exports = { + versionToNum, + forEachTemplate +} diff --git a/package-lock.json b/package-lock.json index c81db527..723e5196 100644 --- a/package-lock.json +++ b/package-lock.json @@ -268,14 +268,6 @@ "yaml": "^1.5.1" }, "dependencies": { - "concat-stream": { - "version": "github:hugomrdias/concat-stream#057bc7b5d6d8df26c8cf00a3f151b6721a0a8034", - "from": "github:hugomrdias/concat-stream#feat/smaller", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^3.0.2" - } - }, "ipfs-http-client": { "version": "34.0.0", "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-34.0.0.tgz", @@ -338,16 +330,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "ndjson": { - "version": "github:hugomrdias/ndjson#4db16da6b42e5b39bf300c3a7cde62abb3fa3a11", - "from": "github:hugomrdias/ndjson#feat/readable-stream3", - "requires": { - "json-stringify-safe": "^5.0.1", - "minimist": "^1.2.0", - "split2": "^3.1.0", - "through2": "^3.0.0" - } } } }, @@ -12220,4 +12202,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 68f4b2eb..aa35056c 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "deploy": "rm -rf src/types && node ops/setup-env.js", "deploy:watch": "npm run deploy -- --watch", "docker:stop": "docker-compose down -v", - "docker:run": "node ops/set-docker-network.js private && docker-compose up -d", + "docker:run": "node ops/set-docker-network.js private && docker-compose up", "docker:run-kovan": "node ops/set-docker-network.js kovan && docker-compose up -d", "docker:run-rinkeby": "node ops/set-docker-network.js rinkeby && docker-compose up -d", "docker:run-mainnet": "node ops/set-docker-network.js mainnet && docker-compose up -d", diff --git a/src/domain/index.ts b/src/domain/index.ts index b7b76bb2..8512f610 100644 --- a/src/domain/index.ts +++ b/src/domain/index.ts @@ -1,5 +1,5 @@ import { Address, BigDecimal, BigInt, ByteArray, Bytes, crypto, Entity, store, Value} from '@graphprotocol/graph-ts'; -import { setContractsInfo } from '../contractsInfo'; +import { setContractsInfo, setTemplatesInfo } from '../contractsInfo'; import { NewContributionProposal, ProposalExecuted, @@ -208,6 +208,7 @@ export function handleRegisterScheme(avatar: Address, ); if (isFirstRegister == null) { setContractsInfo(); + setTemplatesInfo(); let dao = daoModule.insertNewDAO(avatar, nativeTokenAddress , nativeReputationAddress); insertToken(hexToAddress(dao.nativeToken), avatar.toHex()); insertReputation( diff --git a/src/domain/schema.graphql b/src/domain/schema.graphql index 21b0cf25..7ee61805 100644 --- a/src/domain/schema.graphql +++ b/src/domain/schema.graphql @@ -199,6 +199,11 @@ type ContractInfo @entity { address: Bytes! } +type TemplateInfo @entity { + id: ID! + templateName: String! +} + type Event @entity { id: ID! type: EventType! diff --git a/src/mappings/DAOTracker/datasource.yaml b/src/mappings/DAOTracker/datasource.yaml index 332a1e74..d54a96c6 100644 --- a/src/mappings/DAOTracker/datasource.yaml +++ b/src/mappings/DAOTracker/datasource.yaml @@ -4,17 +4,8 @@ entities: - DAOTrackerContract - BlacklistedDAO - ResetDAO -templates: - - mapping: Avatar - version: 0.0.1-rc.31 - - mapping: Controller - version: 0.0.1-rc.31 - - mapping: DAOToken - version: 0.0.1-rc.31 - - mapping: Reputation - version: 0.0.1-rc.31 eventHandlers: - - event: TrackDAO(indexed address,address,address,address) + - event: TrackDAO(indexed address,address,address,address,address,string) handler: handleTrackDAO - event: BlacklistDAO(indexed address,string) handler: handleBlacklistDAO diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index bb6dc43d..858624f3 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -8,17 +8,12 @@ import { import { AvatarContract, BlacklistedDAO, + ContractInfo, DAOTrackerContract, ResetDAO as ResetDAOEntity, UControllerOrganization, } from '../../types/schema'; -import { - Avatar_0_0_1_rc_31, - Controller_0_0_1_rc_31, - DAOToken_0_0_1_rc_31, - Reputation_0_0_1_rc_31, -} from '../../types/templates'; -import { equalStrings } from '../../utils'; +import { createTemplate, equalStrings, fetchTemplateName } from '../../utils'; export function getDAOTrackerContract(address: Address): DAOTrackerContract { let daoTracker = DAOTrackerContract.load(address.toHex()) as DAOTrackerContract; @@ -40,21 +35,51 @@ export function handleTrackDAO(event: TrackDAO): void { let controller = event.params._controller; let reputation = event.params._reputation; let daoToken = event.params._daoToken; + let sender = event.params._sender; + let arcVersion = event.params._arcVersion; // If the avatar already exists, early out if (AvatarContract.load(avatar.toHex()) != null) { return; } + // If the sender of the 'track' call is the DaoCreator contract, use its arcVersion + let daoCreatorInfo = ContractInfo.load(sender.toHex()); + if (daoCreatorInfo != null) { + if (equalStrings(daoCreatorInfo.name, 'DaoCreator')) { + arcVersion = daoCreatorInfo.version; + } + } + + let avatarTemplate = fetchTemplateName('Avatar', arcVersion); + let controllerTemplate = fetchTemplateName('Controller', arcVersion); + let reputationTemplate = fetchTemplateName('Reputation', arcVersion); + let daoTokenTemplate = fetchTemplateName('DAOToken', arcVersion); + + let missingTemplate = avatarTemplate == null || + reputationTemplate == null || + daoTokenTemplate == null; + + let universalController = UControllerOrganization.load(controller.toHex()) != null; + + if (universalController) { + missingTemplate = missingTemplate || controllerTemplate == null; + } + + if (missingTemplate) { + // We're missing a template version in the subgraph + return; + } + // Tell the subgraph to start indexing events from the: // Avatar, Controller, DAOToken, and Reputation contracts - Avatar_0_0_1_rc_31.create(avatar); - Reputation_0_0_1_rc_31.create(reputation); - DAOToken_0_0_1_rc_31.create(daoToken); + createTemplate(avatarTemplate, avatar); + createTemplate(reputationTemplate, reputation); + createTemplate(daoTokenTemplate, daoToken); // Track the Controller if it isn't a UController we're already tracking - if (UControllerOrganization.load(controller.toHex()) == null) { - Controller_0_0_1_rc_31.create(controller); + if (universalController === false) { + createTemplate(controllerTemplate, controller); } // Note, no additional work is needed here because... diff --git a/src/utils.ts b/src/utils.ts index d17e9fbe..42367d84 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,11 +4,12 @@ import { ByteArray, Bytes, crypto, + DataSourceTemplate, EthereumEvent, store, Value, } from '@graphprotocol/graph-ts'; -import { ContractInfo, Debug } from './types/schema'; +import { ContractInfo, Debug, TemplateInfo } from './types/schema'; export function concat(a: ByteArray, b: ByteArray): ByteArray { let out = new Uint8Array(a.length + b.length); @@ -74,7 +75,7 @@ export function equalStrings(a: string, b: string): boolean { export function setContractInfo(address: string, name: string, alias: string, version: string): void { let contractInfo = ContractInfo.load(address); if (contractInfo == null) { - contractInfo = new ContractInfo(address); + contractInfo = new ContractInfo(address); contractInfo.address = Address.fromString(address); contractInfo.name = name; contractInfo.alias = alias; @@ -82,3 +83,27 @@ export function setContractInfo(address: string, name: string, alias: string, ve contractInfo.save(); } } + +export function setTemplateInfo(name: string, version: string, templateName: string): void { + let id = name.concat(version); + let templateInfo = TemplateInfo.load(id); + if (templateInfo == null) { + templateInfo = new TemplateInfo(id); + templateInfo.templateName = templateName; + templateInfo.save(); + } +} + +export function fetchTemplateName(name: string, version: string): string | null { + let id = name.concat(version); + let templateInfo = TemplateInfo.load(id); + if (templateInfo == null) { + return null; + } else { + return templateInfo.templateName; + } +} + +export function createTemplate(templateName: string, address: Address): void { + DataSourceTemplate.create(templateName, [address.toHex()]); +} diff --git a/test/0.0.1-rc.31/DAOTracker.spec.ts b/test/0.0.1-rc.32/DAOTracker.spec.ts similarity index 99% rename from test/0.0.1-rc.31/DAOTracker.spec.ts rename to test/0.0.1-rc.32/DAOTracker.spec.ts index 969e9375..81b515e1 100644 --- a/test/0.0.1-rc.31/DAOTracker.spec.ts +++ b/test/0.0.1-rc.32/DAOTracker.spec.ts @@ -94,7 +94,7 @@ describe('DAOTracker', () => { } // Add the new DAO to the DAOTracker - await daoTracker.methods.track(avatar.options.address, controller.options.address) + await daoTracker.methods.track(avatar.options.address, controller.options.address, '0.0.1-rc.32') .send(); const { daotrackerContract } = await sendQuery(`{ diff --git a/test/0.0.1-rc.31/util.ts b/test/0.0.1-rc.32/util.ts similarity index 98% rename from test/0.0.1-rc.31/util.ts rename to test/0.0.1-rc.32/util.ts index 7c134dfd..cfda9862 100644 --- a/test/0.0.1-rc.31/util.ts +++ b/test/0.0.1-rc.32/util.ts @@ -54,7 +54,7 @@ export async function getWeb3() { export function getContractAddresses() { const addresses = require(`@daostack/migration/migration.json`); - let arcVersion = '0.0.1-rc.31'; + let arcVersion = '0.0.1-rc.32'; return { ...addresses.private.test[arcVersion], ...addresses.private.dao[arcVersion], @@ -67,7 +67,7 @@ export function getContractAddresses() { } export function getOrgName() { - return require(`@daostack/migration/migration.json`).private.dao['0.0.1-rc.31'].name; + return require(`@daostack/migration/migration.json`).private.dao['0.0.1-rc.32'].name; } export async function getOptions(web3) { From 336a558db625e36acaa63e6ba423fe2b11a09acf Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 02:59:21 +0100 Subject: [PATCH 30/38] revert --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa35056c..68f4b2eb 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "deploy": "rm -rf src/types && node ops/setup-env.js", "deploy:watch": "npm run deploy -- --watch", "docker:stop": "docker-compose down -v", - "docker:run": "node ops/set-docker-network.js private && docker-compose up", + "docker:run": "node ops/set-docker-network.js private && docker-compose up -d", "docker:run-kovan": "node ops/set-docker-network.js kovan && docker-compose up -d", "docker:run-rinkeby": "node ops/set-docker-network.js rinkeby && docker-compose up -d", "docker:run-mainnet": "node ops/set-docker-network.js mainnet && docker-compose up -d", From 918ad722b88dfe3d87d1214f55cf8c2250ad88ca Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 03:13:33 +0100 Subject: [PATCH 31/38] fix? --- ops/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ops/utils.js b/ops/utils.js index e296e25f..d73aba42 100644 --- a/ops/utils.js +++ b/ops/utils.js @@ -8,8 +8,8 @@ function versionToNum(version) { } function forEachTemplate(callback) { - const templates = JSON.parse(fs.readFileSync(`${currentDir}/templates.json`, "utf-8")).templates; - const abiDirectories = fs.readdirSync(`${currentDir}/../abis/`, { withFileTypes: true }) + const templates = require("./templates.json").templates; + const abiDirectories = fs.readdirSync(`${currentDir}/../abis`, { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); From 25cbf81dfcb810ac7506f0b62be001710b26a7c4 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 03:20:23 +0100 Subject: [PATCH 32/38] fix --- ops/utils.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ops/utils.js b/ops/utils.js index d73aba42..e60e895b 100644 --- a/ops/utils.js +++ b/ops/utils.js @@ -1,6 +1,5 @@ const fs = require("fs"); const path = require("path"); -const currentDir = path.resolve(`${__dirname}`); function versionToNum(version) { const strlen = version.length; @@ -9,7 +8,7 @@ function versionToNum(version) { function forEachTemplate(callback) { const templates = require("./templates.json").templates; - const abiDirectories = fs.readdirSync(`${currentDir}/../abis`, { withFileTypes: true }) + const abiDirectories = fs.readdirSync("abis", { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); From b43c982c63ff10a5ab0a3d3adedc9c70398d865f Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 03:29:04 +0100 Subject: [PATCH 33/38] ci pls work --- ops/generate-abis.js | 1 - ops/utils.js | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/ops/generate-abis.js b/ops/generate-abis.js index cf8acf99..33ede44d 100644 --- a/ops/generate-abis.js +++ b/ops/generate-abis.js @@ -1,5 +1,4 @@ const fs = require("fs-extra"); -const path = require("path"); /** * Fetch all abis from @daostack/migration into the `abis` folder. diff --git a/ops/utils.js b/ops/utils.js index e60e895b..a704fefd 100644 --- a/ops/utils.js +++ b/ops/utils.js @@ -1,5 +1,4 @@ const fs = require("fs"); -const path = require("path"); function versionToNum(version) { const strlen = version.length; @@ -8,7 +7,7 @@ function versionToNum(version) { function forEachTemplate(callback) { const templates = require("./templates.json").templates; - const abiDirectories = fs.readdirSync("abis", { withFileTypes: true }) + const abiDirectories = fs.readdirSync(`${__dirname}/../abis`, { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); From ea63c15d6a2ed8df055bfb5aab0026aee3f8725a Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 03:39:56 +0100 Subject: [PATCH 34/38] maybe this? --- ops/generate-abis.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops/generate-abis.js b/ops/generate-abis.js index 33ede44d..441e0614 100644 --- a/ops/generate-abis.js +++ b/ops/generate-abis.js @@ -4,7 +4,7 @@ const fs = require("fs-extra"); * Fetch all abis from @daostack/migration into the `abis` folder. */ async function generateAbis() { - fs.copy("node_modules/@daostack/migration/abis", "abis"); + fs.copySync("node_modules/@daostack/migration/abis", `${__dirname}/../abis`); } if (require.main === module) { From 98a82f9ce37021008ff7a87f39d87782fe80071d Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 16:32:37 +0100 Subject: [PATCH 35/38] DaoCreator only --- src/mappings/DAOTracker/mapping.ts | 10 +-- test/0.0.1-rc.32/DAOTracker.spec.ts | 101 +++++++++++----------------- 2 files changed, 45 insertions(+), 66 deletions(-) diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 858624f3..41e0bc77 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -45,10 +45,12 @@ export function handleTrackDAO(event: TrackDAO): void { // If the sender of the 'track' call is the DaoCreator contract, use its arcVersion let daoCreatorInfo = ContractInfo.load(sender.toHex()); - if (daoCreatorInfo != null) { - if (equalStrings(daoCreatorInfo.name, 'DaoCreator')) { - arcVersion = daoCreatorInfo.version; - } + if (daoCreatorInfo != null && equalStrings(daoCreatorInfo.name, 'DaoCreator')) { + arcVersion = daoCreatorInfo.version; + } else { + // We've chosen to disable tracking new DAOs that don't come from the DaoCreator, + // as it's a potential security vulnerability + return; } let avatarTemplate = fetchTemplateName('Avatar', arcVersion); diff --git a/test/0.0.1-rc.32/DAOTracker.spec.ts b/test/0.0.1-rc.32/DAOTracker.spec.ts index 81b515e1..ffb77e68 100644 --- a/test/0.0.1-rc.32/DAOTracker.spec.ts +++ b/test/0.0.1-rc.32/DAOTracker.spec.ts @@ -1,11 +1,8 @@ import { getContractAddresses, getOptions, getWeb3, sendQuery } from './util'; const DAOTracker = require('@daostack/arc/build/contracts/DAOTracker.json'); +const DaoCreator = require('@daostack/arc/build/contracts/DaoCreator.json'); const Avatar = require('@daostack/arc/build/contracts/Avatar.json'); -const Controller = require('@daostack/arc/build/contracts/Controller.json'); -const UController = require('@daostack/arc/build/contracts/UController.json'); -const DAOToken = require('@daostack/arc/build/contracts/DAOToken.json'); -const Reputation = require('@daostack/arc/build/contracts/Reputation.json'); const ContributionReward = require('@daostack/arc/build/contracts/ContributionReward.json'); const GenesisProtocol = require('@daostack/arc/build/contracts/GenesisProtocol.json'); @@ -14,7 +11,7 @@ describe('DAOTracker', () => { let addresses; let opts; let daoTracker; - let uController; + let daoCreator; let contributionReward; let genesisProtocol; let vmParamsHash; @@ -25,7 +22,7 @@ describe('DAOTracker', () => { addresses = getContractAddresses(); opts = await getOptions(web3); daoTracker = new web3.eth.Contract(DAOTracker.abi, addresses.DAOTracker, opts); - uController = new web3.eth.Contract(UController.abi, addresses.UController, opts); + daoCreator = new web3.eth.Contract(DaoCreator.abi, addresses.DaoCreator, opts); contributionReward = new web3.eth.Contract(ContributionReward.abi, addresses.ContributionReward, opts); genesisProtocol = await new web3.eth.Contract(GenesisProtocol.abi, addresses.GenesisProtocol, opts); @@ -68,34 +65,25 @@ describe('DAOTracker', () => { }); const e2eControllerTest = async (isUController: boolean) => { - // Start deploying a new DAO - const nativeToken = await new web3.eth.Contract(DAOToken.abi, undefined, opts) - .deploy({ data: DAOToken.bytecode, arguments: [ 'Test Token', 'TST', '10000000000' ] }) - .send(); - - const reputation = await new web3.eth.Contract(Reputation.abi, undefined, opts) - .deploy({ data: Reputation.bytecode, arguments: [] }) - .send(); - - const avatar = await new web3.eth.Contract(Avatar.abi, undefined, opts) - .deploy({ - data: Avatar.bytecode, - arguments: [ 'Test DAO', nativeToken.options.address, reputation.options.address ] }) - .send(); - - let controller; - - if (!isUController) { - controller = await new web3.eth.Contract(Controller.abi, undefined, opts) - .deploy({ data: Controller.bytecode, arguments: [ avatar.options.address ] }) - .send(); - } else { - controller = uController; - } + const uControllerAddr = isUController ? addresses.UController : '0x0000000000000000000000000000000000000000'; + + const tx = await daoCreator.methods.forgeOrg( + 'Test DAO', + 'Test Token', + 'TST', + [opts.from], + [0], + [0], + uControllerAddr, + 0, + ).send(); - // Add the new DAO to the DAOTracker - await daoTracker.methods.track(avatar.options.address, controller.options.address, '0.0.1-rc.32') - .send(); + const avatarAddress = tx.events.NewOrg.returnValues._avatar; + const avatar = await new web3.eth.Contract(Avatar.abi, avatarAddress, opts); + + const nativeTokenAddress = await avatar.methods.nativeToken().call(); + const reputationAddress = await avatar.methods.nativeReputation().call(); + const controllerAddress = await avatar.methods.owner().call(); const { daotrackerContract } = await sendQuery(`{ daotrackerContract(id: "${daoTracker.options.address.toLowerCase()}") { @@ -111,25 +99,20 @@ describe('DAOTracker', () => { owner: web3.eth.defaultAccount.toLowerCase(), }); - // Finish setting up the new DAO, and verify the contract entities are added - await reputation.methods.transferOwnership(controller.options.address).send(); - const { reputationContract } = await sendQuery(`{ - reputationContract(id: "${reputation.options.address.toLowerCase()}") { + reputationContract(id: "${reputationAddress.toLowerCase()}") { id address } }`, 5000); expect(reputationContract).toMatchObject({ - id: reputation.options.address.toLowerCase(), - address: reputation.options.address.toLowerCase(), + id: reputationAddress.toLowerCase(), + address: reputationAddress.toLowerCase(), }); - await nativeToken.methods.transferOwnership(controller.options.address).send(); - const { tokenContract } = await sendQuery(`{ - tokenContract(id: "${nativeToken.options.address.toLowerCase()}") { + tokenContract(id: "${nativeTokenAddress.toLowerCase()}") { id address owner @@ -137,13 +120,11 @@ describe('DAOTracker', () => { }`, 5000); expect(tokenContract).toMatchObject({ - id: nativeToken.options.address.toLowerCase(), - address: nativeToken.options.address.toLowerCase(), - owner: controller.options.address.toLowerCase(), + id: nativeTokenAddress.toLowerCase(), + address: nativeTokenAddress.toLowerCase(), + owner: controllerAddress.toLowerCase(), }); - await avatar.methods.transferOwnership(controller.options.address).send(); - const { avatarContract } = await sendQuery(`{ avatarContract(id: "${avatar.options.address.toLowerCase()}") { id @@ -159,22 +140,18 @@ describe('DAOTracker', () => { id: avatar.options.address.toLowerCase(), address: avatar.options.address.toLowerCase(), name: 'Test DAO', - nativeToken: nativeToken.options.address.toLowerCase(), - nativeReputation: reputation.options.address.toLowerCase(), - owner: controller.options.address.toLowerCase(), + nativeToken: nativeTokenAddress.toLowerCase(), + nativeReputation: reputationAddress.toLowerCase(), + owner: controllerAddress.toLowerCase(), }); - if (isUController) { - // Add the new organization to the UController - await controller.methods.newOrganization(avatar.options.address).send(); - } - // Add a scheme - await controller.methods.registerScheme( - contributionReward.options.address, - schemeParamsHash, - '0x0000001F', - avatar.options.address, + await daoCreator.methods.setSchemes( + avatarAddress, + [contributionReward.options.address], + [schemeParamsHash], + ['0x0000001F'], + '', ).send(); // Ensure the scheme is in the subgraph @@ -218,13 +195,13 @@ describe('DAOTracker', () => { id: avatar.options.address.toLowerCase(), name: 'Test DAO', nativeToken: { - id: nativeToken.options.address.toLowerCase(), + id: nativeTokenAddress.toLowerCase(), dao: { id: avatar.options.address.toLowerCase(), }, }, nativeReputation: { - id: reputation.options.address.toLowerCase(), + id: reputationAddress.toLowerCase(), dao: { id: avatar.options.address.toLowerCase(), }, From 8599ecc269ebbde83fbe80e45822b4e0af7a4530 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 17:21:45 +0100 Subject: [PATCH 36/38] Hardcoded Blacklist --- README.md | 13 +++++ ops/blacklist.json | 6 +++ ops/generate-contractsinfo.js | 14 ++++- package.json | 2 +- src/mappings/DAOTracker/datasource.yaml | 5 -- src/mappings/DAOTracker/mapping.ts | 69 +++---------------------- src/mappings/DAOTracker/schema.graphql | 12 ----- src/utils.ts | 15 +++++- test/0.0.1-rc.32/DAOTracker.spec.ts | 64 ----------------------- 9 files changed, 54 insertions(+), 146 deletions(-) create mode 100644 ops/blacklist.json diff --git a/README.md b/README.md index b4990bdb..ad7205e5 100644 --- a/README.md +++ b/README.md @@ -165,3 +165,16 @@ The docker images are available as: `daostack/subgraph-postgres:${network}-${migration-version}-${subgraph-version}` `daostack/subgraph-ipfs:${network}-${migration-version}-${subgraph-version}` + +## Blacklist a malicious DAO +Add the DAO's Avatar address to the `ops/blacklist.json` file in the proper network array. For example, blacklisting `0xF7074b67B4B7830694a6f58Df06375F00365d2c2` on mainnet would look like: +```json +{ + "private": [], + "kovan": [], + "rinkeby": [], + "mainnet": [ + "0xF7074b67B4B7830694a6f58Df06375F00365d2c2" + ] +} +``` diff --git a/ops/blacklist.json b/ops/blacklist.json new file mode 100644 index 00000000..acee2508 --- /dev/null +++ b/ops/blacklist.json @@ -0,0 +1,6 @@ +{ + "private": [], + "kovan": [], + "rinkeby": [], + "mainnet": [] +} diff --git a/ops/generate-contractsinfo.js b/ops/generate-contractsinfo.js index 66f9cffb..7916297c 100644 --- a/ops/generate-contractsinfo.js +++ b/ops/generate-contractsinfo.js @@ -20,8 +20,8 @@ async function generateContractInfo(opts={}) { const migration = JSON.parse(fs.readFileSync(require.resolve(opts.migrationFile), "utf-8")); let versions = migration[network].base - let buffer = "import { setContractInfo, setTemplateInfo } from './utils';\n"; - buffer += "// this code was generated automatically . please not edit it -:)\n"; + let buffer = "import {\n setBlacklistedDAO,\n setContractInfo,\n setTemplateInfo,\n} from './utils';\n"; + buffer += "\n// this code was generated automatically . please not edit it -:)\n"; buffer += "/* tslint:disable:max-line-length */\n"; buffer += "export function setContractsInfo(): void {\n"; @@ -62,6 +62,16 @@ async function generateContractInfo(opts={}) { buffer += "}\n"; + const blacklist = require("./blacklist.json")[network]; + + buffer += "\nexport function setBlacklistedDAOs(): void {\n"; + + blacklist.forEach(function(avatar) { + buffer += ` setBlacklistedDAO("${avatar.toLowerCase()}");\n`; + }); + + buffer += "}\n"; + fs.writeFileSync( `${currentDir}/../src/contractsInfo.ts`, buffer, diff --git a/package.json b/package.json index 68f4b2eb..d2f64de5 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "docker:run-mainnet": "node ops/set-docker-network.js mainnet && docker-compose up -d", "docker:rebuild": "docker-compose build", "docker:logs": "docker-compose logs --follow", - "jest": "jest --runInBand --forceExit", + "jest": "jest --runInBand --forceExit ./test/0.0.1-rc.32/", "lint": "tslint -c tslint.json 'src//**/*.ts' -e 'src//types/**/*.ts' && tslint -c tslint.json 'test/**/*.ts'", "migrate": "node ops/migrate.js", "test": "npm run deploy && jest --runInBand --forceExit", diff --git a/src/mappings/DAOTracker/datasource.yaml b/src/mappings/DAOTracker/datasource.yaml index d54a96c6..4e6bc4cb 100644 --- a/src/mappings/DAOTracker/datasource.yaml +++ b/src/mappings/DAOTracker/datasource.yaml @@ -3,11 +3,6 @@ abis: entities: - DAOTrackerContract - BlacklistedDAO - - ResetDAO eventHandlers: - event: TrackDAO(indexed address,address,address,address,address,string) handler: handleTrackDAO - - event: BlacklistDAO(indexed address,string) - handler: handleBlacklistDAO - - event: ResetDAO(indexed address,string) - handler: handleResetDAO diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index 41e0bc77..c1f70345 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -1,8 +1,6 @@ -import { Address, ipfs, store } from '@graphprotocol/graph-ts'; +import { Address } from '@graphprotocol/graph-ts'; import { - BlacklistDAO, DAOTracker, - ResetDAO, TrackDAO, } from '../../types/DAOTracker/DAOTracker'; import { @@ -10,9 +8,9 @@ import { BlacklistedDAO, ContractInfo, DAOTrackerContract, - ResetDAO as ResetDAOEntity, UControllerOrganization, } from '../../types/schema'; +import { setBlacklistedDAOs } from '../../contractsInfo'; import { createTemplate, equalStrings, fetchTemplateName } from '../../utils'; export function getDAOTrackerContract(address: Address): DAOTrackerContract { @@ -23,6 +21,7 @@ export function getDAOTrackerContract(address: Address): DAOTrackerContract { let daoTrackerSC = DAOTracker.bind(address); daoTracker.owner = daoTrackerSC.owner(); daoTracker.save(); + setBlacklistedDAOs(); } return daoTracker; } @@ -43,6 +42,11 @@ export function handleTrackDAO(event: TrackDAO): void { return; } + // If the avatar is blacklisted, early out + if (BlacklistedDAO.load(avatar.toHex()) != null) { + return; + } + // If the sender of the 'track' call is the DaoCreator contract, use its arcVersion let daoCreatorInfo = ContractInfo.load(sender.toHex()); if (daoCreatorInfo != null && equalStrings(daoCreatorInfo.name, 'DaoCreator')) { @@ -89,60 +93,3 @@ export function handleTrackDAO(event: TrackDAO): void { // * AvatarContract, ReputationContract, and TokenContract are added to the store // by the 'RegisterScheme' or 'OwnershipTransfered' events } - -export function handleBlacklistDAO(event: BlacklistDAO): void { - // Ensure the DAOTrackerContract has been added to the store - let daoTracker = getDAOTrackerContract(event.address); - - let avatar = event.params._avatar; - let explanationHash = event.params._explanationHash; - - // Add the BlacklistedDAO to the store - let blacklistedDAO = new BlacklistedDAO(avatar.toHex()); - blacklistedDAO.address = avatar; - blacklistedDAO.tracker = daoTracker.id; - blacklistedDAO.explanationHash = explanationHash; - - if (!equalStrings(explanationHash, '')) { - let explanation = ipfs.cat('/ipfs/' + explanationHash); - - if (explanation != null) { - blacklistedDAO.explanation = explanation.toString(); - } - } - - blacklistedDAO.save(); - - // If the DAO has been previously reset, remove that entity from the store - if (ResetDAOEntity.load(avatar.toHex())) { - store.remove('ResetDAO', avatar.toHex()); - } -} - -export function handleResetDAO(event: ResetDAO): void { - // Ensure the DAOTrackerContract has been added to the store - getDAOTrackerContract(event.address); - - let avatar = event.params._avatar; - let explanationHash = event.params._explanationHash; - - // Remove the BlacklistedDAO from the store - if (BlacklistedDAO.load(avatar.toHex())) { - store.remove('BlacklistedDAO', avatar.toHex()); - } - - // Add the ResetDAO entity to the store - let resetDAO = new ResetDAOEntity(avatar.toHex()); - resetDAO.address = avatar; - resetDAO.explanationHash = explanationHash; - - if (!equalStrings(explanationHash, '')) { - let explanation = ipfs.cat('/ipfs/' + explanationHash); - - if (explanation != null) { - resetDAO.explanation = explanation.toString(); - } - } - - resetDAO.save(); -} diff --git a/src/mappings/DAOTracker/schema.graphql b/src/mappings/DAOTracker/schema.graphql index 39a9301a..7f006e3f 100644 --- a/src/mappings/DAOTracker/schema.graphql +++ b/src/mappings/DAOTracker/schema.graphql @@ -2,20 +2,8 @@ type DAOTrackerContract @entity { id: ID! address: Bytes! owner: Bytes! - blacklisted: [BlacklistedDAO!] @derivedFrom(field: "tracker") } type BlacklistedDAO @entity { id: ID! - address: Bytes! - tracker: DAOTrackerContract! - explanationHash: String! - explanation: String -} - -type ResetDAO @entity { - id: ID! - address: Bytes! - explanationHash: String! - explanation: String } diff --git a/src/utils.ts b/src/utils.ts index 42367d84..aa04ad54 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -9,7 +9,12 @@ import { store, Value, } from '@graphprotocol/graph-ts'; -import { ContractInfo, Debug, TemplateInfo } from './types/schema'; +import { + BlacklistedDAO, + ContractInfo, + Debug, + TemplateInfo, +} from './types/schema'; export function concat(a: ByteArray, b: ByteArray): ByteArray { let out = new Uint8Array(a.length + b.length); @@ -107,3 +112,11 @@ export function fetchTemplateName(name: string, version: string): string | null export function createTemplate(templateName: string, address: Address): void { DataSourceTemplate.create(templateName, [address.toHex()]); } + +export function setBlacklistedDAO(address: string): void { + let blacklistedDAO = BlacklistedDAO.load(address); + if (blacklistedDAO == null) { + blacklistedDAO = new BlacklistedDAO(address); + blacklistedDAO.save(); + } +} diff --git a/test/0.0.1-rc.32/DAOTracker.spec.ts b/test/0.0.1-rc.32/DAOTracker.spec.ts index ffb77e68..2f5c1cf7 100644 --- a/test/0.0.1-rc.32/DAOTracker.spec.ts +++ b/test/0.0.1-rc.32/DAOTracker.spec.ts @@ -220,68 +220,4 @@ describe('DAOTracker', () => { it('UController e2e', async () => { await e2eControllerTest(true); }, 120000); - - it('Blacklist & Reset DAO', async () => { - const { avatar } = await e2eControllerTest(false); - - // Blacklist the deployed DAO - await daoTracker.methods.blacklist(avatar.options.address, '').send(); - - // Ensure the blacklisted DAO is in the subgraph - { - const { blacklistedDAO } = await sendQuery(`{ - blacklistedDAO(id: "${avatar.options.address.toLowerCase()}") { - id - address - tracker { - id - } - explanationHash - } - }`, 5000); - - expect(blacklistedDAO).toMatchObject({ - id: avatar.options.address.toLowerCase(), - address: avatar.options.address.toLowerCase(), - tracker: { - id: daoTracker.options.address.toLowerCase(), - }, - explanationHash: '', - }); - } - - // Reset the DAO - await daoTracker.methods.reset(avatar.options.address, '').send(); - - // Ensure the blacklisted DAO is no longer in the subgraph - { - const { blacklistedDAO } = await sendQuery(`{ - blacklistedDAO(id: "${avatar.options.address.toLowerCase()}") { - id - address - tracker { - id - } - explanationHash - } - }`, 5000); - - expect(blacklistedDAO).toBeFalsy(); - } - - // Ensure the reset DAO is in the subgraph - const { resetDAO } = await sendQuery(`{ - resetDAO(id: "${avatar.options.address.toLowerCase()}") { - id - address - explanationHash - } - }`); - - expect(resetDAO).toMatchObject({ - id: avatar.options.address.toLowerCase(), - address: avatar.options.address.toLowerCase(), - explanationHash: '', - }); - }, 120000); }); From 5cb7cdfa432c3efde6b5107bee7a3a9bdadf1cdc Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 17:22:04 +0100 Subject: [PATCH 37/38] revert --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d2f64de5..68f4b2eb 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "docker:run-mainnet": "node ops/set-docker-network.js mainnet && docker-compose up -d", "docker:rebuild": "docker-compose build", "docker:logs": "docker-compose logs --follow", - "jest": "jest --runInBand --forceExit ./test/0.0.1-rc.32/", + "jest": "jest --runInBand --forceExit", "lint": "tslint -c tslint.json 'src//**/*.ts' -e 'src//types/**/*.ts' && tslint -c tslint.json 'test/**/*.ts'", "migrate": "node ops/migrate.js", "test": "npm run deploy && jest --runInBand --forceExit", From 6ef73160e696ceebfc3e9f03111173b72175edc2 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 12 Nov 2019 17:35:11 +0100 Subject: [PATCH 38/38] fix lint --- ops/generate-contractsinfo.js | 3 ++- src/mappings/DAOTracker/mapping.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ops/generate-contractsinfo.js b/ops/generate-contractsinfo.js index 7916297c..4ee94a0a 100644 --- a/ops/generate-contractsinfo.js +++ b/ops/generate-contractsinfo.js @@ -67,9 +67,10 @@ async function generateContractInfo(opts={}) { buffer += "\nexport function setBlacklistedDAOs(): void {\n"; blacklist.forEach(function(avatar) { - buffer += ` setBlacklistedDAO("${avatar.toLowerCase()}");\n`; + buffer += ` setBlacklistedDAO('${avatar.toLowerCase()}');\n`; }); + buffer += " return;\n"; buffer += "}\n"; fs.writeFileSync( diff --git a/src/mappings/DAOTracker/mapping.ts b/src/mappings/DAOTracker/mapping.ts index c1f70345..4b075ada 100644 --- a/src/mappings/DAOTracker/mapping.ts +++ b/src/mappings/DAOTracker/mapping.ts @@ -1,4 +1,5 @@ import { Address } from '@graphprotocol/graph-ts'; +import { setBlacklistedDAOs } from '../../contractsInfo'; import { DAOTracker, TrackDAO, @@ -10,7 +11,6 @@ import { DAOTrackerContract, UControllerOrganization, } from '../../types/schema'; -import { setBlacklistedDAOs } from '../../contractsInfo'; import { createTemplate, equalStrings, fetchTemplateName } from '../../utils'; export function getDAOTrackerContract(address: Address): DAOTrackerContract {