diff --git a/.sqlx/query-64a4ea56c5c11b04315a5579ba25aa0339b8175c5339ef6a61fa7f04be445ef4.json b/.sqlx/query-64a4ea56c5c11b04315a5579ba25aa0339b8175c5339ef6a61fa7f04be445ef4.json new file mode 100644 index 000000000..084952c02 --- /dev/null +++ b/.sqlx/query-64a4ea56c5c11b04315a5579ba25aa0339b8175c5339ef6a61fa7f04be445ef4.json @@ -0,0 +1,41 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT address as \"address: _\",\n nonce as \"nonce: _\",\n balance as \"balance: _\",\n bytecode as \"bytecode: _\"\n FROM neo_accounts\n WHERE address = $1\n AND block_number = (SELECT MAX(block_number)\n FROM historical_slots\n WHERE address = $1\n AND block_number <= $2)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "address: _", + "type_info": "Bytea" + }, + { + "ordinal": 1, + "name": "nonce: _", + "type_info": "Numeric" + }, + { + "ordinal": 2, + "name": "balance: _", + "type_info": "Numeric" + }, + { + "ordinal": 3, + "name": "bytecode: _", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Bytea", + "Numeric" + ] + }, + "nullable": [ + false, + false, + false, + true + ] + }, + "hash": "64a4ea56c5c11b04315a5579ba25aa0339b8175c5339ef6a61fa7f04be445ef4" +} diff --git a/src/eth/storage/hybrid/hybrid_history.rs b/src/eth/storage/hybrid/hybrid_history.rs index 7c9fe9961..2028b679c 100644 --- a/src/eth/storage/hybrid/hybrid_history.rs +++ b/src/eth/storage/hybrid/hybrid_history.rs @@ -34,7 +34,7 @@ pub struct AccountInfo { #[derive(Debug)] pub struct HybridHistory { pub hybrid_accounts_slots: HashMap, - pool: Arc>, + pub pool: Arc>, } #[derive(FromRow)] diff --git a/src/eth/storage/hybrid/mod.rs b/src/eth/storage/hybrid/mod.rs index 554cc6533..5b820bf03 100644 --- a/src/eth/storage/hybrid/mod.rs +++ b/src/eth/storage/hybrid/mod.rs @@ -6,6 +6,7 @@ use std::sync::atomic::Ordering; use std::sync::Arc; use std::time::Duration; +use anyhow::Context; use async_trait::async_trait; use indexmap::IndexMap; use metrics::atomics::AtomicU64; @@ -238,19 +239,43 @@ impl PermanentStorage for HybridPermanentStorage { async fn maybe_read_account(&self, address: &Address, point_in_time: &StoragePointInTime) -> anyhow::Result> { //XXX TODO deal with point_in_time first, e.g create to_account at hybrid_accounts_slots let hybrid_state = self.hybrid_state.write().await; - match hybrid_state.hybrid_accounts_slots.get(address) { - Some(inmemory_account) => { - let account = inmemory_account.to_account(point_in_time, address).await; - tracing::trace!(%address, ?account, "account found"); - Ok(Some(account)) - } + let account = match point_in_time { + StoragePointInTime::Present => { + match hybrid_state.hybrid_accounts_slots.get(address) { + Some(inmemory_account) => { + let account = inmemory_account.to_account(point_in_time, address).await; + tracing::trace!(%address, ?account, "account found"); + Some(account) + } - None => { - //XXX TODO start a inmemory account from the database maybe using to_account on a empty account - tracing::trace!(%address, "account not found"); - Ok(None) + None => { + //XXX TODO start a inmemory account from the database maybe using to_account on a empty account + tracing::trace!(%address, "account not found"); + None + } + } } - } + StoragePointInTime::Past(block_number) => sqlx::query_as!( + Account, + r#" + SELECT address as "address: _", + nonce as "nonce: _", + balance as "balance: _", + bytecode as "bytecode: _" + FROM neo_accounts + WHERE address = $1 + AND block_number = (SELECT MAX(block_number) + FROM historical_slots + WHERE address = $1 + AND block_number <= $2)"#, + address as _, + block_number as _ + ) + .fetch_optional(&*hybrid_state.pool) + .await + .context("failed to select account")?, + }; + Ok(account) } async fn maybe_read_slot(&self, address: &Address, slot_index: &SlotIndex, point_in_time: &StoragePointInTime) -> anyhow::Result> { diff --git a/static/schema/001-init.sql b/static/schema/001-init.sql index c2cab7dd8..d5c302db2 100644 --- a/static/schema/001-init.sql +++ b/static/schema/001-init.sql @@ -734,8 +734,8 @@ CREATE TABLE public.neo_accounts ( block_number BIGINT NOT NULL, address BYTEA NOT NULL, bytecode BYTEA, - balance NUMERIC(38, 0), - nonce NUMERIC, + balance NUMERIC(38, 0) NOT NULL, + nonce NUMERIC NOT NULL, created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), PRIMARY KEY (address, block_number), FOREIGN KEY (block_number) REFERENCES public.neo_blocks(block_number)