@@ -10,7 +10,7 @@ class NewNodeDataProcessor
1010 value :reorg_started_at , global : true
1111 attr_accessor :local_tip_block , :pending_raw_block , :ckb_txs , :target_block , :target_block_number , :addrs_changes ,
1212 :outputs , :inputs , :outputs_data , :udt_address_ids , :contained_address_ids ,
13- :contained_udt_ids , :cell_datas , :enable_cota , :token_transfer_ckb_tx_ids , :addr_tx_changes
13+ :contained_udt_ids , :cell_datas , :enable_cota , :token_transfer_ckb_tx_ids , :addr_tx_changes , :redis_keys , :tx_previous_outputs
1414
1515 def initialize ( enable_cota = ENV [ "COTA_AGGREGATOR_URL" ] . present? )
1616 @enable_cota = enable_cota
@@ -28,6 +28,7 @@ def call
2828 return if target_block_number > tip_block_number - @offset . to_i
2929
3030 target_block = CkbSync ::Api . instance . get_block_by_number ( target_block_number )
31+
3132 if forked? ( target_block , local_tip_block )
3233 self . reorg_started_at = Time . now
3334 res = RevertBlockJob . perform_now ( local_tip_block )
@@ -45,11 +46,14 @@ def call
4546 rescue StandardError => e
4647 Rails . logger . error e . message
4748 puts e . backtrace . join ( "\n " )
49+ Rails . cache . delete_multi ( @redis_keys )
4850 raise e
4951 end
5052
5153 def process_block ( node_block , refresh_balance : true )
5254 local_block = nil
55+ @redis_keys = [ ]
56+ @tx_previous_outputs = { }
5357
5458 ApplicationRecord . transaction do
5559 # build node data
@@ -414,11 +418,10 @@ def update_or_create_udt_accounts!(local_block)
414418 next unless udt_output . cell_type . in? ( %w( udt m_nft_token nrc_721_token
415419 spore_cell did_cell omiga_inscription xudt xudt_compatible ) )
416420
417- address = Address . find ( udt_output . address_id )
418421 udt_type = udt_type ( udt_output . cell_type )
419- udt_account = address . udt_accounts . where ( type_hash : udt_output . type_hash , udt_type :) . select ( :id ,
422+ udt_account = UdtAccount . where ( address_id : udt_output . address_id ) . where ( type_hash : udt_output . type_hash , udt_type :) . select ( :id ,
420423 :created_at ) . first
421- amount = udt_account_amount ( udt_type , udt_output . type_hash , address )
424+ amount = udt_account_amount ( udt_type , udt_output . type_hash , udt_output . address_id )
422425 nft_token_id =
423426 case udt_type
424427 when "nrc_721_token"
@@ -440,16 +443,15 @@ def update_or_create_udt_accounts!(local_block)
440443 end
441444
442445 local_block . ckb_transactions . pluck ( :id ) . each do |tx_id | # iterator over each tx id for better sql performance
443- CellOutput . where ( consumed_by_id : tx_id ) . select ( :id , :address_id ,
444- :type_hash , :cell_type ) . each do |udt_output |
446+ cell_outputs = @tx_previous_outputs [ tx_id ] || [ ]
447+ cell_outputs . each do |udt_output |
445448 next unless udt_output . cell_type . in? ( %w( udt m_nft_token nrc_721_token
446449 spore_cell did_cell omiga_inscription xudt xudt_compatible ) )
447450
448- address = Address . find ( udt_output . address_id )
449451 udt_type = udt_type ( udt_output . cell_type )
450- udt_account = address . udt_accounts . where ( type_hash : udt_output . type_hash , udt_type :) . select ( :id ,
452+ udt_account = UdtAccount . where ( address_id : udt_output . address_id ) . where ( type_hash : udt_output . type_hash , udt_type :) . select ( :id ,
451453 :created_at ) . first
452- amount = udt_account_amount ( udt_type , udt_output . type_hash , address )
454+ amount = udt_account_amount ( udt_type , udt_output . type_hash , udt_output . address_id )
453455 udt = Udt . where ( type_hash : udt_output . type_hash , udt_type :) . select ( :id , :udt_type , :full_name ,
454456 :symbol , :decimal , :published , :code_hash , :type_hash , :created_at ) . take!
455457 if udt_account . present?
@@ -458,7 +460,7 @@ def update_or_create_udt_accounts!(local_block)
458460 udt_accounts_attributes << { id : udt_account . id , amount :,
459461 created_at : udt . created_at }
460462 when "m_nft_token" , "nrc_721_token" , "spore_cell" , "did_cell"
461- udt_account . destroy unless address . cell_outputs . live . where ( cell_type : udt_type ) . where ( type_hash : udt_output . type_hash ) . exists?
463+ udt_account . destroy unless CellOutput . live . where ( address_id : udt_output . address_id ) . where ( cell_type : udt_type ) . where ( type_hash : udt_output . type_hash ) . exists?
462464 end
463465 end
464466 end
@@ -487,12 +489,12 @@ def udt_type(cell_type)
487489 cell_type == "udt" ? "sudt" : cell_type
488490 end
489491
490- def udt_account_amount ( udt_type , type_hash , address )
492+ def udt_account_amount ( udt_type , type_hash , address_id )
491493 case udt_type
492494 when "sudt" , "ssri"
493- address . cell_outputs . live . udt . where ( type_hash :) . sum ( :udt_amount )
495+ CellOutput . live . where ( address_id : ) . udt . where ( type_hash :) . sum ( :udt_amount )
494496 when "xudt" , "xudt_compatible" , "omiga_inscription" , "m_nft_token" , "spore_cell" , "did_cell"
495- address . cell_outputs . live . where ( cell_type : udt_type ) . where ( type_hash :) . sum ( :udt_amount )
497+ CellOutput . live . where ( address_id : ) . where ( cell_type : udt_type ) . where ( type_hash :) . sum ( :udt_amount )
496498 else
497499 0
498500 end
@@ -558,7 +560,7 @@ def update_block_info!(local_block)
558560 total_transaction_fee : local_block . ckb_transactions . sum ( :transaction_fee ) ,
559561 ckb_transactions_count : local_block . ckb_transactions . count ,
560562 live_cell_changes : local_block . ckb_transactions . sum ( &:live_cell_changes ) ,
561- address_ids : local_block . ckb_transactions . map ( &:contained_address_ids ) . flatten . uniq ,
563+ address_ids : @contained_address_ids . map ( &:to_a ) . flatten . uniq
562564 )
563565 end
564566
@@ -584,7 +586,7 @@ def build_udts!(local_block, outputs, outputs_data)
584586 attrs [ :pre_udt_hash ] = pre_closed_info . udt_hash
585587 attrs [ :is_repeated_symbol ] = pre_closed_info . is_repeated_symbol
586588 else
587- attrs [ :is_repeated_symbol ] = OmigaInscriptionInfo . where ( symbol : info [ :symbol ] . strip ) . exists?
589+ attrs [ :is_repeated_symbol ] = OmigaInscriptionInfo . where ( symbol : CkbUtils . sanitize_string ( info [ :symbol ] ) ) . exists?
588590 end
589591 OmigaInscriptionInfo . upsert ( attrs , unique_by : :udt_hash )
590592 [ info [ :udt_hash ] , "omiga_inscription" ]
@@ -598,8 +600,8 @@ def build_udts!(local_block, outputs, outputs_data)
598600 end
599601
600602 unless Udt . where ( type_hash :) . exists?
601- nft_token_attr = { full_name : nil , icon_file : nil ,
602- published : false , symbol : nil , decimal : nil , nrc_factory_cell_id : nil }
603+ nft_token_attr = { full_name : "" , icon_file : "" ,
604+ published : false , symbol : "" , decimal : nil , nrc_factory_cell_id : nil }
603605 issuer_address = CkbUtils . generate_address ( output . lock , CKB ::Address ::Version ::CKB2021 )
604606 case cell_type
605607 when "m_nft_token"
@@ -610,15 +612,15 @@ def build_udts!(local_block, outputs, outputs_data)
610612 parsed_class_data = CkbUtils . parse_token_class_data ( m_nft_class_cell . data )
611613 TokenCollection . find_or_create_by (
612614 standard : "m_nft" ,
613- name : parsed_class_data . name ,
615+ name : CkbUtils . sanitize_string ( parsed_class_data . name ) ,
614616 cell_id : m_nft_class_cell . id ,
615617 block_timestamp : m_nft_class_cell . block_timestamp ,
616- icon_url : parsed_class_data . renderer ,
618+ icon_url : CkbUtils . sanitize_string ( parsed_class_data . renderer ) ,
617619 creator_id : m_nft_class_cell . address_id ,
618620 )
619621
620- nft_token_attr [ :full_name ] = parsed_class_data . name
621- nft_token_attr [ :icon_file ] = parsed_class_data . renderer
622+ nft_token_attr [ :full_name ] = CkbUtils . sanitize_string ( parsed_class_data . name )
623+ nft_token_attr [ :icon_file ] = CkbUtils . sanitize_string ( parsed_class_data . renderer )
622624 nft_token_attr [ :published ] = true
623625 end
624626 when "spore_cell" , "did_cell"
@@ -630,7 +632,7 @@ def build_udts!(local_block, outputs, outputs_data)
630632 if spore_cluster_type_ids . present?
631633 spore_cluster_cell = CellOutput . where ( type_script_id : spore_cluster_type_ids , status : %i[ pending live ] ) . last
632634 parsed_cluster_data = CkbUtils . parse_spore_cluster_data ( spore_cluster_cell . data )
633- nft_token_attr [ :full_name ] = parsed_cluster_data [ :name ]
635+ nft_token_attr [ :full_name ] = CkbUtils . sanitize_string ( parsed_cluster_data [ :name ] . to_s )
634636 end
635637 end
636638 when "nrc_721_token"
@@ -648,8 +650,8 @@ def build_udts!(local_block, outputs, outputs_data)
648650 nft_token_attr [ :published ] = true
649651 when "omiga_inscription_info"
650652 info = CkbUtils . parse_omiga_inscription_info ( outputs_data [ tx_index ] [ index ] )
651- nft_token_attr [ :full_name ] = info [ :name ]
652- nft_token_attr [ :symbol ] = info [ :symbol ]
653+ nft_token_attr [ :full_name ] = CkbUtils . sanitize_string ( info [ :name ] )
654+ nft_token_attr [ :symbol ] = CkbUtils . sanitize_string ( info [ :symbol ] )
653655 nft_token_attr [ :decimal ] = info [ :decimal ]
654656 nft_token_attr [ :published ] = true
655657 when "xudt" , "xudt_compatible"
@@ -659,8 +661,8 @@ def build_udts!(local_block, outputs, outputs_data)
659661 items . each_with_index do |output , index |
660662 if output . type &.code_hash == CkbSync ::Api . instance . unique_cell_code_hash
661663 info = CkbUtils . parse_unique_cell ( outputs_data [ tx_index ] [ index ] )
662- nft_token_attr [ :full_name ] = info [ :name ]
663- nft_token_attr [ :symbol ] = info [ :symbol ]
664+ nft_token_attr [ :full_name ] = CkbUtils . sanitize_string ( info [ :name ] )
665+ nft_token_attr [ :symbol ] = CkbUtils . sanitize_string ( info [ :symbol ] )
664666 nft_token_attr [ :decimal ] = info [ :decimal ]
665667 nft_token_attr [ :published ] = true
666668 end
@@ -724,7 +726,7 @@ def update_ckb_txs_rel_and_fee(
724726 0
725727 else
726728 CkbUtils . ckb_transaction_fee ( tx , input_capacities [ tx_index ] ,
727- output_capacities [ tx_index ] )
729+ output_capacities [ tx_index ] , @tx_previous_outputs [ tx_id ] || [ ] )
728730 end ,
729731 created_at : tx [ "created_at" ] ,
730732 updated_at : Time . current ,
@@ -876,9 +878,11 @@ def build_addresses!(outputs, local_block)
876878 script_hash = item . lock . compute_hash
877879 key = "lock_script_hash_#{ script_hash } "
878880 lock_script_id = Rails . cache . read ( key ) || LockScript . find_by ( script_hash : script_hash ) &.id
879- unless Rails . cache . exist? ( "address_lock_hash_#{ script_hash } " )
881+ address_redis_key = "address_lock_hash_#{ script_hash } "
882+ unless Rails . cache . exist? ( address_redis_key )
880883 address = Address . find_or_create_address ( item . lock , local_block . timestamp , lock_script_id )
881- Rails . cache . write ( "address_lock_hash_#{ script_hash } " , address . id )
884+ Rails . cache . write ( address_redis_key , address . id )
885+ @redis_keys << address_redis_key
882886 end
883887 end
884888 end
@@ -895,6 +899,7 @@ def build_scripts(outputs)
895899 unless Rails . cache . exist? ( key )
896900 if lock_script = LockScript . find_by ( script_hash : script_hash )
897901 Rails . cache . write ( key , lock_script . id )
902+ @redis_keys << key
898903 else
899904 locks_attributes << script_attributes ( output . lock , script_hash )
900905 end
@@ -906,6 +911,7 @@ def build_scripts(outputs)
906911 unless Rails . cache . exist? ( key )
907912 if type_script = TypeScript . find_by ( script_hash : script_hash )
908913 Rails . cache . write ( key , type_script . id )
914+ @redis_keys << key
909915 else
910916 types_attributes << script_attributes ( output . type , script_hash )
911917 end
@@ -1028,10 +1034,18 @@ def build_cell_outputs!(
10281034 end
10291035 items . each do |item |
10301036 lock_script_hash = item . lock . compute_hash
1031- address_id = Rails . cache . read ( "address_lock_hash_#{ lock_script_hash } " )
1037+ address_key = "address_lock_hash_#{ lock_script_hash } "
1038+ address_id = Rails . cache . read ( address_key )
10321039 unless address_id
10331040 address_id = Address . find_by ( lock_hash : lock_script_hash ) &.id
1034- Rails . cache . write ( "address_lock_hash_#{ lock_script_hash } " , address_id ) if address_id
1041+ unless address_id
1042+ lock_script_id = Rails . cache . read ( "lock_script_hash_#{ lock_script_hash } " ) || LockScript . find_by ( script_hash : lock_script_hash ) &.id
1043+ address_id = Address . find_or_create_address ( item . lock , local_block . timestamp , lock_script_id ) . id
1044+ end
1045+ if address
1046+ Rails . cache . write ( address_key , address_id )
1047+ @redis_keys << key
1048+ end
10351049 end
10361050 cell_data = node_block . transactions [ tx_index ] . outputs_data [ cell_index ]
10371051 change_rec = addrs_changes [ address_id ]
@@ -1190,9 +1204,12 @@ def cell_input_attributes(input, ckb_transaction_id, local_block_id,
11901204 }
11911205 else
11921206 # previous_output = prev_outputs["#{input.previous_output.tx_hash}-#{input.previous_output.index}"]
1193- previous_output = CellOutput . find_by tx_hash : input . previous_output . tx_hash ,
1207+ previous_output = CellOutput . live . find_by tx_hash : input . previous_output . tx_hash ,
11941208 cell_index : input . previous_output . index
11951209
1210+ @tx_previous_outputs [ ckb_transaction_id ] = [ ] if @tx_previous_outputs [ ckb_transaction_id ] == nil
1211+ @tx_previous_outputs [ ckb_transaction_id ] << previous_output
1212+
11961213 {
11971214 cell_input : {
11981215 ckb_transaction_id :,
@@ -1214,7 +1231,7 @@ def cell_input_attributes(input, ckb_transaction_id, local_block_id,
12141231 cell_index : input . previous_output . index ,
12151232 status : "dead" ,
12161233 consumed_by_id : ckb_transaction_id ,
1217- consumed_block_timestamp : CkbTransaction . find ( ckb_transaction_id ) . block_timestamp ,
1234+ consumed_block_timestamp : @local_block . timestamp ,
12181235 } ,
12191236 capacity : previous_output . capacity ,
12201237 type_hash : previous_output . type_hash ,
@@ -1248,10 +1265,10 @@ def build_ckb_transactions!(node_block, local_block, inputs, outputs, outputs_da
12481265 # First update status thus we can use upsert later. otherwise, we may not be able to
12491266 # locate correct record according to tx_hash
12501267 binary_hashes = CkbUtils . hexes_to_bins_sql ( hashes )
1251- pending_txs = CkbTransaction . where ( "tx_hash IN (#{ binary_hashes } )" ) . where ( tx_status : :pending ) . pluck (
1268+ pending_txs = CkbTransaction . where ( tx_status : :pending ) . where ( "tx_hash IN (#{ binary_hashes } )" ) . pluck (
12521269 :tx_hash , :confirmation_time
12531270 )
1254- CkbTransaction . where ( "tx_hash IN (#{ binary_hashes } ) AND tx_status = 0 " ) . update_all tx_status : "committed"
1271+ CkbTransaction . where ( tx_status : :pending ) . where ( "tx_hash IN (#{ binary_hashes } )" ) . update_all tx_status : "committed" if pending_txs . size > 0
12551272 txs = [ ]
12561273 ckb_transactions_attributes . each_slice ( 500 ) do |batch |
12571274 txs . concat CkbTransaction . upsert_all ( batch , unique_by : %i[ tx_status tx_hash ] ,
@@ -1477,10 +1494,12 @@ def generate_address_in_advance(cellbase, block_timestamp)
14771494 script_hash : script_hash
14781495 ) . id
14791496 Rails . cache . write ( key , lock_script_id )
1497+ @redis_keys << key
14801498 end
14811499 unless Rails . cache . exist? ( "address_lock_hash_#{ script_hash } " )
14821500 address = Address . find_or_create_address ( lock_script , block_timestamp , lock_script_id )
14831501 Rails . cache . write ( "address_lock_hash_#{ script_hash } " , address . id )
1502+ @redis_keys << "address_lock_hash_#{ script_hash } "
14841503 end
14851504 end
14861505
@@ -1502,10 +1521,10 @@ def update_nrc_factory_cell_info(type_script, output_data)
15021521 )
15031522 parsed_factory_data = CkbUtils . parse_nrc_721_factory_data ( output_data )
15041523 factory_cell . update (
1505- name : parsed_factory_data . name ,
1506- symbol : parsed_factory_data . symbol ,
1507- base_token_uri : parsed_factory_data . base_token_uri ,
1508- extra_data : parsed_factory_data . extra_data ,
1524+ name : CkbUtils . sanitize_string ( parsed_factory_data . name ) ,
1525+ symbol : CkbUtils . sanitize_string ( parsed_factory_data . symbol ) ,
1526+ base_token_uri : CkbUtils . sanitize_string ( parsed_factory_data . base_token_uri ) ,
1527+ extra_data : CkbUtils . sanitize_string ( parsed_factory_data . extra_data ) ,
15091528 )
15101529 end
15111530
0 commit comments