diff --git a/.sqlx/query-1157509808a9e3d07211f0c19c8d6c226d659b04c774fc062444d0c4e44c1ab0.json b/.sqlx/query-1157509808a9e3d07211f0c19c8d6c226d659b04c774fc062444d0c4e44c1ab0.json new file mode 100644 index 000000000..8963be2c0 --- /dev/null +++ b/.sqlx/query-1157509808a9e3d07211f0c19c8d6c226d659b04c774fc062444d0c4e44c1ab0.json @@ -0,0 +1,124 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n number as \"number: _\",\n hash as \"hash: _\",\n transactions_root as \"transactions_root: _\",\n gas_limit as \"gas_limit: _\",\n gas_used as \"gas_used: _\",\n logs_bloom as \"bloom: _\",\n timestamp_in_secs as \"timestamp: _\",\n parent_hash as \"parent_hash: _\",\n author as \"author: _\",\n extra_data as \"extra_data: _\",\n miner as \"miner: _\",\n difficulty as \"difficulty: _\",\n receipts_root as \"receipts_root: _\",\n uncle_hash as \"uncle_hash: _\",\n size as \"size: _\",\n state_root as \"state_root: _\",\n total_difficulty as \"total_difficulty: _\",\n nonce as \"nonce: _\"\nFROM blocks\nWHERE hash = $1\n", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "number: _", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "hash: _", + "type_info": "Bytea" + }, + { + "ordinal": 2, + "name": "transactions_root: _", + "type_info": "Bytea" + }, + { + "ordinal": 3, + "name": "gas_limit: _", + "type_info": "Numeric" + }, + { + "ordinal": 4, + "name": "gas_used: _", + "type_info": "Numeric" + }, + { + "ordinal": 5, + "name": "bloom: _", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "timestamp: _", + "type_info": "Int8" + }, + { + "ordinal": 7, + "name": "parent_hash: _", + "type_info": "Bytea" + }, + { + "ordinal": 8, + "name": "author: _", + "type_info": "Bytea" + }, + { + "ordinal": 9, + "name": "extra_data: _", + "type_info": "Bytea" + }, + { + "ordinal": 10, + "name": "miner: _", + "type_info": "Bytea" + }, + { + "ordinal": 11, + "name": "difficulty: _", + "type_info": "Numeric" + }, + { + "ordinal": 12, + "name": "receipts_root: _", + "type_info": "Bytea" + }, + { + "ordinal": 13, + "name": "uncle_hash: _", + "type_info": "Bytea" + }, + { + "ordinal": 14, + "name": "size: _", + "type_info": "Numeric" + }, + { + "ordinal": 15, + "name": "state_root: _", + "type_info": "Bytea" + }, + { + "ordinal": 16, + "name": "total_difficulty: _", + "type_info": "Numeric" + }, + { + "ordinal": 17, + "name": "nonce: _", + "type_info": "Numeric" + } + ], + "parameters": { + "Left": [ + "Bytea" + ] + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + "hash": "1157509808a9e3d07211f0c19c8d6c226d659b04c774fc062444d0c4e44c1ab0" +} diff --git a/.sqlx/query-13e5ed4d496851d6ab1a307d75c51cdb3a0c6383c9fd9bd60512d12ff4f8c631.json b/.sqlx/query-13e5ed4d496851d6ab1a307d75c51cdb3a0c6383c9fd9bd60512d12ff4f8c631.json new file mode 100644 index 000000000..6e851ae00 --- /dev/null +++ b/.sqlx/query-13e5ed4d496851d6ab1a307d75c51cdb3a0c6383c9fd9bd60512d12ff4f8c631.json @@ -0,0 +1,124 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n number as \"number: _\",\n hash as \"hash: _\",\n transactions_root as \"transactions_root: _\",\n gas_limit as \"gas_limit: _\",\n gas_used as \"gas_used: _\",\n logs_bloom as \"bloom: _\",\n timestamp_in_secs as \"timestamp: _\",\n parent_hash as \"parent_hash: _\",\n author as \"author: _\",\n extra_data as \"extra_data: _\",\n miner as \"miner: _\",\n difficulty as \"difficulty: _\",\n receipts_root as \"receipts_root: _\",\n uncle_hash as \"uncle_hash: _\",\n size as \"size: _\",\n state_root as \"state_root: _\",\n total_difficulty as \"total_difficulty: _\",\n nonce as \"nonce: _\"\nFROM blocks\nWHERE number = $1\n", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "number: _", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "hash: _", + "type_info": "Bytea" + }, + { + "ordinal": 2, + "name": "transactions_root: _", + "type_info": "Bytea" + }, + { + "ordinal": 3, + "name": "gas_limit: _", + "type_info": "Numeric" + }, + { + "ordinal": 4, + "name": "gas_used: _", + "type_info": "Numeric" + }, + { + "ordinal": 5, + "name": "bloom: _", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "timestamp: _", + "type_info": "Int8" + }, + { + "ordinal": 7, + "name": "parent_hash: _", + "type_info": "Bytea" + }, + { + "ordinal": 8, + "name": "author: _", + "type_info": "Bytea" + }, + { + "ordinal": 9, + "name": "extra_data: _", + "type_info": "Bytea" + }, + { + "ordinal": 10, + "name": "miner: _", + "type_info": "Bytea" + }, + { + "ordinal": 11, + "name": "difficulty: _", + "type_info": "Numeric" + }, + { + "ordinal": 12, + "name": "receipts_root: _", + "type_info": "Bytea" + }, + { + "ordinal": 13, + "name": "uncle_hash: _", + "type_info": "Bytea" + }, + { + "ordinal": 14, + "name": "size: _", + "type_info": "Numeric" + }, + { + "ordinal": 15, + "name": "state_root: _", + "type_info": "Bytea" + }, + { + "ordinal": 16, + "name": "total_difficulty: _", + "type_info": "Numeric" + }, + { + "ordinal": 17, + "name": "nonce: _", + "type_info": "Numeric" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + "hash": "13e5ed4d496851d6ab1a307d75c51cdb3a0c6383c9fd9bd60512d12ff4f8c631" +} diff --git a/.sqlx/query-200cdfb18b0b1d712419d46bf7f0541cf5bf3917530467affd8a266820837f3d.json b/.sqlx/query-200cdfb18b0b1d712419d46bf7f0541cf5bf3917530467affd8a266820837f3d.json new file mode 100644 index 000000000..d6e6a8463 --- /dev/null +++ b/.sqlx/query-200cdfb18b0b1d712419d46bf7f0541cf5bf3917530467affd8a266820837f3d.json @@ -0,0 +1,98 @@ +{ + "db_name": "PostgreSQL", + "query": "WITH block_insert AS (\n INSERT INTO blocks (\n number,\n hash,\n transactions_root,\n gas_limit,\n gas_used,\n logs_bloom,\n timestamp_in_secs,\n parent_hash,\n author,\n extra_data,\n miner,\n difficulty,\n receipts_root,\n uncle_hash,\n size,\n state_root,\n total_difficulty,\n nonce,\n created_at\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, current_timestamp)\n RETURNING 1 as res\n),\n\ntransaction_insert AS (\n INSERT INTO transactions (\n hash,\n signer_address,\n nonce,\n address_from,\n address_to,\n input,\n output,\n gas,\n gas_price,\n idx_in_block,\n block_number,\n block_hash,\n v,\n r,\n s,\n value,\n result\n )\n SELECT *\n FROM\n unnest(\n $19::bytea [],\n $20::bytea [],\n $21::numeric [],\n $22::bytea [],\n $23::bytea [],\n $24::bytea [],\n $25::bytea [],\n $26::numeric [],\n $27::numeric [],\n $28::int4 [],\n $29::int8 [],\n $30::bytea [],\n $31::bytea [],\n $32::bytea [],\n $33::bytea [],\n $34::numeric [],\n $35::text []\n )\n RETURNING 1 as res\n),\n\nlog_insert AS (\n INSERT INTO logs (\n address,\n data,\n transaction_hash,\n transaction_idx,\n log_idx,\n block_number,\n block_hash\n )\n SELECT *\n FROM\n unnest(\n $36::bytea [],\n $37::bytea [],\n $38::bytea [],\n $39::int4 [],\n $40::int4 [],\n $41::int8 [],\n $42::bytea []\n )\n RETURNING 1 as res\n),\n\ntopic_insert AS (\n INSERT INTO topics (\n topic,\n transaction_hash,\n transaction_idx,\n log_idx,\n topic_idx,\n block_number,\n block_hash\n )\n SELECT *\n FROM\n unnest(\n $43::bytea [],\n $44::bytea [],\n $45::int4 [],\n $46::int4 [],\n $47::int4 [],\n $48::int8 [],\n $49::bytea []\n )\n RETURNING 1 as res\n),\n\naccount_insert AS (\n WITH account_updates AS (\n SELECT *\n FROM\n unnest(\n $50::bytea [],\n $51::bytea [],\n $52::numeric [],\n $53::numeric [],\n $54::int8 [],\n $55::numeric [],\n $56::numeric []\n )\n AS t (\n address,\n bytecode,\n new_balance,\n new_nonce,\n creation_block,\n original_balance,\n original_nonce\n )\n )\n\n INSERT INTO accounts (\n address, bytecode, latest_balance, latest_nonce, creation_block\n )\n SELECT\n address,\n bytecode,\n new_balance,\n new_nonce,\n creation_block\n FROM account_updates\n ON CONFLICT (address) DO\n UPDATE\n SET latest_nonce = excluded.latest_nonce,\n latest_balance = excluded.latest_balance\n WHERE accounts.latest_nonce\n = (\n SELECT original_nonce\n FROM account_updates\n WHERE account_updates.address = excluded.address\n )\n AND accounts.latest_balance\n = (\n SELECT original_balance\n FROM account_updates\n WHERE account_updates.address = excluded.address\n )\n RETURNING 1 as res\n),\n\nslot_insert AS (\n WITH slot_updates AS (\n SELECT *\n FROM\n unnest(\n $57::bytea [],\n $58::bytea [],\n $59::bytea [],\n $60::int8 [],\n $61::bytea []\n )\n AS t (idx, value, account_address, creation_block, original_value)\n )\n\n INSERT INTO account_slots (idx, value, account_address, creation_block)\n SELECT\n idx,\n value,\n account_address,\n creation_block\n FROM slot_updates\n ON CONFLICT (idx, account_address) DO\n UPDATE\n SET value = excluded.value\n WHERE account_slots.value = (\n SELECT original_value\n FROM slot_updates\n WHERE\n slot_updates.idx = excluded.idx\n AND slot_updates.account_address = excluded.account_address\n )\n RETURNING 1 as res\n),\n\nhistorical_nonce_insert AS (\n INSERT INTO historical_nonces (address, nonce, block_number)\n SELECT * FROM unnest($62::bytea [], $63::numeric [], $64::int8 [])\n RETURNING 1 as res\n),\n\nhistorical_balance_insert AS (\n INSERT INTO historical_balances (address, balance, block_number)\n SELECT * FROM unnest($65::bytea [], $66::numeric [], $67::int8 [])\n RETURNING 1 as res\n),\n\nhistorical_slots_insert AS (\n INSERT INTO historical_slots (idx, value, account_address, block_number)\n SELECT *\n FROM unnest($68::bytea [], $69::bytea [], $70::bytea [], $71::int8 [])\n RETURNING 1 as res\n)\n\nSELECT modified_accounts, modified_slots FROM\n(SELECT count(*) AS modified_accounts FROM account_insert)\nCROSS JOIN\n(SELECT count(*) AS modified_slots FROM slot_insert);\n", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "modified_accounts", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "modified_slots", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8", + "Bytea", + "Bytea", + "Numeric", + "Numeric", + "Bytea", + "Int8", + "Bytea", + "Bytea", + "Bytea", + "Bytea", + "Numeric", + "Bytea", + "Bytea", + "Numeric", + "Bytea", + "Numeric", + "Numeric", + "ByteaArray", + "ByteaArray", + "NumericArray", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "NumericArray", + "NumericArray", + "Int4Array", + "Int8Array", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "NumericArray", + "TextArray", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "Int4Array", + "Int4Array", + "Int8Array", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "Int4Array", + "Int4Array", + "Int4Array", + "Int8Array", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "NumericArray", + "NumericArray", + "Int8Array", + "NumericArray", + "NumericArray", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "Int8Array", + "ByteaArray", + "ByteaArray", + "NumericArray", + "Int8Array", + "ByteaArray", + "NumericArray", + "Int8Array", + "ByteaArray", + "ByteaArray", + "ByteaArray", + "Int8Array" + ] + }, + "nullable": [ + null, + null + ] + }, + "hash": "200cdfb18b0b1d712419d46bf7f0541cf5bf3917530467affd8a266820837f3d" +} diff --git a/.sqlx/query-94b199f16d33b19e70672a64f25e75e8519e33995ab6101817dc5f202900dd3a.json b/.sqlx/query-94b199f16d33b19e70672a64f25e75e8519e33995ab6101817dc5f202900dd3a.json deleted file mode 100644 index 92e54cea4..000000000 --- a/.sqlx/query-94b199f16d33b19e70672a64f25e75e8519e33995ab6101817dc5f202900dd3a.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "WITH block_insert AS (\n INSERT INTO blocks (\n number,\n hash,\n transactions_root,\n gas,\n logs_bloom,\n timestamp_in_secs,\n parent_hash,\n created_at\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, current_timestamp)\n RETURNING 1 as res\n),\n\ntransaction_insert AS (\n INSERT INTO transactions (\n hash,\n signer_address,\n nonce,\n address_from,\n address_to,\n input,\n output,\n gas,\n gas_price,\n idx_in_block,\n block_number,\n block_hash,\n v,\n r,\n s,\n value,\n result\n )\n SELECT *\n FROM\n unnest(\n $8::bytea [],\n $9::bytea [],\n $10::numeric [],\n $11::bytea [],\n $12::bytea [],\n $13::bytea [],\n $14::bytea [],\n $15::numeric [],\n $16::numeric [],\n $17::int4 [],\n $18::int8 [],\n $19::bytea [],\n $20::bytea [],\n $21::bytea [],\n $22::bytea [],\n $23::numeric [],\n $24::text []\n )\n RETURNING 1 as res\n),\n\nlog_insert AS (\n INSERT INTO logs (\n address,\n data,\n transaction_hash,\n transaction_idx,\n log_idx,\n block_number,\n block_hash\n )\n SELECT *\n FROM\n unnest(\n $25::bytea [],\n $26::bytea [],\n $27::bytea [],\n $28::int4 [],\n $29::int4 [],\n $30::int8 [],\n $31::bytea []\n )\n RETURNING 1 as res\n),\n\ntopic_insert AS (\n INSERT INTO topics (\n topic,\n transaction_hash,\n transaction_idx,\n log_idx,\n topic_idx,\n block_number,\n block_hash\n )\n SELECT *\n FROM\n unnest(\n $32::bytea [],\n $33::bytea [],\n $34::int4 [],\n $35::int4 [],\n $36::int4 [],\n $37::int8 [],\n $38::bytea []\n )\n RETURNING 1 as res\n),\n\naccount_insert AS (\n WITH account_updates AS (\n SELECT *\n FROM\n unnest(\n $39::bytea [],\n $40::bytea [],\n $41::numeric [],\n $42::numeric [],\n $43::int8 [],\n $44::numeric [],\n $45::numeric []\n )\n AS t (\n address,\n bytecode,\n new_balance,\n new_nonce,\n creation_block,\n original_balance,\n original_nonce\n )\n )\n\n INSERT INTO accounts (\n address, bytecode, latest_balance, latest_nonce, creation_block\n )\n SELECT\n address,\n bytecode,\n new_balance,\n new_nonce,\n creation_block\n FROM account_updates\n ON CONFLICT (address) DO\n UPDATE\n SET latest_nonce = excluded.latest_nonce,\n latest_balance = excluded.latest_balance\n WHERE accounts.latest_nonce\n = (\n SELECT original_nonce\n FROM account_updates\n WHERE account_updates.address = excluded.address\n )\n AND accounts.latest_balance\n = (\n SELECT original_balance\n FROM account_updates\n WHERE account_updates.address = excluded.address\n )\n RETURNING 1 as res\n),\n\nslot_insert AS (\n WITH slot_updates AS (\n SELECT *\n FROM\n unnest(\n $46::bytea [],\n $47::bytea [],\n $48::bytea [],\n $49::int8 [],\n $50::bytea []\n )\n AS t (idx, value, account_address, creation_block, original_value)\n )\n\n INSERT INTO account_slots (idx, value, account_address, creation_block)\n SELECT\n idx,\n value,\n account_address,\n creation_block\n FROM slot_updates\n ON CONFLICT (idx, account_address) DO\n UPDATE\n SET value = excluded.value\n WHERE account_slots.value = (\n SELECT original_value\n FROM slot_updates\n WHERE\n slot_updates.idx = excluded.idx\n AND slot_updates.account_address = excluded.account_address\n )\n RETURNING 1 as res\n),\n\nhistorical_nonce_insert AS (\n INSERT INTO historical_nonces (address, nonce, block_number)\n SELECT * FROM unnest($51::bytea [], $52::numeric [], $53::int8 [])\n RETURNING 1 as res\n),\n\nhistorical_balance_insert AS (\n INSERT INTO historical_balances (address, balance, block_number)\n SELECT * FROM unnest($54::bytea [], $55::numeric [], $56::int8 [])\n RETURNING 1 as res\n),\n\nhistorical_slots_insert AS (\n INSERT INTO historical_slots (idx, value, account_address, block_number)\n SELECT *\n FROM unnest($57::bytea [], $58::bytea [], $59::bytea [], $60::int8 [])\n RETURNING 1 as res\n)\n\nSELECT modified_accounts, modified_slots FROM\n(SELECT count(*) AS modified_accounts FROM account_insert)\nCROSS JOIN\n(SELECT count(*) AS modified_slots FROM slot_insert);\n", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "modified_accounts", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "modified_slots", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8", - "Bytea", - "Bytea", - "Numeric", - "Bytea", - "Int8", - "Bytea", - "ByteaArray", - "ByteaArray", - "NumericArray", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "NumericArray", - "NumericArray", - "Int4Array", - "Int8Array", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "NumericArray", - "TextArray", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "Int4Array", - "Int4Array", - "Int8Array", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "Int4Array", - "Int4Array", - "Int4Array", - "Int8Array", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "NumericArray", - "NumericArray", - "Int8Array", - "NumericArray", - "NumericArray", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "Int8Array", - "ByteaArray", - "ByteaArray", - "NumericArray", - "Int8Array", - "ByteaArray", - "NumericArray", - "Int8Array", - "ByteaArray", - "ByteaArray", - "ByteaArray", - "Int8Array" - ] - }, - "nullable": [ - null, - null - ] - }, - "hash": "94b199f16d33b19e70672a64f25e75e8519e33995ab6101817dc5f202900dd3a" -} diff --git a/.sqlx/query-e8a32893d991a776633dbba4e35b868c31f91cfe0c3e4081e7749c6a76cee5d1.json b/.sqlx/query-e8a32893d991a776633dbba4e35b868c31f91cfe0c3e4081e7749c6a76cee5d1.json deleted file mode 100644 index 66cb279a9..000000000 --- a/.sqlx/query-e8a32893d991a776633dbba4e35b868c31f91cfe0c3e4081e7749c6a76cee5d1.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT\n number as \"number: _\"\n ,hash as \"hash: _\"\n ,transactions_root as \"transactions_root: _\"\n ,gas as \"gas: _\"\n ,logs_bloom as \"bloom: _\"\n ,timestamp_in_secs as \"timestamp: _\"\n ,parent_hash as \"parent_hash: _\"\nFROM blocks\nWHERE number = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "number: _", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "hash: _", - "type_info": "Bytea" - }, - { - "ordinal": 2, - "name": "transactions_root: _", - "type_info": "Bytea" - }, - { - "ordinal": 3, - "name": "gas: _", - "type_info": "Numeric" - }, - { - "ordinal": 4, - "name": "bloom: _", - "type_info": "Bytea" - }, - { - "ordinal": 5, - "name": "timestamp: _", - "type_info": "Int8" - }, - { - "ordinal": 6, - "name": "parent_hash: _", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false - ] - }, - "hash": "e8a32893d991a776633dbba4e35b868c31f91cfe0c3e4081e7749c6a76cee5d1" -} diff --git a/.sqlx/query-f401ecc9e454519dd2398bd17f2c0d9c99e4e980bd0de506ddd20d5ab753ff04.json b/.sqlx/query-f401ecc9e454519dd2398bd17f2c0d9c99e4e980bd0de506ddd20d5ab753ff04.json deleted file mode 100644 index bf589a627..000000000 --- a/.sqlx/query-f401ecc9e454519dd2398bd17f2c0d9c99e4e980bd0de506ddd20d5ab753ff04.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT\n number as \"number: _\"\n ,hash as \"hash: _\"\n ,transactions_root as \"transactions_root: _\"\n ,gas as \"gas: _\"\n ,logs_bloom as \"bloom: _\"\n ,timestamp_in_secs as \"timestamp: _\"\n ,parent_hash as \"parent_hash: _\"\nFROM blocks\nWHERE hash = $1\n", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "number: _", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "hash: _", - "type_info": "Bytea" - }, - { - "ordinal": 2, - "name": "transactions_root: _", - "type_info": "Bytea" - }, - { - "ordinal": 3, - "name": "gas: _", - "type_info": "Numeric" - }, - { - "ordinal": 4, - "name": "bloom: _", - "type_info": "Bytea" - }, - { - "ordinal": 5, - "name": "timestamp: _", - "type_info": "Int8" - }, - { - "ordinal": 6, - "name": "parent_hash: _", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Bytea" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false - ] - }, - "hash": "f401ecc9e454519dd2398bd17f2c0d9c99e4e980bd0de506ddd20d5ab753ff04" -} diff --git a/src/eth/block_miner.rs b/src/eth/block_miner.rs index 806745fb9..1ee088265 100644 --- a/src/eth/block_miner.rs +++ b/src/eth/block_miner.rs @@ -127,6 +127,8 @@ impl BlockMiner { } } + // TODO: calculate size, state_root, receipts_root, parent_hash + Ok(block) } } diff --git a/src/eth/primitives/block_header.rs b/src/eth/primitives/block_header.rs index 680db9cad..ac4804716 100644 --- a/src/eth/primitives/block_header.rs +++ b/src/eth/primitives/block_header.rs @@ -19,26 +19,41 @@ use jsonrpsee::SubscriptionMessage; use crate::eth::primitives::logs_bloom::LogsBloom; use crate::eth::primitives::Address; use crate::eth::primitives::BlockNumber; +use crate::eth::primitives::Bytes; +use crate::eth::primitives::Difficulty; use crate::eth::primitives::ExternalBlock; use crate::eth::primitives::Gas; use crate::eth::primitives::Hash; +use crate::eth::primitives::MinerNonce; +use crate::eth::primitives::Size; use crate::eth::primitives::UnixTime; /// Special hash used in block mining to indicate no uncle blocks. const HASH_EMPTY_UNCLES: Hash = Hash::new(hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")); /// Special hash used in block mining to indicate no transaction root and no receipts root. -const HASH_EMPTY_TRANSACTIONS_ROOT: Hash = Hash::new(hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")); +const HASH_EMPTY_TRIE: Hash = Hash::new(hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")); #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct BlockHeader { pub number: BlockNumber, pub hash: Hash, pub transactions_root: Hash, - pub gas: Gas, + pub gas_used: Gas, + pub gas_limit: Gas, pub bloom: LogsBloom, pub timestamp: UnixTime, pub parent_hash: Hash, + pub author: Address, + pub extra_data: Bytes, + pub miner: Address, + pub difficulty: Difficulty, // is always 0x0 + pub receipts_root: Hash, + pub uncle_hash: Hash, // is always 0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 + pub size: Size, + pub state_root: Hash, + pub total_difficulty: Difficulty, // is always 0x0 + pub nonce: MinerNonce, // is always 0x0000000000000000 } impl BlockHeader { @@ -47,11 +62,22 @@ impl BlockHeader { Self { number, hash: number.hash(), - transactions_root: HASH_EMPTY_TRANSACTIONS_ROOT, - gas: Gas::ZERO, + transactions_root: HASH_EMPTY_TRIE, + gas_used: Gas::ZERO, + gas_limit: Gas::ZERO, bloom: LogsBloom::default(), timestamp, parent_hash: number.prev().map(|n| n.hash()).unwrap_or(Hash::zero()), + author: Address::default(), + extra_data: Bytes::default(), + miner: Address::default(), + difficulty: Difficulty::default(), + receipts_root: HASH_EMPTY_TRIE, + uncle_hash: HASH_EMPTY_UNCLES, + size: Size::default(), + state_root: HASH_EMPTY_TRIE, + total_difficulty: Difficulty::default(), + nonce: MinerNonce::default(), } } } @@ -62,10 +88,21 @@ impl Dummy for BlockHeader { number: faker.fake_with_rng(rng), hash: faker.fake_with_rng(rng), transactions_root: faker.fake_with_rng(rng), - gas: faker.fake_with_rng(rng), + gas_used: faker.fake_with_rng(rng), bloom: Default::default(), timestamp: faker.fake_with_rng(rng), parent_hash: faker.fake_with_rng(rng), + gas_limit: faker.fake_with_rng(rng), + author: faker.fake_with_rng(rng), + extra_data: faker.fake_with_rng(rng), + miner: faker.fake_with_rng(rng), + difficulty: faker.fake_with_rng(rng), + receipts_root: faker.fake_with_rng(rng), + uncle_hash: faker.fake_with_rng(rng), + size: faker.fake_with_rng(rng), + state_root: faker.fake_with_rng(rng), + total_difficulty: faker.fake_with_rng(rng), + nonce: faker.fake_with_rng(rng), } } } @@ -100,14 +137,14 @@ where // mining: gas gas_limit: Gas::from(100_000_000).into(), - gas_used: header.gas.into(), + gas_used: header.gas_used.into(), base_fee_per_gas: Some(U256::zero()), blob_gas_used: None, excess_blob_gas: None, // transactions transactions_root: header.transactions_root.into(), - receipts_root: HASH_EMPTY_TRANSACTIONS_ROOT.into(), + receipts_root: HASH_EMPTY_TRIE.into(), // data logs_bloom: Some(*header.bloom), @@ -130,15 +167,26 @@ where // Conversions: Other -> Self // ----------------------------------------------------------------------------- impl From for BlockHeader { - fn from(value: ExternalBlock) -> Self { + fn from(mut value: ExternalBlock) -> Self { Self { number: value.number(), hash: value.hash(), transactions_root: value.transactions_root.into(), - gas: value.gas_used.into(), + gas_used: value.gas_used.into(), bloom: value.logs_bloom.unwrap_or_default().into(), timestamp: value.timestamp.into(), parent_hash: value.parent_hash.into(), + gas_limit: value.gas_limit.into(), + author: value.author(), + extra_data: value.extra_data(), + miner: value.author.unwrap_or_default().into(), + difficulty: value.difficulty.into(), + receipts_root: value.receipts_root.into(), + uncle_hash: value.uncles_hash.into(), + size: value.size.unwrap_or_default().into(), + state_root: value.state_root.into(), + total_difficulty: value.total_difficulty.unwrap_or_default().into(), + nonce: value.nonce.unwrap_or_default().into(), } } } diff --git a/src/eth/primitives/difficulty.rs b/src/eth/primitives/difficulty.rs new file mode 100644 index 000000000..60641416c --- /dev/null +++ b/src/eth/primitives/difficulty.rs @@ -0,0 +1,101 @@ +use std::fmt::Display; +use std::str::FromStr; + +use ethereum_types::U256; +use fake::Dummy; +use fake::Faker; +use sqlx::database::HasArguments; +use sqlx::database::HasValueRef; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::postgres::PgHasArrayType; +use sqlx::types::BigDecimal; + +use crate::gen_newtype_from; + +#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +#[serde(transparent)] +pub struct Difficulty(U256); + +impl Display for Difficulty { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl Dummy for Difficulty { + fn dummy_with_rng(_: &Faker, rng: &mut R) -> Self { + rng.next_u64().into() + } +} + +// ----------------------------------------------------------------------------- +// Conversions: Other -> Self +// ----------------------------------------------------------------------------- +gen_newtype_from!(self = Difficulty, other = u8, u16, u32, u64, u128, U256, usize, i32, [u8; 32]); + +impl TryFrom for Difficulty { + type Error = anyhow::Error; + + fn try_from(value: BigDecimal) -> Result { + let value_str = value.to_string(); + Ok(Difficulty(U256::from_dec_str(&value_str)?)) + } +} + +// ----------------------------------------------------------------------------- +// sqlx traits +// ----------------------------------------------------------------------------- +impl<'r> sqlx::Decode<'r, sqlx::Postgres> for Difficulty { + fn decode(value: >::ValueRef) -> Result { + let value = >::decode(value)?; + Ok(value.try_into()?) + } +} + +impl sqlx::Type for Difficulty { + fn type_info() -> ::TypeInfo { + sqlx::postgres::PgTypeInfo::with_name("NUMERIC") + } +} + +impl<'q> sqlx::Encode<'q, sqlx::Postgres> for Difficulty { + fn encode_by_ref(&self, buf: &mut >::ArgumentBuffer) -> IsNull { + match BigDecimal::try_from(self.clone()) { + Ok(res) => res.encode(buf), + Err(err) => { + tracing::error!(?err, "failed to encode gas"); + IsNull::Yes + } + } + } +} + +impl PgHasArrayType for Difficulty { + fn array_type_info() -> sqlx::postgres::PgTypeInfo { + ::array_type_info() + } +} + +// ----------------------------------------------------------------------------- +// Conversions: Self -> Other +// ---------------------------------------------------------------------------- +impl From for U256 { + fn from(value: Difficulty) -> Self { + value.0 + } +} + +impl From for u64 { + fn from(value: Difficulty) -> Self { + value.0.low_u64() + } +} + +impl TryFrom for BigDecimal { + type Error = anyhow::Error; + fn try_from(value: Difficulty) -> Result { + // HACK: If we could import BigInt or BigUint we could convert the bytes directly. + Ok(BigDecimal::from_str(&U256::from(value).to_string())?) + } +} diff --git a/src/eth/primitives/external_block.rs b/src/eth/primitives/external_block.rs index b4e1df986..6e07b46c2 100644 --- a/src/eth/primitives/external_block.rs +++ b/src/eth/primitives/external_block.rs @@ -1,9 +1,10 @@ use ethers_core::types::Block as EthersBlock; use ethers_core::types::Transaction as EthersTransaction; +use crate::eth::primitives::Address; use crate::eth::primitives::Block; -use crate::eth::primitives::BlockHeader; use crate::eth::primitives::BlockNumber; +use crate::eth::primitives::Bytes; use crate::eth::primitives::ExternalTransaction; use crate::eth::primitives::Hash; use crate::eth::primitives::UnixTime; @@ -28,6 +29,16 @@ impl ExternalBlock { pub fn timestamp(&self) -> UnixTime { self.0.timestamp.into() } + + /// Returns the block timestamp. + pub fn author(&self) -> Address { + self.0.author.unwrap_or_default().into() + } + + /// Returns the block timestamp. + pub fn extra_data(&mut self) -> Bytes { + std::mem::take(&mut self.0.extra_data).into() + } } // ----------------------------------------------------------------------------- @@ -43,15 +54,7 @@ impl From for EthersBlock { impl From for Block { fn from(value: ExternalBlock) -> Self { Block { - header: BlockHeader { - number: value.number.unwrap().into(), - hash: value.hash.unwrap().into(), - transactions_root: value.transactions_root.into(), - gas: value.gas_used.into(), - bloom: value.logs_bloom.unwrap().into(), - timestamp: value.timestamp.into(), - parent_hash: value.parent_hash.into(), - }, + header: value.into(), transactions: vec![], } } diff --git a/src/eth/primitives/miner_nonce.rs b/src/eth/primitives/miner_nonce.rs new file mode 100644 index 000000000..f289edea9 --- /dev/null +++ b/src/eth/primitives/miner_nonce.rs @@ -0,0 +1,82 @@ +use ethereum_types::H64; +use fake::Dummy; +use fake::Faker; +use sqlx::database::HasArguments; +use sqlx::database::HasValueRef; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::postgres::PgHasArrayType; +use sqlx::Decode; + +use crate::gen_newtype_from; + +/// The nonce of an Ethereum block. +#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)] +pub struct MinerNonce(H64); + +impl MinerNonce { + /// Creates a new BlockNonce from the given bytes. + pub const fn new(bytes: [u8; 8]) -> Self { + Self(H64(bytes)) + } +} + +impl Dummy for MinerNonce { + fn dummy_with_rng(_: &Faker, rng: &mut R) -> Self { + H64::random_using(rng).into() + } +} + +// ----------------------------------------------------------------------------- +// Conversions: Other -> Self +// ----------------------------------------------------------------------------- +gen_newtype_from!(self = MinerNonce, other = H64, [u8; 8]); + +// ----------------------------------------------------------------------------- +// sqlx traits +// ----------------------------------------------------------------------------- +impl<'r> sqlx::Decode<'r, sqlx::Postgres> for MinerNonce { + fn decode(value: >::ValueRef) -> Result { + let value = <[u8; 8] as Decode>::decode(value)?; + Ok(value.into()) + } +} + +impl sqlx::Type for MinerNonce { + fn type_info() -> ::TypeInfo { + sqlx::postgres::PgTypeInfo::with_name("BYTEA") + } +} + +impl PgHasArrayType for MinerNonce { + fn array_type_info() -> sqlx::postgres::PgTypeInfo { + <[u8; 8] as PgHasArrayType>::array_type_info() + } +} + +impl AsRef<[u8]> for MinerNonce { + fn as_ref(&self) -> &[u8] { + self.0.as_bytes() + } +} + +impl<'q> sqlx::Encode<'q, sqlx::Postgres> for MinerNonce { + fn encode_by_ref(&self, buf: &mut >::ArgumentBuffer) -> IsNull { + self.0 .0.encode(buf) + } +} + +// ----------------------------------------------------------------------------- +// Conversions: Self -> Other +// ----------------------------------------------------------------------------- +impl From for H64 { + fn from(value: MinerNonce) -> Self { + value.0 + } +} + +impl From for [u8; 8] { + fn from(value: MinerNonce) -> Self { + H64::from(value.clone()).0 + } +} diff --git a/src/eth/primitives/mod.rs b/src/eth/primitives/mod.rs index e42ac11f5..ef2885852 100644 --- a/src/eth/primitives/mod.rs +++ b/src/eth/primitives/mod.rs @@ -84,6 +84,7 @@ mod block_selection; mod bytes; mod call_input; mod chain_id; +mod difficulty; mod ecdsa_rs; mod ecdsa_v; mod execution; @@ -103,7 +104,9 @@ mod log_filter_input; mod log_mined; mod log_topic; mod logs_bloom; +mod miner_nonce; mod nonce; +mod size; mod slot; mod storage_point_in_time; mod transaction_input; @@ -124,6 +127,7 @@ pub use block_selection::BlockSelection; pub use bytes::Bytes; pub use call_input::CallInput; pub use chain_id::ChainId; +pub use difficulty::Difficulty; pub use ecdsa_rs::EcdsaRs; pub use ecdsa_v::EcdsaV; pub use execution::Execution; @@ -147,7 +151,9 @@ pub use log_filter::LogFilterTopicCombination; pub use log_filter_input::LogFilterInput; pub use log_mined::LogMined; pub use log_topic::LogTopic; +pub use miner_nonce::MinerNonce; pub use nonce::Nonce; +pub use size::Size; pub use slot::Slot; pub use slot::SlotIndex; pub use slot::SlotSample; diff --git a/src/eth/primitives/size.rs b/src/eth/primitives/size.rs new file mode 100644 index 000000000..fa31057f7 --- /dev/null +++ b/src/eth/primitives/size.rs @@ -0,0 +1,101 @@ +use std::fmt::Display; +use std::str::FromStr; + +use ethereum_types::U256; +use fake::Dummy; +use fake::Faker; +use sqlx::database::HasArguments; +use sqlx::database::HasValueRef; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::postgres::PgHasArrayType; +use sqlx::types::BigDecimal; + +use crate::gen_newtype_from; + +#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +#[serde(transparent)] +pub struct Size(U256); + +impl Display for Size { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl Dummy for Size { + fn dummy_with_rng(_: &Faker, rng: &mut R) -> Self { + rng.next_u64().into() + } +} + +// ----------------------------------------------------------------------------- +// Conversions: Other -> Self +// ----------------------------------------------------------------------------- +gen_newtype_from!(self = Size, other = u8, u16, u32, u64, u128, U256, usize, i32, [u8; 32]); + +impl TryFrom for Size { + type Error = anyhow::Error; + + fn try_from(value: BigDecimal) -> Result { + let value_str = value.to_string(); + Ok(Size(U256::from_dec_str(&value_str)?)) + } +} + +// ----------------------------------------------------------------------------- +// sqlx traits +// ----------------------------------------------------------------------------- +impl<'r> sqlx::Decode<'r, sqlx::Postgres> for Size { + fn decode(value: >::ValueRef) -> Result { + let value = >::decode(value)?; + Ok(value.try_into()?) + } +} + +impl sqlx::Type for Size { + fn type_info() -> ::TypeInfo { + sqlx::postgres::PgTypeInfo::with_name("NUMERIC") + } +} + +impl<'q> sqlx::Encode<'q, sqlx::Postgres> for Size { + fn encode_by_ref(&self, buf: &mut >::ArgumentBuffer) -> IsNull { + match BigDecimal::try_from(self.clone()) { + Ok(res) => res.encode(buf), + Err(err) => { + tracing::error!(?err, "failed to encode gas"); + IsNull::Yes + } + } + } +} + +impl PgHasArrayType for Size { + fn array_type_info() -> sqlx::postgres::PgTypeInfo { + ::array_type_info() + } +} + +// ----------------------------------------------------------------------------- +// Conversions: Self -> Other +// ---------------------------------------------------------------------------- +impl From for U256 { + fn from(value: Size) -> Self { + value.0 + } +} + +impl From for u64 { + fn from(value: Size) -> Self { + value.0.low_u64() + } +} + +impl TryFrom for BigDecimal { + type Error = anyhow::Error; + fn try_from(value: Size) -> Result { + // HACK: If we could import BigInt or BigUint we could convert the bytes directly. + Ok(BigDecimal::from_str(&U256::from(value).to_string())?) + } +} diff --git a/src/eth/storage/postgres/postgres.rs b/src/eth/storage/postgres/postgres.rs index b635396af..73a1c577b 100644 --- a/src/eth/storage/postgres/postgres.rs +++ b/src/eth/storage/postgres/postgres.rs @@ -148,7 +148,7 @@ impl PermanentStorage for Postgres { let block_number = i64::try_from(current)?; - let header_query = sqlx::query_file_as!(BlockHeader, "src/eth/storage/postgres/queries/select_block_header_by_number.sql", block_number,) + let header_query = sqlx::query_file_as!(BlockHeader, "src/eth/storage/postgres/queries/select_block_header_by_number.sql", block_number) .fetch_optional(&self.connection_pool); let transactions_query = sqlx::query_file_as!( @@ -550,10 +550,21 @@ impl PermanentStorage for Postgres { i64::try_from(block.header.number).context("failed to convert block number")?, block.header.hash.as_ref(), block.header.transactions_root.as_ref(), - BigDecimal::try_from(block.header.gas.clone())?, + block.header.gas_limit as _, + block.header.gas_used as _, block.header.bloom.as_ref(), i64::try_from(block.header.timestamp).context("failed to convert block timestamp")?, block.header.parent_hash.as_ref(), + block.header.author as _, + block.header.extra_data as _, + block.header.miner as _, + block.header.difficulty as _, + block.header.receipts_root as _, + block.header.uncle_hash as _, + block.header.size as _, + block.header.state_root as _, + block.header.total_difficulty as _, + block.header.nonce as _, transaction_batch.hash as _, transaction_batch.signer as _, transaction_batch.nonce as _, diff --git a/src/eth/storage/postgres/queries/insert_entire_block.sql b/src/eth/storage/postgres/queries/insert_entire_block.sql index 92dcd32c5..c37cde43c 100644 --- a/src/eth/storage/postgres/queries/insert_entire_block.sql +++ b/src/eth/storage/postgres/queries/insert_entire_block.sql @@ -3,13 +3,24 @@ WITH block_insert AS ( number, hash, transactions_root, - gas, + gas_limit, + gas_used, logs_bloom, timestamp_in_secs, parent_hash, + author, + extra_data, + miner, + difficulty, + receipts_root, + uncle_hash, + size, + state_root, + total_difficulty, + nonce, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, current_timestamp) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, current_timestamp) RETURNING 1 as res ), @@ -36,23 +47,23 @@ transaction_insert AS ( SELECT * FROM unnest( - $8::bytea [], - $9::bytea [], - $10::numeric [], - $11::bytea [], - $12::bytea [], - $13::bytea [], - $14::bytea [], - $15::numeric [], - $16::numeric [], - $17::int4 [], - $18::int8 [], $19::bytea [], $20::bytea [], - $21::bytea [], + $21::numeric [], $22::bytea [], - $23::numeric [], - $24::text [] + $23::bytea [], + $24::bytea [], + $25::bytea [], + $26::numeric [], + $27::numeric [], + $28::int4 [], + $29::int8 [], + $30::bytea [], + $31::bytea [], + $32::bytea [], + $33::bytea [], + $34::numeric [], + $35::text [] ) RETURNING 1 as res ), @@ -70,13 +81,13 @@ log_insert AS ( SELECT * FROM unnest( - $25::bytea [], - $26::bytea [], - $27::bytea [], - $28::int4 [], - $29::int4 [], - $30::int8 [], - $31::bytea [] + $36::bytea [], + $37::bytea [], + $38::bytea [], + $39::int4 [], + $40::int4 [], + $41::int8 [], + $42::bytea [] ) RETURNING 1 as res ), @@ -94,13 +105,13 @@ topic_insert AS ( SELECT * FROM unnest( - $32::bytea [], - $33::bytea [], - $34::int4 [], - $35::int4 [], - $36::int4 [], - $37::int8 [], - $38::bytea [] + $43::bytea [], + $44::bytea [], + $45::int4 [], + $46::int4 [], + $47::int4 [], + $48::int8 [], + $49::bytea [] ) RETURNING 1 as res ), @@ -110,13 +121,13 @@ account_insert AS ( SELECT * FROM unnest( - $39::bytea [], - $40::bytea [], - $41::numeric [], - $42::numeric [], - $43::int8 [], - $44::numeric [], - $45::numeric [] + $50::bytea [], + $51::bytea [], + $52::numeric [], + $53::numeric [], + $54::int8 [], + $55::numeric [], + $56::numeric [] ) AS t ( address, @@ -163,11 +174,11 @@ slot_insert AS ( SELECT * FROM unnest( - $46::bytea [], - $47::bytea [], - $48::bytea [], - $49::int8 [], - $50::bytea [] + $57::bytea [], + $58::bytea [], + $59::bytea [], + $60::int8 [], + $61::bytea [] ) AS t (idx, value, account_address, creation_block, original_value) ) @@ -194,20 +205,20 @@ slot_insert AS ( historical_nonce_insert AS ( INSERT INTO historical_nonces (address, nonce, block_number) - SELECT * FROM unnest($51::bytea [], $52::numeric [], $53::int8 []) + SELECT * FROM unnest($62::bytea [], $63::numeric [], $64::int8 []) RETURNING 1 as res ), historical_balance_insert AS ( INSERT INTO historical_balances (address, balance, block_number) - SELECT * FROM unnest($54::bytea [], $55::numeric [], $56::int8 []) + SELECT * FROM unnest($65::bytea [], $66::numeric [], $67::int8 []) RETURNING 1 as res ), historical_slots_insert AS ( INSERT INTO historical_slots (idx, value, account_address, block_number) SELECT * - FROM unnest($57::bytea [], $58::bytea [], $59::bytea [], $60::int8 []) + FROM unnest($68::bytea [], $69::bytea [], $70::bytea [], $71::int8 []) RETURNING 1 as res ) diff --git a/src/eth/storage/postgres/queries/select_block_header_by_hash.sql b/src/eth/storage/postgres/queries/select_block_header_by_hash.sql index 9c7d3abb5..5409d0629 100644 --- a/src/eth/storage/postgres/queries/select_block_header_by_hash.sql +++ b/src/eth/storage/postgres/queries/select_block_header_by_hash.sql @@ -1,10 +1,21 @@ SELECT - number as "number: _" - ,hash as "hash: _" - ,transactions_root as "transactions_root: _" - ,gas as "gas: _" - ,logs_bloom as "bloom: _" - ,timestamp_in_secs as "timestamp: _" - ,parent_hash as "parent_hash: _" + number as "number: _", + hash as "hash: _", + transactions_root as "transactions_root: _", + gas_limit as "gas_limit: _", + gas_used as "gas_used: _", + logs_bloom as "bloom: _", + timestamp_in_secs as "timestamp: _", + parent_hash as "parent_hash: _", + author as "author: _", + extra_data as "extra_data: _", + miner as "miner: _", + difficulty as "difficulty: _", + receipts_root as "receipts_root: _", + uncle_hash as "uncle_hash: _", + size as "size: _", + state_root as "state_root: _", + total_difficulty as "total_difficulty: _", + nonce as "nonce: _" FROM blocks WHERE hash = $1 diff --git a/src/eth/storage/postgres/queries/select_block_header_by_number.sql b/src/eth/storage/postgres/queries/select_block_header_by_number.sql index 848e546f6..e88dcf486 100644 --- a/src/eth/storage/postgres/queries/select_block_header_by_number.sql +++ b/src/eth/storage/postgres/queries/select_block_header_by_number.sql @@ -1,10 +1,21 @@ SELECT - number as "number: _" - ,hash as "hash: _" - ,transactions_root as "transactions_root: _" - ,gas as "gas: _" - ,logs_bloom as "bloom: _" - ,timestamp_in_secs as "timestamp: _" - ,parent_hash as "parent_hash: _" + number as "number: _", + hash as "hash: _", + transactions_root as "transactions_root: _", + gas_limit as "gas_limit: _", + gas_used as "gas_used: _", + logs_bloom as "bloom: _", + timestamp_in_secs as "timestamp: _", + parent_hash as "parent_hash: _", + author as "author: _", + extra_data as "extra_data: _", + miner as "miner: _", + difficulty as "difficulty: _", + receipts_root as "receipts_root: _", + uncle_hash as "uncle_hash: _", + size as "size: _", + state_root as "state_root: _", + total_difficulty as "total_difficulty: _", + nonce as "nonce: _" FROM blocks -WHERE number = $1 \ No newline at end of file +WHERE number = $1 diff --git a/static/schema/001-init.sql b/static/schema/001-init.sql index d0d400a65..927861f98 100644 --- a/static/schema/001-init.sql +++ b/static/schema/001-init.sql @@ -1,14 +1,25 @@ -- TODO: maybe call this table `block_headers` CREATE TABLE IF NOT EXISTS blocks ( - number BIGSERIAL NOT NULL CHECK (number >= 0) UNIQUE - ,hash BYTEA NOT NULL CHECK (LENGTH(hash) = 32) UNIQUE - ,transactions_root BYTEA NOT NULL CHECK (LENGTH(transactions_root) = 32) - ,gas NUMERIC NOT NULL CHECK (gas >= 0) - ,logs_bloom BYTEA NOT NULL CHECK (LENGTH(logs_bloom) = 256) - ,timestamp_in_secs BIGINT NOT NULL CHECK (timestamp_in_secs >= 0) - ,parent_hash BYTEA NOT NULL CHECK (LENGTH(parent_hash) = 32) UNIQUE - ,created_at TIMESTAMP NOT NULL - ,PRIMARY KEY (number, hash) + number BIGSERIAL NOT NULL CHECK (number >= 0) UNIQUE, + hash BYTEA NOT NULL CHECK (LENGTH(hash) = 32) UNIQUE, + transactions_root BYTEA NOT NULL CHECK (LENGTH(transactions_root) = 32), + gas_limit NUMERIC NOT NULL CHECK (gas_limit >= 0), + gas_used NUMERIC NOT NULL CHECK (gas_used >= 0), + logs_bloom BYTEA NOT NULL CHECK (LENGTH(logs_bloom) = 256), + timestamp_in_secs BIGINT NOT NULL CHECK (timestamp_in_secs >= 0), + parent_hash BYTEA NOT NULL CHECK (LENGTH(parent_hash) = 32) UNIQUE, + author BYTEA NOT NULL CHECK (LENGTH(author) = 20), + extra_data BYTEA NOT NULL CHECK (LENGTH(extra_data) <= 32), + miner BYTEA NOT NULL CHECK (LENGTH(miner) = 20), + difficulty NUMERIC NOT NULL CHECK (difficulty >= 0), + receipts_root BYTEA NOT NULL CHECK (LENGTH(receipts_root) = 32), + uncle_hash BYTEA NOT NULL CHECK (LENGTH(uncle_hash) = 32), + size NUMERIC NOT NULL CHECK (size >= 0), + state_root BYTEA NOT NULL CHECK (LENGTH(state_root) = 32), + total_difficulty NUMERIC NOT NULL CHECK (total_difficulty >= 0), + nonce BYTEA NOT NULL CHECK (LENGTH(nonce) = 8), + created_at TIMESTAMP NOT NULL, + PRIMARY KEY (number, hash) ); CREATE TABLE IF NOT EXISTS accounts ( @@ -98,16 +109,47 @@ CREATE TABLE IF NOT EXISTS topics ( -- Insert genesis block and the pre-funded account on database creation. These should be -- present in the database regardless of how stratus is started. -INSERT INTO blocks(number, hash, transactions_root, gas, logs_bloom, timestamp_in_secs, parent_hash, created_at) +INSERT INTO blocks( + number, + hash, + transactions_root, + gas_limit, + gas_used, + logs_bloom, + timestamp_in_secs, + parent_hash, + author, + extra_data, + miner, + difficulty, + receipts_root, + uncle_hash, + size, + state_root, + total_difficulty, + nonce, + created_at +) VALUES ( - 0, - decode('011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce', 'hex'), - decode('56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', 'hex'), - 0, - decode('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', 'hex'), - 0, - decode('0000000000000000000000000000000000000000000000000000000000000000', 'hex'), - current_timestamp + 0, -- number + decode('011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce', 'hex'), -- hash + decode('56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', 'hex'), -- transactions_root + 4294967295, -- gas_limit + 0, -- gas_used + decode('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', 'hex'), -- logs_bloom + 0, -- timestamp_in_secs + decode('0000000000000000000000000000000000000000000000000000000000000000', 'hex'), -- parent_hash + decode('0000000000000000000000000000000000000000', 'hex'), -- author + decode('', 'hex'), -- extra_data + decode('0000000000000000000000000000000000000000', 'hex'), -- miner + 0, -- difficulty + decode('56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', 'hex'), -- receipts_root + decode('1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', 'hex'), -- uncle_hash + 505, -- size + decode('c7cc35e75df400dd94a7f2a4db18729e87dacab31eacc7ab4a26b41fc5e32937', 'hex'), -- state_root + 0, -- total_difficulty + decode('0000000000000000', 'hex'), -- nonce + current_timestamp -- created_at ); INSERT INTO accounts (address, bytecode, latest_balance, latest_nonce, creation_block)