@@ -23,8 +23,8 @@ defmodule Aecore.Chain.Worker do
2323    genesis_block_map  =  % { genesis_block_hash  =>  Block . genesis_block ( ) } 
2424    genesis_chain_state  =  ChainState . calculate_block_state ( Block . genesis_block ( ) . txs ) 
2525    latest_block_chain_state  =  % { genesis_block_hash  =>  genesis_chain_state } 
26- 
27-     initial_state  =  { genesis_block_map ,  latest_block_chain_state } 
26+      txs_index   =   calculate_block_acc_txs_info ( Block . genesis_block ( ) ) 
27+     initial_state  =  { genesis_block_map ,  latest_block_chain_state ,   txs_index } 
2828
2929    { :ok ,  initial_state } 
3030  end 
@@ -70,13 +70,18 @@ defmodule Aecore.Chain.Worker do
7070    GenServer . call ( __MODULE__ ,  { :chain_state ,  latest_block_hash } ) 
7171  end 
7272
73+   @ spec  txs_index ( )  ::  map ( ) 
74+   def  txs_index ( )  do 
75+     GenServer . call ( __MODULE__ ,  :txs_index ) 
76+   end 
77+ 
7378  def  handle_call ( :get_latest_block_chain_state ,  _from ,  state )  do 
74-     { _ ,  latest_block_chain_state }  =  state 
79+     { _ ,  latest_block_chain_state ,   _ }  =  state 
7580    { :reply ,  latest_block_chain_state ,  state } 
7681  end 
7782
7883  def  handle_call ( { :get_block ,  block_hash } ,  _from ,  state )  do 
79-     { block_map ,  _ }  =  state 
84+     { block_map ,  _ ,   _ }  =  state 
8085    block  =  block_map [ block_hash ] 
8186
8287    if ( block  !=  nil )  do 
@@ -87,7 +92,7 @@ defmodule Aecore.Chain.Worker do
8792  end 
8893
8994  def  handle_call ( { :get_block_by_hex_hash ,  hash } ,  _from ,  state )  do 
90-     { chain ,  _ }  =  state 
95+     { chain ,  _ ,   _ }  =  state 
9196    case ( Enum . find ( chain ,  fn { block_hash ,  _block }  -> 
9297      block_hash  |>  Base . encode16 ( )  ==  hash  end ) )  do 
9398      { _ ,  block }  -> 
@@ -98,17 +103,19 @@ defmodule Aecore.Chain.Worker do
98103  end 
99104
100105  def  handle_call ( { :add_block ,  % Block { }  =  block } ,  _from ,  state )  do 
101-     { chain ,   chain_state }  =  state 
102-     prev_block_chain_state  =  chain_state [ block . header . prev_hash ] 
106+     { block_map ,   latest_block_chain_state ,   txs_index }  =  state 
107+     prev_block_chain_state  =  latest_block_chain_state [ block . header . prev_hash ] 
103108    new_block_state  =  ChainState . calculate_block_state ( block . txs ) 
104-     new_chain_state  =  ChainState . calculate_chain_state ( new_block_state ,  prev_block_chain_state ) 
109+     new_chain_state  = 
110+       ChainState . calculate_chain_state ( new_block_state ,  prev_block_chain_state ) 
105111
112+     new_block_txs_index  =  calculate_block_acc_txs_info ( block ) 
113+     new_txs_index  =  update_txs_index ( txs_index ,  new_block_txs_index ) 
106114    try  do 
107-       BlockValidation . validate_block! ( block ,  chain [ block . header . prev_hash ] ,  new_chain_state ) 
115+       BlockValidation . validate_block! ( block ,  block_map [ block . header . prev_hash ] ,  new_chain_state ) 
108116
109117      Enum . each ( block . txs ,  fn ( tx )  ->  Pool . remove_transaction ( tx )  end ) 
110118
111-       { block_map ,  latest_block_chain_state }  =  state 
112119      block_hash  =  BlockValidation . block_header_hash ( block . header ) 
113120      updated_block_map  =  Map . put ( block_map ,  block_hash ,  block ) 
114121      has_prev_block  =  Map . has_key? ( latest_block_chain_state ,  block . header . prev_hash ) 
@@ -121,10 +128,8 @@ defmodule Aecore.Chain.Worker do
121128          { latest_block_chain_state ,  % { } } 
122129      end 
123130
124-       new_block_state  =  ChainState . calculate_block_state ( block . txs ) 
125-       new_chain_state  =  ChainState . calculate_chain_state ( new_block_state ,  prev_chain_state ) 
126- 
127-       updated_latest_block_chainstate  =  Map . put ( deleted_latest_chain_state ,  block_hash ,  new_chain_state ) 
131+       updated_latest_block_chainstate  = 
132+         Map . put ( deleted_latest_chain_state ,  block_hash ,  new_chain_state ) 
128133
129134      total_tokens  =  ChainState . calculate_total_tokens ( new_chain_state ) 
130135
@@ -137,7 +142,7 @@ defmodule Aecore.Chain.Worker do
137142      ## Block was validated, now we can send it to other peers 
138143      Peers . broadcast_to_all ( { :new_block ,  block } ) 
139144
140-       { :reply ,  :ok ,  { updated_block_map ,  updated_latest_block_chainstate } } 
145+       { :reply ,  :ok ,  { updated_block_map ,  updated_latest_block_chainstate ,   new_txs_index } } 
141146    catch 
142147      { :error ,  message }  -> 
143148        Logger . error ( fn  -> 
@@ -148,10 +153,15 @@ defmodule Aecore.Chain.Worker do
148153  end 
149154
150155  def  handle_call ( { :chain_state ,  latest_block_hash } ,  _from ,  state )  do 
151-     { _ ,  chain_state }  =  state 
156+     { _ ,  chain_state ,   _ }  =  state 
152157    { :reply ,  chain_state [ latest_block_hash ] ,  state } 
153158  end 
154159
160+   def  handle_call ( :txs_index ,  _from ,  state )  do 
161+     { _ ,  _ ,  txs_index }  =  state 
162+     { :reply ,  txs_index ,  state } 
163+   end 
164+ 
155165  def  chain_state ( )  do 
156166    latest_block  =  latest_block ( ) 
157167    latest_block_hash  =  BlockValidation . block_header_hash ( latest_block . header ) 
@@ -164,6 +174,34 @@ defmodule Aecore.Chain.Worker do
164174    get_blocks ( latest_block_hash ,  latest_block_obj . header . height ) 
165175  end 
166176
177+   def  calculate_block_acc_txs_info ( block )  do 
178+     block_hash  =  BlockValidation . block_header_hash ( block . header ) 
179+     accounts  =  for  tx  <-  block . txs  do 
180+       [ tx . data . from_acc ,  tx . data . to_acc ] 
181+     end 
182+     accounts  =  accounts  |>  List . flatten ( )  |>  Enum . uniq ( )  |>  List . delete ( nil ) 
183+     for  account  <-  accounts ,  into:  % { }  do 
184+       acc_txs  =  Enum . filter ( block . txs ,  fn ( tx )  -> 
185+           tx . data . from_acc  ==  account  ||  tx . data . to_acc  ==  account 
186+         end ) 
187+       tx_hashes  =  Enum . map ( acc_txs ,  fn ( tx )  -> 
188+           tx_bin  =  :erlang . term_to_binary ( tx ) 
189+           :crypto . hash ( :sha256 ,  tx_bin ) 
190+         end ) 
191+       tx_tuples  =  Enum . map ( tx_hashes ,  fn ( hash )  -> 
192+           { block_hash ,  hash } 
193+         end ) 
194+       { account ,  tx_tuples } 
195+     end 
196+   end 
197+ 
198+   def  update_txs_index ( current_txs_index ,  new_block_txs_index )  do 
199+     Map . merge ( current_txs_index ,  new_block_txs_index , 
200+       fn ( _ ,  current_list ,  new_block_list )  -> 
201+         current_list  ++  new_block_list 
202+       end ) 
203+   end 
204+ 
167205  defp  get_blocks ( blocks_acc ,  next_block_hash ,  size )  do 
168206    cond  do 
169207      size  >  0  -> 
0 commit comments