Transaction ordering within a block


#1

Hello.

I have noticed that some transactions within a block have the same timestamp:
I would like to know what was the ordering (sorting) criteria in NIS for the blocks that have the same timestamp?

Example in the block below:

http://explorer.nemchina.com/#/s_block?height=1976750

{
    "timeStamp": 119653253,
    "signature": "2dffe765e12f5bd278e98b6760edd2527bdc8d6cf28f908597f05c6e4c8cc6b56ebc0453034125e168cad79cf8a8073d0ba3cc1695900f49fbde798fc8930507",
    "prevBlockHash": {
        "data": "74c7eee3ddc9449e77623e28d115acd036e5b72127902dfcf8f3597608e3dfda"
    },
    "type": 1,
    "transactions": [
        {
            "timeStamp": 119653129,
            "amount": 50000,
            "signature": "aac37c3cf7f1547278fb2dbd4639afb9221c190b952633ee03c61602af717e80be82a72c717b5cb35c7086fc6aaf7f9f0585353cfde106ad17f9b11e6b5fc20c",
            "fee": 50000,
            "recipient": "NAX7HGLBVTHITH2SQVEN35VWXTSFLMDYNCZHEQ5G",
            "type": 257,
            "deadline": 119739529,
            "message": {},
            "version": 1744830465,
            "signer": "d22b047b670fd32ad9fa421a37415ab0677a786b916cad34820bcd395066cd49"
        },
        {
            "timeStamp": 119653138,
            "amount": 50000,
            "signature": "abb63c37db564f55d4c39cf6154cff5459592fd3e30eccd4272ac614be108c7d616bd387ec194ebcf2738c02bbc5c4926546a913714bfce2b00693675a417d02",
            "fee": 50000,
            "recipient": "NDXZ5Z7QSYS2I2COTRBD63RKPYDKKZ7LCBNCVYX6",
            "type": 257,
            "deadline": 119739538,
            "message": {},
            "version": 1744830465,
            "signer": "d22b047b670fd32ad9fa421a37415ab0677a786b916cad34820bcd395066cd49"
        },
        {
            "timeStamp": 119653161,
            "amount": 50000,
            "signature": "201faf7ca143ea4aaa391970eed56c7c270405e1daea1b7edbe9ca980419aa69e3cce54768d9cf0c70011e27d1853966f0975367332f6e69bb261a179623f908",
            "fee": 50000,
            "recipient": "NDP7A3GDUOH5H5FFV3PXFUAUHLS4NEOY6X3KZI3V",
            "type": 257,
            "deadline": 119739561,
            "message": {},
            "version": 1744830465,
            "signer": "d22b047b670fd32ad9fa421a37415ab0677a786b916cad34820bcd395066cd49"
        },
        {
            "timeStamp": 119653177,
            "amount": 1000000,
            "signature": "1a0d94728abe5f0448ad8fd2aecdaa6d87c319c2a76f9370642b445ebb8b4d00ec4dac84f361dabe7dca2b42d53960950dc6e880a44f8143e7b9eb7c302c9806",
            "fee": 50000,
            "recipient": "NDGXSWM5Q45WQM3JJZMQCD2AH7Z2WOSTAEFJA76D",
            "mosaics": [
                {
                    "quantity": 111,
                    "mosaicId": {
                        "namespaceId": "native",
                        "name": "coin"
                    }
                }
            ],
            "type": 257,
            "deadline": 119739577,
            "message": {},
            "version": 1744830466,
            "signer": "cb8a9f417f44eabc6e15501f9816a81349723c27106efe634ed9589753bcd40a"
        },
        {
            "timeStamp": 119653177,
            "amount": 1000000,
            "signature": "a22325e65394271a8c8c9340c8ea43c99a3abee2b79144e83809cbd15f7980b9ecff23fd8d36d63e63c63d17b6e9bf9e8dea8e10bc95aa0b4c4be485a880af02",
            "fee": 50000,
            "recipient": "NCU7PN44VEVKJTVHWS5UMPKLDRSCAYL2OIJZWNU7",
            "mosaics": [
                {
                    "quantity": 112,
                    "mosaicId": {
                        "namespaceId": "native",
                        "name": "coin"
                    }
                }
            ],
            "type": 257,
            "deadline": 119739577,
            "message": {},
            "version": 1744830466,
            "signer": "fff118575750c94cfdbdf1aaf6f3cb07b930b33cc1a5f0e8d121990e827d0c22"
        },
        {
            "timeStamp": 119653177,
            "amount": 1000000,
            "signature": "5a191230490209f50983226809354fe48d11f1839238db9a83ebcbc82907d72d6ae19bc81456393448b0d37d01efe3d1cf37c85374a1e1259867c31ef2ccef0b",
            "fee": 50000,
            "recipient": "NCUB5CP4NUSPAZBM4NDILHT5COIMBLOKQ6WLZPSJ",
            "mosaics": [
                {
                    "quantity": 116,
                    "mosaicId": {
                        "namespaceId": "native",
                        "name": "coin"
                    }
                }
            ],
            "type": 257,
            "deadline": 119739577,
            "message": {},
            "version": 1744830466,
            "signer": "b608f7153613deb3f80728b2ee258a124ce8d20bc96cb36579e4ac6e92f9503a"
        },
        {
            "timeStamp": 119653177,
            "amount": 1000000,
            "signature": "b157ff3f5eecdd6096509e84fd7701ad801d342d92c1cb6b2aa22da551fa8261ca1a83902dc6731791979665d808ac739c88a4e7637bc44ea1c6a2f24aeeab04",
            "fee": 50000,
            "recipient": "NBTF3COSQH5U7ZKENG2RTKXVWNVL5R7QJXRLWYON",
            "mosaics": [
                {
                    "quantity": 24,
                    "mosaicId": {
                        "namespaceId": "native",
                        "name": "coin"
                    }
                }
            ],
            "type": 257,
            "deadline": 119739577,
            "message": {},
            "version": 1744830466,
            "signer": "2f2ec371d5bbe1227cce467afb13815f970d4194463986ffc752e00f6d83ad70"
        },
        {
            "timeStamp": 119653178,
            "amount": 50000,
            "signature": "264227a6bb8a4db8cf1cdca962309c06e18328505de8b81e58c1f577d618000918e95214369a1a9f0d561df1d9fd61fd4981674ee95c7b52f84c58ca6f3ebe04",
            "fee": 50000,
            "recipient": "NDTVNHCCVJR3S7YTE4YKPOGZFUSJ3S7CSZ7LEKGN",
            "type": 257,
            "deadline": 119739578,
            "message": {},
            "version": 1744830465,
            "signer": "d22b047b670fd32ad9fa421a37415ab0677a786b916cad34820bcd395066cd49"
        },
        {
            "timeStamp": 119653226,
            "amount": 50000,
            "signature": "bc00fc963df0c525626496e3f83ba275f1423bbcb85904d3fb034039482ba26668098788e544f92a86f90ac35ea5fd9848a6c5a03de9bed216a20203c1698804",
            "fee": 50000,
            "recipient": "NDGKH3M7BQBUJHMCRPG6ZFCZ4GASEH66XB57UNVX",
            "type": 257,
            "deadline": 119739626,
            "message": {},
            "version": 1744830465,
            "signer": "d22b047b670fd32ad9fa421a37415ab0677a786b916cad34820bcd395066cd49"
        }
    ],
    "version": 1744830465,
    "signer": "06ca67e71a3b45d25b97a5bb3b3f789bea2a4aa4f609e547bf8572d1c21b778e",
    "height": 1976750
}

