Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New logic for search in API #356

Merged
merged 13 commits into from
Dec 9, 2024
Merged
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
100 changes: 92 additions & 8 deletions packages/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Reference:
* [Transfers by Identity](#transfers-by-identity)
* [Transactions history](#transactions-history)
* [Rate](#rate)
* [Search](#search)
* [Decode Raw Transaction](#decode-raw-transaction)

### Status
Expand Down Expand Up @@ -546,7 +547,8 @@ GET /transaction/DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEE
aliases: [
{
alias: "alias.dash",
status: "locked"
status: "locked",
contested: true
}
]
}
Expand Down Expand Up @@ -598,7 +600,8 @@ GET /transactions?=1&limit=10&order=asc&owner=6q9RFbeea73tE31LGMBLFZhtBUX3wZL3Tc
aliases: [
{
alias: "alias.dash",
status: "locked"
status: "locked",
contested: true
}
]
}
Expand Down Expand Up @@ -753,7 +756,8 @@ GET /identity/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec
aliases: [
{
alias: "alias.dash",
status: "locked"
status: "locked",
contested: true
}
]
}
Expand All @@ -770,10 +774,17 @@ Return identity by given DPNS/alias
```
GET /dpns/identity?dpns=canuseethat2.dash

{
"identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc",
"alias": "canuseethat2.dash"
}
[
{
"identity_identifier": "8eTDkBhpQjHeqgbVeriwLeZr1tCa6yBGw76SckvD1cwc",
"alias": "canuseethat2.dash",
"status": {
"alias": "canuseethat2.dash",
"contested": false,
"status": "ok"
}
}
]
```
Response codes:
```
Expand Down Expand Up @@ -812,7 +823,8 @@ GET /identities?page=1&limit=10&order=asc&order_by=block_height
aliases: [
{
alias: "alias.dash",
status: "locked"
status: "locked",
contested: true
}
]
}, ...
Expand Down Expand Up @@ -999,6 +1011,78 @@ Response codes:
200: OK
500: Internal Server Error
```
---
### Search
This endpoint allows search any types of data

* `query` required and must contains data for search
* Response may contain array for Identity and Data Contract when searching by part of field

#### Can be found:
* Block
* Full `height`
* Full `hash`
* Transaction
* Full `hash`
* Validator
* Full `proTxHash`
* Full `Identifier` of Masternode Identity
* Identity
* Full `Identifier`
* Part `alias`
* Data Contract
* Full `Identifier`
* Part `name`
* Document
* Full `Identifier`

```
GET /search?query=xyz

{
"identities": [
{
"identifier": "36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm",
"alias": "xyz.dash",
"status": {
"alias": "xyz.dash",
"status": "ok",
"contested": true
}
},
{
"identifier": "5bUPV8KGgL42ZBS9fsmmKU3wweQbVeHHsiVrG3YMHyG5",
"alias": "xyz.dash",
"status": {
"alias": "xyz.dash",
"status": "locked",
"contested": true
}
}
]
}
```

```
GET /search?query=36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm

{
"identity": {
"identifier": "36LGwPSXef8q8wpdnx4EdDeVNuqCYNAE9boDu5bxytsm",
"alias": "xyz.dash",
"status": {
"alias": "xyz.dash",
"status": "ok",
"contested": true
}
}
}
```
Response codes:
```
200: OK
500: Internal Server Error
```
### Transactions history
Return a series data for the amount of transactions chart

Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/controllers/IdentitiesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class IdentitiesController {
getIdentityByDPNSName = async (request, response) => {
const { dpns } = request.query

const identity = await this.identitiesDAO.getIdentityByDPNSName(dpns)
const identity = await this.identitiesDAO.getIdentitiesByDPNSName(dpns)

if (!identity) {
return response.status(404).send({ message: 'not found' })
Expand Down
51 changes: 36 additions & 15 deletions packages/api/src/controllers/MainController.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const IdentitiesDAO = require('../dao/IdentitiesDAO')
const ValidatorsDAO = require('../dao/ValidatorsDAO')
const TenderdashRPC = require('../tenderdashRpc')
const Epoch = require('../models/Epoch')
const { base58 } = require('@scure/base')

const API_VERSION = require('../../package.json').version
const PLATFORM_VERSION = '1' + require('../../package.json').dependencies.dash.substring(1)
Expand Down Expand Up @@ -72,6 +73,8 @@ class MainController {
search = async (request, response) => {
const { query } = request.query

let result = {}

const epoch = Epoch.fromObject({
startTime: 0,
endTime: 0
Expand All @@ -82,7 +85,7 @@ class MainController {
const block = await this.blocksDAO.getBlockByHeight(query)

if (block) {
return response.send({ block })
result = { ...result, block }
}
}

Expand All @@ -91,21 +94,21 @@ class MainController {
const block = await this.blocksDAO.getBlockByHash(query)

if (block) {
return response.send({ block })
result = { ...result, block }
}

// search transactions
const transaction = await this.transactionsDAO.getTransactionByHash(query)

if (transaction) {
return response.send({ transaction })
result = { ...result, transaction }
}

// search validators
// search validators by hash
const validator = await this.validatorsDAO.getValidatorByProTxHash(query, null, epoch)

if (validator) {
return response.send({ validator })
result = { ...result, validator }
}
}

Expand All @@ -115,34 +118,52 @@ class MainController {
const identity = await this.identitiesDAO.getIdentityByIdentifier(query)

if (identity) {
return response.send({ identity })
result = { ...result, identity }
}

// search data contracts
// search validator by MasterNode identity
const proTxHash = Buffer.from(base58.decode(query)).toString('hex')

const validator = await this.validatorsDAO.getValidatorByProTxHash(proTxHash, null, epoch)

if (validator) {
result = { ...result, validator }
}

// search data contract by id
const dataContract = await this.dataContractsDAO.getDataContractByIdentifier(query)

if (dataContract) {
return response.send({ dataContract })
result = { ...result, dataContract }
}

// search documents
const document = await this.documentsDAO.getDocumentByIdentifier(query)

if (document) {
return response.send({ document })
result = { ...result, document }
}
}

// by dpns name
if (/^[^\s.]+(\.[^\s.]+)*$/.test(query)) {
const identity = await this.identitiesDAO.getIdentityByDPNSName(query)
const identities = await this.identitiesDAO.getIdentitiesByDPNSName(query)

if (identity) {
return response.send({ identity })
}
if (identities) {
result = { ...result, identities }
}

// by data-contract name
const dataContracts = await this.dataContractsDAO.getDataContractByName(query)

if (dataContracts) {
result = { ...result, dataContracts }
}

if (Object.keys(result).length === 0) {
response.status(404).send({ message: 'not found' })
}

response.status(404).send({ message: 'not found' })
response.send(result)
}
}

Expand Down
12 changes: 2 additions & 10 deletions packages/api/src/dao/BlocksDAO.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const Block = require('../models/Block')
const PaginatedResultSet = require('../models/PaginatedResultSet')
const { getAliasInfo } = require('../utils')
const { base58 } = require('@scure/base')
const { getAliasInfo, getAliasStateByVote } = require('../utils')
const Transaction = require('../models/Transaction')

module.exports = class BlockDAO {
Expand Down Expand Up @@ -70,14 +69,7 @@ module.exports = class BlockDAO {
const aliases = await Promise.all((row.aliases ?? []).map(async alias => {
const aliasInfo = await getAliasInfo(alias, this.dapi)

const isLocked = base58.encode(
Buffer.from(aliasInfo.contestedState?.finishedVoteInfo?.wonByIdentityId ?? ''),
'base64') !== row.identifier

return {
alias,
status: (aliasInfo.contestedState !== null && isLocked) ? 'locked' : 'ok'
}
return getAliasStateByVote(aliasInfo, alias, row.owner)
}))

return Transaction.fromRow({ ...row, aliases })
Expand Down
26 changes: 26 additions & 0 deletions packages/api/src/dao/DataContractsDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,30 @@ module.exports = class DataContractsDAO {

return DataContract.fromRow(row)
}

getDataContractByName = async (name) => {
const rows = await this.knex('data_contracts')
.select(
'data_contracts.identifier as identifier', 'data_contracts.name as name',
'data_contracts.owner as owner', 'data_contracts.is_system as is_system',
'data_contracts.version as version', 'data_contracts.schema as schema',
'data_contracts.state_transition_hash as tx_hash', 'blocks.timestamp as timestamp'
)
.select(
this.knex('documents')
.count('*')
.leftJoin('data_contracts', 'data_contracts.id', 'documents.data_contract_id')
.whereILike('data_contracts.name', `${name}%`)
.as('documents_count')
)
.whereILike('data_contracts.name', `${name}%`)
.leftJoin('state_transitions', 'state_transitions.hash', 'data_contracts.state_transition_hash')
.leftJoin('blocks', 'state_transitions.block_hash', 'blocks.hash')

if (rows.length === 0) {
return null
}

return rows.map(row => DataContract.fromRow(row))
}
}
Loading
Loading