@@ -927,6 +927,12 @@ func (bc *BlockChain) truncateAncient(head uint64) error {
927
927
return nil
928
928
}
929
929
930
+ // numberHash is just a container for a number and a hash, to represent a block
931
+ type numberHash struct {
932
+ number uint64
933
+ hash common.Hash
934
+ }
935
+
930
936
// InsertReceiptChain attempts to complete an already existing header chain with
931
937
// transaction and receipt data.
932
938
func (bc * BlockChain ) InsertReceiptChain (blockChain types.Blocks , receiptChain []types.Receipts , ancientLimit uint64 ) (int , error ) {
@@ -998,7 +1004,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
998
1004
}
999
1005
}
1000
1006
}()
1001
- var deleted types. Blocks
1007
+ var deleted [] * numberHash
1002
1008
for i , block := range blockChain {
1003
1009
// Short circuit insertion if shutting down or processing failed
1004
1010
if atomic .LoadInt32 (& bc .procInterrupt ) == 1 {
@@ -1033,12 +1039,40 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
1033
1039
1034
1040
// Always keep genesis block in active database.
1035
1041
if b .NumberU64 () != 0 {
1036
- deleted = append (deleted , b )
1042
+ deleted = append (deleted , & numberHash { b . NumberU64 (), b . Hash ()} )
1037
1043
}
1038
1044
if time .Since (logged ) > 8 * time .Second {
1039
1045
log .Info ("Migrating ancient blocks" , "count" , count , "elapsed" , common .PrettyDuration (time .Since (start )))
1040
1046
logged = time .Now ()
1041
1047
}
1048
+ // Don't collect too much in-memory, write it out every 100K blocks
1049
+ if len (deleted ) > 100000 {
1050
+
1051
+ // Sync the ancient store explicitly to ensure all data has been flushed to disk.
1052
+ if err := bc .db .Sync (); err != nil {
1053
+ return 0 , err
1054
+ }
1055
+ // Wipe out canonical block data.
1056
+ for _ , nh := range deleted {
1057
+ rawdb .DeleteBlockWithoutNumber (batch , nh .hash , nh .number )
1058
+ rawdb .DeleteCanonicalHash (batch , nh .number )
1059
+ }
1060
+ if err := batch .Write (); err != nil {
1061
+ return 0 , err
1062
+ }
1063
+ batch .Reset ()
1064
+ // Wipe out side chain too.
1065
+ for _ , nh := range deleted {
1066
+ for _ , hash := range rawdb .ReadAllHashes (bc .db , nh .number ) {
1067
+ rawdb .DeleteBlock (batch , hash , nh .number )
1068
+ }
1069
+ }
1070
+ if err := batch .Write (); err != nil {
1071
+ return 0 , err
1072
+ }
1073
+ batch .Reset ()
1074
+ deleted = deleted [0 :]
1075
+ }
1042
1076
}
1043
1077
if count > 0 {
1044
1078
log .Info ("Migrated ancient blocks" , "count" , count , "elapsed" , common .PrettyDuration (time .Since (start )))
@@ -1066,7 +1100,11 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
1066
1100
previous = nil // disable rollback explicitly
1067
1101
1068
1102
// Wipe out canonical block data.
1069
- for _ , block := range append (deleted , blockChain ... ) {
1103
+ for _ , nh := range deleted {
1104
+ rawdb .DeleteBlockWithoutNumber (batch , nh .hash , nh .number )
1105
+ rawdb .DeleteCanonicalHash (batch , nh .number )
1106
+ }
1107
+ for _ , block := range blockChain {
1070
1108
// Always keep genesis block in active database.
1071
1109
if block .NumberU64 () != 0 {
1072
1110
rawdb .DeleteBlockWithoutNumber (batch , block .Hash (), block .NumberU64 ())
@@ -1079,7 +1117,12 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
1079
1117
batch .Reset ()
1080
1118
1081
1119
// Wipe out side chain too.
1082
- for _ , block := range append (deleted , blockChain ... ) {
1120
+ for _ , nh := range deleted {
1121
+ for _ , hash := range rawdb .ReadAllHashes (bc .db , nh .number ) {
1122
+ rawdb .DeleteBlock (batch , hash , nh .number )
1123
+ }
1124
+ }
1125
+ for _ , block := range blockChain {
1083
1126
// Always keep genesis block in active database.
1084
1127
if block .NumberU64 () != 0 {
1085
1128
for _ , hash := range rawdb .ReadAllHashes (bc .db , block .NumberU64 ()) {
0 commit comments