1
1
package arsyncer
2
2
3
3
import (
4
+ "crypto/sha256"
4
5
"errors"
5
6
"fmt"
6
7
"github.com/everFinance/goar"
7
8
"github.com/everFinance/goar/types"
8
9
"github.com/everFinance/goar/utils"
10
+ "strings"
9
11
)
10
12
11
13
type BlockIdxs struct {
@@ -15,16 +17,24 @@ type BlockIdxs struct {
15
17
}
16
18
17
19
func GetBlockIdxs (startHeight int64 , arCli * goar.Client ) (* BlockIdxs , error ) {
18
- list , err := arCli .GetBlockHashList ()
20
+ info , err := arCli .GetInfo ()
19
21
if err != nil {
22
+ log .Error ("arCli.GetInfo()" , "err" , err )
20
23
return nil , err
21
24
}
22
- endHeight := int64 (len (list ) - 1 )
23
- if startHeight > endHeight {
24
- return nil , fmt .Errorf ("startHeight:%d must less than endHeight:%d" , startHeight , endHeight )
25
+ endHeight := info .Height
26
+
27
+ // get block hash_list from trust node
28
+ spiltList , err := GetBlockHashList (arCli , startHeight , endHeight )
29
+ if err != nil {
30
+ log .Error ("GetBlockHashList(arCli,startHeight,endHeight)" , "err" , err )
31
+ // get block hash_list from no-trust node
32
+ spiltList , err = GetBlockHashListFromPeers (arCli , startHeight , endHeight , 5 )
25
33
}
26
34
27
- spiltList := list [:endHeight - startHeight + 1 ]
35
+ if err != nil {
36
+ return nil , err
37
+ }
28
38
29
39
hashMap := make (map [string ]struct {})
30
40
for _ , h := range spiltList {
@@ -58,3 +68,70 @@ func (l *BlockIdxs) VerifyBlock(b types.Block) error {
58
68
}
59
69
return nil
60
70
}
71
+
72
+ func GetBlockHashList (arCli * goar.Client , startHeight , endHeight int64 ) ([]string , error ) {
73
+ list , err := arCli .GetBlockHashList ()
74
+ if err != nil {
75
+ return nil , err
76
+ }
77
+ curHeight := int64 (len (list ) - 1 )
78
+ if curHeight < endHeight {
79
+ return nil , fmt .Errorf ("curHeight must >= endHeight; curHeight:%d,endHeight:%d" , curHeight , endHeight )
80
+ }
81
+ spiltList := list [curHeight - endHeight : endHeight - startHeight + 1 ]
82
+ return spiltList , nil
83
+ }
84
+
85
+ func GetBlockHashListFromPeers (c * goar.Client , startHeight , endHeight int64 , checkNum int , peers ... string ) ([]string , error ) {
86
+ var err error
87
+ if len (peers ) == 0 {
88
+ peers , err = c .GetPeers ()
89
+ if err != nil {
90
+ return nil , err
91
+ }
92
+ }
93
+
94
+ checkSum := ""
95
+ successCount := 0
96
+ failedCount := 0
97
+ pNode := goar .NewTempConn ()
98
+ for _ , peer := range peers {
99
+ pNode .SetTempConnUrl ("http://" + peer )
100
+ hashList , err := pNode .GetBlockHashList ()
101
+ if err != nil {
102
+ log .Error ("pNode.GetBlockHashList()" , "err" , err )
103
+ continue
104
+ }
105
+ curHeight := int64 (len (hashList ) - 1 )
106
+ if curHeight < endHeight {
107
+ continue
108
+ }
109
+
110
+ spiltList := hashList [curHeight - endHeight : curHeight - startHeight + 1 ]
111
+ sum := strArrCheckSum (spiltList )
112
+ if checkSum == "" {
113
+ checkSum = sum
114
+ }
115
+
116
+ if checkSum == sum {
117
+ fmt .Printf ("success get block hash_list; peer: %s\n " , peer )
118
+ successCount ++
119
+ } else {
120
+ fmt .Printf ("failed get block hash_list, checksum failed; peer:%s\n " , peer )
121
+ failedCount ++
122
+ }
123
+
124
+ if successCount >= checkNum {
125
+ return spiltList , nil
126
+ }
127
+ if failedCount >= checkNum / 2 {
128
+ return nil , errors .New ("get hash_list from peers failed" )
129
+ }
130
+ }
131
+ return nil , errors .New ("get hash_list from peers failed" )
132
+ }
133
+
134
+ func strArrCheckSum (ss []string ) string {
135
+ hash := sha256 .Sum256 ([]byte (strings .Join (ss , "" )))
136
+ return string (hash [:])
137
+ }
0 commit comments