Skip to content
This repository has been archived by the owner on Jul 18, 2020. It is now read-only.

Commit

Permalink
store utxos data to txio index.
Browse files Browse the repository at this point in the history
  • Loading branch information
crchemist-ip committed Sep 17, 2019
1 parent 754a04c commit b93c4d2
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 37 deletions.
22 changes: 4 additions & 18 deletions src/blockchain/block.js
@@ -1,6 +1,5 @@
// @flow

import _ from 'lodash'
import cbor from 'cbor'

import utils from './utils'
Expand Down Expand Up @@ -63,6 +62,10 @@ export default class Block {
}
}

getTxs() {
return this.txs
}

static handleEpochBoundaryBlock(header: HeaderType) {
const [epoch, [chainDifficulty]] = header[3]
const lead = null
Expand Down Expand Up @@ -112,23 +115,6 @@ export default class Block {
return this.time
}

getReceivedAmount(): number {
// TODO: reduce number of iterations
const sent = _.sumBy(_.flatten(_.map(this.txs, 'outputs')), o => o.value)
return sent
}

getSentAmount() {
const txInputs = _.flatten(_.map(this.txs, 'inputs'))
const amount = 0
return amount
}

getFees(): number {
const sentAmount = this.getSentAmount()
const receivedAmount = this.getReceivedAmount()
return sentAmount - receivedAmount
}

static parseBlock(blob: Buffer, handleRegularBlock: number): Block {
const [type, [header, body]] = cbor.decode(blob)
Expand Down
1 change: 1 addition & 0 deletions src/blockchain/utils.js
Expand Up @@ -128,6 +128,7 @@ const rawTxToObj = (tx: Array<any>, extraData: {
const [[inputs, outputs], witnesses] = tx
const [txId, txBody] = packRawTxIdAndBody(tx)
return {
isGenesis: false,
id: txId,
inputs: inputs.map(inp => {
const [type, tagged] = inp
Expand Down
66 changes: 58 additions & 8 deletions src/entities/elastic-storage/block-data.js
@@ -1,26 +1,77 @@
// @flow

import _ from 'lodash'

import type { Block } from '../../blockchain'

import ElasticData, { coinFormat } from './elastic-data'
import type { UtxoType } from './utxo-data'
import UtxoData from './utxo-data'

class BlockData extends ElasticData {
block: Block

amountSent: number
utxos: Array<mixed>

blockUtxos: Array<mixed>

storedUTxOs: Array<UtxoType>

allUtxos: {}

fees: number
inputsData: []

constructor(block: Block) {
constructor(block: Block, storedUTxOs: Array<UtxoType> = []) {
super()
this.block = block
this.amountSent = this.block.getSentAmount()
this.fees = this.block.getFees()
this.storedUTxOs = storedUTxOs
this.blockUtxos = block.getTxs().flatMap(tx => tx.outputs.map(
(out, idx) => (new UtxoData({
tx_hash: tx.id,
tx_index: idx,
receiver: out.address,
amount: out.value,
})).toPlainObject(),
))
this.allUtxos = _.keyBy([
...this.storedUTxOs,
...this.blockUtxos,
], u => `${u.tx_hash}${u.io_ordinal}`)

this.inputsData = _.flatMap(_.flatMap(this.block.getTxs(), 'inputs'), inp => {
return this.allUtxos[`${inp.txId}${inp.idx}`]
})
}

getBlockUtxos() {
return this.blockUtxos
}

getReceivedAmount(): number {
// TODO: reduce number of iterations
const received = _.sumBy(this.inputsData, inp => inp.value.full)
return received
}

getSentAmount(): number {
const sent = _.sumBy(this.inputsData, u => u.value.full)
return sent
}

getFees(): number {
const sentAmount = this.getSentAmount()
const receivedAmount = this.getReceivedAmount()
return sentAmount - receivedAmount
}

toPlainObject() {
const time = this.block.getTime().toISOString()
let sent = 0
let fees = 0
if (this.block.getTxs().length > 0) {
sent = this.getSentAmount()
fees = this.getFees()
}
return {
epoch: this.block.epoch,
slot: this.block.slot,
Expand All @@ -29,9 +80,8 @@ class BlockData extends ElasticData {
time,
branch: 0,
tx_num: this.block.txs.length,
sent: coinFormat(this.amountSent),
fees: coinFormat(this.fees),
// lead: this.block.lead,
sent: coinFormat(sent),
fees: coinFormat(fees),
}
}
}
Expand Down
60 changes: 49 additions & 11 deletions src/entities/elastic-storage/elastic-storage-processor.js
Expand Up @@ -12,7 +12,7 @@ import SERVICE_IDENTIFIER from '../../constants/identifiers'
import type { UtxoType } from './utxo-data'

import BlockData from './block-data'
import UtxoData from './utxo-data'
import UtxoData, { getTxInputUtxoId } from './utxo-data'
import TxData from './tx-data'

const INDEX_SLOT = 'seiza.slot'
Expand Down Expand Up @@ -70,7 +70,7 @@ class ElasticStorageProcessor implements StorageProcessor {
{
index: {
_index: INDEX_TX,
_id: utxoData.getId(),
_id: utxoData.getHash(),
},
},
TxData.fromGenesisUtxo(utxoData, this.networkStartTime).toPlainObject(),
Expand Down Expand Up @@ -101,22 +101,60 @@ class ElasticStorageProcessor implements StorageProcessor {
return source
}

async storeBlockData(block: Block, cache: any = []) {
this.logger.debug('storeBlockData', block)
const body = cache.flatMap(blk => [
async bulkUpload(body) {
const resp = await this.client.bulk({
refresh: true,
body,
})
this.logger.debug('bulkUpload', resp)
return resp
}

async storeBlocksToSlotIdx(blocks: Array<Block>, storedUTxOs: Array<UtxoType>) {
const body = blocks.flatMap(blk => [
{
index: {
_index: INDEX_SLOT,
_id: blk.hash,
},
},
(new BlockData(blk)).toPlainObject(),
(new BlockData(blk, storedUTxOs)).toPlainObject(),
])
const resp = await this.client.bulk({
refresh: true,
body,
})
this.logger.debug('storeBlockData', resp)
await this.bulkUpload(body)
}

async storeBlockUtxos(block: Block) {
const blockUtxos = (new BlockData(block)).getBlockUtxos()
const body = blockUtxos.flatMap(utxo => [
{
index: {
_index: INDEX_TXIO,
_id: utxo.id,
},
},
utxo,
])
await this.bulkUpload(body)
}

async storeBlockData(block: Block, cache: any = []) {
const txInputsIds = _.flatten(_.map(block.txs, 'inputs')).map(getTxInputUtxoId)
let storedUTxOs = []
if (txInputsIds.length > 0) {
this.logger.debug('storeBlockData', block)
const txInputs = await this.client.mget({
index: INDEX_TXIO,
body: {
ids: txInputsIds,
},
})
storedUTxOs = _.map(txInputs.body.docs, '_source')
}

if (block.getTxs().length > 0) {
await this.storeBlockUtxos(block)
}
await this.storeBlocksToSlotIdx(cache, storedUTxOs)
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/entities/elastic-storage/utxo-data.js
Expand Up @@ -4,6 +4,8 @@ import ElasticData, { coinFormat } from './elastic-data'

const UTXO_OUTPUT_TYPE = 'output'

export const getTxInputUtxoId = (input) => `${UTXO_OUTPUT_TYPE}:${input.txId}:${input.idx}`

export type UtxoType = {
tx_hash: string,
tx_index: number,
Expand Down

0 comments on commit b93c4d2

Please sign in to comment.