mirror of
https://github.com/alexgo-io/stacks-blockchain-api.git
synced 2026-01-12 22:43:34 +08:00
fix: support multiple BNS name events in the same transaction (#1337)
* fix: multiple name transfers in same block * fix: support multiple name events in same tx
This commit is contained in:
@@ -517,11 +517,12 @@ export interface DbBnsName {
|
||||
expire_block: number;
|
||||
grace_period?: number;
|
||||
renewal_deadline?: number;
|
||||
resolver?: string | undefined;
|
||||
resolver?: string;
|
||||
zonefile: string;
|
||||
zonefile_hash: string;
|
||||
tx_id: string;
|
||||
tx_index: number;
|
||||
event_index?: number;
|
||||
status?: string;
|
||||
canonical: boolean;
|
||||
}
|
||||
@@ -1106,6 +1107,7 @@ export interface BnsNameInsertValues {
|
||||
namespace_id: string;
|
||||
tx_index: number;
|
||||
tx_id: PgBytea;
|
||||
event_index: number | null;
|
||||
status: string | null;
|
||||
canonical: boolean;
|
||||
index_block_hash: PgBytea;
|
||||
|
||||
@@ -3127,7 +3127,7 @@ export class PgStore {
|
||||
WHERE namespace_id = ${namespace}
|
||||
AND registered_at <= ${maxBlockHeight}
|
||||
AND canonical = true AND microblock_canonical = true
|
||||
ORDER BY name, registered_at DESC, microblock_sequence DESC, tx_index DESC
|
||||
ORDER BY name, registered_at DESC, microblock_sequence DESC, tx_index DESC, event_index DESC
|
||||
LIMIT 100
|
||||
OFFSET ${offset}
|
||||
`;
|
||||
@@ -3187,7 +3187,10 @@ export class PgStore {
|
||||
AND n.registered_at <= ${maxBlockHeight}
|
||||
AND n.canonical = true
|
||||
AND n.microblock_canonical = true
|
||||
ORDER BY n.registered_at DESC, n.microblock_sequence DESC, n.tx_index DESC
|
||||
ORDER BY n.registered_at DESC,
|
||||
n.microblock_sequence DESC,
|
||||
n.tx_index DESC,
|
||||
n.event_index DESC
|
||||
LIMIT 1
|
||||
`;
|
||||
if (nameZonefile.length === 0) {
|
||||
@@ -3455,7 +3458,7 @@ export class PgStore {
|
||||
FROM names
|
||||
WHERE canonical = true AND microblock_canonical = true
|
||||
AND registered_at <= ${maxBlockHeight}
|
||||
ORDER BY name, registered_at DESC, microblock_sequence DESC, tx_index DESC
|
||||
ORDER BY name, registered_at DESC, microblock_sequence DESC, tx_index DESC, event_index DESC
|
||||
LIMIT 100
|
||||
OFFSET ${offset}
|
||||
`;
|
||||
|
||||
@@ -1404,12 +1404,25 @@ export class PgWriteStore extends PgStore {
|
||||
namespace_id,
|
||||
tx_id,
|
||||
tx_index,
|
||||
event_index,
|
||||
status,
|
||||
canonical,
|
||||
} = bnsName;
|
||||
// Try to figure out the name's expiration block based on its namespace's lifetime. However, if
|
||||
// the name was only transferred, keep the expiration from the last register/renewal we had.
|
||||
// Try to figure out the name's expiration block based on its namespace's lifetime.
|
||||
let expireBlock = expire_block;
|
||||
const namespaceLifetime = await sql<{ lifetime: number }[]>`
|
||||
SELECT lifetime
|
||||
FROM namespaces
|
||||
WHERE namespace_id = ${namespace_id}
|
||||
AND canonical = true AND microblock_canonical = true
|
||||
ORDER BY namespace_id, ready_block DESC, microblock_sequence DESC, tx_index DESC
|
||||
LIMIT 1
|
||||
`;
|
||||
if (namespaceLifetime.length > 0) {
|
||||
expireBlock = registered_at + namespaceLifetime[0].lifetime;
|
||||
}
|
||||
// If the name was transferred, keep the expiration from the last register/renewal we had (if
|
||||
// any).
|
||||
if (status === 'name-transfer') {
|
||||
const prevExpiration = await sql<{ expire_block: number }[]>`
|
||||
SELECT expire_block
|
||||
@@ -1422,18 +1435,6 @@ export class PgWriteStore extends PgStore {
|
||||
if (prevExpiration.length > 0) {
|
||||
expireBlock = prevExpiration[0].expire_block;
|
||||
}
|
||||
} else {
|
||||
const namespaceLifetime = await sql<{ lifetime: number }[]>`
|
||||
SELECT lifetime
|
||||
FROM namespaces
|
||||
WHERE namespace_id = ${namespace_id}
|
||||
AND canonical = true AND microblock_canonical = true
|
||||
ORDER BY namespace_id, ready_block DESC, microblock_sequence DESC, tx_index DESC
|
||||
LIMIT 1
|
||||
`;
|
||||
if (namespaceLifetime.length > 0) {
|
||||
expireBlock = registered_at + namespaceLifetime[0].lifetime;
|
||||
}
|
||||
}
|
||||
// If we didn't receive a zonefile, keep the last valid one.
|
||||
let finalZonefile = zonefile;
|
||||
@@ -1476,6 +1477,7 @@ export class PgWriteStore extends PgStore {
|
||||
namespace_id: namespace_id,
|
||||
tx_index: tx_index,
|
||||
tx_id: tx_id,
|
||||
event_index: event_index ?? null,
|
||||
status: status ?? null,
|
||||
canonical: canonical,
|
||||
index_block_hash: blockData.index_block_hash,
|
||||
@@ -1486,7 +1488,7 @@ export class PgWriteStore extends PgStore {
|
||||
};
|
||||
await sql`
|
||||
INSERT INTO names ${sql(nameValues)}
|
||||
ON CONFLICT ON CONSTRAINT unique_name_tx_id_index_block_hash_microblock_hash DO
|
||||
ON CONFLICT ON CONSTRAINT unique_name_tx_id_index_block_hash_microblock_hash_event_index DO
|
||||
UPDATE SET
|
||||
address = EXCLUDED.address,
|
||||
registered_at = EXCLUDED.registered_at,
|
||||
@@ -1494,6 +1496,7 @@ export class PgWriteStore extends PgStore {
|
||||
zonefile_hash = EXCLUDED.zonefile_hash,
|
||||
namespace_id = EXCLUDED.namespace_id,
|
||||
tx_index = EXCLUDED.tx_index,
|
||||
event_index = EXCLUDED.event_index,
|
||||
status = EXCLUDED.status,
|
||||
canonical = EXCLUDED.canonical,
|
||||
parent_index_block_hash = EXCLUDED.parent_index_block_hash,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { BufferCV, ChainID, ClarityType, hexToCV, StringAsciiCV } from '@stacks/transactions';
|
||||
import { hexToBuffer, hexToUtf8String } from '../../helpers';
|
||||
import { bnsNameCV, hexToBuffer, hexToUtf8String } from '../../helpers';
|
||||
import {
|
||||
CoreNodeEvent,
|
||||
CoreNodeEventType,
|
||||
@@ -281,6 +281,7 @@ export function parseNameRenewalWithNoZonefileHashFromContractCall(
|
||||
zonefile: '',
|
||||
tx_id: tx.parsed_tx.tx_id,
|
||||
tx_index: tx.core_tx.tx_index,
|
||||
event_index: undefined,
|
||||
status: 'name-renewal',
|
||||
canonical: true,
|
||||
};
|
||||
@@ -290,7 +291,7 @@ export function parseNameRenewalWithNoZonefileHashFromContractCall(
|
||||
export function parseNameFromContractEvent(
|
||||
event: SmartContractEvent,
|
||||
tx: CoreNodeParsedTxMessage,
|
||||
txEvents: CoreNodeEvent[],
|
||||
allEvents: CoreNodeEvent[],
|
||||
blockHeight: number,
|
||||
chainId: ChainID
|
||||
): DbBnsName | undefined {
|
||||
@@ -303,24 +304,27 @@ export function parseNameFromContractEvent(
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
let name_address = attachment.attachment.metadata.tx_sender.address;
|
||||
const fullName = `${attachment.attachment.metadata.name}.${attachment.attachment.metadata.namespace}`;
|
||||
let ownerAddress = attachment.attachment.metadata.tx_sender.address;
|
||||
// Is this a `name-transfer`? If so, look for the new owner in an `nft_transfer` event bundled in
|
||||
// the same transaction.
|
||||
if (attachment.attachment.metadata.op === 'name-transfer') {
|
||||
for (const txEvent of txEvents) {
|
||||
for (const eventItem of allEvents) {
|
||||
if (
|
||||
txEvent.type === CoreNodeEventType.NftTransferEvent &&
|
||||
txEvent.nft_transfer_event.asset_identifier === `${getBnsContractID(chainId)}::names`
|
||||
eventItem.txid === event.txid &&
|
||||
eventItem.type === CoreNodeEventType.NftTransferEvent &&
|
||||
eventItem.nft_transfer_event.asset_identifier === `${getBnsContractID(chainId)}::names` &&
|
||||
eventItem.nft_transfer_event.raw_value === bnsNameCV(fullName)
|
||||
) {
|
||||
name_address = txEvent.nft_transfer_event.recipient;
|
||||
ownerAddress = eventItem.nft_transfer_event.recipient;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const name: DbBnsName = {
|
||||
name: `${attachment.attachment.metadata.name}.${attachment.attachment.metadata.namespace}`,
|
||||
name: fullName,
|
||||
namespace_id: attachment.attachment.metadata.namespace,
|
||||
address: name_address,
|
||||
address: ownerAddress,
|
||||
// expire_block will be calculated upon DB insert based on the namespace's lifetime.
|
||||
expire_block: 0,
|
||||
registered_at: blockHeight,
|
||||
@@ -329,6 +333,7 @@ export function parseNameFromContractEvent(
|
||||
zonefile: '',
|
||||
tx_id: event.txid,
|
||||
tx_index: tx.core_tx.tx_index,
|
||||
event_index: event.event_index,
|
||||
status: attachment.attachment.metadata.op,
|
||||
canonical: true,
|
||||
};
|
||||
|
||||
@@ -52,6 +52,7 @@ export async function up(pgm: MigrationBuilder): Promise<void> {
|
||||
type: 'smallint',
|
||||
notNull: true,
|
||||
},
|
||||
event_index: 'integer',
|
||||
status: {
|
||||
type: 'string',
|
||||
notNull: false
|
||||
@@ -89,10 +90,11 @@ export async function up(pgm: MigrationBuilder): Promise<void> {
|
||||
{ name: 'registered_at', sort: 'DESC' },
|
||||
{ name: 'microblock_sequence', sort: 'DESC' },
|
||||
{ name: 'tx_index', sort: 'DESC' },
|
||||
{ name: 'event_index', sort: 'DESC' }
|
||||
]);
|
||||
pgm.addConstraint(
|
||||
'names',
|
||||
'unique_name_tx_id_index_block_hash_microblock_hash',
|
||||
'UNIQUE(name, tx_id, index_block_hash, microblock_hash)'
|
||||
'unique_name_tx_id_index_block_hash_microblock_hash_event_index',
|
||||
'UNIQUE(name, tx_id, index_block_hash, microblock_hash, event_index)'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -586,6 +586,447 @@ describe('BNS event server tests', () => {
|
||||
expect(result[0].zonefile).toBe('$ORIGIN jnj.btc.\n$TTL 3600\n_http._tcp\tIN\tURI\t10\t1\t"https://gaia.blockstack.org/hub/1z8AzyhC42n8TvoFaUL2nscaCGHqQQWUr/profile.json"\n\n');
|
||||
});
|
||||
|
||||
test('name-register and name-transfer for several names in one block', async () => {
|
||||
const block = new TestBlockBuilder({
|
||||
block_height: 1,
|
||||
block_hash: '0x161bd86201417a55fb0dd851ac0e6b10c67a0b443e593008a4cf46fb6938b369',
|
||||
index_block_hash: '0x8cc3d58350082f3161ae34deaad77c1c8887947ff0295be59ec5caccf984fe78',
|
||||
burn_block_height: 756266,
|
||||
burn_block_hash: '0x00000000000000000002e78c9c19a055ca0e680674e1a2f0f01a48c04a24f627',
|
||||
burn_block_time: 1664489645,
|
||||
})
|
||||
.addTx({
|
||||
tx_id: '0x1234',
|
||||
sender_address: 'SP3GWTV1SMF9HDS4VY5NMM833CHH266W4YBASVYMZ'
|
||||
})
|
||||
.addTxBnsNamespace({
|
||||
namespace_id: 'btc',
|
||||
lifetime: 1000
|
||||
})
|
||||
.build();
|
||||
await db.update(block);
|
||||
const microblock = new TestMicroblockStreamBuilder()
|
||||
.addMicroblock({
|
||||
microblock_hash: '0xc44f4e3ed66bacaaa5cbe5b9c35b4e2ce2467933b57974fa03b539a2b2b88063',
|
||||
microblock_sequence: 0,
|
||||
parent_index_block_hash: '0x8cc3d58350082f3161ae34deaad77c1c8887947ff0295be59ec5caccf984fe78'
|
||||
})
|
||||
.build();
|
||||
await db.updateMicroblocks(microblock);
|
||||
|
||||
const payload = {
|
||||
// In the block message, events are not sorted by `event_index`.
|
||||
"events": [
|
||||
{
|
||||
"txid": "0xd5803813a0befbf7e426ca897a5940c691a18e5959170e12ddb9e71c91ea4f12",
|
||||
"type": "nft_mint_event",
|
||||
"committed": true,
|
||||
"event_index": 405,
|
||||
"nft_mint_event": {
|
||||
"raw_value": "0x0c00000002046e616d6502000000086b6574656c6f6e65096e616d6573706163650200000003627463",
|
||||
"recipient": "SP253DQBW2ZBKE10PBQVBDJ5XSQQ4P06PVP9PR6S8",
|
||||
"asset_identifier": "SP000000000000000000002Q6VF78.bns::names"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xd5803813a0befbf7e426ca897a5940c691a18e5959170e12ddb9e71c91ea4f12",
|
||||
"type": "contract_event",
|
||||
"committed": true,
|
||||
"event_index": 406,
|
||||
"contract_event": {
|
||||
"topic": "print",
|
||||
"raw_value": "0x0c000000010a6174746163686d656e740c00000003106174746163686d656e742d696e64657801000000000000000000000000000144ea04686173680200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb086d657461646174610c00000004046e616d6502000000086b6574656c6f6e65096e616d6573706163650200000003627463026f700d0000000d6e616d652d72656769737465720974782d73656e64657205168a36dd7c17d73704165df6b6c8bdcdee4b00d6dd",
|
||||
"contract_identifier": "SP000000000000000000002Q6VF78.bns"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xa106e30d1df4607a993ff2ec0d68a4acfb3d5ab2ae597179869df8d6da8f1b95",
|
||||
"type": "nft_transfer_event",
|
||||
"committed": true,
|
||||
"event_index": 407,
|
||||
"nft_transfer_event": {
|
||||
"sender": "SP253DQBW2ZBKE10PBQVBDJ5XSQQ4P06PVP9PR6S8",
|
||||
"raw_value": "0x0c00000002046e616d6502000000086b6574656c6f6e65096e616d6573706163650200000003627463",
|
||||
"recipient": "SP2WPXVTZE2RG4SZGJT5HTZ7JK6CAWTEV0A55HFH7",
|
||||
"asset_identifier": "SP000000000000000000002Q6VF78.bns::names"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xa106e30d1df4607a993ff2ec0d68a4acfb3d5ab2ae597179869df8d6da8f1b95",
|
||||
"type": "contract_event",
|
||||
"committed": true,
|
||||
"event_index": 408,
|
||||
"contract_event": {
|
||||
"topic": "print",
|
||||
"raw_value": "0x0c000000010a6174746163686d656e740c00000003106174746163686d656e742d696e64657801000000000000000000000000000144eb04686173680200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb086d657461646174610c00000004046e616d6502000000086b6574656c6f6e65096e616d6573706163650200000003627463026f700d0000000d6e616d652d7472616e736665720974782d73656e64657205168a36dd7c17d73704165df6b6c8bdcdee4b00d6dd",
|
||||
"contract_identifier": "SP000000000000000000002Q6VF78.bns"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0x1784633b879ffcf15c18dcf627047a44358f2f0660c14f5188c9f17b28abb8af",
|
||||
"type": "nft_mint_event",
|
||||
"committed": true,
|
||||
"event_index": 381,
|
||||
"nft_mint_event": {
|
||||
"raw_value": "0x0c00000002046e616d65020000000f637269636b6574776972656c657373096e616d6573706163650200000003627463",
|
||||
"recipient": "SP2MM4ETXDE26HQ64F29VG05Q577DEPTSDJ2DQV8N",
|
||||
"asset_identifier": "SP000000000000000000002Q6VF78.bns::names"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0x1784633b879ffcf15c18dcf627047a44358f2f0660c14f5188c9f17b28abb8af",
|
||||
"type": "contract_event",
|
||||
"committed": true,
|
||||
"event_index": 382,
|
||||
"contract_event": {
|
||||
"topic": "print",
|
||||
"raw_value": "0x0c000000010a6174746163686d656e740c00000003106174746163686d656e742d696e64657801000000000000000000000000000144e204686173680200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb086d657461646174610c00000004046e616d65020000000f637269636b6574776972656c657373096e616d6573706163650200000003627463026f700d0000000d6e616d652d72656769737465720974782d73656e6465720516a9423b5d6b8468dcc47893b800b729ced75b596c",
|
||||
"contract_identifier": "SP000000000000000000002Q6VF78.bns"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0x28715dc6e09e75cec4d26d6a52426c8cc13c6e5a16d5252886c33ffc6bcceef7",
|
||||
"type": "nft_transfer_event",
|
||||
"committed": true,
|
||||
"event_index": 389,
|
||||
"nft_transfer_event": {
|
||||
"sender": "SP2MM4ETXDE26HQ64F29VG05Q577DEPTSDJ2DQV8N",
|
||||
"raw_value": "0x0c00000002046e616d65020000000f637269636b6574776972656c657373096e616d6573706163650200000003627463",
|
||||
"recipient": "SP1QFKSVQP3J2PF45KFFCVBR4Q24Y09G0PJDECHS7",
|
||||
"asset_identifier": "SP000000000000000000002Q6VF78.bns::names"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0x28715dc6e09e75cec4d26d6a52426c8cc13c6e5a16d5252886c33ffc6bcceef7",
|
||||
"type": "contract_event",
|
||||
"committed": true,
|
||||
"event_index": 390,
|
||||
"contract_event": {
|
||||
"topic": "print",
|
||||
"raw_value": "0x0c000000010a6174746163686d656e740c00000003106174746163686d656e742d696e64657801000000000000000000000000000144e304686173680200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb086d657461646174610c00000004046e616d65020000000f637269636b6574776972656c657373096e616d6573706163650200000003627463026f700d0000000d6e616d652d7472616e736665720974782d73656e6465720516a9423b5d6b8468dcc47893b800b729ced75b596c",
|
||||
"contract_identifier": "SP000000000000000000002Q6VF78.bns"
|
||||
}
|
||||
}
|
||||
],
|
||||
"block_hash": "0x41e158fe192103d2a5f895c6f9093a548ecc35db3a4c3c5de0e616fd3894338e",
|
||||
"miner_txid": "0x9c48f6c748177cd049db40172e5044e5a98f8fe5b798f33212f876121e764b72",
|
||||
"block_height": 2,
|
||||
"transactions": [
|
||||
{
|
||||
"txid": "0x1784633b879ffcf15c18dcf627047a44358f2f0660c14f5188c9f17b28abb8af",
|
||||
"raw_tx": "0x00000000010400a9423b5d6b8468dcc47893b800b729ced75b596c00000000000000010000000000014ed6010055b3a6e2581eaaf686bc9596a4c9cf62cbdb30ffaad167c094824b5d89598ce1101ff56aeb58e2020c10954da05cd80b733ec79ecd71db1921aa202d377aac740302000000000216000000000000000000000000000000000000000003626e730d6e616d652d7265676973746572000000040200000003627463020000000f637269636b6574776972656c65737302000000149a3db4f009ad960c5a0cad7ad9c19f21fa0fe3680200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb",
|
||||
"status": "success",
|
||||
"tx_index": 274,
|
||||
"raw_result": "0x0703",
|
||||
"contract_abi": null,
|
||||
"execution_cost": {
|
||||
"runtime": 311527,
|
||||
"read_count": 17,
|
||||
"read_length": 43206,
|
||||
"write_count": 4,
|
||||
"write_length": 242
|
||||
},
|
||||
"microblock_hash": null,
|
||||
"microblock_sequence": null,
|
||||
"microblock_parent_hash": null
|
||||
},
|
||||
{
|
||||
"txid": "0x28715dc6e09e75cec4d26d6a52426c8cc13c6e5a16d5252886c33ffc6bcceef7",
|
||||
"raw_tx": "0x00000000010400a9423b5d6b8468dcc47893b800b729ced75b596c00000000000000020000000000014941010173c47aad0c8e5e8e2c655f488e4b8f514a63fd0190ae392f6cc6f22c1ec93aa44facb412a9d6504efd7945eeb52407011069ca1d3a7138e7a889c7c15aa82df2030200000001020216a9423b5d6b8468dcc47893b800b729ced75b596c16000000000000000000000000000000000000000003626e73056e616d65730c00000002046e616d65020000000f637269636b6574776972656c657373096e616d6573706163650200000003627463100216000000000000000000000000000000000000000003626e730d6e616d652d7472616e73666572000000040200000003627463020000000f637269636b6574776972656c65737305166ef9e777b0e42b3c859bdecdaf04b889e02600b40a0200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb",
|
||||
"status": "success",
|
||||
"tx_index": 276,
|
||||
"raw_result": "0x0703",
|
||||
"contract_abi": null,
|
||||
"execution_cost": {
|
||||
"runtime": 183670,
|
||||
"read_count": 19,
|
||||
"read_length": 44047,
|
||||
"write_count": 5,
|
||||
"write_length": 266
|
||||
},
|
||||
"microblock_hash": null,
|
||||
"microblock_sequence": null,
|
||||
"microblock_parent_hash": null
|
||||
},
|
||||
{
|
||||
"txid": "0xd5803813a0befbf7e426ca897a5940c691a18e5959170e12ddb9e71c91ea4f12",
|
||||
"raw_tx": "0x000000000104008a36dd7c17d73704165df6b6c8bdcdee4b00d6dd0000000000000001000000000001449f0101bd23afc22da4e356847d76d07261a861488389d4864c8d42ce002be439e0e78b3aa1088a8aaac189f7c85e674fd871b787f1fb0cd5a19acd827a011f5e38921c0302000000000216000000000000000000000000000000000000000003626e730d6e616d652d726567697374657200000004020000000362746302000000086b6574656c6f6e6502000000146cd23e487d9068d24e1e1bc90636a6e48c1546a50200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb",
|
||||
"status": "success",
|
||||
"tx_index": 285,
|
||||
"raw_result": "0x0703",
|
||||
"contract_abi": null,
|
||||
"execution_cost": {
|
||||
"runtime": 229244,
|
||||
"read_count": 17,
|
||||
"read_length": 43199,
|
||||
"write_count": 4,
|
||||
"write_length": 228
|
||||
},
|
||||
"microblock_hash": null,
|
||||
"microblock_sequence": null,
|
||||
"microblock_parent_hash": null
|
||||
},
|
||||
{
|
||||
"txid": "0xa106e30d1df4607a993ff2ec0d68a4acfb3d5ab2ae597179869df8d6da8f1b95",
|
||||
"raw_tx": "0x000000000104008a36dd7c17d73704165df6b6c8bdcdee4b00d6dd00000000000000020000000000015cb70101ac9a2e87c627c605ac68f0c40d59ff6bd5543705a5710ee4679d936a664d20f60a0b91e98770cb3597ea25af005e9eb083a827e860b6ba975c0a819205b4792f0302000000010202168a36dd7c17d73704165df6b6c8bdcdee4b00d6dd16000000000000000000000000000000000000000003626e73056e616d65730c00000002046e616d6502000000086b6574656c6f6e65096e616d6573706163650200000003627463100216000000000000000000000000000000000000000003626e730d6e616d652d7472616e7366657200000004020000000362746302000000086b6574656c6f6e650516b96eef5f70b10267f0968b1d7cf29998ae69db020a0200000014b472a266d0bd89c13706a4132ccfb16f7c3b9fcb",
|
||||
"status": "success",
|
||||
"tx_index": 286,
|
||||
"raw_result": "0x0703",
|
||||
"contract_abi": null,
|
||||
"execution_cost": {
|
||||
"runtime": 183264,
|
||||
"read_count": 19,
|
||||
"read_length": 44026,
|
||||
"write_count": 5,
|
||||
"write_length": 252
|
||||
},
|
||||
"microblock_hash": null,
|
||||
"microblock_sequence": null,
|
||||
"microblock_parent_hash": null
|
||||
}
|
||||
],
|
||||
"anchored_cost": {
|
||||
"runtime": 37717625,
|
||||
"read_count": 3184,
|
||||
"read_length": 10513899,
|
||||
"write_count": 710,
|
||||
"write_length": 42932
|
||||
},
|
||||
"burn_block_hash": "0x0000000000000000000213c1512c2bffae7378f2b890bfea3ee6dc8e2e7836a2",
|
||||
"burn_block_time": 1664490688,
|
||||
"index_block_hash": "0x2eb444d32bb66a6acc3ba66aedabbb19c3adde8b6a9717765960bdc67ea32070",
|
||||
"burn_block_height": 756268,
|
||||
"parent_block_hash": "0x161bd86201417a55fb0dd851ac0e6b10c67a0b443e593008a4cf46fb6938b369",
|
||||
"parent_microblock": "0xc44f4e3ed66bacaaa5cbe5b9c35b4e2ce2467933b57974fa03b539a2b2b88063",
|
||||
"matured_miner_rewards": [],
|
||||
"parent_burn_block_hash": "0x00000000000000000002e78c9c19a055ca0e680674e1a2f0f01a48c04a24f627",
|
||||
"parent_index_block_hash": "0x8cc3d58350082f3161ae34deaad77c1c8887947ff0295be59ec5caccf984fe78",
|
||||
"parent_burn_block_height": 756266,
|
||||
"confirmed_microblocks_cost": {
|
||||
"runtime": 5707388,
|
||||
"read_count": 545,
|
||||
"read_length": 2095326,
|
||||
"write_count": 127,
|
||||
"write_length": 8025
|
||||
},
|
||||
"parent_microblock_sequence": 0,
|
||||
"parent_burn_block_timestamp": 1664489645
|
||||
};
|
||||
|
||||
await httpPostRequest({
|
||||
host: '127.0.0.1',
|
||||
port: eventServer.serverAddress.port,
|
||||
path: '/new_block',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: Buffer.from(JSON.stringify(payload), 'utf8'),
|
||||
throwOnNotOK: true,
|
||||
});
|
||||
|
||||
const name = await db.getName({
|
||||
name: 'cricketwireless.btc',
|
||||
includeUnanchored: true,
|
||||
chainId: ChainID.Mainnet
|
||||
});
|
||||
expect(name.found).toBe(true);
|
||||
expect(name.result?.namespace_id).toBe('btc');
|
||||
expect(name.result?.tx_id).toBe('0x28715dc6e09e75cec4d26d6a52426c8cc13c6e5a16d5252886c33ffc6bcceef7');
|
||||
expect(name.result?.status).toBe('name-transfer');
|
||||
expect(name.result?.address).toBe('SP1QFKSVQP3J2PF45KFFCVBR4Q24Y09G0PJDECHS7');
|
||||
});
|
||||
|
||||
test('name-register and name-transfer in same tx from non-BNS contract', async () => {
|
||||
const block = new TestBlockBuilder({
|
||||
block_height: 1,
|
||||
block_hash: '0x08cdd83644176e87cd5fdc584a5193de84c4c54cbe8b3839225e75f396f64468',
|
||||
index_block_hash: '0x82239cdbd3903ca032d300101990120947132a8a005a92d7a1cdcd5a61b35ba1',
|
||||
burn_block_height: 749980,
|
||||
burn_block_hash: '0x000000000000000000089afaf672605818e368521d9ad2d8e4b5763956b75363',
|
||||
burn_block_time: 1660833970,
|
||||
})
|
||||
.addTx({
|
||||
tx_id: '0x1234',
|
||||
sender_address: 'SP3GWTV1SMF9HDS4VY5NMM833CHH266W4YBASVYMZ'
|
||||
})
|
||||
.addTxBnsNamespace({
|
||||
namespace_id: 'mega',
|
||||
lifetime: 1000
|
||||
})
|
||||
.build();
|
||||
await db.update(block);
|
||||
const microblock = new TestMicroblockStreamBuilder()
|
||||
.addMicroblock({
|
||||
microblock_hash: '0x2ad76cc1eadb6e0dd155a7b5ac82ff81a2c664552dacb99a524a410856330529',
|
||||
microblock_sequence: 0,
|
||||
parent_index_block_hash: '0x82239cdbd3903ca032d300101990120947132a8a005a92d7a1cdcd5a61b35ba1'
|
||||
})
|
||||
.build();
|
||||
await db.updateMicroblocks(microblock);
|
||||
|
||||
const payload = {
|
||||
"events": [
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"type": "contract_event",
|
||||
"committed": true,
|
||||
"event_index": 85,
|
||||
"contract_event": {
|
||||
"topic": "print",
|
||||
"raw_value": "0x0c000000010a6174746163686d656e740c00000003106174746163686d656e742d696e646578010000000000000000000000000000f65804686173680200000000086d657461646174610c00000004046e616d650200000003617065096e616d65737061636502000000046d656761026f700d0000000d6e616d652d7472616e736665720974782d73656e64657206161809f2ab9182b6ff1678f82846131c0709e51cf91b72796465722d68616e646c65732d636f6e74726f6c6c65722d7631",
|
||||
"contract_identifier": "SP000000000000000000002Q6VF78.bns"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"type": "stx_burn_event",
|
||||
"committed": true,
|
||||
"event_index": 81,
|
||||
"stx_burn_event": {
|
||||
"amount": "1",
|
||||
"sender": "SPC0KWNBJ61BDZRPF3W2GHGK3G3GKS8WZ7ND33PS.ryder-handles-controller-v1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"type": "nft_transfer_event",
|
||||
"committed": true,
|
||||
"event_index": 84,
|
||||
"nft_transfer_event": {
|
||||
"sender": "SPC0KWNBJ61BDZRPF3W2GHGK3G3GKS8WZ7ND33PS.ryder-handles-controller-v1",
|
||||
"raw_value": "0x0c00000002046e616d650200000003617065096e616d65737061636502000000046d656761",
|
||||
"recipient": "SPV48Q8E5WP4TCQ63E9TV6KF9R4HP01Z8WS3FBTG",
|
||||
"asset_identifier": "SP000000000000000000002Q6VF78.bns::names"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"type": "nft_mint_event",
|
||||
"committed": true,
|
||||
"event_index": 82,
|
||||
"nft_mint_event": {
|
||||
"raw_value": "0x0c00000002046e616d650200000003617065096e616d65737061636502000000046d656761",
|
||||
"recipient": "SPC0KWNBJ61BDZRPF3W2GHGK3G3GKS8WZ7ND33PS.ryder-handles-controller-v1",
|
||||
"asset_identifier": "SP000000000000000000002Q6VF78.bns::names"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"type": "stx_transfer_event",
|
||||
"committed": true,
|
||||
"event_index": 79,
|
||||
"stx_transfer_event": {
|
||||
"amount": "3000000",
|
||||
"sender": "SPC0KWNBJ61BDZRPF3W2GHGK3G3GKS8WZ7ND33PS.ryder-handles-controller-v1",
|
||||
"recipient": "SP2J9XB6CNJX9C36D5SY4J85SA0P1MQX7R5VFKZZX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"type": "stx_transfer_event",
|
||||
"committed": true,
|
||||
"event_index": 80,
|
||||
"stx_transfer_event": {
|
||||
"amount": "1",
|
||||
"sender": "SP3C8QH2R3909YQZ7WVZ71N8RJ6Y0P317T8MG8XSZ",
|
||||
"recipient": "SPC0KWNBJ61BDZRPF3W2GHGK3G3GKS8WZ7ND33PS.ryder-handles-controller-v1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"type": "contract_event",
|
||||
"committed": true,
|
||||
"event_index": 83,
|
||||
"contract_event": {
|
||||
"topic": "print",
|
||||
"raw_value": "0x0c000000010a6174746163686d656e740c00000003106174746163686d656e742d696e646578010000000000000000000000000000f65704686173680200000000086d657461646174610c00000004046e616d650200000003617065096e616d65737061636502000000046d656761026f700d0000000d6e616d652d72656769737465720974782d73656e64657206161809f2ab9182b6ff1678f82846131c0709e51cf91b72796465722d68616e646c65732d636f6e74726f6c6c65722d7631",
|
||||
"contract_identifier": "SP000000000000000000002Q6VF78.bns"
|
||||
}
|
||||
}
|
||||
],
|
||||
"block_hash": "0xbcf632eaa887b66a6356bf9410eb61377cced2d3f444a2286fb59b12a63e48e4",
|
||||
"miner_txid": "0x037d5016d21839a46f136ad846ea99967eda65bf5cdb31feabc60c8eaef5b96d",
|
||||
"block_height": 2,
|
||||
"transactions": [
|
||||
{
|
||||
"txid": "0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16",
|
||||
"raw_tx": "0x00000000010400d88bc4581a409f5fe7e6fe70d51891bc0b0c27d2000000000000001100000000000003e80001fff157398074931aca859d34de1f3070359b8493033cd79fde329ecd66e4bd090235cf61f9916f76cdbaa37ff4d2ee3358322f6a58ec2fb05717115c913fd6e103010000000002161809f2ab9182b6ff1678f82846131c0709e51cf91b72796465722d68616e646c65732d636f6e74726f6c6c65722d76310d6e616d652d72656769737465720000000602000000046d656761020000000361706502000000057337306b35020000004107d00910104bba0ee68b131ceead109ccea598a267a2000140b3277809f1ab535dcef753028c00e7239be1477801ac7d5b8c10e0a7b242261285212da194bdad01051636445d0e2f2c4d32e61b93ad9a6f4e091b003f470200000000",
|
||||
"status": "success",
|
||||
"tx_index": 25,
|
||||
"raw_result": "0x0703",
|
||||
"contract_abi": null,
|
||||
"execution_cost": {
|
||||
"runtime": 643399,
|
||||
"read_count": 69,
|
||||
"read_length": 231108,
|
||||
"write_count": 16,
|
||||
"write_length": 1948
|
||||
},
|
||||
"microblock_hash": null,
|
||||
"microblock_sequence": null,
|
||||
"microblock_parent_hash": null
|
||||
}
|
||||
],
|
||||
"anchored_cost": {
|
||||
"runtime": 39996577,
|
||||
"read_count": 4234,
|
||||
"read_length": 13859444,
|
||||
"write_count": 676,
|
||||
"write_length": 53049
|
||||
},
|
||||
"burn_block_hash": "0x0000000000000000000867b5dd6ec7ebb50404acabcdb35193b6b2fcd3ea7a37",
|
||||
"burn_block_time": 1660834638,
|
||||
"index_block_hash": "0xe43e505d4c7ca5f64a6d9617fbb658a84344610eb0e6495f8f9b7ab3b2648f61",
|
||||
"burn_block_height": 749981,
|
||||
"parent_block_hash": "0x08cdd83644176e87cd5fdc584a5193de84c4c54cbe8b3839225e75f396f64468",
|
||||
"parent_microblock": "0x2ad76cc1eadb6e0dd155a7b5ac82ff81a2c664552dacb99a524a410856330529",
|
||||
"matured_miner_rewards": [],
|
||||
"parent_burn_block_hash": "0x000000000000000000089afaf672605818e368521d9ad2d8e4b5763956b75363",
|
||||
"parent_index_block_hash": "0x82239cdbd3903ca032d300101990120947132a8a005a92d7a1cdcd5a61b35ba1",
|
||||
"parent_burn_block_height": 749980,
|
||||
"confirmed_microblocks_cost": {
|
||||
"runtime": 0,
|
||||
"read_count": 0,
|
||||
"read_length": 0,
|
||||
"write_count": 0,
|
||||
"write_length": 0
|
||||
},
|
||||
"parent_microblock_sequence": 0,
|
||||
"parent_burn_block_timestamp": 1660833970
|
||||
};
|
||||
|
||||
await httpPostRequest({
|
||||
host: '127.0.0.1',
|
||||
port: eventServer.serverAddress.port,
|
||||
path: '/new_block',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: Buffer.from(JSON.stringify(payload), 'utf8'),
|
||||
throwOnNotOK: true,
|
||||
});
|
||||
|
||||
const name = await db.getName({
|
||||
name: 'ape.mega',
|
||||
includeUnanchored: true,
|
||||
chainId: ChainID.Mainnet
|
||||
});
|
||||
expect(name.found).toBe(true);
|
||||
expect(name.result?.namespace_id).toBe('mega');
|
||||
expect(name.result?.tx_id).toBe('0xf9f9144793f6d4da9aba92a54ab601eb23bfe7f44c1edb29c2920bf5e7d2ac16');
|
||||
expect(name.result?.status).toBe('name-transfer');
|
||||
expect(name.result?.expire_block).toBe(1002);
|
||||
expect(name.result?.address).toBe('SPV48Q8E5WP4TCQ63E9TV6KF9R4HP01Z8WS3FBTG');
|
||||
|
||||
const list = await db.getNamesList({ page: 0, includeUnanchored: true });
|
||||
expect(list.results.length).toBe(1);
|
||||
expect(list.results).toStrictEqual(['ape.mega']);
|
||||
|
||||
const namespaceList = await db.getNamespaceNamesList({
|
||||
namespace: 'mega',
|
||||
page: 0,
|
||||
includeUnanchored: true
|
||||
});
|
||||
expect(namespaceList.results.length).toBe(1);
|
||||
expect(namespaceList.results).toStrictEqual(['ape.mega']);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await eventServer.closeAsync();
|
||||
await db?.close();
|
||||
|
||||
Reference in New Issue
Block a user