@@ -608,7 +608,8 @@ impl<Block: BlockT> Backend<Block> {
608
608
} ;
609
609
610
610
trace ! ( target: "db" , "Canonicalize block #{} ({:?})" , new_canonical, hash) ;
611
- let commit = self . storage . state_db . canonicalize_block ( & hash) ;
611
+ let commit = self . storage . state_db . canonicalize_block ( & hash)
612
+ . map_err ( |e : state_db:: Error < io:: Error > | client:: error:: Error :: from ( format ! ( "State database error: {:?}" , e) ) ) ?;
612
613
apply_state_commit ( transaction, commit) ;
613
614
} ;
614
615
@@ -641,7 +642,8 @@ impl<Block: BlockT> Backend<Block> {
641
642
let lookup_key = :: utils:: number_and_hash_to_lookup_key ( f_num, f_hash. clone ( ) ) ;
642
643
transaction. put ( columns:: META , meta_keys:: FINALIZED_BLOCK , & lookup_key) ;
643
644
644
- let commit = self . storage . state_db . canonicalize_block ( & f_hash) ;
645
+ let commit = self . storage . state_db . canonicalize_block ( & f_hash)
646
+ . map_err ( |e : state_db:: Error < io:: Error > | client:: error:: Error :: from ( format ! ( "State database error: {:?}" , e) ) ) ?;
645
647
apply_state_commit ( transaction, commit) ;
646
648
647
649
// read config from genesis, since it is readonly atm
@@ -654,67 +656,11 @@ impl<Block: BlockT> Backend<Block> {
654
656
655
657
Ok ( ( ) )
656
658
}
657
- }
658
-
659
- fn apply_state_commit ( transaction : & mut DBTransaction , commit : state_db:: CommitSet < H256 > ) {
660
- for ( key, val) in commit. data . inserted . into_iter ( ) {
661
- transaction. put ( columns:: STATE , & key[ ..] , & val) ;
662
- }
663
- for key in commit. data . deleted . into_iter ( ) {
664
- transaction. delete ( columns:: STATE , & key[ ..] ) ;
665
- }
666
- for ( key, val) in commit. meta . inserted . into_iter ( ) {
667
- transaction. put ( columns:: STATE_META , & key[ ..] , & val) ;
668
- }
669
- for key in commit. meta . deleted . into_iter ( ) {
670
- transaction. delete ( columns:: STATE_META , & key[ ..] ) ;
671
- }
672
- }
673
-
674
- impl < Block > client:: backend:: AuxStore for Backend < Block > where Block : BlockT < Hash =H256 > {
675
- fn insert_aux <
676
- ' a ,
677
- ' b : ' a ,
678
- ' c : ' a ,
679
- I : IntoIterator < Item =& ' a ( & ' c [ u8 ] , & ' c [ u8 ] ) > ,
680
- D : IntoIterator < Item =& ' a & ' b [ u8 ] > ,
681
- > ( & self , insert : I , delete : D ) -> client:: error:: Result < ( ) > {
682
- let mut transaction = DBTransaction :: new ( ) ;
683
- for ( k, v) in insert {
684
- transaction. put ( columns:: AUX , k, v) ;
685
- }
686
- for k in delete {
687
- transaction. delete ( columns:: AUX , k) ;
688
- }
689
- self . storage . db . write ( transaction) . map_err ( db_err) ?;
690
- Ok ( ( ) )
691
- }
692
-
693
- fn get_aux ( & self , key : & [ u8 ] ) -> Result < Option < Vec < u8 > > , client:: error:: Error > {
694
- Ok ( self . storage . db . get ( columns:: AUX , key) . map ( |r| r. map ( |v| v. to_vec ( ) ) ) . map_err ( db_err) ?)
695
- }
696
- }
697
-
698
- impl < Block > client:: backend:: Backend < Block , Blake2Hasher > for Backend < Block > where Block : BlockT < Hash =H256 > {
699
- type BlockImportOperation = BlockImportOperation < Block , Blake2Hasher > ;
700
- type Blockchain = BlockchainDb < Block > ;
701
- type State = CachingState < Blake2Hasher , DbState , Block > ;
702
- type ChangesTrieStorage = DbChangesTrieStorage < Block > ;
703
659
704
- fn begin_operation ( & self , block : BlockId < Block > ) -> Result < Self :: BlockImportOperation , client:: error:: Error > {
705
- let state = self . state_at ( block) ?;
706
- Ok ( BlockImportOperation {
707
- pending_block : None ,
708
- old_state : state,
709
- db_updates : MemoryDB :: default ( ) ,
710
- storage_updates : Default :: default ( ) ,
711
- changes_trie_updates : MemoryDB :: default ( ) ,
712
- aux_ops : Vec :: new ( ) ,
713
- } )
714
- }
715
-
716
- fn commit_operation ( & self , mut operation : Self :: BlockImportOperation )
660
+ fn try_commit_operation ( & self , mut operation : BlockImportOperation < Block , Blake2Hasher > )
717
661
-> Result < ( ) , client:: error:: Error >
662
+ where
663
+ Block : BlockT < Hash =H256 > ,
718
664
{
719
665
let mut transaction = DBTransaction :: new ( ) ;
720
666
operation. apply_aux ( & mut transaction) ;
@@ -747,7 +693,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
747
693
retracted. push ( r. hash . clone ( ) ) ;
748
694
if r. hash == meta. finalized_hash {
749
695
warn ! ( "Potential safety failure: reverting finalized block {:?}" ,
750
- ( & r. number, & r. hash) ) ;
696
+ ( & r. number, & r. hash) ) ;
751
697
752
698
return Err ( :: client:: error:: ErrorKind :: NotInFinalizedChain . into ( ) ) ;
753
699
}
@@ -812,22 +758,27 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
812
758
let commit = self . storage . state_db . insert_block ( & hash, number_u64, & pending_block. header . parent_hash ( ) , changeset)
813
759
. map_err ( |e : state_db:: Error < io:: Error > | client:: error:: Error :: from ( format ! ( "State database error: {:?}" , e) ) ) ?;
814
760
apply_state_commit ( & mut transaction, commit) ;
815
- self . changes_tries_storage . commit ( & mut transaction, operation. changes_trie_updates ) ;
816
761
817
762
let finalized = match pending_block. leaf_state {
818
763
NewBlockState :: Final => true ,
819
764
_ => false ,
820
765
} ;
821
766
767
+ let header = & pending_block. header ;
768
+ let is_best = pending_block. leaf_state . is_best ( ) ;
769
+ let changes_trie_updates = operation. changes_trie_updates ;
770
+
771
+
772
+ self . changes_tries_storage . commit ( & mut transaction, changes_trie_updates) ;
773
+
822
774
if finalized {
823
775
// TODO: ensure best chain contains this block.
824
776
self . note_finalized ( & mut transaction, & pending_block. header , hash) ?;
825
777
} else {
826
778
// canonicalize blocks which are old enough, regardless of finality.
827
- self . force_delayed_canonicalize ( & mut transaction, hash, * pending_block . header . number ( ) ) ?
779
+ self . force_delayed_canonicalize ( & mut transaction, hash, * header. number ( ) ) ?
828
780
}
829
781
830
- let is_best = pending_block. leaf_state . is_best ( ) ;
831
782
debug ! ( target: "db" , "DB Commit {:?} ({}), best = {}" , hash, number, is_best) ;
832
783
833
784
{
@@ -849,7 +800,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
849
800
self . blockchain . update_meta (
850
801
hash. clone ( ) ,
851
802
number. clone ( ) ,
852
- pending_block . leaf_state . is_best ( ) ,
803
+ is_best,
853
804
finalized,
854
805
) ;
855
806
@@ -865,31 +816,114 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
865
816
}
866
817
Ok ( ( ) )
867
818
}
819
+ }
820
+
821
+ fn apply_state_commit ( transaction : & mut DBTransaction , commit : state_db:: CommitSet < H256 > ) {
822
+ for ( key, val) in commit. data . inserted . into_iter ( ) {
823
+ transaction. put ( columns:: STATE , & key[ ..] , & val) ;
824
+ }
825
+ for key in commit. data . deleted . into_iter ( ) {
826
+ transaction. delete ( columns:: STATE , & key[ ..] ) ;
827
+ }
828
+ for ( key, val) in commit. meta . inserted . into_iter ( ) {
829
+ transaction. put ( columns:: STATE_META , & key[ ..] , & val) ;
830
+ }
831
+ for key in commit. meta . deleted . into_iter ( ) {
832
+ transaction. delete ( columns:: STATE_META , & key[ ..] ) ;
833
+ }
834
+ }
835
+
836
+ impl < Block > client:: backend:: AuxStore for Backend < Block > where Block : BlockT < Hash =H256 > {
837
+ fn insert_aux <
838
+ ' a ,
839
+ ' b : ' a ,
840
+ ' c : ' a ,
841
+ I : IntoIterator < Item =& ' a ( & ' c [ u8 ] , & ' c [ u8 ] ) > ,
842
+ D : IntoIterator < Item =& ' a & ' b [ u8 ] > ,
843
+ > ( & self , insert : I , delete : D ) -> client:: error:: Result < ( ) > {
844
+ let mut transaction = DBTransaction :: new ( ) ;
845
+ for ( k, v) in insert {
846
+ transaction. put ( columns:: AUX , k, v) ;
847
+ }
848
+ for k in delete {
849
+ transaction. delete ( columns:: AUX , k) ;
850
+ }
851
+ self . storage . db . write ( transaction) . map_err ( db_err) ?;
852
+ Ok ( ( ) )
853
+ }
854
+
855
+ fn get_aux ( & self , key : & [ u8 ] ) -> Result < Option < Vec < u8 > > , client:: error:: Error > {
856
+ Ok ( self . storage . db . get ( columns:: AUX , key) . map ( |r| r. map ( |v| v. to_vec ( ) ) ) . map_err ( db_err) ?)
857
+ }
858
+ }
859
+
860
+ impl < Block > client:: backend:: Backend < Block , Blake2Hasher > for Backend < Block > where Block : BlockT < Hash =H256 > {
861
+ type BlockImportOperation = BlockImportOperation < Block , Blake2Hasher > ;
862
+ type Blockchain = BlockchainDb < Block > ;
863
+ type State = CachingState < Blake2Hasher , DbState , Block > ;
864
+ type ChangesTrieStorage = DbChangesTrieStorage < Block > ;
865
+
866
+ fn begin_operation ( & self , block : BlockId < Block > ) -> Result < Self :: BlockImportOperation , client:: error:: Error > {
867
+ let state = self . state_at ( block) ?;
868
+ Ok ( BlockImportOperation {
869
+ pending_block : None ,
870
+ old_state : state,
871
+ db_updates : MemoryDB :: default ( ) ,
872
+ storage_updates : Default :: default ( ) ,
873
+ changes_trie_updates : MemoryDB :: default ( ) ,
874
+ aux_ops : Vec :: new ( ) ,
875
+ } )
876
+ }
877
+
878
+ fn commit_operation ( & self , operation : Self :: BlockImportOperation )
879
+ -> Result < ( ) , client:: error:: Error >
880
+ {
881
+ match self . try_commit_operation ( operation) {
882
+ Ok ( _) => {
883
+ self . storage . state_db . apply_pending ( ) ;
884
+ Ok ( ( ) )
885
+ } ,
886
+ e @ Err ( _) => {
887
+ self . storage . state_db . revert_pending ( ) ;
888
+ e
889
+ }
890
+ }
891
+ }
868
892
869
893
fn finalize_block ( & self , block : BlockId < Block > , justification : Option < Justification > )
870
894
-> Result < ( ) , client:: error:: Error >
871
895
{
872
896
use runtime_primitives:: traits:: Header ;
873
897
874
- if let Some ( header) = :: client:: blockchain:: HeaderBackend :: header ( & self . blockchain , block) ? {
875
- let mut transaction = DBTransaction :: new ( ) ;
876
- // TODO: ensure best chain contains this block.
877
- let hash = header. hash ( ) ;
878
- self . note_finalized ( & mut transaction, & header, hash. clone ( ) ) ?;
879
- if let Some ( justification) = justification {
880
- let number = header. number ( ) . clone ( ) ;
881
- transaction. put (
882
- columns:: JUSTIFICATION ,
883
- & :: utils:: number_and_hash_to_lookup_key ( number, hash. clone ( ) ) ,
884
- & justification. encode ( ) ,
885
- ) ;
898
+ let commit = || {
899
+ if let Some ( header) = :: client:: blockchain:: HeaderBackend :: header ( & self . blockchain , block) ? {
900
+ let mut transaction = DBTransaction :: new ( ) ;
901
+ // TODO: ensure best chain contains this block.
902
+ let hash = header. hash ( ) ;
903
+ self . note_finalized ( & mut transaction, & header, hash. clone ( ) ) ?;
904
+ if let Some ( justification) = justification {
905
+ let number = header. number ( ) . clone ( ) ;
906
+ transaction. put (
907
+ columns:: JUSTIFICATION ,
908
+ & :: utils:: number_and_hash_to_lookup_key ( number, hash. clone ( ) ) ,
909
+ & justification. encode ( ) ,
910
+ ) ;
911
+ }
912
+ self . storage . db . write ( transaction) . map_err ( db_err) ?;
913
+ self . blockchain . update_meta ( hash, header. number ( ) . clone ( ) , false , true ) ;
914
+ Ok ( ( ) )
915
+ } else {
916
+ Err ( client:: error:: ErrorKind :: UnknownBlock ( format ! ( "Cannot finalize block {:?}" , block) ) . into ( ) )
917
+ }
918
+ } ;
919
+ match commit ( ) {
920
+ Ok ( ( ) ) => self . storage . state_db . apply_pending ( ) ,
921
+ e @ Err ( _) => {
922
+ self . storage . state_db . revert_pending ( ) ;
923
+ return e;
886
924
}
887
- self . storage . db . write ( transaction) . map_err ( db_err) ?;
888
- self . blockchain . update_meta ( hash, header. number ( ) . clone ( ) , false , true ) ;
889
- Ok ( ( ) )
890
- } else {
891
- Err ( client:: error:: ErrorKind :: UnknownBlock ( format ! ( "Cannot finalize block {:?}" , block) ) . into ( ) )
892
925
}
926
+ Ok ( ( ) )
893
927
}
894
928
895
929
fn changes_trie_storage ( & self ) -> Option < & Self :: ChangesTrieStorage > {
0 commit comments