From f30b39e5237a4c08339401101726e0defc66e984 Mon Sep 17 00:00:00 2001 From: James Calfee Date: Wed, 14 Oct 2015 09:46:47 -0500 Subject: [PATCH 1/8] Initial address/account auth checks (on own branc pending test cases) #330 --- dl/src/stores/AccountStore.js | 108 ++++++++++++++++++------ web/app/components/Forms/MyAccounts.jsx | 2 +- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/dl/src/stores/AccountStore.js b/dl/src/stores/AccountStore.js index bb52089b47..ec9c51ed3e 100644 --- a/dl/src/stores/AccountStore.js +++ b/dl/src/stores/AccountStore.js @@ -8,6 +8,7 @@ import PrivateKeyStore from "./PrivateKeyStore" import validation from "common/validation" import ChainStore from "api/ChainStore" import AccountRefsStore from "stores/AccountRefsStore" +import AddressIndex from "stores/AddressIndex" /** * This Store holds information about accounts in this wallet @@ -89,10 +90,15 @@ class AccountStore extends BaseStore { continue } if(account == null) { - console.log("... ChainStore.getAccount("+account_name+") == null") + console.log("WARN: non-chain account name in linkedAccounts", account_name) continue } - if(this.getMyAuthorityForAccount(account) === "full") { + var auth = this.getMyAuthorityForAccount(account) + if(auth === undefined) { + this.state.update = true + continue + } + if(auth === "full") { accounts.push(account_name) } } @@ -101,40 +107,58 @@ class AccountStore extends BaseStore { /** @todo "partial" - @return string "none", "full", "partial" + @return string "none", "full", "partial" or undefined (pending a chain store lookup) */ - getMyAuthorityForAccount(account) { - return "full" // pending support for Addresses and Accounts - } - - // Balance claims will still use this as a security precaution - getMyAuthorityForAccount_pubkeyonly(account) { + getMyAuthorityForAccount(account, recursion_count = 1) { if (! account) return undefined - // @return 3 full, 2 partial, 0 none - function pubkeyThreshold(authority) { - var available = 0 - var required = authority.get("weight_threshold") - for (let k of authority.get("key_auths")) { - if (PrivateKeyStore.hasKey(k.get(0))) { - available += k.get(1) - } - if(available >= required) break - } - return available >= required ? 3 : available > 0 ? 2 : 0 - } - var owner = pubkeyThreshold(account.get("owner")) - if(owner == 3) return "full" - var active = pubkeyThreshold(account.get("active")) - if(active == 3) return "full" + var owner_authority = account.get("owner") + var active_authority = account.get("active") + + var owner_pubkey_threshold = pubkeyThreshold(owner_authority) + if(owner_pubkey_threshold == "full") return "full" + var active_pubkey_threshold = pubkeyThreshold(active_authority) + if(active_pubkey_threshold == "full") return "full" - if(owner == 2 || active == 2) return "partial" + var owner_address_threshold = addressThreshold(owner_authority) + if(owner_address_threshold == "full") return "full" + var active_address_threshold = addressThreshold(active_authority) + if(active_address_threshold == "full") return "full" + var owner_account_threshold, active_account_threshold + if(recursion_count < 3) { + owner_account_threshold = this._accountThreshold(owner_authority, recursion_count) + if ( owner_account_threshold === undefined ) return undefined + if(owner_account_threshold == "full") return "full" + active_account_threshold = this._accountThreshold(active_authority, recursion_count) + if ( active_account_threshold === undefined ) return undefined + if(active_account_threshold == "full") return "full" + } + if( + owner_pubkey_threshold === "partial" || active_pubkey_threshold === "partial" || + owner_address_threshold === "partial" || owner_address_threshold === "partial" || + owner_account_threshold === "parital" || active_account_threshold === "partial" + ) return "partial" return "none" } + _accountThreshold(authority, recursion_count) { + var account_auths = authority.get("account_auths") + if( ! account_auths.size ) return "none" + for (let a of account_auths) + // get all accounts in the queue for fetching + ChainStore.getAccount(a) + + for (let a of account_auths) { + var account = ChainStore.getAccount(a) + if(account === undefined) return undefined + return this.getMyAuthorityForAccount(account, ++recursion_count) + } + } + isMyAccount(account) { let authority = this.getMyAuthorityForAccount(account); + if( authority === undefined ) return undefined return authority === "partial" || authority === "full"; } @@ -224,3 +248,35 @@ class AccountStore extends BaseStore { } module.exports = alt.createStore(AccountStore, "AccountStore"); + +// @return 3 full, 2 partial, 0 none +function pubkeyThreshold(authority) { + var available = 0 + var required = authority.get("weight_threshold") + var key_auths = authority.get("key_auths") + for (let k of key_auths) { + if (PrivateKeyStore.hasKey(k.get(0))) { + available += k.get(1) + } + if(available >= required) break + } + return available >= required ? "full" : available > 0 ? "partial" : "none" +} + +// @return 3 full, 2 partial, 0 none +function addressThreshold(authority) { + var available = 0 + var required = authority.get("weight_threshold") + var address_auths = authority.get("address_auths") + if( ! address_auths.size) return "none" + var addresses = AddressIndex.getState().addresses + for (let k of address_auths) { + var address = k.get(0) + var pubkey = addresses.get(address) + if (PrivateKeyStore.hasKey(pubkey)) { + available += k.get(1) + } + if(available >= required) break + } + return available >= required ? "full" : available > 0 ? "partial" : "none" +} diff --git a/web/app/components/Forms/MyAccounts.jsx b/web/app/components/Forms/MyAccounts.jsx index e6f24225a0..0813e32991 100644 --- a/web/app/components/Forms/MyAccounts.jsx +++ b/web/app/components/Forms/MyAccounts.jsx @@ -15,7 +15,7 @@ export default class MyAccounts extends Component { render() { var account_names = this.props.accounts .filter( account => !!account ) - .filter( account => AccountStore.getMyAuthorityForAccount_pubkeyonly(account) === "full" ) + .filter( account => AccountStore.getMyAuthorityForAccount(account) === "full" ) .map( account => account.get("name") ).sort() return From 56ad52dfc60de6351783d3d6b77c329270784892 Mon Sep 17 00:00:00 2001 From: Alex Chien Date: Thu, 15 Oct 2015 01:18:58 +0800 Subject: [PATCH 2/8] correct fee rate translation close #328 --- web/app/assets/locales/locale-cn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/assets/locales/locale-cn.js b/web/app/assets/locales/locale-cn.js index c5cba48c1e..c28745611b 100644 --- a/web/app/assets/locales/locale-cn.js +++ b/web/app/assets/locales/locale-cn.js @@ -470,7 +470,7 @@ module.exports = { confirm_buy: "确认订单: 以 %(price_amount)s %(price_symbol)s 的价格,买入 %(buy_amount)s %(buy_symbol)s ", confirm_sell: "确认订单: 以 %(price_amount)s %(price_symbol)s 的价格,卖出 %(sell_amount)s %(sell_symbol)s ", settle: "清算价格", - core_rate: "喂价", + core_rate: "转账手续费汇率", squeeze: "强制平仓价", maintenance: "维持保证金价", your_price: "你的强平触发价", From f6f337453b9ea64c2706c7397a31a0113d581f8e Mon Sep 17 00:00:00 2001 From: svk31 Date: Wed, 14 Oct 2015 21:42:01 +0200 Subject: [PATCH 3/8] Add previous/next block navigation buttons to Block page, improve layout, fix some translations --- web/app/assets/locales/locale-en.js | 1 + web/app/components/Blockchain/Block.jsx | 31 +++++++++---------- web/app/components/Blockchain/Transaction.jsx | 1 - 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/web/app/assets/locales/locale-en.js b/web/app/assets/locales/locale-en.js index 6a781f4109..5e9a715f0f 100644 --- a/web/app/assets/locales/locale-en.js +++ b/web/app/assets/locales/locale-en.js @@ -361,6 +361,7 @@ precision: "Precision" }, asset: { + title: "Asset", not_found: "The asset %(name)s does not exist", summary: { asset_type: "Asset type", diff --git a/web/app/components/Blockchain/Block.jsx b/web/app/components/Blockchain/Block.jsx index 1ae337f68f..53530fdb26 100644 --- a/web/app/components/Blockchain/Block.jsx +++ b/web/app/components/Blockchain/Block.jsx @@ -75,7 +75,7 @@ class Block extends BaseComponent { !Immutable.is(nextProps.blocks, this.props.blocks) || nextProps.height !== this.props.height || nextProps.dynGlobalObject !== this.props.dynGlobalObject - ); + ); } _getBlock(height) { @@ -117,30 +117,29 @@ class Block extends BaseComponent { let height = parseInt(this.props.height, 10); let block = blocks.get(height); - if (!block) { - return null; - } - return (
-
-
- -

