@@ -11,12 +11,12 @@ import (
11
11
)
12
12
13
13
const protocol = "tcp"
14
- const dnsNodeID = "3000"
15
14
const nodeVersion = 1
16
15
const commandLength = 12
17
16
18
17
var nodeAddress string
19
- var knownNodes []string
18
+ var knownNodes = []string {"localhost:3000" }
19
+ var blocksInTransit = [][]byte {}
20
20
21
21
type addr struct {
22
22
AddrList []string
@@ -43,13 +43,10 @@ type inv struct {
43
43
Items [][]byte
44
44
}
45
45
46
- type verack struct {
47
- }
48
-
49
46
type verzion struct {
50
- Version int
51
-
52
- AddrFrom string
47
+ Version int
48
+ BestHeight int
49
+ AddrFrom string
53
50
}
54
51
55
52
func commandToBytes (command string ) []byte {
@@ -136,22 +133,15 @@ func sendGetData(address, kind string, id []byte) {
136
133
sendData (address , request )
137
134
}
138
135
139
- func sendVersion (addr string ) {
140
- payload := gobEncode (verzion {nodeVersion , nodeAddress })
136
+ func sendVersion (addr string , bc * Blockchain ) {
137
+ bestHeight := bc .GetBestHeight ()
138
+ payload := gobEncode (verzion {nodeVersion , bestHeight , nodeAddress })
141
139
142
140
request := append (commandToBytes ("version" ), payload ... )
143
141
144
142
sendData (addr , request )
145
143
}
146
144
147
- func sendVrack (addr string ) {
148
- payload := gobEncode (verack {})
149
-
150
- request := append (commandToBytes ("verack" ), payload ... )
151
-
152
- sendData (addr , request )
153
- }
154
-
155
145
func handleAddr (request []byte ) {
156
146
var buff bytes.Buffer
157
147
var payload addr
@@ -184,6 +174,16 @@ func handleBlock(request []byte, bc *Blockchain) {
184
174
185
175
fmt .Println ("Recevied a new block!" )
186
176
bc .AddBlock (block )
177
+ fmt .Printf ("Added block %x\n " , block .Hash )
178
+ fmt .Printf ("Added block %d\n " , block .Height )
179
+
180
+ fmt .Println (blocksInTransit )
181
+ if len (blocksInTransit ) > 0 {
182
+ blockHash := blocksInTransit [0 ]
183
+ sendGetData (payload .AddrFrom , "block" , blockHash )
184
+
185
+ blocksInTransit = blocksInTransit [1 :]
186
+ }
187
187
}
188
188
189
189
func handleInv (request []byte , bc * Blockchain ) {
@@ -198,12 +198,20 @@ func handleInv(request []byte, bc *Blockchain) {
198
198
}
199
199
200
200
fmt .Printf ("Recevied inventory with %d %s\n " , len (payload .Items ), payload .Type )
201
- blocks := bc .GetBlockHashes ()
202
201
203
- if len (blocks ) < len (payload .Items ) {
204
- for _ , blockHash := range payload .Items {
205
- sendGetData (payload .AddrFrom , "block" , blockHash )
202
+ if payload .Type == "blocks" {
203
+ blocksInTransit = payload .Items
204
+
205
+ blockHash := payload .Items [0 ]
206
+ sendGetData (payload .AddrFrom , "block" , blockHash )
207
+
208
+ newInTransit := [][]byte {}
209
+ for _ , b := range blocksInTransit {
210
+ if bytes .Compare (b , blockHash ) != 0 {
211
+ newInTransit = append (newInTransit , b )
212
+ }
206
213
}
214
+ blocksInTransit = newInTransit
207
215
}
208
216
}
209
217
@@ -243,7 +251,7 @@ func handleGetData(request []byte, bc *Blockchain) {
243
251
}
244
252
}
245
253
246
- func handleVersion (request []byte ) {
254
+ func handleVersion (request []byte , bc * Blockchain ) {
247
255
var buff bytes.Buffer
248
256
var payload verzion
249
257
@@ -254,9 +262,19 @@ func handleVersion(request []byte) {
254
262
log .Panic (err )
255
263
}
256
264
257
- sendVrack (payload .AddrFrom )
258
- sendAddr (payload .AddrFrom )
259
- knownNodes = append (knownNodes , payload .AddrFrom )
265
+ myBestHeight := bc .GetBestHeight ()
266
+ foreignerBestHeight := payload .BestHeight
267
+
268
+ if myBestHeight < foreignerBestHeight {
269
+ sendGetBlocks (payload .AddrFrom )
270
+ } else {
271
+ sendVersion (payload .AddrFrom , bc )
272
+ }
273
+
274
+ // sendAddr(payload.AddrFrom)
275
+ if ! nodeIsKnown (payload .AddrFrom ) {
276
+ knownNodes = append (knownNodes , payload .AddrFrom )
277
+ }
260
278
}
261
279
262
280
func handleConnection (conn net.Conn , bc * Blockchain ) {
@@ -279,9 +297,7 @@ func handleConnection(conn net.Conn, bc *Blockchain) {
279
297
case "getdata" :
280
298
handleGetData (request , bc )
281
299
case "version" :
282
- handleVersion (request )
283
- case "verack" :
284
- //
300
+ handleVersion (request , bc )
285
301
default :
286
302
fmt .Println ("Unknown command!" )
287
303
}
@@ -298,12 +314,12 @@ func StartServer(nodeID string) {
298
314
}
299
315
defer ln .Close ()
300
316
301
- if nodeID != dnsNodeID {
302
- sendVersion (fmt .Sprintf ("localhost:%s" , dnsNodeID ))
303
- }
304
-
305
317
bc := NewBlockchain (nodeID )
306
318
319
+ if nodeAddress != knownNodes [0 ] {
320
+ sendVersion (knownNodes [0 ], bc )
321
+ }
322
+
307
323
for {
308
324
conn , err := ln .Accept ()
309
325
if err != nil {
@@ -324,3 +340,13 @@ func gobEncode(data interface{}) []byte {
324
340
325
341
return buff .Bytes ()
326
342
}
343
+
344
+ func nodeIsKnown (addr string ) bool {
345
+ for _ , node := range knownNodes {
346
+ if node == addr {
347
+ return true
348
+ }
349
+ }
350
+
351
+ return false
352
+ }
0 commit comments