explorer: Misleading transaction time when in micro block

Describe the bug A time in the past is shown for transactions in micro blocks

The time does not makes sense as it looks like that the tx is executed at the already confirmed block, more precisely, that the clarity variable block_height is the height of the confirmed block. This is not true.

To Reproduce Steps to reproduce the behavior:

  1. Go to https://explorer.stacks.co/transactions?chain=testnet
  2. See timestamp on microblock

Expected behavior Do not show a transaction time until the block with the block_height used during processing the transaction is confirmed on Bitcoin.

Screenshots image

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 5
  • Comments: 17 (2 by maintainers)

Most upvoted comments

Follow up. I see that in the API code, is unanchored is being set to !dbTx.block_hash in db-controller.ts. But as we see in the response, the block_hash is not null, rather, it is "block_hash": "0x",

function parseDbAbstractTx(dbTx: DbTx, baseTx: BaseTransaction): AbstractTransaction {
  const abstractTx: AbstractTransaction = {
    ...baseTx,
    is_unanchored: !dbTx.block_hash,
    block_hash: dbTx.block_hash,

@JackNapolitano you’re right, thanks for digging! I’ll get on it ASAP

@rafaelcr I believe it is an API issue: take a look at the response of:

https://stacks-node-api.stacks.co/extended/v1/tx/0x2e61434f2bfa98dd4aba504836b13f3329be46a5244c1d8db0e6f5a7cf51acd2?event_offset=0&event_limit=100&unanchored=true

{
  "tx_id": "0x2e61434f2bfa98dd4aba504836b13f3329be46a5244c1d8db0e6f5a7cf51acd2",
  "nonce": 676,
  "fee_rate": "3500",
  "sender_address": "SP2R3CHRAP1HE4M64X1NZXHZT41JG3XGNHJW4HX2W",
  "sponsored": false,
  "post_condition_mode": "deny",
  "post_conditions": [],
  "anchor_mode": "any",
  "is_unanchored": false,
  "block_hash": "0x",
  "parent_block_hash": "0xdfded07bb693850e7f2f42d11430471890767eb8e791fe05f5d3c4830b1c0b0c",
  "block_height": 86941,
  "burn_block_time": -1,
  "burn_block_time_iso": "",
  "parent_burn_block_time": 1670887714,
  "parent_burn_block_time_iso": "2022-12-12T23:28:34.000Z",
  "canonical": true,
  "tx_index": 3,
  "tx_status": "success",
  "tx_result": {
    "hex": "0x0703",
    "repr": "(ok true)"
  },
  "microblock_hash": "0xb7f32e25268c4d93a2d197a3130d9aa66170d7831b9d2111176d622db2ae7c2c",
  "microblock_sequence": 0,
  "microblock_canonical": true,
  "event_count": 1,
  "events": [
    {
      "event_index": 0,
      "event_type": "smart_contract_log",
      "tx_id": "0x2e61434f2bfa98dd4aba504836b13f3329be46a5244c1d8db0e6f5a7cf51acd2",
      "contract_log": {
        "contract_id": "SP176ZMV706NZGDDX8VSQRGMB7QN33BBDVZ6BMNHD.project-indigo-act1",
        "topic": "print",
        "value": {
          "hex": "0x0c0000000401610d0000000c6c6973742d696e2d757374780a636f6d6d697373696f6e06162bcf9762d5b90bc36dc1b4759b1727690f92ddd31f67616d6d612d77617374656c616e6465722d636f6d6d697373696f6e2d76330269640100000000000000000000000000000006057072696365010000000000000000000000022d0d8159",
          "repr": "(tuple (a \"list-in-ustx\") (commission 'SPNWZ5V2TPWGQGVDR6T7B6RQ4XMGZ4PXTEE0VQ0S.gamma-wastelander-commission-v3) (id u6) (price u9345794393))"
        }
      }
    }
  ],
  "execution_cost_read_count": 5,
  "execution_cost_read_length": 6831,
  "execution_cost_runtime": 35709,
  "execution_cost_write_count": 1,
  "execution_cost_write_length": 112,
  "tx_type": "contract_call",
  "contract_call": {
    "contract_id": "SP176ZMV706NZGDDX8VSQRGMB7QN33BBDVZ6BMNHD.project-indigo-act1",
    "function_name": "list-in-ustx",
    "function_signature": "(define-public (list-in-ustx (id uint) (price uint) (comm trait_reference)))",
    "function_args": [
      {
        "hex": "0x0100000000000000000000000000000006",
        "repr": "u6",
        "name": "id",
        "type": "uint"
      },
      {
        "hex": "0x010000000000000000000000022d0d8159",
        "repr": "u9345794393",
        "name": "price",
        "type": "uint"
      },
      {
        "hex": "0x06162bcf9762d5b90bc36dc1b4759b1727690f92ddd31f67616d6d612d77617374656c616e6465722d636f6d6d697373696f6e2d7633",
        "repr": "'SPNWZ5V2TPWGQGVDR6T7B6RQ4XMGZ4PXTEE0VQ0S.gamma-wastelander-commission-v3",
        "name": "comm",
        "type": "trait_reference"
      }
    ]
  }
}

vs

https://stacks-node-api.mainnet.stacks.co/extended/v1/tx/0x2e61434f2bfa98dd4aba504836b13f3329be46a5244c1d8db0e6f5a7cf51acd2

{
  "tx_id": "0x2e61434f2bfa98dd4aba504836b13f3329be46a5244c1d8db0e6f5a7cf51acd2",
  "nonce": 676,
  "fee_rate": "3500",
  "sender_address": "SP2R3CHRAP1HE4M64X1NZXHZT41JG3XGNHJW4HX2W",
  "sponsored": false,
  "post_condition_mode": "deny",
  "post_conditions": [],
  "anchor_mode": "any",
  "tx_status": "pending",
  "receipt_time": 1670887491,
  "receipt_time_iso": "2022-12-12T23:24:51.000Z",
  "tx_type": "contract_call",
  "contract_call": {
    "contract_id": "SP176ZMV706NZGDDX8VSQRGMB7QN33BBDVZ6BMNHD.project-indigo-act1",
    "function_name": "list-in-ustx",
    "function_signature": "(define-public (list-in-ustx (id uint) (price uint) (comm trait_reference)))",
    "function_args": [
      {
        "hex": "0x0100000000000000000000000000000006",
        "repr": "u6",
        "name": "id",
        "type": "uint"
      },
      {
        "hex": "0x010000000000000000000000022d0d8159",
        "repr": "u9345794393",
        "name": "price",
        "type": "uint"
      },
      {
        "hex": "0x06162bcf9762d5b90bc36dc1b4759b1727690f92ddd31f67616d6d612d77617374656c616e6465722d636f6d6d697373696f6e2d7633",
        "repr": "'SPNWZ5V2TPWGQGVDR6T7B6RQ4XMGZ4PXTEE0VQ0S.gamma-wastelander-commission-v3",
        "name": "comm",
        "type": "trait_reference"
      }
    ]
  }
}

It seems that when setting “unanchored=true” in the API calls, the api is returning "is_unanchored": false," , and the check that is happening on the explorer side of things for microblock tx’s is the following:

if (tx?.tx_status === 'success' && tx.is_unanchored) {
    return TransactionStatus.SUCCESS_MICROBLOCK;
}

Shouldn’t a microblock “is_unanchored” be set to true?

In this case the blockhash is shown as 0x image

It would be good to show something more user friendly.

🎉 This issue has been resolved in version 1.68.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

The API fix has been deployed: https://stacks-node-api.testnet.stacks.co/extended/v1/tx/0x1abc7363e913cf735bafba2ce498e1b8437163773f92999aa179e88c966cc38f?unanchored

{
  "tx_id": "0x1abc7363e913cf735bafba2ce498e1b8437163773f92999aa179e88c966cc38f",
  "nonce": 9,
  "fee_rate": "3000",
  "sender_address": "ST3DSBNTDCMJYZR0RGA55ATYYPV94K4H6HG73NKK8",
  "sponsored": false,
  "post_condition_mode": "allow",
  "post_conditions": [],
  "anchor_mode": "any",
  "is_unanchored": true,
  "block_hash": "0x",

@markmhx @Hero-Gamer so far I don’t believe this is an API issue.

I just reproduced the error (saw a tx “confirmed in anchor block” in Explorer) but also checked that same tx ID in the API, and it returns it as still in the mempool:

{
  "tx_id": "0x87dd4830d5e99991a3d98cb32de005a3751059b1bb0d2af908fd42f3de0ea875",
  "nonce": 1215,
  "fee_rate": "3000",
  "sender_address": "SP2EAJ6Y0STA70HBJF4V2DVRHEZZ50RXYHB2HP73K",
  "sponsored": false,
  "post_condition_mode": "deny",
  "post_conditions": [],
  "anchor_mode": "any",
  "tx_status": "pending",
  "receipt_time": 1670861948,
  "receipt_time_iso": "2022-12-12T16:19:08.000Z",
  "tx_type": "contract_call",
  "contract_call": {
    "contract_id": "SPSCWDV3RKV5ZRN1FQD84YE1NQFEDJ9R1F4DYQ11.newyorkcitycoin-core-v2",
    "function_name": "claim-mining-reward",
    "function_signature": "(define-public (claim-mining-reward (minerBlockHeight uint)))",
    "function_args": [
      {
        "hex": "0x01000000000000000000000000000152e3",
        "repr": "u86755",
        "name": "minerBlockHeight",
        "type": "uint"
      }
    ]
  }
}

@He1DAr this was taken from https://stacks-node-api.mainnet.stacks.co/extended/v1/tx/0x87dd4830d5e99991a3d98cb32de005a3751059b1bb0d2af908fd42f3de0ea875

Do you use any other endpoint for populating the tx landing page? I tried https://stacks-node-api.mainnet.stacks.co/extended/v1/address/SP2EAJ6Y0STA70HBJF4V2DVRHEZZ50RXYHB2HP73K/0x87dd4830d5e99991a3d98cb32de005a3751059b1bb0d2af908fd42f3de0ea875/with_transfers but it returns blank of course given that the tx is not yet confirmed

I also see txs in micro-blocks that are shown as “anchor block” but the anchor block hash is 0x. This is so confusing.

This is a huge issue for us too, it creates a lot of confusion around blockchain state. Why does it show as “in anchor block” when it is in microblock? We’re getting a lot of issues and complaints from users, and since microblocks are often not actually final, people are (rightly) concerned when a transaction confirms “in anchor” and then gets reorged and their transaction fails / get a different NFT ID than they initially expected.

Understood this can happen with an actual anchor block too, but it’s exacerbated here. Until the APIs actually treat microblocks as first-class blocks and dapps can easily index microblock state, easily call read-only contracts at microblock state, and we have some better finality, this is a poor UX decision.

So if one sends a transaction and gets caught in a microblock it can show on the explorer as confirmed 15 minutes ago even when it was send 1 minute ago. very strange indeed. A bit more context.

Describe the solution you’d like

  1. If the microblock does not have a timestamp then do not show a timestamp.
  2. If you can show a timestamp of when the transaction was send, show that instead.
  3. As soon as the transaction is anchored show the timestamp of that block.

Describe alternatives you’ve considered Alternatively it could be left as it is. However users will rightly find it strange. jnapp18 says: “…the explorer should be showing information that makes sense to the end user.”

Why do microblocks not have timestamp, could they be made to have them? probably a question for the stacks-blockchain team.

Additional context image

image

image