From 03bd49cf649a676c36f28fc9e2397af8b31bd44a Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Wed, 18 Dec 2019 15:18:12 -0500 Subject: [PATCH] fix(@embark/rpc-manager): fix duplicated accounts in rpc manager Was caused by the fact that each rpc-modifier got its own node accounts, but once the eth_accounts modifier is enabled, the "node" accounts are always going to contain the custom accounts too Now, the node accounts are set once eth_accounts is initiated, so that every modifier is on the same page Also implement a second layer of protection to make sure that if a duplication happens, it is gotten rid of --- packages/core/utils/src/accountParser.js | 17 +++++++++++++++-- .../plugins/rpc-manager/src/lib/eth_accounts.ts | 3 ++- packages/plugins/rpc-manager/src/lib/index.ts | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/core/utils/src/accountParser.js b/packages/core/utils/src/accountParser.js index 4a934af57..d58ff3b7a 100644 --- a/packages/core/utils/src/accountParser.js +++ b/packages/core/utils/src/accountParser.js @@ -3,7 +3,7 @@ const bip39 = require("bip39"); const hdkey = require('ethereumjs-wallet/hdkey'); const ethereumjsWallet = require('ethereumjs-wallet'); const fs = require('fs'); -import {getHexBalanceFromString} from './web3Utils'; +import {getHexBalanceFromString, toChecksumAddress} from './web3Utils'; const {utils} = require('web3'); const path = require('path'); @@ -31,7 +31,20 @@ export default class AccountParser { accounts.push(account); }); } - return accounts; + // Clean up accounts duplicated + return accounts.filter((acct, index) => { + const sameAccountIndex = accounts.findIndex((acct2, index2) => { + if (index === index2) { + return false; + } + const addr1 = acct.address || acct; + const addr2 = acct2.address || acct2; + // Two different entries have the same address + return toChecksumAddress(addr1) === toChecksumAddress(addr2); + }); + // Only keep the account if there is no duplicate and if there is one, only keep the one an address or the first one in the list + return (sameAccountIndex === -1 || (acct.privateKey && (!accounts[sameAccountIndex].privateKey || sameAccountIndex > index))); + }); } /*eslint complexity: ["error", 30]*/ diff --git a/packages/plugins/rpc-manager/src/lib/eth_accounts.ts b/packages/plugins/rpc-manager/src/lib/eth_accounts.ts index 6845003ba..740cb7c55 100644 --- a/packages/plugins/rpc-manager/src/lib/eth_accounts.ts +++ b/packages/plugins/rpc-manager/src/lib/eth_accounts.ts @@ -26,7 +26,8 @@ export default class EthAccounts extends RpcModifier { } private async init() { - await this.nodeAccounts; + const nodeAccounts = await this.nodeAccounts; + this.rpcModifierEvents.request2("nodeAccounts:updated", nodeAccounts); this.embark.registerActionForEvent("blockchain:proxy:response", this.ethAccountsResponse.bind(this)); } diff --git a/packages/plugins/rpc-manager/src/lib/index.ts b/packages/plugins/rpc-manager/src/lib/index.ts index 49922d125..4c4258fbd 100644 --- a/packages/plugins/rpc-manager/src/lib/index.ts +++ b/packages/plugins/rpc-manager/src/lib/index.ts @@ -51,6 +51,7 @@ export default class RpcManager { } private async updateAccounts(updatedNodeAccounts: any[], cb: Callback) { + this._nodeAccounts = updatedNodeAccounts; for (const modifier of this.modifiers) { await (modifier.nodeAccounts = Promise.resolve(updatedNodeAccounts)); }