Skip to content

Commit

Permalink
refactor address extraction into reducers (#488)
Browse files Browse the repository at this point in the history
  • Loading branch information
faboweb authored Mar 20, 2020
1 parent 030c12d commit b065738
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 119 deletions.
14 changes: 1 addition & 13 deletions lib/block-listeners/cosmos-node-subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,7 @@ class CosmosNodeSubscription {
// transaction to each subscribed user.
// TODO doesn't handle failing txs as it doesn't extract addresses from those txs (they are not tagged)
block.transactions.forEach(tx => {
let addresses = []
try {
this.cosmosAPI.extractInvolvedAddresses(tx.raw).forEach(address => {
addresses.push(address)
})
} catch (err) {
Sentry.withScope(function(scope) {
scope.setExtra('transaction', tx.raw)
Sentry.captureException(err)
})
}
addresses = _.uniq(addresses)
addresses.forEach(address => {
tx.involvedAddresses.forEach(address => {
publishUserTransactionAddedV2(this.network.id, address, tx)
publishEvent(this.network.id, 'transaction', address, tx)
})
Expand Down
3 changes: 2 additions & 1 deletion lib/block-listeners/polkadot-node-subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ class PolkadotNodeSubscription {
// A GraphQL resolver is listening for these messages and sends the
// transaction to each subscribed user.

// TODO move address extraction to transaction reducer
// let addresses = []
// addresses = this.polkadotAPI.extractInvolvedAddresses(block.transactions)
// addresses = this.polkadotAPI.reducers.extractInvolvedAddresses(block.transactions)
// addresses = _.uniq(addresses)

// if (addresses.length > 0) {
Expand Down
23 changes: 21 additions & 2 deletions lib/reducers/cosmosV0-reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,23 @@ function formatTransactionsReducer(txs, reducers) {
return reversedTxs.map(tx => transactionReducer(tx, reducers))
}

function extractInvolvedAddresses(transaction) {
// If the transaction has failed, it doesn't get tagged
if (!Array.isArray(transaction.tags)) return []

const involvedAddresses = transaction.tags.reduce((addresses, tag) => {
// temporary in here to identify why this fails
if (!tag.value) {
return addresses
}
if (tag.value.startsWith(`cosmos`)) {
addresses.push(tag.value)
}
return addresses
}, [])
return involvedAddresses
}

function transactionReducerV2(transaction, reducers, stakingDenom) {
// TODO check if this is anywhere not an array
let fees
Expand Down Expand Up @@ -559,7 +576,8 @@ function transactionReducerV2(transaction, reducers, stakingDenom) {
? transaction.logs[index].log
: transaction.logs[0] // failing txs show the first logs
? transaction.logs[0].log
: ''
: '',
involvedAddresses: _.uniq(reducers.extractInvolvedAddresses(transaction))
}))
return returnedMessages
}
Expand Down Expand Up @@ -822,5 +840,6 @@ module.exports = {
getValidatorStatus,
expectedRewardsPerToken,
getGroupByType,
denomLookup
denomLookup,
extractInvolvedAddresses
}
31 changes: 30 additions & 1 deletion lib/reducers/cosmosV2-reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,34 @@ function validatorReducer(networkId, signedBlocksWindow, validator) {
}
}

function extractInvolvedAddresses(transaction) {
// If the transaction has failed, it doesn't get tagged
if (!Array.isArray(transaction.events)) return []

// extract all addresses from events that are either sender or recipient
const involvedAddresses = transaction.events.reduce(
(involvedAddresses, event) => {
const senderAttributes = event.attributes
.filter(({ key }) => key === 'sender')
.map(sender => sender.value)
if (senderAttributes.length) {
involvedAddresses = [...involvedAddresses, ...senderAttributes]
}

const recipientAttribute = event.attributes.find(
({ key }) => key === 'recipient'
)
if (recipientAttribute) {
involvedAddresses.push(recipientAttribute.value)
}

return involvedAddresses
},
[]
)
return involvedAddresses
}

function undelegationEndTimeReducer(transaction) {
if (transaction.events) {
let completionTimeAttribute
Expand All @@ -103,5 +131,6 @@ module.exports = {
proposalReducer,
delegationReducer,
validatorReducer,
undelegationEndTimeReducer
undelegationEndTimeReducer,
extractInvolvedAddresses
}
59 changes: 58 additions & 1 deletion lib/reducers/polkadotV0-reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,66 @@ function delegationReducer(network, delegation, validator) {
}
}

function extractInvolvedAddresses(blockEvents) {
let involvedAddresses = []
blockEvents.forEach(async record => {
const { event } = record

// event.section balances
// event.method NewAccount
// event.data ["FNtKsMaSWe2UAatJjnCkikEJsiQYDqTcB4ujUebs51KRE1V",100000000000]

if (event.section === `balances` && event.method === `NewAccount`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
}

// event.section balances
// event.method Deposit
// event.data ["D948vxMSA6u7G5gqPGQdAUDMJbiR7wgqZ1La8XeBiXr9FTF",2000000000]

if (event.section === `balances` && event.method === `Deposit`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
}

// event.section balances
// event.method ReapedAccount
// event.data ["GksmapjLhJBS4vA7JBT6oMbc98YLGheR9qmTHDkeo4F9koh",0]

if (event.section === `balances` && event.method === `ReapedAccount`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
}

// event.section balances
// event.method Transfer
// event.data ["GksmapjLhJBS4vA7JBT6oMbc98YLGheR9qmTHDkeo4F9koh","GwoksmaSpMdDwxxRYV9P4BwCcF1agXNWjdxSF2oEWwEc1iy",60000000000,10000000000]

if (event.section === `balances` && event.method === `ReapedAccount`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
console.log(`Involved address:`, event.data[1])
involvedAddresses.push(event.data[1])
}

// console.log(
// `\x1b[36mNew kusama extrinsic for block #${blockHeight} index: ${index} section: ${
// event.section
// } method: ${
// event.method
// } phase: ${phase.toString()} data: ${JSON.stringify(
// event.data
// )}\x1b[0m`
// )
})
return involvedAddresses
}

module.exports = {
blockReducer,
validatorReducer,
balanceReducer,
delegationReducer
delegationReducer,
extractInvolvedAddresses
}
17 changes: 0 additions & 17 deletions lib/source/cosmosV0-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,6 @@ class CosmosV0API extends RESTDataSource {
return slashingParams.signed_blocks_window
}

extractInvolvedAddresses(transaction) {
// If the transaction has failed, it doesn't get tagged
if (!Array.isArray(transaction.tags)) return []

const involvedAddresses = transaction.tags.reduce((addresses, tag) => {
// temporary in here to identify why this fails
if (!tag.value) {
return addresses
}
if (tag.value.startsWith(`cosmos`)) {
addresses.push(tag.value)
}
return addresses
}, [])
return involvedAddresses
}

checkAddress(address) {
if (!address.startsWith(this.delegatorBech32Prefix)) {
throw new UserInputError(
Expand Down
28 changes: 0 additions & 28 deletions lib/source/cosmosV2-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,34 +142,6 @@ class CosmosV2API extends CosmosV0API {
return this.reducers.transactionsReducerV2(txs, this.reducers, stakingDenom)
}

extractInvolvedAddresses(transaction) {
// If the transaction has failed, it doesn't get tagged
if (!Array.isArray(transaction.events)) return []

// extract all addresses from events that are either sender or recipient
const involvedAddresses = transaction.events.reduce(
(involvedAddresses, event) => {
const senderAttributes = event.attributes
.filter(({ key }) => key === 'sender')
.map(sender => sender.value)
if (senderAttributes.length) {
involvedAddresses = [...involvedAddresses, ...senderAttributes]
}

const recipientAttribute = event.attributes.find(
({ key }) => key === 'recipient'
)
if (recipientAttribute) {
involvedAddresses.push(recipientAttribute.value)
}

return involvedAddresses
},
[]
)
return involvedAddresses
}

async getTransactionsByHeight(height) {
const txs = await this.loadPaginatedTxs(`txs?tx.height=${height}`)
return Array.isArray(txs)
Expand Down
56 changes: 0 additions & 56 deletions lib/source/polkadotV0-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,62 +53,6 @@ class polkadotAPI {
)
}

extractInvolvedAddresses(blockEvents) {
let involvedAddresses = []
blockEvents.forEach(async record => {
const { event } = record

// event.section balances
// event.method NewAccount
// event.data ["FNtKsMaSWe2UAatJjnCkikEJsiQYDqTcB4ujUebs51KRE1V",100000000000]

if (event.section === `balances` && event.method === `NewAccount`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
}

// event.section balances
// event.method Deposit
// event.data ["D948vxMSA6u7G5gqPGQdAUDMJbiR7wgqZ1La8XeBiXr9FTF",2000000000]

if (event.section === `balances` && event.method === `Deposit`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
}

// event.section balances
// event.method ReapedAccount
// event.data ["GksmapjLhJBS4vA7JBT6oMbc98YLGheR9qmTHDkeo4F9koh",0]

if (event.section === `balances` && event.method === `ReapedAccount`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
}

// event.section balances
// event.method Transfer
// event.data ["GksmapjLhJBS4vA7JBT6oMbc98YLGheR9qmTHDkeo4F9koh","GwoksmaSpMdDwxxRYV9P4BwCcF1agXNWjdxSF2oEWwEc1iy",60000000000,10000000000]

if (event.section === `balances` && event.method === `ReapedAccount`) {
console.log(`Involved address:`, event.data[0])
involvedAddresses.push(event.data[0])
console.log(`Involved address:`, event.data[1])
involvedAddresses.push(event.data[1])
}

// console.log(
// `\x1b[36mNew kusama extrinsic for block #${blockHeight} index: ${index} section: ${
// event.section
// } method: ${
// event.method
// } phase: ${phase.toString()} data: ${JSON.stringify(
// event.data
// )}\x1b[0m`
// )
})
return involvedAddresses
}

async getAllValidators() {
console.time(`getAllValidators`)

Expand Down

0 comments on commit b065738

Please sign in to comment.