#{height}

+
+
+

#{height}

    -
  • : : {block ? + /> : null}
  • -
  • :
  • -
  • : {block.previous}
  • -
  • : {block.transactions.length}
  • +
  • : {block ? : null}
  • +
  • : {block ? block.previous : null}
  • +
  • : {block ? block.transactions.length : null}
- +
+
+
+ {block ? + /> : null}
diff --git a/web/app/components/Blockchain/Transaction.jsx b/web/app/components/Blockchain/Transaction.jsx index 836ecb77ea..804f949dd7 100644 --- a/web/app/components/Blockchain/Transaction.jsx +++ b/web/app/components/Blockchain/Transaction.jsx @@ -607,7 +607,6 @@ class Transaction extends React.Component { case "asset_publish_feed": color = "warning"; let {feed} = op[1]; - console.log("op:", op, feed); rows.push( From 3bad43bcc13e11a65667fe8ee9f1fbb88997e001 Mon Sep 17 00:00:00 2001 From: James Calfee Date: Wed, 14 Oct 2015 15:18:40 -0500 Subject: [PATCH 4/8] Tested implementation of address and account threshold #330 --- dl/src/dl_cli_index.js | 3 +- dl/src/stores/AccountStore.js | 135 ++++++++++++------------ web/app/components/Forms/MyAccounts.jsx | 4 +- 3 files changed, 73 insertions(+), 69 deletions(-) diff --git a/dl/src/dl_cli_index.js b/dl/src/dl_cli_index.js index 51e69ab59f..17cb18349a 100644 --- a/dl/src/dl_cli_index.js +++ b/dl/src/dl_cli_index.js @@ -15,7 +15,7 @@ import BackupActions from "actions/BackupActions" import alt from 'alt-instance' import iDB from 'idb-instance' - +import chain_config from "chain/config" module.exports = { @@ -24,6 +24,7 @@ module.exports = { AccountStore, BackupActions, ChainStore, + chain_config, alt, iDB, Apis, db: ()=> Apis.instance().db_api(), diff --git a/dl/src/stores/AccountStore.js b/dl/src/stores/AccountStore.js index ec9c51ed3e..540f985fb3 100644 --- a/dl/src/stores/AccountStore.js +++ b/dl/src/stores/AccountStore.js @@ -28,7 +28,7 @@ class AccountStore extends BaseStore { // onNewPrivateKeys: [ PrivateKeyActions.loadDbData, PrivateKeyActions.addKey ] }); this._export("loadDbData", "tryToSetCurrentAccount", "onCreateAccount", - "getMyAccounts", "isMyAccount", "getMyAuthorityForAccount"); + "getMyAccounts", "isMyAccount"); } _getInitialState() { @@ -93,73 +93,22 @@ class AccountStore extends BaseStore { console.log("WARN: non-chain account name in linkedAccounts", account_name) continue } - var auth = this.getMyAuthorityForAccount(account) + var auth = getMyAuthorityForAccount(account) if(auth === undefined) { this.state.update = true continue } - if(auth === "full") { + if(auth === 1) { accounts.push(account_name) } } return accounts.sort() } - - /** - @todo "partial" - @return string "none", "full", "partial" or undefined (pending a chain store lookup) - */ - getMyAuthorityForAccount(account, recursion_count = 1) { - if (! account) return undefined - - var owner_authority = account.get("owner") - var active_authority = account.get("active") - - var owner_pubkey_threshold = pubkeyThreshold(owner_authority) - if(owner_pubkey_threshold == "full") return "full" - var active_pubkey_threshold = pubkeyThreshold(active_authority) - if(active_pubkey_threshold == "full") return "full" - - var owner_address_threshold = addressThreshold(owner_authority) - if(owner_address_threshold == "full") return "full" - var active_address_threshold = addressThreshold(active_authority) - if(active_address_threshold == "full") return "full" - - var owner_account_threshold, active_account_threshold - if(recursion_count < 3) { - owner_account_threshold = this._accountThreshold(owner_authority, recursion_count) - if ( owner_account_threshold === undefined ) return undefined - if(owner_account_threshold == "full") return "full" - active_account_threshold = this._accountThreshold(active_authority, recursion_count) - if ( active_account_threshold === undefined ) return undefined - if(active_account_threshold == "full") return "full" - } - if( - owner_pubkey_threshold === "partial" || active_pubkey_threshold === "partial" || - owner_address_threshold === "partial" || owner_address_threshold === "partial" || - owner_account_threshold === "parital" || active_account_threshold === "partial" - ) return "partial" - return "none" - } - - _accountThreshold(authority, recursion_count) { - var account_auths = authority.get("account_auths") - if( ! account_auths.size ) return "none" - for (let a of account_auths) - // get all accounts in the queue for fetching - ChainStore.getAccount(a) - - for (let a of account_auths) { - var account = ChainStore.getAccount(a) - if(account === undefined) return undefined - return this.getMyAuthorityForAccount(account, ++recursion_count) - } - } isMyAccount(account) { - let authority = this.getMyAuthorityForAccount(account); - if( authority === undefined ) return undefined - return authority === "partial" || authority === "full"; + let weight = getMyAuthorityForAccount(account); + if( weight === undefined ) return undefined + return weight === 1 // full } onAccountSearch(payload) { @@ -249,26 +198,81 @@ class AccountStore extends BaseStore { module.exports = alt.createStore(AccountStore, "AccountStore"); -// @return 3 full, 2 partial, 0 none +/** @return threshold percent 1 full, .n partial, 0 none */ +function getMyAuthorityForAccount(account, recursion_count = 1) { + if (! account) return undefined + + var owner_authority = account.get("owner") + var owner_threshold = owner_authority.get("weight_threshold") + var active_authority = account.get("active") + var active_threshold = active_authority.get("weight_threshold") + + var owner_pubkey_threshold = pubkeyThreshold(owner_authority) + if(owner_pubkey_threshold >= owner_threshold) return 1 + var active_pubkey_threshold = pubkeyThreshold(active_authority) + if(active_pubkey_threshold >= active_threshold) return 1 + + var owner_address_threshold = addressThreshold(owner_authority) + if(owner_address_threshold >= owner_threshold) return 1 + var active_address_threshold = addressThreshold(active_authority) + if(active_address_threshold >= active_threshold) return 1 + + var owner_account_threshold, active_account_threshold + if(recursion_count < 3) { + owner_account_threshold = accountThreshold(owner_authority, recursion_count) + if ( owner_account_threshold === undefined ) return undefined + if(owner_account_threshold >= owner_threshold) return 1 + active_account_threshold = accountThreshold(active_authority, recursion_count) + if ( active_account_threshold === undefined ) return undefined + if(active_account_threshold >= active_threshold) return 1 + } + var threshold = 0 + threshold = Math.max(threshold, owner_pubkey_threshold / owner_threshold) + threshold = Math.max(threshold, active_pubkey_threshold / active_threshold) + threshold = Math.max(threshold, owner_address_threshold / owner_threshold) + threshold = Math.max(threshold, active_address_threshold / active_threshold) + threshold = Math.max(threshold, owner_account_threshold / owner_threshold) + threshold = Math.max(threshold, active_account_threshold / active_threshold) + return threshold +} + +/** @return sum available threshold >= 0 */ +function accountThreshold(authority, recursion_count) { + var account_auths = authority.get("account_auths") + if( ! account_auths.size ) return 0 + for (let k of account_auths) { + // get all accounts in the queue for fetching + var account_id = k.get(0) + ChainStore.getAccount(account_id) + } + var available = 0 + for (let k of account_auths) { + var account_id = k.get(0) + var account = ChainStore.getAccount(account_id) + if(account === undefined) return undefined + var weight = getMyAuthorityForAccount(account, ++recursion_count) + if( weight === 1) available += k.get(1) + } + return available +} + +/** @return 1 full, .n partial, 0 none */ function pubkeyThreshold(authority) { var available = 0 - var required = authority.get("weight_threshold") var key_auths = authority.get("key_auths") for (let k of key_auths) { if (PrivateKeyStore.hasKey(k.get(0))) { available += k.get(1) } - if(available >= required) break } - return available >= required ? "full" : available > 0 ? "partial" : "none" + return available } -// @return 3 full, 2 partial, 0 none +/** @return 1 full, .n partial, 0 none */ function addressThreshold(authority) { var available = 0 - var required = authority.get("weight_threshold") var address_auths = authority.get("address_auths") - if( ! address_auths.size) return "none" + if( ! address_auths.size) return 0 var addresses = AddressIndex.getState().addresses for (let k of address_auths) { var address = k.get(0) @@ -276,7 +280,6 @@ function addressThreshold(authority) { if (PrivateKeyStore.hasKey(pubkey)) { available += k.get(1) } - if(available >= required) break } - return available >= required ? "full" : available > 0 ? "partial" : "none" + return available } diff --git a/web/app/components/Forms/MyAccounts.jsx b/web/app/components/Forms/MyAccounts.jsx index 0813e32991..273e79c806 100644 --- a/web/app/components/Forms/MyAccounts.jsx +++ b/web/app/components/Forms/MyAccounts.jsx @@ -15,7 +15,7 @@ export default class MyAccounts extends Component { render() { var account_names = this.props.accounts .filter( account => !!account ) - .filter( account => AccountStore.getMyAuthorityForAccount(account) === "full" ) + .filter( account => AccountStore.isMyAccount(account) ) .map( account => account.get("name") ).sort() return @@ -28,4 +28,4 @@ export default class MyAccounts extends Component { this.props.onChange(account_name) } -} \ No newline at end of file +} From 70dc0e2444b56348eb2d4f1b6222d65e48793899 Mon Sep 17 00:00:00 2001 From: valzav Date: Wed, 14 Oct 2015 16:50:22 -0400 Subject: [PATCH 5/8] make electron linux package name to comply to standards --- electron/build/package.json | 10 +++++----- electron/tasks/release_linux.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/electron/build/package.json b/electron/build/package.json index 97e56ce2ab..fb6836ee4c 100644 --- a/electron/build/package.json +++ b/electron/build/package.json @@ -1,10 +1,10 @@ { - "name": "GrapheneOct5-light-wallet", - "productName": "GrapheneOct5-light-wallet", - "identifier": "org.bitshares.graphene", - "description": "BitShares - cryptocurrency and decentralized exchange", + "name": "Graphene_light", + "productName": "Graphene_light", + "identifier": "com.cryptonomex.graphene", + "description": "Graphene - financial smart contracts platform", "version": "0.0.1", - "author": "cryptonomex.com", + "author": "contact@cryptonomex.com", "main": "electron.js", "config": { "target": "development" diff --git a/electron/tasks/release_linux.js b/electron/tasks/release_linux.js index 5cfe843252..72123c7749 100644 --- a/electron/tasks/release_linux.js +++ b/electron/tasks/release_linux.js @@ -20,7 +20,7 @@ var init = function () { tmpDir = projectDir.dir('./tmp', { empty: true }); releasesDir = projectDir.dir('./releases'); manifest = projectDir.read('build/package.json', 'json'); - packName = manifest.name + '_' + manifest.version; + packName = manifest.name.toLowerCase() + '_' + manifest.version; packDir = tmpDir.dir(packName); readyAppDir = packDir.cwd('opt', manifest.name); From 1f953142228075cd4cede3281204c7610e305db2 Mon Sep 17 00:00:00 2001 From: valzav Date: Wed, 14 Oct 2015 16:50:49 -0400 Subject: [PATCH 6/8] cosmetic css updates --- web/app/assets/index-dev.html | 10 ++++++++-- web/app/assets/index.html | 10 ++++++++-- web/app/components/Explorer/witnesses.scss | 5 +++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/web/app/assets/index-dev.html b/web/app/assets/index-dev.html index e1bd0809f4..3913c758f5 100644 --- a/web/app/assets/index-dev.html +++ b/web/app/assets/index-dev.html @@ -7,10 +7,16 @@ Graphene diff --git a/web/app/assets/index.html b/web/app/assets/index.html index 00c7575969..cd7be9f54f 100644 --- a/web/app/assets/index.html +++ b/web/app/assets/index.html @@ -7,10 +7,16 @@ Graphene diff --git a/web/app/components/Explorer/witnesses.scss b/web/app/components/Explorer/witnesses.scss index 00b598f037..dd0609146f 100644 --- a/web/app/components/Explorer/witnesses.scss +++ b/web/app/components/Explorer/witnesses.scss @@ -1,6 +1,7 @@ .active-witness { > td { - background-color: rgba(80, 210, 194, 0.74902); + background-color: rgba(80, 210, 194, 0.4); + transition: background-color 0.6s ease; } } @@ -11,4 +12,4 @@ .view-switcher { padding-top: 1rem; text-align: right; -} \ No newline at end of file +} From 90c5dc3da13c2908340738595c4c70f1e3afdb1b Mon Sep 17 00:00:00 2001 From: valzav Date: Wed, 14 Oct 2015 16:57:10 -0400 Subject: [PATCH 7/8] copy built dist files to electron/build --- web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/package.json b/web/package.json index 3dedaf8a78..63b1bc5eda 100644 --- a/web/package.json +++ b/web/package.json @@ -16,7 +16,7 @@ "scripts": { "test": "jest", "start": "node server.js", - "build": "webpack --config conf/webpack-prod.js --progress --profile --colors" + "build": "webpack --config conf/webpack-prod.js --progress --profile --colors; echo 'copying to electron/build..'; cp -r dist/* ../electron/build/; echo 'done.'" }, "dependencies": { "alt": "~0.17.1", From 3ede9d56e506c7aa8f1dcc0570f5845a2b5ce28e Mon Sep 17 00:00:00 2001 From: James Calfee Date: Wed, 14 Oct 2015 16:03:25 -0500 Subject: [PATCH 8/8] Comment cleanup #330 --- dl/src/stores/AccountStore.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/dl/src/stores/AccountStore.js b/dl/src/stores/AccountStore.js index 540f985fb3..ca98f2e0b2 100644 --- a/dl/src/stores/AccountStore.js +++ b/dl/src/stores/AccountStore.js @@ -236,7 +236,6 @@ function getMyAuthorityForAccount(account, recursion_count = 1) { return threshold } -/** @return sum available threshold >= 0 */ function accountThreshold(authority, recursion_count) { var account_auths = authority.get("account_auths") if( ! account_auths.size ) return 0 @@ -256,7 +255,6 @@ function accountThreshold(authority, recursion_count) { return available } -/** @return 1 full, .n partial, 0 none */ function pubkeyThreshold(authority) { var available = 0 var key_auths = authority.get("key_auths") @@ -268,7 +266,6 @@ function pubkeyThreshold(authority) { return available } -/** @return 1 full, .n partial, 0 none */ function addressThreshold(authority) { var available = 0 var address_auths = authority.get("address_auths")