Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Update validators when they change #1083

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added

* storing balance, tx history and delegations locally to serve an old state faster @faboweb
* added error message for missing network config @faboweb

### Fixed

* added error message for missing network config @faboweb
* testnets not properly available after download @faboweb
* Tell the main process when we switch to the mock network. @NodeGuy

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,26 +169,26 @@ Write down the 12 word secret phrase to be able to import an account that holds
Copy the configuration files (assuming you are in the Voyager dir):

```bash
$ mkdir builds/testnets/local-testnet
$ cp ~/.gaiad-testnet/config/{genesis.json,config.toml} builds/testnets/local-testnet/
$ mkdir app/networks/local-testnet
$ cp ~/.gaiad-testnet/config/{genesis.json,config.toml} app/networks/local-testnet/
```

Enter your local node as a seed:

```bash
$ sed -i.bak 's/seeds = ""/seeds = "localhost"/g' ./builds/testnets/local-testnet/config.toml
$ sed -i.bak 's/seeds = ""/seeds = "localhost"/g' ./app/networks/local-testnet/config.toml
```

Activate TX indexing in your local node:

```bash
$ sed -i.bak 's/index_all_tags = true/index_all_tags = false/g' ./builds/testnets/local-testnet/config.toml
$ sed -i.bak 's/index_all_tags = true/index_all_tags = false/g' ./app/networks/local-testnet/config.toml
```

Store the gaia version used in your local testnet:

```bash
$ ./builds/Gaia/{OS}/gaiad version > ./builds/testnets/local-testnet/gaiaversion.txt
$ ./builds/Gaia/{OS}/gaiad version > ./app/networks/local-testnet/gaiaversion.txt
```

Start your local node:
Expand Down
2 changes: 1 addition & 1 deletion app/networks
63 changes: 59 additions & 4 deletions app/src/renderer/connectors/lcdClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,67 @@ Object.assign(Client.prototype, {
},
tx: argReq("GET", "/txs"),

// staking
updateDelegations: req("POST", "/stake/delegations"),
/* ============ STAKE ============ */

// Get all delegations information from a delegator
getDelegator: function(addr) {
return req("GET", `/stake/delegators/${addr}`).call(this)
},
// Get all txs from a delegator
getDelegatorTxs: function(addr) {
return req("GET", `/stake/delegators/${addr}/txs`).call(this)
},
// Get a specific tx from a delegator
getDelegatorTx: function(addr, id, types) {
if (types === "") {
return req("GET", `/stake/delegators/${addr}/txs`).call(this)
} else {
return req("GET", `/stake/delegators/${addr}/txs?type=${types}`).call(
this
)
}
},
// // Query all validators that a delegator is bonded to
// getDelegatorValidators: function(delegatorAddr) {
// return req("GET", `/stake/delegators/${delegatorAddr}/validators`).call(this)
// },
// // Query a validator info that a delegator is bonded to
// getDelegatorValidator: function(delegatorAddr, validatorAddr) {
// return req("GET", `/stake/delegators/${delegatorAddr}/validators/${validatorAddr}`).call(this)
// },

// Get a list containing all the validator candidates
getValidators: req("GET", "/stakes/validators/"),
// Get information from a validator
getValidator: function(addr) {
return req("GET", `/stake/validators/${addr}`).call(this)
},
// // Get all of the validator bonded delegators
// getValidatorDelegators: function(addr) {
// return req("GET", `/stake/validator/${addr}/delegators`).call(this)
// },

// Get the list of the validators in the latest validator set
getValidatorSet: req("GET", "/validatorsets/latest"),

updateDelegations: function(delegatorAddr) {
return req("POST", `/stake/delegators/${delegatorAddr}/delegations`)
},

candidates: req("GET", "/stake/validators"),
getValidators: req("GET", "/validatorsets/latest"),
queryDelegation: function(delegator, validator) {
return req("GET", `/stake/${delegator}/delegation/${validator}`).call(this)
// Query a delegation between a delegator and a validator
queryDelegation: function(delegatorAddr, validatorAddr) {
return req(
"GET",
`/stake/delegators/${delegatorAddr}/delegations/${validatorAddr}`
).call(this)
},
queryUnbonding: function(delegatorAddr, validatorAddr) {
return req(
"GET",
`/stake/delegators/${delegatorAddr}/unbonding_delegations/${validatorAddr}`
).call(this)
}
})

