Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

Commit

Permalink
Merge branch 'develop' into add-onctract-title-store-test
Browse files Browse the repository at this point in the history
  • Loading branch information
n1c01a5 committed Feb 28, 2018
2 parents 374c243 + c1c2dee commit e7b1225
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 73 deletions.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<a name="0.0.62"></a>
## 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))



<a name="0.0.61"></a>

## 0.0.61 (2018-02-27)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
</p>

<p align="center">
<a href="https://badge.fury.io/js/kleros-api"><img src="https://badge.fury.io/js/kleros-api.svg" alt="NPM Version"></a>
<a href="https://travis-ci.org/kleros/kleros-api"><img src="https://travis-ci.org/kleros/kleros-api.svg?branch=master" alt="Build Status"></a>
<a href="https://badge.fury.io/js/kleros-api"><img src="https://badge.fury.io/js/kleros-api.svg" alt="npm version" height="18"></a>
<a href="https://coveralls.io/github/kleros/kleros-api?branch=master"><img src="https://coveralls.io/repos/github/kleros/kleros-api/badge.svg?branch=master" alt="Coverage Status"></a>
<a href="https://david-dm.org/kleros/kleros-api"><img src="https://david-dm.org/kleros/kleros-api.svg" alt="Dependencies"></a>
<a href="https://david-dm.org/kleros/kleros-api?type=dev"><img src="https://david-dm.org/kleros/kleros-api/dev-status.svg" alt="Dev Dependencies"></a>
Expand Down
13 changes: 9 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{
"name": "kleros-api",
"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"],
"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",
Expand All @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion src/abstractWrappers/ArbitrableContract.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ArbitrableContract extends AbstractWrapper {
* @param {string} partyB - Ethereum address of the other party in the contract.
* @param {bytes} arbitratorExtraData - Extra data for the arbitrator.
* @param {string} email - Email address of the contract creator (default empty string).
* @param {string} title - Title of the contract(default empty string).
* @param {string} title - Title of the contract (default empty string).
* @param {string} description - Description of what the contract is about (default empty string).
* @param {...any} args - Extra arguments for the contract.
* @returns {object | Error} - The contract object or an error.
Expand Down
208 changes: 166 additions & 42 deletions src/abstractWrappers/Disputes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -36,7 +36,16 @@ 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)
const blockNumber = event.blockNumber
const block = this._Arbitrator._Web3Wrapper.getBlock(blockNumber)

// add new dispute with timestamp
await this._updateStoreForDispute(
contractAddress,
disputeId,
address,
block.timestamp * 1000
)
}
}

Expand Down Expand Up @@ -97,6 +106,127 @@ class Disputes extends AbstractWrapper {
)
}

/**
* 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 - <optional> function to be called when event is triggered.
*/
addDisputeRulingHandler = async (arbitratorAddress, account, callback) => {
if (!this._eventListener) return

const _disputeRulingHandler = async (
event,
contractAddress = arbitratorAddress,
address = account,
notificationCallback = callback
) => {
const newPeriod = event.args._period.toNumber()
const txHash = event.transactionHash
// send appeal possible notifications
if (newPeriod === arbitratorConstants.PERIOD.APPEAL) {
this._checkArbitratorWrappersSet()
const userProfile = await this._StoreProvider.getUserProfile(address)
// contract data
const arbitratorData = await this._Arbitrator.getData(
contractAddress,
address
)
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 === 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
}
}
}
}

await this._eventListener.registerArbitratorEvent(
'NewPeriod',
_disputeRulingHandler
)
}

// **************************** //
// * Public * //
// **************************** //
Expand All @@ -123,7 +253,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)
Expand Down Expand Up @@ -151,39 +280,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
* @returns {object[]} dispute data objects for user
*/
getDisputesForUser = async (arbitratorAddress, account) => {
// FIXME don't like having to call this every fnc
Expand Down Expand Up @@ -381,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,
Expand All @@ -404,19 +508,29 @@ class Disputes extends AbstractWrapper {
* @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 <optional> epoch timestamp of when dispute was created
* @param {number} ruledAt <optional> epoch timestamp of when dispute was ruled on
* @returns {object} updated dispute object
*/
_updateStoreForDispute = async (arbitratorAddress, disputeId, account) => {
_updateStoreForDispute = async (
arbitratorAddress,
disputeId,
account,
createdAt,
ruledAt
) => {
const disputeData = await this.getDataForDispute(
arbitratorAddress,
disputeId,
account
)

// 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,
Expand All @@ -425,8 +539,10 @@ class Disputes extends AbstractWrapper {
disputeData.fee,
disputeData.information,
disputeData.justification,
disputeData.resolutionOptions
).body
disputeData.resolutionOptions,
createdAt || disputeData.createdAt,
ruledAt || disputeData.ruledAt
)

// update profile for account
await this._StoreProvider.updateDisputeProfile(
Expand All @@ -435,9 +551,11 @@ class Disputes extends AbstractWrapper {
disputeData.arbitratorAddress,
disputeData.disputeId,
disputeData.votes.length > 0,
false,
0
disputeData.hasRuled,
disputeData.netPNK ? disputeData.netPNK : 0
)

return dispute
}

/**
Expand Down Expand Up @@ -561,17 +679,21 @@ 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 {
const userData = await this.getUserDisputeFromStore(
const userData = await this._StoreProvider.getDisputeData(
arbitratorAddress,
disputeId,
account
)
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
Expand Down Expand Up @@ -622,7 +744,9 @@ class Disputes extends AbstractWrapper {
hasRuled,
ruling,
evidence,
netPNK
netPNK,
ruledAt,
createdAt
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/abstractWrappers/Notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ class Notifications extends AbstractWrapper {
dispute.arbitratorAddress,
dispute.disputeId
)

if (
disputeData.firstSession + disputeData.numberOfAppeals ===
currentSession
Expand Down
Loading

0 comments on commit e7b1225

Please sign in to comment.