#2

The harvesting node defines the ordering. And you cant really tell from the block itself other than by requesting the transaction content (including id).

if you request the transaction content by hash from the node that harvested said block, you would get the corect order with transaction ids… but it gets complicated because if you fetch the transactions from a different node, it may be, that those transactions have arrived in a different order at the node, meaning the transaction ids will not be ordered the same way (effectively giving you a wrong ordering).

I put the accent on harvesting node, because the order in which transactions have reached that node (or “have arrived at…”) is the order that you will see in the block.

dont get me wrong, reading the block X from node A and node B, where node A is harvester of block X, will give you exact same output. But transaction ids may differ from node A to node B because the transactions may have reached nodes in different order or with delay (propagation…).

This means that you would need to know the harvesting node for the said block, in order to get the exact same ordering when reading transaction ids…

To make this possible, you would need to link harvester public keys with harvesting nodes… which is wuite complicated because accounts can be set to harvest on multiple nodes at the same time.

I hope this sheds some light, not sure there is a solution for this with NIS.


#3

OK I think I’ve understood.
But then I think transaction ID are not calculated into the block hash otherwise the hash would be different on every node. The same applies for the transaction ordering in the block.

Having the same block retrieved from different nodes
and having the different transaction order depending from which node the block
is requested would give different block hash wouldn’t it?

Can you confirm?


#4

But then I think transaction ID are not calculated into the block hash

correct.

Requesting blocks from different nodes will always give you the same ordering. Blocks are just serialized data strings, so when the block arrives to each node, it actually contains the same transaction list.

The only thing about transaction ordering is with ids. As there is also a socket in NIS for transactions, thats where sometimes they can be in a different order (and then, be affected different ids…), but the block itself will always contain the same ordering.

Like you said, including transaction ids in blocks would sometimes produce different hashes on different nodes which would not be ok.

Regarding transaction hashes, they are excluded from block contents because they can be reproduced by the client easily enough.