Expand Down
12 changes: 12 additions & 0 deletions app/src/renderer/connectors/lcdClientMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,21 @@ module.exports = {
return delegator[validatorAddress]
},
async candidates() {
// sort validators by power
state.candidates.sort(function(candidate1, candidate2) {
let power1 = candidate1.tokens + candidate1.delegator_shares
let power2 = candidate2.tokens + candidate2.delegator_shares
return power2 - power1
})
return state.candidates
},
async getValidators() {
// sort validators by power
state.candidates.sort(function(candidate1, candidate2) {
let power1 = candidate1.tokens + candidate1.delegator_shares
let power2 = candidate2.tokens + candidate2.delegator_shares
return power2 - power1 // sort in DESC order
})
return {
block_height: 1,
validators: state.candidates
Expand Down
5 changes: 2 additions & 3 deletions app/src/renderer/vuex/modules/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,13 @@ export default function({ node }) {
}

const actions = {
setLastHeader({ state, rootState, dispatch }, header) {
setLastHeader({ state, rootState }, header) {
state.lastHeader = header

// TODO do this somewhere else probably
if (!rootState.wallet.zoneIds.find(x => x === header.chain_id)) {
rootState.wallet.zoneIds.unshift(header.chain_id)
}

dispatch("maybeUpdateValidators", header)
},
async reconnect({ commit }) {
if (state.stopConnecting) return
Expand Down Expand Up @@ -93,6 +91,7 @@ export default function({ node }) {
}
)

dispatch("validatorUpdateSubscribe")
dispatch("walletSubscribe")
dispatch("checkNodeHalted")
dispatch("pollRPCConnection")
Expand Down
42 changes: 42 additions & 0 deletions app/src/renderer/vuex/modules/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ export default ({ node }) => {
const state = {
validators: [],
loading: false,
subscription: false,
validatorHash: null
}

const mutations = {
setValidators(state, validators) {
state.validators = validators
},
updateValidator(state, index, updatedValidator) {
state.validators[index] = updatedValidator
},
addValidator(state, validator) {
state.validators.push(validator)
},
setValidatorHash(state, validatorHash) {
state.validatorHash = validatorHash
}
Expand Down Expand Up @@ -39,6 +46,41 @@ export default ({ node }) => {
if (validatorHash === state.validatorHash) return
commit("setValidatorHash", validatorHash)
dispatch("getValidators")
},
validatorUpdateSubscribe({ state, commit, dispatch }) {
// Return if already subscribed to updates
if (state.subscription) return

// TODO move to common file since subscribeToBlock also uses it
function error(err) {
if (err.data === "already subscribed") {
console.error("Tryed to subscribe to an already subscribed rpc event")
return
}
dispatch("nodeHasHalted")
console.error(
`Error subscribing to new validator set updates: ${
err.message
} ${err.data || ""}`
)
}
node.rpc.subscribe(
{ query: "tm.event = 'ValidatorSetUpdates'" },
(err, event) => {
if (err) return error(err)
// https://github.com/tendermint/tendermint/pull/2161/files#diff-76d6626766e8d862e9acb34c166664b5
for (var validator in event.data.value.validator_updates) {
if (validator.power == 0) {
let dumpedValIdx = state.validators.findIndex(
v => v.pubkey == validator.pubkey
)
commit("updateValidator", dumpedValIdx, validator)
} else {
commit("addValidator", validator)
}
}
}
)
}
}

Expand Down
2 changes: 1 addition & 1 deletion tasks/build/testnets/localBuild.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

if [ ! -f $(pwd)/../../../builds/gaia/linux_amd64/gaiad ]; then
if [ ! -f builds/Gaia/linux_amd64/gaiad ]; then
printf "Gaia missing; building first.\n"
(cd ../../.. && yarn build:gaia)
fi
Expand Down
7 changes: 0 additions & 7 deletions tasks/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,6 @@ function startRendererServer() {
}

module.exports = async function(networkPath) {
if (!fs.existsSync(networkPath)) {
console.error(
"The network configuration for the network you want to connect to doesn't exist. Have you run `yarn build:testnets` to download the latest configurations?"
)
process.exit()
}

let renderProcess = await startRendererServer()

console.log(
Expand Down
15 changes: 15 additions & 0 deletions test/unit/specs/store/validators.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,19 @@ describe("Module: Validators", () => {
store.dispatch("reconnected")
expect(node.rpc.validators).not.toHaveBeenCalled()
})

it("should not error when subscribing without previous subscription", async () => {
store.state.wallet.subscribed = false
store.dispatch("validatorUpdateSubscribe")
})

it("should handle ignore already subscribed errors", () => {
console.error = jest.fn()
node.rpc.subscribe = (query, cb) => {
cb({ message: "expected error", data: "already subscribed" })
}
store.dispatch("validatorUpdateSubscribe")
expect(console.error.mock.calls.length).toBe(1)
expect(store.dispatch).not.toHaveBeenCalledWith("nodeHasHalted")
})
})
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2689,8 +2689,8 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"

escodegen@^1.6.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.10.0.tgz#f647395de22519fbd0d928ffcf1d17e0dec2603e"
version "1.11.0"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589"
dependencies:
esprima "^3.1.3"
estraverse "^4.2.0"
Expand Down