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:
Rafael Cárdenas
2022-09-30 11:37:12 -05:00
committed by GitHub
parent 75e51875e1
commit 1edb25697d
6 changed files with 486 additions and 30 deletions

View File

@@ -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;

View File

@@ -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}
`;

View File

@@ -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,

View File

@@ -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,
};

View File

@@ -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)'
);
}

View File

@@ -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();