Merge pull request #84 from unjapones/popa-addresses-by-voting-or-mining-key

(Improvement) Get validator's PoPA addresses by voting/mining key.
This commit is contained in:
Vadim Arasev 2018-10-03 12:04:36 +03:00 committed by GitHub
commit 52c3d2087c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 26 deletions

View File

@ -7,6 +7,7 @@ export default class AllValidators extends Component {
super(props)
this.getMetadataContract = this.getMetadataContract.bind(this)
this.getProofOfPhysicalAddressContract = this.getProofOfPhysicalAddressContract.bind(this)
this.getKeysManagerContract = this.getKeysManagerContract.bind(this)
this.state = {
validators: [],
loading: true
@ -46,8 +47,38 @@ export default class AllValidators extends Component {
if (popa === null) {
throw new Error(`ProofOfPhysicalAddress not deployed in the current network`)
}
const validatorsWalletAddresses = validators.map(validator => validator.address)
const validatorsPhysicalAddresses = await popa.getPhysicalAddressesOfWalletAddressArray(validatorsWalletAddresses)
// Get each validator's voting & mining key array (if voting key is present set it as the 1st element)
let validatorsVotingAndMiningKeys = await Promise.all(
validators.map((validator, index) => {
const miningKey = validators[index].address
return this.getKeysManagerContract()
.getVotingByMining(validator.address)
.then(votingKey => {
const isNotVotingKey =
votingKey === '0x0000000000000000000000000000000000000000' ||
votingKey === '0x00' ||
votingKey === '0x0' ||
votingKey === '0x'
return isNotVotingKey ? [miningKey] : [votingKey, miningKey]
})
})
)
// Get PoPA physical address of validator using voting & mining array
const addressRegisteredEvents = await popa.getAllAddressRegisteredEvents()
const getValidatorsPhysicalAddressesPromises = validatorsVotingAndMiningKeys.map(validatorKeys => {
return popa
.getPhysicalAddressesOfWalletAddress(validatorKeys[0], addressRegisteredEvents)
.then(getPhysicalAddressesResult => {
// If addresses not found and the keys array has an extra element, retry the fetch and return its result
return getPhysicalAddressesResult === null && validatorKeys.length > 1
? popa.getPhysicalAddressesOfWalletAddress(validatorKeys[1], addressRegisteredEvents)
: getPhysicalAddressesResult
})
})
const validatorsPhysicalAddresses = await Promise.all(getValidatorsPhysicalAddressesPromises)
augmentedValidators = validatorsPhysicalAddresses.map((physicalAddresses, index) => {
const validator = validators[index]
let validatorPhysicalAddresses
@ -107,6 +138,9 @@ export default class AllValidators extends Component {
getProofOfPhysicalAddressContract() {
return this.props.web3Config.proofOfPhysicalAddressContract
}
getKeysManagerContract() {
return this.props.web3Config.keysManager
}
render() {
const loading = this.state.loading ? <Loading netId={this.state.netId} /> : ''
const filtered = this.state.validators.filter((validator, index) => {

View File

@ -18,4 +18,7 @@ export default class KeysManager {
async miningKeyByVoting(votingKey) {
return await this.keysInstance.methods.miningKeyByVoting(votingKey).call()
}
async getVotingByMining(miningKey) {
return await this.keysInstance.methods.getVotingByMining(miningKey).call()
}
}

View File

@ -15,42 +15,41 @@ export default class ProofOfPhysicalAddress {
let proofOfPhysicalAddressAbi = await helpers.getABI(branch, 'ProofOfPhysicalAddress')
this.instance = new web3_10.eth.Contract(proofOfPhysicalAddressAbi, PROOF_OF_PHYSICAL_ADDRESS)
this.getPhysicalAddressesOfWalletAddressArray = this.getPhysicalAddressesOfWalletAddressArray.bind(this)
this.getPhysicalAddressesOfWalletAddress = this.getPhysicalAddressesOfWalletAddress.bind(this)
this.getAllEvents = this.getAllEvents.bind(this)
this.getAllAddressRegisteredEvents = this.getAllAddressRegisteredEvents.bind(this)
this.getPhysicalAddressesByWalletAddressAndKeccakIdentifierArray = this.getPhysicalAddressesByWalletAddressAndKeccakIdentifierArray.bind(
this
)
}
/**
* Given a wallet address array, return a promise that resolves to an array of physical addresses from
* PoPA contract.
* @param {String[]} walletAddressArray
* Given a wallet address, return a promise that resolves to an array of physical addresses from PoPA contract or null.
* If a cached registeredAddressEvents is provided, it will be used to get the corresponding keccakIdentifiers from it.
* @param {String} walletAddress
* @param {Object[]} registeredAddressEvents (optional)
* @return {Promise}
*/
async getPhysicalAddressesOfWalletAddressArray(walletAddressArray) {
let result = []
async getPhysicalAddressesOfWalletAddress(walletAddress, registeredAddressEvents) {
let result = null
try {
const registeredAddressEvents = await this.getAllEvents(REGISTER_ADDRESS_EVENT_NAME)
const allPhysicalAddressesPromises = walletAddressArray.map(walletAddress => {
let physicalAddresses = null
let keccakIdentifiers = registeredAddressEvents
.filter(event => event.returnValues.wallet === walletAddress)
.map(event => event.returnValues.keccakIdentifier)
if (!registeredAddressEvents) {
registeredAddressEvents = await this.getAllEvents(REGISTER_ADDRESS_EVENT_NAME)
}
if (keccakIdentifiers.length > 0) {
physicalAddresses = this.getPhysicalAddressesByWalletAddressAndKeccakIdentifierArray(
walletAddress,
keccakIdentifiers
).then(physicalAddresses => {
return physicalAddresses.length > 0 ? physicalAddresses : null
})
}
return Promise.resolve(physicalAddresses)
})
result = await Promise.all(allPhysicalAddressesPromises)
let keccakIdentifiers = registeredAddressEvents
.filter(event => event.returnValues.wallet === walletAddress)
.map(event => event.returnValues.keccakIdentifier)
if (keccakIdentifiers.length > 0) {
let physicalAddresses = await this.getPhysicalAddressesByWalletAddressAndKeccakIdentifierArray(
walletAddress,
keccakIdentifiers
)
result = physicalAddresses.length > 0 ? physicalAddresses : result
}
} catch (e) {
console.error(`Error in getPhysicalAddressesOfWalletAddressArray`, e)
console.error(`Error in getPhysicalAddressesOfWalletAddress`, e)
}
return result
}
@ -104,4 +103,12 @@ export default class ProofOfPhysicalAddress {
}
return result
}
/**
* Get all addressRegistered event objects.
* @return {Promise}
*/
async getAllAddressRegisteredEvents() {
return this.getAllEvents(REGISTER_ADDRESS_EVENT_NAME)
}
}