mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-01-12 22:43:42 +08:00
487 lines
16 KiB
Markdown
487 lines
16 KiB
Markdown
# Event dispatching / observer interface
|
|
|
|
The `stacks-node` supports a configurable event observer interface.
|
|
This is enabled by adding an entry to the node's `config.toml` file:
|
|
|
|
```toml
|
|
...
|
|
[[events_observer]]
|
|
endpoint = "listener:3700"
|
|
events_keys = [
|
|
"*"
|
|
]
|
|
...
|
|
```
|
|
|
|
The `stacks-node` will then execute HTTP POSTs to the configured
|
|
endpoint in two events:
|
|
|
|
1. A new Stacks block is processed.
|
|
2. New mempool transactions have been received.
|
|
|
|
These events are sent to the configured endpoint at two URLs:
|
|
|
|
|
|
### `POST /new_block`
|
|
|
|
This payload includes data related to a newly processed block,
|
|
and any events emitted from Stacks transactions during the block.
|
|
|
|
If the transaction originally comes from the parent microblock stream
|
|
preceding this block, the microblock related fields will be filled in.
|
|
|
|
If the `raw_tx` field for a particular transaction is "0x00", that indicates
|
|
that it is a burnchain operation. A burnchain operation is a transaction that
|
|
is executed on the Stacks network, but was sent through the Bitcoin network.
|
|
The Stacks network supports a few specific burnchain operations. You can read
|
|
more about them [here](https://github.com/stacksgov/sips/blob/main/sips/sip-007/sip-007-stacking-consensus.md#stx-operations-on-bitcoin).
|
|
The section below has example json encodings for each of the burnchain operations.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"block_hash": "0x4eaabcd105865e471f697eff5dd5bd85d47ecb5a26a3379d74fae0ae87c40904",
|
|
"block_height": 3,
|
|
"burn_block_time": 1591301733,
|
|
"events": [
|
|
{
|
|
"event_index": 1,
|
|
"committed": true,
|
|
"stx_transfer_event": {
|
|
"amount": "1000",
|
|
"recipient": "ST31DA6FTSJX2WGTZ69SFY11BH51NZMB0ZZ239N96",
|
|
"sender": "ST3WM51TCWMJYGZS1QFMC28DH5YP86782YGR113C1"
|
|
},
|
|
"txid": "0x738e4d44636023efa08374033428e44eca490582bd39a6e61f3b6cf749b4214c",
|
|
"type": "stx_transfer_event"
|
|
}
|
|
],
|
|
"index_block_hash": "0x329efcbcc6daf5ac3f264522e0df50eddb5be85df6ee8a9fc2384c54274d7afc",
|
|
"parent_block_hash": "0xf5d4ce0efe1d42c963d615ce57f0d014f263a985175e4ece766eceff10e0a358",
|
|
"parent_index_block_hash": "0x0c8b38d44d6af72703a4767ff4cea683ec965346d9e9a7ded2d773fb4f257c28",
|
|
"parent_microblock": "0xedd15cf1e697c28df934e259f0f82970a7c9edc2d39bef04bdd0d422116235c6",
|
|
"transactions": [
|
|
{
|
|
"contract_abi": null,
|
|
"burnchain_op": null,
|
|
"raw_result": "0x03",
|
|
"raw_tx": "0x808000000004008bc5147525b8f477f0bc4522a88c8339b2494db50000000000000002000000000000000001015814daf929d8700af344987681f44e913890a12e38550abe8e40f149ef5269f40f4008083a0f2e0ddf65dcd05ecfc151c7ff8a5308ad04c77c0e87b5aeadad31010200000000040000000000000000000000000000000000000000000000000000000000000000",
|
|
"status": "success",
|
|
"tx_index": 0,
|
|
"txid": "0x3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
|
|
"microblock_sequence": "None",
|
|
"microblock_hash": "None",
|
|
"microblock_parent_hash": "None"
|
|
},
|
|
{
|
|
"contract_abi": null,
|
|
"burnchain_op": null,
|
|
"raw_result": "0x03",
|
|
"raw_tx": "0x80800000000400f942874ce525e87f21bbe8c121b12fac831d02f4000000000000000000000000000003e800006ae29867aec4b0e4f776bebdcea7f6d9a24eeff370c8c739defadfcbb52659b30736ad4af021e8fb741520a6c65da419fdec01989fdf0032fc1838f427a9a36102010000000000051ac2d519faccba2e435f3272ff042b89435fd160ff00000000000003e800000000000000000000000000000000000000000000000000000000000000000000",
|
|
"status": "success",
|
|
"tx_index": 1,
|
|
"txid": "0x738e4d44636023efa08374033428e44eca490582bd39a6e61f3b6cf749b4214c",
|
|
"microblock_sequence": "3",
|
|
"microblock_hash": "0x9304fcbcc6daf5ac3f264522e0df50eddb5be85df6ee8a9fc2384c54274daaac",
|
|
"microblock_parent_hash": "0x4893ab44636023efa08374033428e44eca490582bd39a6e61f3b6cf749b474bd"
|
|
},
|
|
{
|
|
"burnchain_op": {
|
|
"transfer_stx": {
|
|
"burn_block_height": 10,
|
|
"burn_header_hash": "1410131010105914101010101013704010101010221010101010101010101010",
|
|
"memo": "0x000102030405",
|
|
"recipient": {
|
|
"address": "SP24ZBZ8ZE6F48JE9G3F3HRTG9FK7E2H6K2QZ3Q1K",
|
|
"address_hash_bytes": "0x89f5fd1f719e4449c980de38e3504be6770a2698",
|
|
"address_version": 22
|
|
},
|
|
"sender": {
|
|
"address": "ST2QKZ4FKHAH1NQKYKYAYZPY440FEPK7GZ1R5HBP2",
|
|
"address_hash_bytes": "0xaf3f91f38aa21ade7e9f95efdbc4201eeb4cf0f8",
|
|
"address_version": 26
|
|
},
|
|
"transfered_ustx": 10,
|
|
"burn_txid": "85aa2106186723f3c4f1d8bb58e3a02746ca9be1be9f4be0c6557079e1f660e6",
|
|
"vtxindex": 10
|
|
}
|
|
},
|
|
"contract_abi": null,
|
|
"execution_cost": {
|
|
"read_count": 0,
|
|
"read_length": 0,
|
|
"runtime": 0,
|
|
"write_count": 0,
|
|
"write_length": 0
|
|
},
|
|
"microblock_hash": null,
|
|
"microblock_parent_hash": null,
|
|
"microblock_sequence": null,
|
|
"raw_result": "0x0703",
|
|
"raw_tx": "0x00",
|
|
"status": "success",
|
|
"tx_index": 2,
|
|
"txid": "0x85aa2106186723f3c4f1d8bb58e3a02746ca9be1be9f4be0c6557079e1f660e6"
|
|
}
|
|
],
|
|
"matured_miner_rewards": [
|
|
{
|
|
"recipient": "ST31DA6FTSJX2WGTZ69SFY11BH51NZMB0ZZ239N96",
|
|
"coinbase_amount": "1000",
|
|
"tx_fees_anchored": "800",
|
|
"tx_fees_streamed_confirmed": "0",
|
|
"from_stacks_block_hash": "0xf5d4ce0efe1d42c963d615ce57f0d014f263a985175e4ece766eceff10e0a358",
|
|
"from_index_block_hash": "0x329efcbcc6daf5ac3f264522e0df50eddb5be85df6ee8a9fc2384c54274d7afc",
|
|
}
|
|
],
|
|
"anchored_cost": {
|
|
"runtime": 100,
|
|
"read_count": 10,
|
|
"write_count": 5,
|
|
"read_length": 150,
|
|
"write_length": 75
|
|
},
|
|
"confirmed_microblocks_cost": {
|
|
"runtime": 100,
|
|
"read_count": 10,
|
|
"write_count": 5,
|
|
"read_length": 150,
|
|
"write_length": 75
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Example json values for burnchain operations
|
|
- TransferStx
|
|
```json
|
|
{
|
|
"transfer_stx": {
|
|
"burn_block_height": 10,
|
|
"burn_header_hash": "1410131010105914101010101013704010101010221010101010101010101010",
|
|
"memo": "0x000102030405",
|
|
"recipient": {
|
|
"address": "SP24ZBZ8ZE6F48JE9G3F3HRTG9FK7E2H6K2QZ3Q1K",
|
|
"address_hash_bytes": "0x89f5fd1f719e4449c980de38e3504be6770a2698",
|
|
"address_version": 22
|
|
},
|
|
"sender": {
|
|
"address": "ST2QKZ4FKHAH1NQKYKYAYZPY440FEPK7GZ1R5HBP2",
|
|
"address_hash_bytes": "0xaf3f91f38aa21ade7e9f95efdbc4201eeb4cf0f8",
|
|
"address_version": 26
|
|
},
|
|
"transfered_ustx": 10,
|
|
"burn_txid": "85aa2106186723f3c4f1d8bb58e3a02746ca9be1be9f4be0c6557079e1f660e6",
|
|
"vtxindex": 10
|
|
}
|
|
}
|
|
```
|
|
|
|
- StackStx
|
|
```json
|
|
{
|
|
"stack_stx": {
|
|
"burn_block_height": 10,
|
|
"burn_header_hash": "1010101010101010101010101010101010101010101010101010101010101010",
|
|
"num_cycles": 10,
|
|
"reward_addr": "16Jswqk47s9PUcyCc88MMVwzgvHPvtEpf",
|
|
"sender": {
|
|
"address": "ST2QKZ4FKHAH1NQKYKYAYZPY440FEPK7GZ1R5HBP2",
|
|
"address_hash_bytes": "0xaf3f91f38aa21ade7e9f95efdbc4201eeb4cf0f8",
|
|
"address_version": 26
|
|
},
|
|
"stacked_ustx": 10,
|
|
"burn_txid": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a",
|
|
"vtxindex": 10
|
|
}
|
|
}
|
|
```
|
|
|
|
- DelegateStx
|
|
```json
|
|
{
|
|
"delegate_stx": {
|
|
"burn_block_height": 10,
|
|
"burn_header_hash": "1010101010101010101010101010101010101010101010101010101010101010",
|
|
"delegate_to": {
|
|
"address": "SP24ZBZ8ZE6F48JE9G3F3HRTG9FK7E2H6K2QZ3Q1K",
|
|
"address_hash_bytes": "0x89f5fd1f719e4449c980de38e3504be6770a2698",
|
|
"address_version": 22
|
|
},
|
|
"delegated_ustx": 10,
|
|
"sender": {
|
|
"address": "ST2QKZ4FKHAH1NQKYKYAYZPY440FEPK7GZ1R5HBP2",
|
|
"address_hash_bytes": "0xaf3f91f38aa21ade7e9f95efdbc4201eeb4cf0f8",
|
|
"address_version": 26
|
|
},
|
|
"reward_addr": [10, "16Jswqk47s9PUcyCc88MMVwzgvHPvtEpf"],
|
|
"burn_txid": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a",
|
|
"until_burn_height": null,
|
|
"vtxindex": 10
|
|
}
|
|
}
|
|
```
|
|
|
|
### `POST /new_burn_block`
|
|
|
|
This payload includes information about burn blocks as their sortitions are processed.
|
|
In the event of PoX forks, a `new_burn_block` event may be triggered for a burn block
|
|
previously processed.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"burn_block_hash": "0x4eaabcd105865e471f697eff5dd5bd85d47ecb5a26a3379d74fae0ae87c40904",
|
|
"burn_block_height": 331,
|
|
"reward_recipients": [
|
|
{
|
|
"recipient": "1C56LYirKa3PFXFsvhSESgDy2acEHVAEt6",
|
|
"amt": 5000
|
|
}
|
|
],
|
|
"reward_slot_holders": [
|
|
"1C56LYirKa3PFXFsvhSESgDy2acEHVAEt6",
|
|
"1C56LYirKa3PFXFsvhSESgDy2acEHVAEt6"
|
|
],
|
|
"burn_amount": 12000
|
|
}
|
|
```
|
|
|
|
* `reward_recipients` is an array of all the rewards received during this burn block. It may
|
|
include recipients who did _not_ have reward slots during the block. This could happen if
|
|
a miner's commitment was included a block or two later than intended. Such commitments would
|
|
not be valid, but the reward recipient would still receive the burn `amt`.
|
|
* `reward_slot_holders` is an array of the Bitcoin addresses that would validly receive
|
|
PoX commitments during this block. These addresses may not actually receive rewards during
|
|
this block if the block is faster than miners have an opportunity to commit.
|
|
|
|
### `POST /new_microblocks`
|
|
|
|
This payload includes data related to one or more microblocks that are either emmitted by the
|
|
node itself, or received through the network.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"parent_index_block_hash": "0x999b38d44d6af72703a476dde4cea683ec965346d9e9a7ded2d773fb4f257a3b",
|
|
"events": [
|
|
{
|
|
"event_index": 1,
|
|
"committed": true,
|
|
"stx_transfer_event": {
|
|
"amount": "1000",
|
|
"recipient": "ST31DA6FTSJX2WGTZ69SFY11BH51NZMB0ZZ239N96",
|
|
"sender": "ST3WM51TCWMJYGZS1QFMC28DH5YP86782YGR113C1"
|
|
},
|
|
"txid": "0x738e4d44636023efa08374033428e44eca490582bd39a6e61f3b6cf749b4214c",
|
|
"type": "stx_transfer_event"
|
|
}
|
|
],
|
|
"transactions": [
|
|
{
|
|
"contract_abi": null,
|
|
"burnchain_op": null,
|
|
"raw_result": "0x03",
|
|
"raw_tx": "0x808000000004008bc5147525b8f477f0bc4522a88c8339b2494db50000000000000002000000000000000001015814daf929d8700af344987681f44e913890a12e38550abe8e40f149ef5269f40f4008083a0f2e0ddf65dcd05ecfc151c7ff8a5308ad04c77c0e87b5aeadad31010200000000040000000000000000000000000000000000000000000000000000000000000000",
|
|
"status": "success",
|
|
"tx_index": 0,
|
|
"txid": "0x3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
|
|
"microblock_sequence": "3",
|
|
"microblock_hash": "0x9304fcbcc6daf5ac3f264522e0df50eddb5be85df6ee8a9fc2384c54274daaac",
|
|
"microblock_parent_hash": "0x4893ab44636023efa08374033428e44eca490582bd39a6e61f3b6cf749b474bd"
|
|
},
|
|
{
|
|
"contract_abi": null,
|
|
"burnchain_op": null,
|
|
"raw_result": "0x03",
|
|
"raw_tx": "0x80800000000400f942874ce525e87f21bbe8c121b12fac831d02f4000000000000000000000000000003e800006ae29867aec4b0e4f776bebdcea7f6d9a24eeff370c8c739defadfcbb52659b30736ad4af021e8fb741520a6c65da419fdec01989fdf0032fc1838f427a9a36102010000000000051ac2d519faccba2e435f3272ff042b89435fd160ff00000000000003e800000000000000000000000000000000000000000000000000000000000000000000",
|
|
"status": "success",
|
|
"tx_index": 1,
|
|
"txid": "0x738e4d44636023efa08374033428e44eca490582bd39a6e61f3b6cf749b4214c",
|
|
"microblock_sequence": "4",
|
|
"microblock_hash": "0xfcd4fc34c6daf5ac3f264522e0df50eddb5be85df6ee8a9fc2384c5427459e43",
|
|
"microblock_parent_hash": "0x9304fcbcc6daf5ac3f264522e0df50eddb5be85df6ee8a9fc2384c54274daaac"
|
|
}
|
|
],
|
|
"burn_block_hash": "0x4eaabcd105865e471f697eff5dd5bd85d47ecb5a26a3379d74fae0ae87c40904",
|
|
"burn_block_height": 331,
|
|
"burn_block_timestamp": 1651301734
|
|
}
|
|
```
|
|
|
|
* `burn_block_{}` are the stats related to the burn block that is associated with the stacks
|
|
block that precedes this microblock stream.
|
|
* Each transaction json object includes information about the microblock the transaction was packaged into.
|
|
|
|
### `POST /new_mempool_tx`
|
|
|
|
This payload includes raw transactions newly received in the
|
|
node's mempool.
|
|
|
|
Example:
|
|
|
|
```json
|
|
[
|
|
"0x80800000000400f942874ce525e87f21bbe8c121b12fac831d02f4000000000000000000000000000003e800006ae29867aec4b0e4f776bebdcea7f6d9a24eeff370c8c739defadfcbb52659b30736ad4af021e8fb741520a6c65da419fdec01989fdf0032fc1838f427a9a36102010000000000051ac2d519faccba2e435f3272ff042b89435fd160ff00000000000003e800000000000000000000000000000000000000000000000000000000000000000000"
|
|
]
|
|
```
|
|
|
|
|
|
### `POST /drop_mempool_tx`
|
|
|
|
This payload includes raw transactions newly received in the
|
|
node's mempool.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"dropped_txids": ["d7b667bb93898b1d3eba4fee86617b06b95772b192f3643256dd0821b476e36f"],
|
|
"reason": "ReplaceByFee"
|
|
}
|
|
```
|
|
|
|
Reason can be one of:
|
|
|
|
* `ReplaceByFee` - replaced by a transaction with the same nonce, but a higher fee
|
|
* `ReplaceAcrossFork` - replaced by a transaction with the same nonce but in the canonical fork
|
|
* `TooExpensive` - the transaction is too expensive to include in a block
|
|
* `StaleGarbageCollect` - transaction was dropped because it became stale
|
|
|
|
### `POST /mined_block`
|
|
|
|
This payload includes data related to block mined by this Stacks node. This
|
|
will never be invoked if the node is configured only as a follower. This is invoked
|
|
when the miner **assembles** the block; this block may or may not win the sortition.
|
|
|
|
This endpoint will only broadcast events to observers that explicitly register for
|
|
`MinedBlocks` events, `AnyEvent` observers will not receive the events by default.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"block_hash": "0x4eaabcd105865e471f697eff5dd5bd85d47ecb5a26a3379d74fae0ae87c40904",
|
|
"stacks_height": 3,
|
|
"target_burn_height": 745000,
|
|
"block_size": 145000,
|
|
"anchored_cost": {
|
|
"runtime": 100,
|
|
"read_count": 10,
|
|
"write_count": 5,
|
|
"read_length": 150,
|
|
"write_length": 75
|
|
},
|
|
"confirmed_microblocks_cost": {
|
|
"runtime": 100,
|
|
"read_count": 10,
|
|
"write_count": 5,
|
|
"read_length": 150,
|
|
"write_length": 75
|
|
},
|
|
"tx_events": [
|
|
{
|
|
"Success": {
|
|
"txid": "3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
|
|
"fee": 0,
|
|
"execution_cost": {
|
|
"write_length": 0,
|
|
"write_count": 0,
|
|
"read_length": 0,
|
|
"read_count": 0,
|
|
"runtime": 0
|
|
},
|
|
"result": {
|
|
"ResponseData":
|
|
{
|
|
"committed": true,
|
|
"data": true
|
|
}
|
|
}
|
|
}},
|
|
{
|
|
"ProcessingError": {
|
|
"txid": "eef9f46b20fb637bd07ec92ad3ec175a5a4bdf3e8799259fc5b16a272090d4de",
|
|
"error": "Duplicate contract 'ST3BMYNT1DW2QSRZWB6M4S183NK1BXGJ41TEBCCH8.example'"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### `POST /mined_microblock`
|
|
|
|
This payload includes data related to microblocks mined by this Stacks node. This
|
|
will never be invoked if the node is configured only as a follower. This is invoked
|
|
when the miner **assembles** the microblock; this microblock may or may be incorporated
|
|
into the canonical chain.
|
|
|
|
This endpoint will only broadcast events to observers that explicitly register for
|
|
`MinedMicroblocks` events, `AnyEvent` observers will not receive the events by default.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"block_hash": "0x4eaabcd105865e471f697eff5dd5bd85d47ecb5a26a3379d74fae0ae87c40904",
|
|
"sequence": 3,
|
|
"anchor_block_consensus_hash": "53c166a709a9abd64a92a57f928a8b26aad08992",
|
|
"anchor_block": "43dbf6095c7622db6607d9584c3f65e908ca4eb77d86ee8cc1352aafec5d68b5",
|
|
"tx_events": [
|
|
{
|
|
"Success": {
|
|
"txid": "3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
|
|
"fee": 0,
|
|
"execution_cost": {
|
|
"write_length": 10,
|
|
"write_count": 10,
|
|
"read_length": 20,
|
|
"read_count": 10,
|
|
"runtime": 1290
|
|
},
|
|
"result": {
|
|
"ResponseData":
|
|
{
|
|
"committed": true,
|
|
"data": true
|
|
}
|
|
}
|
|
}},
|
|
{
|
|
"Skipped": {
|
|
"txid": "eef9f46b20fb637bd07ec92ad3ec175a5a4bdf3e8799259fc5b16a272090d4de",
|
|
"reason": "tx.anchor_mode does not support microblocks, anchor_mode=OnChainOnly."
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### `POST /stackerdb_chunks`
|
|
|
|
This payload includes data related to a single mutation to a StackerDB replica
|
|
that this node subscribes to. The data will only get sent here if the
|
|
corresponding chunk has already been successfully stored. The data includes the
|
|
chunk ID, chunk version, smart contract ID, signature, and data.
|
|
|
|
This endpoint broadcasts events to `AnyEvent` observers, as well as to
|
|
`StackerDBChunks` observers.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"contract_id": "STVN97YYA10MY5F6KQJHKNYJNM24C4A1AT39WRW.hello-world",
|
|
"modified_slots": [
|
|
{
|
|
"slot_id": 4,
|
|
"slot_version": 1,
|
|
"signature": "0073feb0a3b8794c95042ac23734eb0db226049665a52a4f7402499256c83d43dd4edf6eb2cb039d7f204b4c4076afde96aca143ea285ff40f10ed68cc6e5fcbc2",
|
|
"data": "68656c6c6f20776f726c64"
|
|
}
|
|
]
|
|
}
|
|
```
|