From 9bece8a9cb0099c1a1fcdbc6b31e7d0661b0540e Mon Sep 17 00:00:00 2001
From: Sam Vitello
Date: Thu, 22 Feb 2018 17:09:06 -0500
Subject: [PATCH 1/4] update createdAt and ruledAt timestamps
---
src/abstractWrappers/Disputes.js | 169 +++++++++++++++++++-------
src/abstractWrappers/Notifications.js | 66 ++++------
src/kleros.js | 3 +-
src/utils/StoreProviderWrapper.js | 8 +-
src/utils/Web3Wrapper.js | 2 +
5 files changed, 164 insertions(+), 84 deletions(-)
diff --git a/src/abstractWrappers/Disputes.js b/src/abstractWrappers/Disputes.js
index d5df842..04a274e 100644
--- a/src/abstractWrappers/Disputes.js
+++ b/src/abstractWrappers/Disputes.js
@@ -28,6 +28,7 @@ class Disputes extends AbstractWrapper {
contractAddress = arbitratorAddress,
address = account
) => {
+ console.log("adding dispute for " + address)
const disputeId = event.args._disputeID.toNumber()
const disputeData = await this.getDataForDispute(
contractAddress,
@@ -36,7 +37,12 @@ class Disputes extends AbstractWrapper {
)
// if listener is a party in dispute add to store
if (disputeData.partyA === address || disputeData.partyB === address) {
- await this._updateStoreForDispute(contractAddress, disputeId, address)
+ console.log("should be for partyA")
+ const blockNumber = event.blockNumber
+ const block = this._Arbitrator._Web3Wrapper.getBlock(blockNumber)
+
+ // add new dispute with timestamp
+ const dispute = await this._updateStoreForDispute(contractAddress, disputeId, address, block.timestamp)
}
}
@@ -97,6 +103,95 @@ class Disputes extends AbstractWrapper {
)
}
+ addDisputeRulingHandler = async (
+ arbitratorAddress,
+ account,
+ callback
+ ) => {
+ if (!this._eventListener) return
+
+ const _disputeRulingHandler = async (
+ event,
+ contractAddress = arbitratorAddress,
+ address = account,
+ notificationCallback = callback
+ ) => {
+ console.log("in handler")
+ const newPeriod = event.args._period.toNumber()
+ const txHash = event.transactionHash
+ // send appeal possible notifications
+ if (newPeriod === PERIODS.APPEAL) {
+ console.log("doing the do")
+ this._checkArbitratorWrappersSet()
+ const userProfile = await this._StoreProvider.getUserProfile(address)
+ // contract data
+ const arbitratorData = await this._Arbitrator.getData(contractAddress, address)
+ const currentDisputes = []
+ let disputeId = 0
+ const currentSession = arbitratorData.session
+
+ let dispute
+ while (1) {
+ // iterate over all disputes (FIXME inefficient)
+ try {
+ dispute = await this._Arbitrator.getDispute(contractAddress, disputeId)
+ if (dispute.arbitratedContract === NULL_ADDRESS) break
+ // session + number of appeals
+ const disputeSession = dispute.firstSession + dispute.numberOfAppeals
+ // if dispute not in current session skip
+ if (disputeSession !== currentSession) {
+ disputeId++
+ dispute = await this._Arbitrator.getDispute(contractAddress, disputeId)
+ continue
+ }
+
+ const ruling = await this._Arbitrator.currentRulingForDispute(contractAddress, disputeId)
+
+ if (_.findIndex(userProfile.disputes, dispute => {
+ return (dispute.disputeId === disputeId && dispute.arbitratorAddress === contractAddress)
+ }) >= 0) {
+ await this._StoreProvider.newNotification(
+ address,
+ txHash,
+ disputeId, // use disputeId instead of logIndex since it doens't have its own event
+ NOTIFICATION_TYPES.APPEAL_POSSIBLE,
+ 'A ruling has been made. Appeal is possible',
+ {
+ disputeId,
+ contractAddress,
+ ruling
+ }
+ )
+ // get ruledAt from block timestamp
+ const blockNumber = event.blockNumber
+ const block = this._Arbitrator._Web3Wrapper.getBlock(blockNumber)
+ // add ruledAt to store
+ await this._updateStoreForDispute(contractAddress, disputeId, address, null, block.timestamp)
+
+ if (callback) {
+ const userProfile = await this._StoreProvider.getUserProfile(address)
+ const notification = _.filter(userProfile.notifications, notification => {
+ return (notification.txHash === txHash && notification.logIndex === disputeId)
+ })
+
+ if (notification) {
+ callback(notification[0])
+ }
+ }
+ }
+ // check next dispute
+ disputeId += 1
+ } catch (e) {
+ // getDispute(n) throws an error if index out of range
+ break
+ }
+ }
+ }
+ }
+
+ await this._eventListener.registerArbitratorEvent('NewPeriod', _disputeRulingHandler)
+ }
+
// **************************** //
// * Public * //
// **************************** //
@@ -123,7 +218,6 @@ class Disputes extends AbstractWrapper {
)
if (!txHash) throw new Error('unable to pay arbitration fee for party A')
- await this._storeNewDispute(arbitrableContractAddress, account)
return txHash
} catch (err) {
throw new Error(err)
@@ -151,39 +245,14 @@ class Disputes extends AbstractWrapper {
)
if (!txHash) throw new Error('unable to pay arbitration fee for party B')
- await this._storeNewDispute(arbitrableContractAddress, account)
return txHash
}
/**
- * If there is a dispute in contract update store.
- * @param {string} arbitrableContractAddress - The arbitrable contract's address.
- * @param {string} account - The account.
- */
- _storeNewDispute = async (arbitrableContractAddress, account) => {
- this._checkArbitratorWrappersSet()
- this._checkArbitrableWrappersSet()
-
- const arbitrableContractData = await this._ArbitrableContract.getData(
- arbitrableContractAddress
- )
-
- if (
- arbitrableContractData.status === contractConstants.STATUS.DISPUTE_CREATED
- ) {
- await this._updateStoreForDispute(
- arbitrableContractData.arbitrator,
- arbitrableContractData.disputeId,
- account
- )
- }
- }
-
- /**
- * Get disputes for user with extra data from arbitrated transaction and store.
- * @param {string} arbitratorAddress - Address of Kleros contract.
- * @param {string} account - Address of user.
- * @returns {object[]} - Dispute data objects for user.
+ * Get disputes for user with extra data from arbitrated transaction and store
+ * @param {string} arbitratorAddress address of Kleros contract
+ * @param {string} account address of user
+ * @return {object[]} dispute data objects for user
*/
getDisputesForUser = async (arbitratorAddress, account) => {
// FIXME don't like having to call this every fnc
@@ -400,12 +469,18 @@ class Disputes extends AbstractWrapper {
}
/**
- * update store with new dispute data
- * @param {string} arbitratorAddress Address address of arbitrator contract
- * @param {int} disputeId index of dispute
- * @param {string} account address of party to update dispute or
- */
- _updateStoreForDispute = async (arbitratorAddress, disputeId, account) => {
+ * update store with new dispute data
+ * @param {string} arbitratorAddress Address address of arbitrator contract
+ * @param {int} disputeId index of dispute
+ * @param {string} account address of party to update dispute or
+ */
+ _updateStoreForDispute = async (
+ arbitratorAddress,
+ disputeId,
+ account,
+ createdAt,
+ ruledAt
+ ) => {
const disputeData = await this.getDataForDispute(
arbitratorAddress,
disputeId,
@@ -425,7 +500,9 @@ class Disputes extends AbstractWrapper {
disputeData.fee,
disputeData.information,
disputeData.justification,
- disputeData.resolutionOptions
+ disputeData.resolutionOptions,
+ createdAt ? createdAt : disputeData.createdAt,
+ ruledAt ? ruledAt : disputeData.ruledAt
).body
// update profile for account
@@ -435,9 +512,11 @@ class Disputes extends AbstractWrapper {
disputeData.arbitratorAddress,
disputeData.disputeId,
disputeData.votes.length > 0,
- false,
- 0
+ disputeData.hasRuled,
+ disputeData.netPNK ? disputeData.netPNK : 0
)
+
+ return dispute
}
/**
@@ -561,6 +640,8 @@ class Disputes extends AbstractWrapper {
let votes = []
let hasRuled = false
let netPNK = 0
+ let createdAt
+ let ruledAt
if (account) {
votes = await this.getVotesForJuror(arbitratorAddress, disputeId, account)
try {
@@ -572,6 +653,8 @@ class Disputes extends AbstractWrapper {
isJuror = userData.isJuror
hasRuled = userData.hasRuled
netPNK = userData.netPNK
+ createdAt = userData.createdAt
+ ruledAt = userData.ruledAt
// eslint-disable-next-line no-unused-vars
} catch (err) {
// fetching dispute will fail if it hasn't been added to the store yet. this is ok we can just not return store data
@@ -622,8 +705,10 @@ class Disputes extends AbstractWrapper {
hasRuled,
ruling,
evidence,
- netPNK
- }
+ netPNK,
+ ruledAt,
+ createdAt
+ })
}
}
diff --git a/src/abstractWrappers/Notifications.js b/src/abstractWrappers/Notifications.js
index e3b35c3..8402979 100644
--- a/src/abstractWrappers/Notifications.js
+++ b/src/abstractWrappers/Notifications.js
@@ -160,46 +160,34 @@ class Notifications extends AbstractWrapper {
}
// Repartition and execute
- if (currentPeriod === arbitratorConstants.PERIOD.EXECUTE) {
- await Promise.all(
- userProfile.disputes.map(async dispute => {
- const disputeData = await this._Arbitrator.getDispute(
- dispute.arbitratorAddress,
- dispute.disputeId
- )
-
- if (
- disputeData.firstSession + disputeData.numberOfAppeals ===
- currentSession
- ) {
- if (disputeData.state <= disputeConstants.STATE.RESOLVING) {
- notifications.push(
- this._createNotification(
- notificationConstants.TYPE.CAN_REPARTITION,
- 'Ready to repartition dispute',
- {
- disputeId: dispute.disputeId,
- arbitratorAddress: dispute.arbitratorAddress
- }
- )
- )
- } else if (
- disputeData.state === disputeConstants.STATE.EXECUTABLE
- ) {
- notifications.push(
- this._createNotification(
- notificationConstants.TYPE.CAN_EXECUTE,
- 'Ready to execute dispute',
- {
- disputeId: dispute.disputeId,
- arbitratorAddress: dispute.arbitratorAddress
- }
- )
- )
- }
+ if (currentPeriod === PERIODS.EXECUTE) {
+ console.log("Starting....")
+ await Promise.all(userProfile.disputes.map(async dispute => {
+ const disputeData = await this._Arbitrator.getDispute(dispute.arbitratorAddress, dispute.disputeId)
+ if (disputeData.firstSession + disputeData.numberOfAppeals === currentSession) {
+ if (disputeData.state <= DISPUTE_STATES.RESOLVING) {
+ notifications.push(this._createNotification(
+ NOTIFICATION_TYPES.CAN_REPARTITION,
+ "Ready to repartition dispute",
+ {
+ disputeId: dispute.disputeId,
+ arbitratorAddress: dispute.arbitratorAddress
+ }
+ ))
+ console.log("did stuff")
+ } else if (disputeData.state === DISPUTE_STATES.EXECUTABLE) {
+ notifications.push(this._createNotification(
+ NOTIFICATION_TYPES.CAN_EXECUTE,
+ "Ready to execute dispute",
+ {
+ disputeId: dispute.disputeId,
+ arbitratorAddress: dispute.arbitratorAddress
+ }
+ ))
}
- })
- )
+ }
+ }))
+ console.log("Done....")
}
return notifications
diff --git a/src/kleros.js b/src/kleros.js
index bcd9dba..e159866 100644
--- a/src/kleros.js
+++ b/src/kleros.js
@@ -85,7 +85,8 @@ class Kleros {
await this.disputes.addDisputeEventListener(arbitratorAddress, account)
await this.disputes.addTokenShiftToJurorProfileEventListener(
arbitratorAddress,
- account
+ account,
+ callback
)
await this.notifications.registerNotificationListeners(
arbitratorAddress,
diff --git a/src/utils/StoreProviderWrapper.js b/src/utils/StoreProviderWrapper.js
index 96f44db..e03bf43 100644
--- a/src/utils/StoreProviderWrapper.js
+++ b/src/utils/StoreProviderWrapper.js
@@ -218,7 +218,9 @@ class StoreProviderWrapper {
fee,
information,
justification,
- resolutionOptions
+ resolutionOptions,
+ createdAt,
+ ruledAt
) => {
const httpResponse = await this._makeRequest(
'POST',
@@ -238,7 +240,9 @@ class StoreProviderWrapper {
fee,
information,
justification,
- resolutionOptions
+ resolutionOptions,
+ createdAt,
+ ruledAt
})
)
diff --git a/src/utils/Web3Wrapper.js b/src/utils/Web3Wrapper.js
index e42a585..bbe065c 100644
--- a/src/utils/Web3Wrapper.js
+++ b/src/utils/Web3Wrapper.js
@@ -32,6 +32,8 @@ class Web3Wrapper {
blockNumber = () => this._web3.eth.blockNumber
+ getBlock = () => this._web3.eth.getBlock
+
doesContractExistAtAddressAsync = async address => {
const code = await this._web3.eth.getCode(address)
// Regex matches 0x0, 0x00, 0x in order to accommodate poorly implemented clients
From 8e9cafa1e75c621298fea7af1b5e067e5c5115f2 Mon Sep 17 00:00:00 2001
From: Sam Vitello
Date: Tue, 27 Feb 2018 16:52:03 -0500
Subject: [PATCH 2/4] feat(disputes): createdAt and ruledAt timestamps added in
events
---
src/abstractWrappers/Disputes.js | 193 ++++++++++++++++----------
src/abstractWrappers/Notifications.js | 65 +++++----
src/constants/eth.js | 2 +-
src/kleros.js | 5 +
src/utils/StoreProviderWrapper.js | 5 +-
src/utils/Web3Wrapper.js | 2 +-
tests/kleros.test.js | 35 +++--
7 files changed, 185 insertions(+), 122 deletions(-)
diff --git a/src/abstractWrappers/Disputes.js b/src/abstractWrappers/Disputes.js
index 04a274e..1dc421f 100644
--- a/src/abstractWrappers/Disputes.js
+++ b/src/abstractWrappers/Disputes.js
@@ -2,7 +2,7 @@ import _ from 'lodash'
import * as ethConstants from '../constants/eth'
import * as arbitratorConstants from '../constants/arbitrator'
-import * as contractConstants from '../constants/contract'
+import * as notificationConstants from '../constants/notification'
import AbstractWrapper from './AbstractWrapper'
@@ -28,7 +28,6 @@ class Disputes extends AbstractWrapper {
contractAddress = arbitratorAddress,
address = account
) => {
- console.log("adding dispute for " + address)
const disputeId = event.args._disputeID.toNumber()
const disputeData = await this.getDataForDispute(
contractAddress,
@@ -37,12 +36,16 @@ class Disputes extends AbstractWrapper {
)
// if listener is a party in dispute add to store
if (disputeData.partyA === address || disputeData.partyB === address) {
- console.log("should be for partyA")
const blockNumber = event.blockNumber
const block = this._Arbitrator._Web3Wrapper.getBlock(blockNumber)
// add new dispute with timestamp
- const dispute = await this._updateStoreForDispute(contractAddress, disputeId, address, block.timestamp)
+ await this._updateStoreForDispute(
+ contractAddress,
+ disputeId,
+ address,
+ block.timestamp * 1000
+ )
}
}
@@ -103,11 +106,13 @@ class Disputes extends AbstractWrapper {
)
}
- addDisputeRulingHandler = async (
- arbitratorAddress,
- account,
- callback
- ) => {
+ /**
+ * Event listener that sends notification when a dispute has been ruled on.
+ * @param {string} arbitratorAddress - The arbitrator contract's address.
+ * @param {string} account - The users eth account.
+ * @param {function} callback - function to be called when event is triggered.
+ */
+ addDisputeRulingHandler = async (arbitratorAddress, account, callback) => {
if (!this._eventListener) return
const _disputeRulingHandler = async (
@@ -116,17 +121,17 @@ class Disputes extends AbstractWrapper {
address = account,
notificationCallback = callback
) => {
- console.log("in handler")
const newPeriod = event.args._period.toNumber()
const txHash = event.transactionHash
// send appeal possible notifications
- if (newPeriod === PERIODS.APPEAL) {
- console.log("doing the do")
+ if (newPeriod === arbitratorConstants.PERIOD.APPEAL) {
this._checkArbitratorWrappersSet()
const userProfile = await this._StoreProvider.getUserProfile(address)
// contract data
- const arbitratorData = await this._Arbitrator.getData(contractAddress, address)
- const currentDisputes = []
+ const arbitratorData = await this._Arbitrator.getData(
+ contractAddress,
+ address
+ )
let disputeId = 0
const currentSession = arbitratorData.session
@@ -134,54 +139,81 @@ class Disputes extends AbstractWrapper {
while (1) {
// iterate over all disputes (FIXME inefficient)
try {
- dispute = await this._Arbitrator.getDispute(contractAddress, disputeId)
- if (dispute.arbitratedContract === NULL_ADDRESS) break
- // session + number of appeals
- const disputeSession = dispute.firstSession + dispute.numberOfAppeals
- // if dispute not in current session skip
- if (disputeSession !== currentSession) {
- disputeId++
- dispute = await this._Arbitrator.getDispute(contractAddress, disputeId)
- continue
- }
-
- const ruling = await this._Arbitrator.currentRulingForDispute(contractAddress, disputeId)
-
- if (_.findIndex(userProfile.disputes, dispute => {
- return (dispute.disputeId === disputeId && dispute.arbitratorAddress === contractAddress)
- }) >= 0) {
- await this._StoreProvider.newNotification(
- address,
- txHash,
- disputeId, // use disputeId instead of logIndex since it doens't have its own event
- NOTIFICATION_TYPES.APPEAL_POSSIBLE,
- 'A ruling has been made. Appeal is possible',
- {
- disputeId,
- contractAddress,
- ruling
- }
- )
- // get ruledAt from block timestamp
- const blockNumber = event.blockNumber
- const block = this._Arbitrator._Web3Wrapper.getBlock(blockNumber)
- // add ruledAt to store
- await this._updateStoreForDispute(contractAddress, disputeId, address, null, block.timestamp)
-
- if (callback) {
- const userProfile = await this._StoreProvider.getUserProfile(address)
- const notification = _.filter(userProfile.notifications, notification => {
- return (notification.txHash === txHash && notification.logIndex === disputeId)
- })
-
- if (notification) {
- callback(notification[0])
- }
- }
- }
- // check next dispute
- disputeId += 1
- } catch (e) {
+ dispute = await this._Arbitrator.getDispute(
+ contractAddress,
+ disputeId
+ )
+ if (dispute.arbitratedContract === ethConstants.NULL_ADDRESS) break
+ // session + number of appeals
+ const disputeSession =
+ dispute.firstSession + dispute.numberOfAppeals
+ // if dispute not in current session skip
+ if (disputeSession !== currentSession) {
+ disputeId++
+ dispute = await this._Arbitrator.getDispute(
+ contractAddress,
+ disputeId
+ )
+ continue
+ }
+
+ const ruling = await this._Arbitrator.currentRulingForDispute(
+ contractAddress,
+ disputeId
+ )
+
+ if (
+ _.findIndex(
+ userProfile.disputes,
+ dispute =>
+ dispute.disputeId === disputeId &&
+ dispute.arbitratorAddress === contractAddress
+ ) >= 0
+ ) {
+ await this._StoreProvider.newNotification(
+ address,
+ txHash,
+ disputeId, // use disputeId instead of logIndex since it doens't have its own event
+ notificationConstants.TYPE.APPEAL_POSSIBLE,
+ 'A ruling has been made. Appeal is possible',
+ {
+ disputeId,
+ contractAddress,
+ ruling
+ }
+ )
+ // get ruledAt from block timestamp
+ const blockNumber = event.blockNumber
+ const block = this._Arbitrator._Web3Wrapper.getBlock(blockNumber)
+ // add ruledAt to store
+ await this._updateStoreForDispute(
+ contractAddress,
+ disputeId,
+ address,
+ null,
+ block.timestamp * 1000
+ )
+
+ if (notificationCallback) {
+ const userProfile = await this._StoreProvider.getUserProfile(
+ address
+ )
+ const notification = _.filter(
+ userProfile.notifications,
+ notification =>
+ notification.txHash === txHash &&
+ notification.logIndex === disputeId
+ )
+
+ if (notification) {
+ notificationCallback(notification[0])
+ }
+ }
+ }
+ // check next dispute
+ disputeId += 1
+ // eslint-disable-next-line no-unused-vars
+ } catch (err) {
// getDispute(n) throws an error if index out of range
break
}
@@ -189,7 +221,10 @@ class Disputes extends AbstractWrapper {
}
}
- await this._eventListener.registerArbitratorEvent('NewPeriod', _disputeRulingHandler)
+ await this._eventListener.registerArbitratorEvent(
+ 'NewPeriod',
+ _disputeRulingHandler
+ )
}
// **************************** //
@@ -252,7 +287,7 @@ class Disputes extends AbstractWrapper {
* Get disputes for user with extra data from arbitrated transaction and store
* @param {string} arbitratorAddress address of Kleros contract
* @param {string} account address of user
- * @return {object[]} dispute data objects for user
+ * @returns {object[]} dispute data objects for user
*/
getDisputesForUser = async (arbitratorAddress, account) => {
// FIXME don't like having to call this every fnc
@@ -450,8 +485,8 @@ class Disputes extends AbstractWrapper {
/**
* Gets the deadline for an arbitrator's period, which is also the deadline for all its disputes.
* @param {string} arbitratorAddress - The address of the arbitrator contract.
- * @param {number} [period=arbitratorConstants.PERIOD.VOTE] - The period to get the deadline for.
- * @returns {Date} - A date object.
+ * @param {number} [period=PERIODS.VOTE] - The period to get the deadline for.
+ * @returns {number} - epoch timestamp
*/
getDeadlineForDispute = async (
arbitratorAddress,
@@ -469,11 +504,14 @@ class Disputes extends AbstractWrapper {
}
/**
- * update store with new dispute data
- * @param {string} arbitratorAddress Address address of arbitrator contract
- * @param {int} disputeId index of dispute
- * @param {string} account address of party to update dispute or
- */
+ * update store with new dispute data
+ * @param {string} arbitratorAddress Address address of arbitrator contract
+ * @param {int} disputeId index of dispute
+ * @param {string} account address of party to update dispute or
+ * @param {number} createdAt epoch timestamp of when dispute was created
+ * @param {number} ruledAt epoch timestamp of when dispute was ruled on
+ * @returns {object} updated dispute object
+ */
_updateStoreForDispute = async (
arbitratorAddress,
disputeId,
@@ -488,10 +526,11 @@ class Disputes extends AbstractWrapper {
)
// update dispute
- await this._StoreProvider.updateDispute(
+ const dispute = await this._StoreProvider.updateDispute(
disputeData.disputeId,
disputeData.arbitratorAddress,
disputeData.hash,
+ disputeData.arbitrableContractAddress,
disputeData.partyA,
disputeData.partyB,
disputeData.title,
@@ -501,9 +540,9 @@ class Disputes extends AbstractWrapper {
disputeData.information,
disputeData.justification,
disputeData.resolutionOptions,
- createdAt ? createdAt : disputeData.createdAt,
- ruledAt ? ruledAt : disputeData.ruledAt
- ).body
+ createdAt || disputeData.createdAt,
+ ruledAt || disputeData.ruledAt
+ )
// update profile for account
await this._StoreProvider.updateDisputeProfile(
@@ -645,7 +684,7 @@ class Disputes extends AbstractWrapper {
if (account) {
votes = await this.getVotesForJuror(arbitratorAddress, disputeId, account)
try {
- const userData = await this.getUserDisputeFromStore(
+ const userData = await this._StoreProvider.getDisputeData(
arbitratorAddress,
disputeId,
account
@@ -708,7 +747,7 @@ class Disputes extends AbstractWrapper {
netPNK,
ruledAt,
createdAt
- })
+ }
}
}
diff --git a/src/abstractWrappers/Notifications.js b/src/abstractWrappers/Notifications.js
index 8402979..4e5b6c0 100644
--- a/src/abstractWrappers/Notifications.js
+++ b/src/abstractWrappers/Notifications.js
@@ -160,34 +160,45 @@ class Notifications extends AbstractWrapper {
}
// Repartition and execute
- if (currentPeriod === PERIODS.EXECUTE) {
- console.log("Starting....")
- await Promise.all(userProfile.disputes.map(async dispute => {
- const disputeData = await this._Arbitrator.getDispute(dispute.arbitratorAddress, dispute.disputeId)
- if (disputeData.firstSession + disputeData.numberOfAppeals === currentSession) {
- if (disputeData.state <= DISPUTE_STATES.RESOLVING) {
- notifications.push(this._createNotification(
- NOTIFICATION_TYPES.CAN_REPARTITION,
- "Ready to repartition dispute",
- {
- disputeId: dispute.disputeId,
- arbitratorAddress: dispute.arbitratorAddress
- }
- ))
- console.log("did stuff")
- } else if (disputeData.state === DISPUTE_STATES.EXECUTABLE) {
- notifications.push(this._createNotification(
- NOTIFICATION_TYPES.CAN_EXECUTE,
- "Ready to execute dispute",
- {
- disputeId: dispute.disputeId,
- arbitratorAddress: dispute.arbitratorAddress
- }
- ))
+ if (currentPeriod === arbitratorConstants.PERIOD.EXECUTE) {
+ await Promise.all(
+ userProfile.disputes.map(async dispute => {
+ const disputeData = await this._Arbitrator.getDispute(
+ dispute.arbitratorAddress,
+ dispute.disputeId
+ )
+ if (
+ disputeData.firstSession + disputeData.numberOfAppeals ===
+ currentSession
+ ) {
+ if (disputeData.state <= disputeConstants.STATE.RESOLVING) {
+ notifications.push(
+ this._createNotification(
+ notificationConstants.TYPE.CAN_REPARTITION,
+ 'Ready to repartition dispute',
+ {
+ disputeId: dispute.disputeId,
+ arbitratorAddress: dispute.arbitratorAddress
+ }
+ )
+ )
+ } else if (
+ disputeData.state === disputeConstants.STATE.EXECUTABLE
+ ) {
+ notifications.push(
+ this._createNotification(
+ notificationConstants.TYPE.CAN_EXECUTE,
+ 'Ready to execute dispute',
+ {
+ disputeId: dispute.disputeId,
+ arbitratorAddress: dispute.arbitratorAddress
+ }
+ )
+ )
+ }
}
- }
- }))
- console.log("Done....")
+ })
+ )
}
return notifications
diff --git a/src/constants/eth.js b/src/constants/eth.js
index 857efe7..4724b63 100644
--- a/src/constants/eth.js
+++ b/src/constants/eth.js
@@ -1,5 +1,5 @@
export const LOCALHOST_ETH_PROVIDER = 'http://localhost:8545'
-export const LOCALHOST_STORE_PROVIDER = 'https://kleros.in'
+export const LOCALHOST_STORE_PROVIDER = 'http://localhost:3001'
export const NULL_ADDRESS = '0x'
diff --git a/src/kleros.js b/src/kleros.js
index e159866..4cbc6b5 100644
--- a/src/kleros.js
+++ b/src/kleros.js
@@ -88,6 +88,11 @@ class Kleros {
account,
callback
)
+ await this.disputes.addDisputeRulingHandler(
+ arbitratorAddress,
+ account,
+ callback
+ )
await this.notifications.registerNotificationListeners(
arbitratorAddress,
account,
diff --git a/src/utils/StoreProviderWrapper.js b/src/utils/StoreProviderWrapper.js
index e03bf43..c318396 100644
--- a/src/utils/StoreProviderWrapper.js
+++ b/src/utils/StoreProviderWrapper.js
@@ -80,7 +80,7 @@ class StoreProviderWrapper {
return httpResponse
}
- getDisputeData = async (userAddress, arbitratorAddress, disputeId) => {
+ getDisputeData = async (arbitratorAddress, disputeId, userAddress) => {
const userProfile = await this.getUserProfile(userAddress)
if (!userProfile)
throw new Error(`No profile found for address: ${userAddress}`)
@@ -91,7 +91,6 @@ class StoreProviderWrapper {
o.arbitratorAddress === arbitratorAddress && o.disputeId === disputeId
)
- if (_.isEmpty(disputeData)) return null
const httpResponse = await this._makeRequest(
'GET',
`${this._storeUri}/arbitrators/${arbitratorAddress}/disputes/${disputeId}`
@@ -245,7 +244,6 @@ class StoreProviderWrapper {
ruledAt
})
)
-
return httpResponse
}
@@ -306,7 +304,6 @@ class StoreProviderWrapper {
data
})
)
-
return httpResponse
}
}
diff --git a/src/utils/Web3Wrapper.js b/src/utils/Web3Wrapper.js
index bbe065c..a2025a1 100644
--- a/src/utils/Web3Wrapper.js
+++ b/src/utils/Web3Wrapper.js
@@ -32,7 +32,7 @@ class Web3Wrapper {
blockNumber = () => this._web3.eth.blockNumber
- getBlock = () => this._web3.eth.getBlock
+ getBlock = blockNumber => this._web3.eth.getBlock(blockNumber)
doesContractExistAtAddressAsync = async address => {
const code = await this._web3.eth.getCode(address)
diff --git a/tests/kleros.test.js b/tests/kleros.test.js
index 8c51f51..83468d1 100644
--- a/tests/kleros.test.js
+++ b/tests/kleros.test.js
@@ -580,7 +580,7 @@ describe('Kleros', () => {
})
let newState
- // pass state so juror1s are selected
+ // pass state so jurors are selected
for (let i = 1; i < 3; i++) {
// NOTE we need to make another block before we can generate the random number. Should not be an issue on main nets where avg block time < period length
if (i === 2)
@@ -687,6 +687,7 @@ describe('Kleros', () => {
// delay 1 second
await delaySecond()
+
// move to execute period
await KlerosInstance.arbitrator.passPeriod(klerosCourt.address, other)
// stateful notifications
@@ -700,13 +701,13 @@ describe('Kleros', () => {
notificationConstants.TYPE.CAN_REPARTITION
)
- partyBStatefullNotifications = await KlerosInstance.notifications.getStatefulNotifications(
+ let partyAStatefullNotifications = await KlerosInstance.notifications.getStatefulNotifications(
klerosCourt.address,
- partyB,
+ partyA,
false
)
- expect(partyBStatefullNotifications.length).toEqual(1)
- expect(partyBStatefullNotifications[0].notificationType).toEqual(
+ expect(partyAStatefullNotifications.length).toEqual(1)
+ expect(partyAStatefullNotifications[0].notificationType).toEqual(
notificationConstants.TYPE.CAN_REPARTITION
)
@@ -731,13 +732,13 @@ describe('Kleros', () => {
notificationConstants.TYPE.CAN_EXECUTE
)
- partyBStatefullNotifications = await KlerosInstance.notifications.getStatefulNotifications(
+ partyAStatefullNotifications = await KlerosInstance.notifications.getStatefulNotifications(
klerosCourt.address,
- partyB,
+ partyA,
false
)
- expect(partyBStatefullNotifications.length).toEqual(1)
- expect(partyBStatefullNotifications[0].notificationType).toEqual(
+ expect(partyAStatefullNotifications.length).toEqual(1)
+ expect(partyAStatefullNotifications[0].notificationType).toEqual(
notificationConstants.TYPE.CAN_EXECUTE
)
@@ -779,12 +780,12 @@ describe('Kleros', () => {
)
expect(juror1StatefullNotifications.length).toEqual(0)
- partyBStatefullNotifications = await KlerosInstance.notifications.getStatefulNotifications(
+ partyAStatefullNotifications = await KlerosInstance.notifications.getStatefulNotifications(
klerosCourt.address,
- partyB,
+ partyA,
false
)
- expect(partyBStatefullNotifications.length).toEqual(0)
+ expect(partyAStatefullNotifications.length).toEqual(0)
expect(notifications.length).toBeTruthy()
// partyA got notifications
@@ -854,6 +855,16 @@ describe('Kleros', () => {
KlerosInstance.eventListener.stopWatchingArbitratorEvents(
klerosCourt.address
)
+
+ // make sure createdAt set
+ const disputeData = await KlerosInstance.disputes.getDataForDispute(
+ klerosCourt.address,
+ 0,
+ partyA
+ )
+
+ expect(disputeData.createdAt).toBeTruthy()
+ expect(disputeData.ruledAt).toBeTruthy()
},
80000
)
From 3656d335a19da60e82381d322b69994d1447400e Mon Sep 17 00:00:00 2001
From: Sam Vitello
Date: Tue, 27 Feb 2018 17:09:41 -0500
Subject: [PATCH 3/4] feat(disputes): submittedAt timestamp for evidence
---
README.md | 2 +-
src/constants/eth.js | 2 +-
src/utils/StoreProviderWrapper.js | 10 ++++++----
tests/kleros.test.js | 2 +-
4 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index e0ab2cd..8ee99cc 100644
--- a/README.md
+++ b/README.md
@@ -3,8 +3,8 @@
+
-
diff --git a/src/constants/eth.js b/src/constants/eth.js
index 4724b63..857efe7 100644
--- a/src/constants/eth.js
+++ b/src/constants/eth.js
@@ -1,5 +1,5 @@
export const LOCALHOST_ETH_PROVIDER = 'http://localhost:8545'
-export const LOCALHOST_STORE_PROVIDER = 'http://localhost:3001'
+export const LOCALHOST_STORE_PROVIDER = 'https://kleros.in'
export const NULL_ADDRESS = '0x'
diff --git a/src/utils/StoreProviderWrapper.js b/src/utils/StoreProviderWrapper.js
index c318396..706d15f 100644
--- a/src/utils/StoreProviderWrapper.js
+++ b/src/utils/StoreProviderWrapper.js
@@ -21,9 +21,8 @@ class StoreProviderWrapper {
let body = null
try {
body = JSON.parse(httpRequest.responseText)
- } catch (err) {
- console.log(err)
- }
+ // eslint-disable-next-line no-unused-vars
+ } catch (err) {}
resolve({
body: body,
status: httpRequest.status
@@ -153,13 +152,16 @@ class StoreProviderWrapper {
}
addEvidenceContract = async (address, account, name, description, url) => {
+ // get timestamp for submission
+ const submittedAt = new Date().getTime()
const httpResponse = await this._makeRequest(
'POST',
`${this._storeUri}/${account}/contracts/${address}/evidence`,
JSON.stringify({
name,
description,
- url
+ url,
+ submittedAt
})
)
diff --git a/tests/kleros.test.js b/tests/kleros.test.js
index 83468d1..d788b5d 100644
--- a/tests/kleros.test.js
+++ b/tests/kleros.test.js
@@ -537,7 +537,6 @@ describe('Kleros', () => {
expect(resolutionOptions.length).toEqual(2)
// add an evidence for partyA
- // FIXME use arbitrableTransaction
const testName = 'test name'
const testDesc = 'test description'
const testURL = 'http://test.com'
@@ -563,6 +562,7 @@ describe('Kleros', () => {
)
expect(contractStoreData.evidences[0].url).toBe(testURL)
+ expect(contractStoreData.evidences[0].submittedAt).toBeTruthy()
// check initial state of contract
// FIXME var must be more explicit
From f9eae71df35c9be3e5bb2d5b6b6804f836b23ecb Mon Sep 17 00:00:00 2001
From: epiqueras
Date: Tue, 27 Feb 2018 17:03:36 -0800
Subject: [PATCH 4/4] chore(release): 0.0.62
---
CHANGELOG.md | 25 +++++++++++++++++++++++++
package.json | 15 ++++++++++-----
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 914bf2b..ea99c10 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,31 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+
+## 0.0.62 (2018-02-28)
+
+
+### Bug Fixes
+
+* **getDeadlineForDispute:** fix wrong computation and return date object ([7ee05f5](https://github.com/kleros/kleros-api/commit/7ee05f5))
+* skip broken test assertions ([d210c53](https://github.com/kleros/kleros-api/commit/d210c53))
+* test suite ([98b777d](https://github.com/kleros/kleros-api/commit/98b777d))
+
+
+### Features
+
+* normalize token units ([d0d40f8](https://github.com/kleros/kleros-api/commit/d0d40f8))
+* **disputes:** build voteCounters and PNKRepartitions from getters ([ba48e67](https://github.com/kleros/kleros-api/commit/ba48e67))
+* **disputes:** change approach to getting netPNK and votesCounter ([366340f](https://github.com/kleros/kleros-api/commit/366340f))
+* **disputes:** createdAt and ruledAt timestamps added in events ([8e9cafa](https://github.com/kleros/kleros-api/commit/8e9cafa))
+* **disputes:** remove netPNK until events are fixed ([255bf03](https://github.com/kleros/kleros-api/commit/255bf03))
+* **disputes:** return appealsRepartitioned ([1246968](https://github.com/kleros/kleros-api/commit/1246968))
+* **disputes:** return deadline as epoch in ms instead of a date object ([90d4856](https://github.com/kleros/kleros-api/commit/90d4856))
+* **disputes:** return dispute status ([32db45c](https://github.com/kleros/kleros-api/commit/32db45c))
+* **disputes:** submittedAt timestamp for evidence ([3656d33](https://github.com/kleros/kleros-api/commit/3656d33))
+
+
+
## 0.0.61 (2018-02-27)
diff --git a/package.json b/package.json
index 4a1bb38..3e17dd1 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,12 @@
{
"name": "kleros-api",
- "version": "0.0.61",
- "description":
- "A Javascript library that makes it easy to build relayers and other DApps that use the Kleros protocol.",
- "keywords": ["Blockchain", "Ethereum", "Kleros"],
+ "version": "0.0.62",
+ "description": "A Javascript library that makes it easy to build relayers and other DApps that use the Kleros protocol.",
+ "keywords": [
+ "Blockchain",
+ "Ethereum",
+ "Kleros"
+ ],
"homepage": "https://kleros.io",
"repository": "github:kleros/kleros-api",
"bugs": "https://github.com/kleros/kleros-api/issues",
@@ -28,7 +31,9 @@
"build": "webpack --env.NODE_ENV=production -p"
},
"commitlint": {
- "extends": ["@commitlint/config-conventional"]
+ "extends": [
+ "@commitlint/config-conventional"
+ ]
},
"devDependencies": {
"babel-core": "^6.26.0",