From 728f5ba1d5d00177c89cc9da808739ecfbeefedb Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 23 Jan 2026 15:59:27 +0300 Subject: [PATCH 1/3] update dao --- packages/api/src/dao/TransactionsDAO.js | 12 ++++++++++-- packages/api/src/dao/ValidatorsDAO.js | 26 +++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/api/src/dao/TransactionsDAO.js b/packages/api/src/dao/TransactionsDAO.js index 00baa0a1d..88bf11cd3 100644 --- a/packages/api/src/dao/TransactionsDAO.js +++ b/packages/api/src/dao/TransactionsDAO.js @@ -214,6 +214,9 @@ module.exports = class TransactionsDAO { const rows = await this.knex(heightSubquery) .select('tx_count', 'block_height', 'hash as block_hash', 'date_from') + .select( + this.knex.raw('SUM(tx_count) OVER (ORDER BY date_from) AS running_total') + ) .leftJoin('blocks', function () { this.on('blocks.height', '=', 'block_height').andOnNotNull('block_height') }) @@ -222,7 +225,8 @@ module.exports = class TransactionsDAO { .map(row => ({ timestamp: new Date(row.date_from).toISOString(), data: { - txs: parseInt(row.tx_count ?? 0), + txs: Number(row.tx_count ?? 0), + runningTotal: Number(row.running_total ?? 0), blockHeight: row.block_height, blockHash: row.block_hash } @@ -277,6 +281,9 @@ module.exports = class TransactionsDAO { const rows = await this.knex(heightSubquery) .select('gas', 'block_height', 'hash as block_hash', 'date_from') + .select( + this.knex.raw('SUM(gas) OVER (ORDER BY date_from) AS running_total') + ) .leftJoin('blocks', function () { this.on('blocks.height', '=', 'block_height').andOnNotNull('block_height') }) @@ -285,7 +292,8 @@ module.exports = class TransactionsDAO { .map(row => ({ timestamp: new Date(row.date_from).toISOString(), data: { - gas: parseInt(row.gas ?? 0), + gas: Number(row.gas ?? 0), + runningTotal: Number(row.running_total ?? 0), blockHeight: row.block_height, blockHash: row.block_hash } diff --git a/packages/api/src/dao/ValidatorsDAO.js b/packages/api/src/dao/ValidatorsDAO.js index 4ad274997..efdd5773b 100644 --- a/packages/api/src/dao/ValidatorsDAO.js +++ b/packages/api/src/dao/ValidatorsDAO.js @@ -252,7 +252,7 @@ module.exports = class ValidatorsDAO { .from(this.knex.raw(`generate_series(${startSql}, ${endSql}, '${interval}'::interval) date_to`)) .select('date_to', this.knex.raw(`LAG(date_to, 1, '${start.toISOString()}'::timestamptz) over (order by date_to asc) date_from`)) - const rows = await this.knex.with('ranges', ranges) + const subquery = this.knex.with('ranges', ranges) .select('date_from') .select( this.knex('blocks') @@ -263,11 +263,20 @@ module.exports = class ValidatorsDAO { ) .from('ranges') + const rows = await this.knex + .with('subquery', subquery) + .select('date_from', 'blocks_count') + .select( + this.knex.raw('SUM(blocks_count) OVER (ORDER BY date_from) AS running_total') + ) + .from('subquery') + return rows .map(row => ({ timestamp: row.date_from, data: { - blocksCount: parseInt(row.blocks_count) + blocksCount: Number(row.blocks_count), + runningTotal: Number(row.running_total ?? 0) } })) .map(({ timestamp, data }) => new SeriesData(timestamp, data)) @@ -282,7 +291,7 @@ module.exports = class ValidatorsDAO { .from(this.knex.raw(`generate_series(${startSql}, ${endSql}, '${interval}'::interval) date_to`)) .select('date_to', this.knex.raw(`LAG(date_to, 1, '${start.toISOString()}'::timestamptz) over (order by date_to asc) date_from`)) - const rows = await this.knex.with('ranges', ranges) + const subquery = this.knex.with('ranges', ranges) .select('date_from') .select( this.knex('blocks') @@ -294,12 +303,21 @@ module.exports = class ValidatorsDAO { ) .from('ranges') + const rows = await this.knex + .with('subquery', subquery) + .select('date_from', 'gas_used') + .select( + this.knex.raw('SUM(gas_used) OVER (ORDER BY date_from) AS running_total') + ) + .from('subquery') + return rows .slice(1) .map(row => ({ timestamp: row.date_from, data: { - reward: parseInt(row.gas_used ?? 0) + reward: Number(row.gas_used ?? 0), + runningTotal: Number(row.running_total ?? 0) } })) .map(({ timestamp, data }) => new SeriesData(timestamp, data)) From 58d57f4cfd2cb26a419782b9bbe8e827c61e84a5 Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 23 Jan 2026 15:59:36 +0300 Subject: [PATCH 2/3] update tests --- .../api/test/integration/transactions.spec.js | 144 +++++++++++++++--- .../api/test/integration/validators.spec.js | 36 ++++- 2 files changed, 150 insertions(+), 30 deletions(-) diff --git a/packages/api/test/integration/transactions.spec.js b/packages/api/test/integration/transactions.spec.js index 3626397d3..40e9415ff 100644 --- a/packages/api/test/integration/transactions.spec.js +++ b/packages/api/test/integration/transactions.spec.js @@ -957,7 +957,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 300000 * i @@ -978,7 +978,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.txs).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 2H', async () => { @@ -991,7 +999,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 1440000 * i @@ -1012,7 +1020,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.txs).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 24h', async () => { @@ -1025,7 +1041,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 17280000 * i @@ -1046,7 +1062,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.txs).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 3d', async () => { @@ -1059,7 +1083,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 51840000 * i @@ -1080,7 +1104,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.txs).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 1w', async () => { @@ -1093,7 +1125,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 120960000 * i @@ -1114,7 +1146,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.txs).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return series of 6 intervals timespan 3d', async () => { const start = new Date(new Date().getTime()) @@ -1129,7 +1169,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - Math.ceil((end - start) / 1000 / 6) * 1000 * i @@ -1150,7 +1190,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.txs).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) }) @@ -1165,7 +1213,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 300000 * i @@ -1188,7 +1236,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.gas).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 2H', async () => { @@ -1201,7 +1257,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 1440000 * i @@ -1224,7 +1280,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.gas).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 24h', async () => { @@ -1237,7 +1301,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 17280000 * i @@ -1260,7 +1324,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.gas).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 3d', async () => { @@ -1273,7 +1345,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 51840000 * i @@ -1296,7 +1368,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.gas).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return default series set timespan 1w', async () => { @@ -1309,7 +1389,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 120960000 * i @@ -1332,7 +1412,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.gas).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) it('should return series of 6 intervals timespan 3d', async () => { const start = new Date(new Date().getTime()) @@ -1347,7 +1435,7 @@ describe('Transaction routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp) - const expectedSeriesData = [] + let expectedSeriesData = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - Math.ceil((end - start) / 1000 / 6) * 1000 * i @@ -1370,7 +1458,15 @@ describe('Transaction routes', () => { }) } - assert.deepEqual(expectedSeriesData.reverse(), body) + expectedSeriesData = expectedSeriesData.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.gas).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedSeriesData, body) }) }) }) diff --git a/packages/api/test/integration/validators.spec.js b/packages/api/test/integration/validators.spec.js index c01fac43c..482ac8ea4 100644 --- a/packages/api/test/integration/validators.spec.js +++ b/packages/api/test/integration/validators.spec.js @@ -2049,7 +2049,7 @@ describe('Validators routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp).getTime() - const expectedStats = [] + let expectedStats = [] for (let i = 0; i < 12; i++) { const nextPeriod = firstTimestamp - 300000 * i @@ -2071,7 +2071,15 @@ describe('Validators routes', () => { ) } - assert.deepEqual(expectedStats.reverse(), body) + expectedStats = expectedStats.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.blocksCount).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedStats, body) }) it('should return stats by proTxHash with custom timespan', async () => { @@ -2084,7 +2092,7 @@ describe('Validators routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp).getTime() - const expectedStats = [] + let expectedStats = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - 7200000 * i @@ -2106,7 +2114,15 @@ describe('Validators routes', () => { ) } - assert.deepEqual(expectedStats.reverse(), body) + expectedStats = expectedStats.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.blocksCount).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedStats, body) }) it('should return stats by proTxHash with custom timespan with intervalsCount', async () => { @@ -2122,7 +2138,7 @@ describe('Validators routes', () => { const [firstPeriod] = body.toReversed() const firstTimestamp = new Date(firstPeriod.timestamp).getTime() - const expectedStats = [] + let expectedStats = [] for (let i = 0; i < body.length; i++) { const nextPeriod = firstTimestamp - Math.ceil((end - start) / 1000 / 3) * 1000 * i @@ -2144,7 +2160,15 @@ describe('Validators routes', () => { ) } - assert.deepEqual(expectedStats.reverse(), body) + expectedStats = expectedStats.toReversed().map((seriesData, i, arr) => ({ + ...seriesData, + data: { + ...seriesData.data, + runningTotal: arr.slice(0, i + 1).map(v => v.data.blocksCount).reduce((a, b) => a + b, 0) + } + })) + + assert.deepEqual(expectedStats, body) }) it('should return error on wrong bounds', async () => { From bbdb992fc2950c84aad112bf69ee68a63ad244c3 Mon Sep 17 00:00:00 2001 From: owl352 Date: Fri, 23 Jan 2026 15:59:43 +0300 Subject: [PATCH 3/3] update README.md --- packages/api/README.md | 26 +++++++++++++++++++++--- packages/frontend/src/app/api/content.md | 26 +++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/packages/api/README.md b/packages/api/README.md index a631d03e1..15bfd8876 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -592,7 +592,15 @@ GET /validator/F60A6BF9EC0794BB0CFD1E0F2217933F4B33EDE6FE810692BC275CA18148AEF0/ { "timestamp": "2024-06-23T13:51:44.154Z", "data": { - "reward": 34000000 + "reward": 34000000, + "runningTotal": 34000000 + } + }, + { + "timestamp": "2024-06-23T13:53:44.154Z", + "data": { + "reward": 34000000, + "runningTotal": 68000000 } },... ] @@ -611,7 +619,15 @@ GET /validator/F60A6BF9EC0794BB0CFD1E0F2217933F4B33EDE6FE810692BC275CA18148AEF0/ { "timestamp": "2024-06-23T13:51:44.154Z", "data": { - "blocksCount": 2 + "blocksCount": 2, + "runningTotal": 2 + } + }, + { + "timestamp": "2024-06-23T13:53:44.154Z", + "data": { + "blocksCount": 2, + "runningTotal": 4 } },... ] @@ -1744,7 +1760,8 @@ GET /transactions/history?timestamp_start=2024-01-01T00:00:00×tamp_end=2025 { "timestamp": "2024-04-22T08:45:20.911Z", "data": { - "txs": 5 + "txs": 5, + "runningTotal": 5, "blockHeight": 2, "blockHash": "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" } @@ -1753,6 +1770,7 @@ GET /transactions/history?timestamp_start=2024-01-01T00:00:00×tamp_end=2025 "timestamp": "2024-04-22T08:50:20.911Z", "data": { "txs": 13, + "runningTotal": 18, "blockHeight": 7, "blockHash": "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" } @@ -1780,6 +1798,7 @@ GET /transactions/gas/history?timestamp_start=2024-01-01T00:00:00×tamp_end= "timestamp": "2024-04-22T08:45:20.911Z", "data": { "gas": 772831320, + "runningTotal": 772831320, "blockHeight": 64060, "blockHash": "4A1F6B5238032DDAC55009A28797D909DB4288D5B5EC14B86DEC6EA8F25EC71A" } @@ -1788,6 +1807,7 @@ GET /transactions/gas/history?timestamp_start=2024-01-01T00:00:00×tamp_end= "timestamp": "2024-04-22T08:50:20.911Z", "data": { "gas": 14108752440, + "runningTotal": 14881583760, "blockHeight": 64333, "blockHash": "507659D9BE2FF76A031F4219061F3D2D39475A7FA4B24F25AEFDB34CD4DF2A57" } diff --git a/packages/frontend/src/app/api/content.md b/packages/frontend/src/app/api/content.md index ffa568097..a0e0d76d9 100644 --- a/packages/frontend/src/app/api/content.md +++ b/packages/frontend/src/app/api/content.md @@ -559,7 +559,15 @@ GET /validator/F60A6BF9EC0794BB0CFD1E0F2217933F4B33EDE6FE810692BC275CA18148AEF0/ { "timestamp": "2024-06-23T13:51:44.154Z", "data": { - "reward": 34000000 + "reward": 34000000, + "runningTotal": 34000000 + } + }, + { + "timestamp": "2024-06-23T13:53:44.154Z", + "data": { + "reward": 34000000, + "runningTotal": 68000000 } },... ] @@ -578,7 +586,15 @@ GET /validator/F60A6BF9EC0794BB0CFD1E0F2217933F4B33EDE6FE810692BC275CA18148AEF0/ { "timestamp": "2024-06-23T13:51:44.154Z", "data": { - "blocksCount": 2 + "blocksCount": 2, + "runningTotal": 2 + } + }, + { + "timestamp": "2024-06-23T13:53:44.154Z", + "data": { + "blocksCount": 2, + "runningTotal": 4 } },... ] @@ -1711,7 +1727,8 @@ GET /transactions/history?timestamp_start=2024-01-01T00:00:00×tamp_end=2025 { "timestamp": "2024-04-22T08:45:20.911Z", "data": { - "txs": 5 + "txs": 5, + "runningTotal": 5, "blockHeight": 2, "blockHash": "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" } @@ -1720,6 +1737,7 @@ GET /transactions/history?timestamp_start=2024-01-01T00:00:00×tamp_end=2025 "timestamp": "2024-04-22T08:50:20.911Z", "data": { "txs": 13, + "runningTotal": 18, "blockHeight": 7, "blockHash": "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" } @@ -1747,6 +1765,7 @@ GET /transactions/gas/history?timestamp_start=2024-01-01T00:00:00×tamp_end= "timestamp": "2024-04-22T08:45:20.911Z", "data": { "gas": 772831320, + "runningTotal": 772831320, "blockHeight": 64060, "blockHash": "4A1F6B5238032DDAC55009A28797D909DB4288D5B5EC14B86DEC6EA8F25EC71A" } @@ -1755,6 +1774,7 @@ GET /transactions/gas/history?timestamp_start=2024-01-01T00:00:00×tamp_end= "timestamp": "2024-04-22T08:50:20.911Z", "data": { "gas": 14108752440, + "runningTotal": 14881583760, "blockHeight": 64333, "blockHash": "507659D9BE2FF76A031F4219061F3D2D39475A7FA4B24F25AEFDB34CD4DF2A57" }