Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1253,9 +1253,9 @@ GET /identities?page=1&limit=10&order=asc&order_by=block_height
"timestamp": "2024-03-18T10:13:54.150Z",
"txHash": "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
"totalTxs": 1,
"totalTransfers": 0,
"totalDocuments": 0,
"totalDataContracts": 0,
"totalTransfers": null,
"totalDocuments": null,
"totalDataContracts": null,
"isSystem": false,
"aliases": [
{
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/controllers/ValidatorsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ValidatorsController {

const validators = await TenderdashRPC.getValidators()

const isActive = validators.some(validator => validator.pro_tx_hash === hash)
const isActive = validators.some(validator => validator.pro_tx_hash === hash.toLowerCase())

const cached = cache.get(`${VALIDATORS_CACHE_KEY}_${validator.proTxHash}`)

Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/dao/BlocksDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ module.exports = class BlockDAO {
const validatorQuery = validator
? [
'validator = ?',
validator
validator.toLowerCase()
]
: ['true']

Expand Down
103 changes: 64 additions & 39 deletions packages/api/src/dao/IdentitiesDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ module.exports = class IdentitiesDAO {
}

getIdentities = async (page, limit, order, orderBy) => {
const fromRank = (page - 1) * limit + 1
const toRank = fromRank + limit - 1
const fromRank = (page - 1) * limit
// const toRank = fromRank + limit - 1

const orderByOptions = [{ column: 'identity_id', order }]

Expand All @@ -235,49 +235,75 @@ module.exports = class IdentitiesDAO {
orderByOptions.unshift({ column: 'balance', order })
}

const getRankString = () => {
return orderByOptions.reduce((acc, value, index, arr) =>
acc + ` ${value.column} ${value.order}${index === arr.length - 1 ? '' : ','}`, 'order by')
}

const subquery = this.knex('identities')
.select('identities.id as identity_id', 'identities.identifier as identifier', 'identities.owner as identity_owner',
'identities.is_system as is_system', 'identities.state_transition_hash as tx_hash', 'identities.state_transition_id as tx_id', 'identities.revision as revision')
.select(this.knex.raw('COALESCE((select sum(amount) from transfers where recipient = identifier), 0) - COALESCE((select sum(amount) from transfers where sender = identifier), 0) as balance'))
.select(this.knex('state_transitions').count('*').whereRaw('owner = identifier').as('total_txs'))
.select(this.knex.raw('rank() over (partition by identities.identifier order by identities.id desc) rank'))
.as('identities')
.select('identities.id as identity_id', 'identities.identifier as identifier',
'identities.owner as identity_owner', 'identities.is_system as is_system',
'identities.state_transition_hash as tx_hash', 'identities.state_transition_id as tx_id',
'identities.revision as revision')
.where('revision', 0)

const countSubquery = this.knex('with_alias')
.select(this.knex.raw('count(*) over () as total_count'))
.limit(1)
.as('total_count')

const filteredIdentities = this.knex(subquery)
.select('balance', 'total_txs', 'identity_id', 'identifier', 'identity_owner', 'tx_hash', 'tx_id', 'revision', 'rank', 'is_system')
.select(this.knex.raw(`row_number() over (${getRankString()}) row_number`))
.where('rank', 1)
const transfersSubquery = this.knex('transfers')
.whereRaw('recipient_id = with_alias.identity_id')
.orWhereRaw('sender_id = with_alias.identity_id')
.as('balance')

const documentsSubQuery = this.knex('documents')
.select('id', 'identifier')
.whereRaw('documents.owner = with_alias.identifier')
.as('as_documents')
const txCountSubquery = this.knex('state_transitions')
.select('owner_id')
.select(this.knex.raw('COUNT(*) as total_txs'))
.groupBy('owner_id')
.as('txs_count_subquery')

const dataContractsSubQuery = this.knex('data_contracts')
.select('id', 'identifier')
.whereRaw('data_contracts.owner = with_alias.identifier')
.as('as_data_contracts')
const identityDataSubquery = this.knex
.with('with_alias', subquery)
.select('identity_id', 'identifier', 'identity_owner',
'revision', 'tx_hash', 'is_system', 'tx_id', 'total_count')
.select(this.knex.raw('COALESCE(txs_count_subquery.total_txs, 0) as total_txs'))
.select(
this.knex(transfersSubquery)
.sum(this.knex.raw('CASE WHEN recipient_id = with_alias.identity_id THEN amount WHEN recipient_id = with_alias.identity_id THEN -amount ELSE 0 END'))
.as('balance')
.limit(1)
.as('balance')
)
.leftJoin(countSubquery, this.knex.raw('true'), this.knex.raw('true'))
.leftJoin(txCountSubquery, 'owner_id', 'identity_id')
.from('with_alias')
.as('subquery')

const rows = await this.knex.with('with_alias', filteredIdentities)
.select('total_txs', 'identity_id', 'identifier', 'identity_owner', 'revision', 'tx_hash', 'tx_id', 'blocks.timestamp as timestamp', 'row_number', 'is_system', 'balance')
.select(this.knex('with_alias').count('*').as('total_count'))
.select(this.knex(this.knex(documentsSubQuery)
.select('id', this.knex.raw('rank() over (partition by as_documents.identifier order by as_documents.id desc) rank')).as('ranked_documents'))
.count('*').where('rank', '1').as('total_documents'))
.select(this.knex(this.knex(dataContractsSubQuery)
.select('id', this.knex.raw('rank() over (partition by as_data_contracts.identifier order by as_data_contracts.id desc) rank')).as('ranked_data_contracts'))
.count('*').where('rank', '1').as('total_data_contracts'))
.select(this.knex('transfers').count('*').whereRaw('sender = identifier or recipient = identifier').as('total_transfers'))
const limitedDataSubquery = this.knex(identityDataSubquery)
.select(
'identity_id', 'identifier', 'identity_owner', 'tx_hash',
'is_system', 'tx_id', 'total_txs', 'total_count', 'balance'
)
.select(
this.knex('identities')
.select('revision')
.whereRaw('subquery.identifier = identities.identifier')
.orderBy('revision', 'DESC')
.limit(1)
.as('revision')
)
.limit(limit)
.offset(fromRank)
.orderBy(orderByOptions)
.as('limited_subquery')

const timestampSubquery = this.knex(limitedDataSubquery)
.select(
'blocks.timestamp as timestamp', 'revision', 'identity_id', 'identifier', 'balance',
'identity_owner', 'tx_hash', 'is_system', 'tx_id', 'total_txs', 'total_count'
)
.leftJoin('state_transitions', 'state_transitions.id', 'tx_id')
.leftJoin('blocks', 'state_transitions.block_hash', 'blocks.hash')
.whereBetween('row_number', [fromRank, toRank])
.leftJoin('blocks', 'state_transitions.block_height', 'blocks.height')
.as('timestamp_subquery')

const rows = await this.knex(timestampSubquery)
.orderBy(orderByOptions)
.from('with_alias')

const totalCount = rows.length > 0 ? Number(rows[0].total_count) : 0

Expand All @@ -296,7 +322,6 @@ module.exports = class IdentitiesDAO {
owner: row.identity_owner,
total_data_contracts: parseInt(row.total_data_contracts),
total_documents: parseInt(row.total_documents),
total_txs: parseInt(row.total_txs),
balance: String(balance),
aliases
})
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/dao/MasternodeVotesDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ module.exports = class MasternodeVotesDAO {
.select('pro_tx_hash', 'masternode_votes.state_transition_hash as state_transition_hash', 'voter_identity_id', 'choice',
'blocks.timestamp as timestamp', 'towards_identity_identifier', 'document_type_name',
'data_contracts.identifier as data_contract_identifier', 'index_name', 'index_values', 'power')
.where('masternode_votes.state_transition_hash', '=', hash)
.where('masternode_votes.state_transition_hash', '=', hash.toLowerCase())
.leftJoin('state_transitions', 'state_transition_hash', 'state_transitions.hash')
.leftJoin('blocks', 'blocks.hash', 'state_transitions.block_hash')
.leftJoin('data_contracts', 'data_contract_id', 'data_contracts.id')
Expand Down
8 changes: 8 additions & 0 deletions packages/api/src/enums/IdentityTypeEnum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const IdentityTypeEnum = {
REGULAR: 0,
MASTERNODE: 1,
VOTING: 2,
0: 'REGULAR',
1: 'MASTERNODE',
2: 'VOTING'
}
2 changes: 1 addition & 1 deletion packages/api/src/models/Vote.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ module.exports = class Vote {

/* eslint-disable camelcase */
static fromRow ({ pro_tx_hash, state_transition_hash, voter_identity_id, choice, timestamp, towards_identity_identifier, data_contract_identifier, document_type_name, index_name, index_values, aliases, power, document_identifier }) {
return new Vote(pro_tx_hash?.toUpperCase(), state_transition_hash, voter_identity_id?.trim(), choice, timestamp, towards_identity_identifier?.trim(), aliases, data_contract_identifier, document_type_name?.trim(), index_name?.trim(), index_values, power, document_identifier?.trim())
return new Vote(pro_tx_hash?.toLowerCase(), state_transition_hash, voter_identity_id?.trim(), choice, timestamp, towards_identity_identifier?.trim(), aliases, data_contract_identifier, document_type_name?.trim(), index_name?.trim(), index_values, power, document_identifier?.trim())
}
}
Loading
Loading