Skip to content

Commit

Permalink
feat(Events): Move decoding of events to builder. Add ability to deco…
Browse files Browse the repository at this point in the history
…de events without ACI
  • Loading branch information
nduchak committed Feb 7, 2020
1 parent 25d2dec commit e3fbbc5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 70 deletions.
6 changes: 3 additions & 3 deletions es/contract/aci/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ import * as R from 'ramda'
import {
validateArguments,
transform,
transformDecodedData,
transformDecodedEvents
transformDecodedData
} from './transformation'
import { buildContractMethods, getFunctionACI } from './helpers'
import { isAddressValid } from '../../utils/crypto'
Expand All @@ -38,6 +37,7 @@ import { BigNumber } from 'bignumber.js'
import { COMPILER_LT_VERSION } from '../compiler'
import semverSatisfies from '../../utils/semver-satisfies'
import { AMOUNT, DEPOSIT, GAS, MIN_GAS_PRICE } from '../../tx/builder/schema'
import { decodeEvents } from '../../tx/builder'

/**
* Validated contract call arguments using contract ACI
Expand Down Expand Up @@ -172,7 +172,7 @@ const decodeCallResult = async (result, fnACI, opt) => {
await result.decode(),
{ ...opt, bindings: fnACI.bindings }
),
decodedEvents: transformDecodedEvents(result.result.log, fnACI, opt)
decodedEvents: decodeEvents(result.result.log, { ...opt, fnACI })
}
}
const call = ({ client, instance }) => async (fn, params = [], options = {}) => {
Expand Down
65 changes: 0 additions & 65 deletions es/contract/aci/transformation.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import Joi from 'joi-browser'
import { toBytes } from '../../utils/bytes'
import { addressFromDecimal, hash } from '../../utils/crypto'
import { decode } from '../../tx/builder/helpers'

export const SOPHIA_TYPES = [
'int',
Expand Down Expand Up @@ -171,68 +168,6 @@ export function transformMap (value, generic, { bindings }) {

// FUNCTION RETURN VALUE TRANSFORMATION ↓↓↓

/**
* Transform decoded event to JS type
* @param {Object[]} events Array of events
* @param {Object} fnACI SC function ACI schema
* @param {Object} [options={}] Options
* @return {Object}
*/
export function transformDecodedEvents (events, fnACI, options = {}) {
if (!events.length) return []

const eventsSchema = fnACI.event.map(e => {
const name = Object.keys(e)[0]
return { name, value: e[name], nameHash: hash(name).toString('hex') }
})

return events.map(l => {
const [eName, ...eParams] = l.topics
const hexHash = toBytes(eName, true).toString('hex')
const { schema, isHasNonIndexed } = eventsSchema
.reduce(
(acc, el) => {
if (el.nameHash === hexHash) {
l.name = el.name
return {
schema: el.value.filter(e => e !== 'string'),
isHasNonIndexed: el.value.includes('string'),
name: el.name
}
}
return acc
},
{ schema: [], isHasNonIndexed: false }
)
return {
...l,
decoded: [
...isHasNonIndexed ? [decode(l.data).toString('utf-8')] : [],
...eParams.map((event, i) => transformEvent(event, schema[i]))
]
}
})
}

/**
* Transform Event based on type
* @param {String|Number} event Event data
* @param {String} type Event type from schema
* @return {*}
*/
function transformEvent (event, type) {
switch (type) {
case SOPHIA_TYPES.bool:
return !!event
case SOPHIA_TYPES.hash:
return toBytes(event, true).toString('hex')
case SOPHIA_TYPES.address:
return addressFromDecimal(event).split('_')[1]
default:
return event
}
}

/**
* Transform decoded data to JS type
* @param aci
Expand Down
68 changes: 66 additions & 2 deletions es/tx/builder/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BigNumber } from 'bignumber.js'
import { assertedType, rlp } from '../../utils/crypto'
import { addressFromDecimal, assertedType, hash, rlp } from '../../utils/crypto'

import {
DEFAULT_FEE,
Expand Down Expand Up @@ -27,6 +27,7 @@ import {
} from './helpers'
import { toBytes } from '../../utils/bytes'
import * as mpt from '../../utils/mptree'
import { SOPHIA_TYPES } from '../../contract/aci/transformation'

/**
* JavaScript-based Transaction builder
Expand All @@ -40,6 +41,69 @@ const ORACLE_TTL_TYPES = {
block: 'block'
}

// Events
/**
* Transform decoded event to JS type
* @param {Object[]} events Array of events
* @param {Object} fnACI SC function ACI schema
* @param {Object} [options={}] Options
* @return {Object}
*/
export function decodeEvents (events, options = { fnACI: [] }) {
if (!events.length) return []

const eventsSchema = options.fnACI.event.map(e => {
const name = Object.keys(e)[0]
return { name, value: e[name], nameHash: hash(name).toString('hex') }
})

return events.map(l => {
const [eName, ...eParams] = l.topics
const hexHash = toBytes(eName, true).toString('hex')
const { schema, isHasNonIndexed } = eventsSchema
.reduce(
(acc, el) => {
if (el.nameHash === hexHash) {
l.name = el.name
return {
schema: el.value.filter(e => e !== 'string'),
isHasNonIndexed: el.value.includes('string'),
name: el.name
}
}
return acc
},
{ schema: [], isHasNonIndexed: true }
)
return {
...l,
decoded: [
...isHasNonIndexed ? [decode(l.data).toString('utf-8')] : [],
...eParams.map((event, i) => transformEvent(event, schema[i]))
]
}
})
}

/**
* Transform Event based on type
* @param {String|Number} event Event data
* @param {String} type Event type from schema
* @return {*}
*/
function transformEvent (event, type) {
switch (type) {
case SOPHIA_TYPES.bool:
return !!event
case SOPHIA_TYPES.hash:
return toBytes(event, true).toString('hex')
case SOPHIA_TYPES.address:
return addressFromDecimal(event).split('_')[1]
default:
return toBytes(event, true)
}
}

// SERIALIZE AND DESERIALIZE PART
function deserializeField (value, type, prefix) {
if (!value) return ''
Expand Down Expand Up @@ -391,4 +455,4 @@ export function buildTxHash (rawTx) {
return buildHash('th', rawTx)
}

export default { calculateMinFee, calculateFee, unpackTx, unpackRawTx, buildTx, buildRawTx, validateParams, buildTxHash }
export default { calculateMinFee, calculateFee, unpackTx, unpackRawTx, buildTx, buildRawTx, validateParams, buildTxHash, transformDecodedEvents: decodeEvents }

0 comments on commit e3fbbc5

Please sign in to comment.