Skip to content
Permalink
Browse files

feat: fetch minimal data and cache where possible (#167)

* feat: fetch minimal data and cache where possible

* chore: cleanup
  • Loading branch information...
satello committed Aug 13, 2018
1 parent d994aac commit 0b8670f905514c86299615df53991746de801e01
@@ -15,6 +15,8 @@ class Arbitrable extends ContractImplementation {
*/
constructor(web3Provider, contractArtifact, contractAddress) {
super(web3Provider, contractArtifact, contractAddress)

this.metaEvidenceCache = {}
}

/**
@@ -23,6 +25,9 @@ class Arbitrable extends ContractImplementation {
* and make an http request to the resource.
*/
getMetaEvidence = async () => {
if (this.metaEvidenceCache[this.contractAddress])
return this.metaEvidenceCache[this.contractAddress]

const metaEvidenceLog = await EventListener.getEventLogs(
this,
'MetaEvidence',
@@ -43,6 +48,7 @@ class Arbitrable extends ContractImplementation {
if (metaEvidenceResponse.status >= 400)
throw new Error(`Unable to fetch meta-evidence at ${metaEvidenceUri}`)

this.metaEvidenceCache[this.contractAddress] = metaEvidenceResponse.body || metaEvidenceResponse
return metaEvidenceResponse.body || metaEvidenceResponse
}

@@ -20,6 +20,10 @@ class Kleros extends ContractImplementation {
*/
constructor(web3Provider, contractAddress, artifact = klerosArtifact) {
super(web3Provider, artifact, contractAddress)
this._disputeDeadlineCache = {}
this._appealCreationTimestampCache = {}
this._appealRuledAtTimestampCache = {}
this._openDisputesCache = {}
}

/**
@@ -348,7 +352,7 @@ class Kleros extends ContractImplementation {
* @param {number} disputeId - The index of the dispute.
* @returns {object} - The dispute data from the contract.
*/
getDispute = async disputeId => {
getDispute = async (disputeId, withVoteCount = false) => {
await this.loadContract()

try {
@@ -357,22 +361,21 @@ class Kleros extends ContractImplementation {
const rulingChoices = dispute[3].toNumber()

let voteCounters = []
let status
for (let appeal = 0; appeal <= numberOfAppeals; appeal++) {
const voteCounts = []
for (let choice = 0; choice <= rulingChoices; choice++)
voteCounts.push(
this.contractInstance
.getVoteCount(disputeId, appeal, choice)
.then(v => v.toNumber())
)
voteCounters.push(voteCounts)
}
const status = await this.contractInstance.disputeStatus(disputeId)
if (withVoteCount) {
for (let appeal = 0; appeal <= numberOfAppeals; appeal++) {
const voteCounts = []
for (let choice = 0; choice <= rulingChoices; choice++)
voteCounts.push(
this.contractInstance
.getVoteCount(disputeId, appeal, choice)
.then(v => v.toNumber())
)
voteCounters.push(voteCounts)
}

;[voteCounters, status] = await Promise.all([
Promise.all(voteCounters.map(voteCounts => Promise.all(voteCounts))),
this.contractInstance.disputeStatus(disputeId)
])
voteCounters = await Promise.all(voteCounters.map(voteCounts => Promise.all(voteCounts)))
}

return {
arbitratorAddress: this.contractAddress,
@@ -385,7 +388,7 @@ class Kleros extends ContractImplementation {
arbitrationFeePerJuror: this._Web3Wrapper.fromWei(dispute[5], 'ether'),
state: dispute[6].toNumber(),
voteCounters,
status: status.toNumber()
status: status ? status.toNumber() : null
}
// eslint-disable-next-line no-unused-vars
} catch (err) {
@@ -580,6 +583,8 @@ class Kleros extends ContractImplementation {
await this.loadContract()

const currentSession = await this.getSession()
if (this._openDisputesCache[currentSession])
return this._openDisputesCache[currentSession]
const openDisputes = []

let disputeId = 0
@@ -607,6 +612,7 @@ class Kleros extends ContractImplementation {
disputeId++
}

this._openDisputesCache[currentSession] = openDisputes
return openDisputes
}

@@ -659,6 +665,8 @@ class Kleros extends ContractImplementation {
* @returns {number[]} an array of timestamps
*/
getAppealRuledAtTimestamp = async session => {
if (this._appealRuledAtTimestampCache[session])
return this._appealRuledAtTimestampCache[session]
const eventLog = await this._getNewPeriodEventLogForSession(
session,
arbitratorConstants.PERIOD.APPEAL
@@ -670,7 +678,9 @@ class Kleros extends ContractImplementation {
eventLog.blockNumber
)

return ruledAtTimestamp * 1000
const timestamp = ruledAtTimestamp * 1000
this._appealRuledAtTimestampCache[session] = timestamp
return timestamp
}

/**
@@ -679,6 +689,9 @@ class Kleros extends ContractImplementation {
* @returns {number[]} an array of timestamps
*/
getDisputeDeadlineTimestamp = async session => {
if (this._disputeDeadlineCache[session])
return this._disputeDeadlineCache[session]

const eventLog = await this._getNewPeriodEventLogForSession(
session,
arbitratorConstants.PERIOD.VOTE
@@ -695,7 +708,9 @@ class Kleros extends ContractImplementation {
eventLog.blockNumber
)

return (periodLength + periodStartTimestamp) * 1000
const deadline = (periodLength + periodStartTimestamp) * 1000
this._disputeDeadlineCache[session] = deadline
return deadline
}

/**
@@ -704,6 +719,8 @@ class Kleros extends ContractImplementation {
* @returns {number[]} an array of timestamps
*/
getAppealCreationTimestamp = async session => {
if (this._appealCreationTimestampCache[session])
return this._appealCreationTimestampCache[session]
const eventLog = await this._getNewPeriodEventLogForSession(
session,
arbitratorConstants.PERIOD.EXECUTE
@@ -716,7 +733,9 @@ class Kleros extends ContractImplementation {
eventLog.blockNumber
)

return createdAtTimestamp * 1000
const timestamp = createdAtTimestamp * 1000
this._appealCreationTimestampCache[session] = timestamp
return timestamp
}

/**
@@ -302,7 +302,7 @@ class Disputes {
const arbitratorAddress = this._ArbitratorInstance.getContractAddress()
// Get dispute data from contract. Also get the current session and period.
const [dispute, period, session] = await Promise.all([
this._ArbitratorInstance.getDispute(disputeId),
this._ArbitratorInstance.getDispute(disputeId, true),
this._ArbitratorInstance.getPeriod(),
this._ArbitratorInstance.getSession()
])
@@ -347,9 +347,9 @@ class Disputes {
const lastSession = dispute.firstSession + dispute.numberOfAppeals
const appealJuror = []
const appealRulings = []

for (let appeal = 0; appeal <= dispute.numberOfAppeals; appeal++) {
const isLastAppeal = dispute.firstSession + appeal === lastSession

// Get appeal data
const draws = appealDraws[appeal] || []
let canRule = false
@@ -378,7 +378,7 @@ class Disputes {
// Wait for parallel requests to complete
;[ruling, canRule] = await Promise.all(rulingPromises)

let jurorRuling = []
let jurorRuling = null
// if can't rule that means they already did or they missed it
if (!canRule) {
jurorRuling = await this._ArbitratorInstance.getVoteForJuror(
@@ -16,6 +16,7 @@ class StoreProviderWrapper {
constructor(storeProviderUri) {
this._storeUri = storeProviderUri
this._storeQueue = new PromiseQueue()
this._cachedProfiles = {}
}

/**
@@ -25,10 +26,15 @@ class StoreProviderWrapper {
* @param {string} uri uri to call
* @returns {promise} promise that returns result of request. wait on this if you need it to be syncronous
*/
queueWriteRequest = (getBodyFn, verb, uri = null) =>
this._storeQueue.fetch(() =>
queueWriteRequest = (getBodyFn, verb, uri = null, userAddress) => {
// Clear cache on write TODO update cache after every write
this._cachedProfiles[userAddress] = null

return this._storeQueue.fetch(() =>
getBodyFn().then(result => httpRequest(verb, uri, result))
)
}


/**
* If we know we are waiting on some other write before we want to read we can add a read request to the end of the queue.
@@ -62,6 +68,7 @@ class StoreProviderWrapper {
'GET',
`${this._storeUri}/${userAddress}`
)
this._cachedProfiles[userAddress] = httpResponse.body

return httpResponse.body
}

0 comments on commit 0b8670f

Please sign in to comment.
You can’t perform that action at this time.