1
1
package block
2
2
3
3
import (
4
+ "bytes"
4
5
"crypto/ecdsa"
5
6
"crypto/sha256"
6
7
"encoding/json"
7
8
"fmt"
8
9
"goBlockchain/utils"
9
10
"log"
11
+ "net/http"
10
12
"strings"
11
13
"sync"
12
14
"time"
@@ -17,6 +19,12 @@ const (
17
19
MINING_SENDER = "THE BLOCKCHAIN"
18
20
MINING_REWARD = 1.0
19
21
MINING_TIMER_SEC = 20
22
+
23
+ BLOCKCHAIN_PORT_RANGE_START = 5000
24
+ BLOCKCHAIN_PORT_RANGE_END = 5003
25
+ NEIGHBOR_IP_RANGE_START = 0
26
+ NEIGHBOR_IP_RANGE_END = 1
27
+ BLOCKCHAIN_NEIGHBOR_SYNC_TIME_SEC = 20
20
28
)
21
29
22
30
type Block struct {
@@ -69,6 +77,8 @@ type Blockchain struct {
69
77
blockchainAddress string
70
78
port uint16
71
79
mux sync.Mutex
80
+ neighbors []string
81
+ muxNeighbors sync.Mutex
72
82
}
73
83
74
84
func NewBlockchain (blockchainAddress string , port uint16 ) * Blockchain {
@@ -80,10 +90,34 @@ func NewBlockchain(blockchainAddress string, port uint16) *Blockchain {
80
90
return bc
81
91
}
82
92
93
+ func (bc * Blockchain ) Run () {
94
+ bc .StartSyncNeighbors ()
95
+ }
96
+
97
+ func (bc * Blockchain ) SetNeighbors () {
98
+ bc .neighbors = utils .FindNeighbors (utils .GetHost (), bc .port , NEIGHBOR_IP_RANGE_START , NEIGHBOR_IP_RANGE_END , BLOCKCHAIN_PORT_RANGE_START , BLOCKCHAIN_PORT_RANGE_END )
99
+ log .Printf ("%v" , bc .neighbors )
100
+ }
101
+
102
+ func (bc * Blockchain ) SyncNeighbors () {
103
+ bc .muxNeighbors .Lock ()
104
+ defer bc .muxNeighbors .Unlock ()
105
+ bc .SetNeighbors ()
106
+ }
107
+
108
+ func (bc * Blockchain ) StartSyncNeighbors () {
109
+ bc .SyncNeighbors ()
110
+ _ = time .AfterFunc (time .Second * BLOCKCHAIN_NEIGHBOR_SYNC_TIME_SEC , bc .StartSyncNeighbors )
111
+ }
112
+
83
113
func (bc * Blockchain ) TransactionPool () []* Transaction {
84
114
return bc .transactionPool
85
115
}
86
116
117
+ func (bc * Blockchain ) ClearTransactionPool () {
118
+ bc .transactionPool = bc .transactionPool [:0 ]
119
+ }
120
+
87
121
func (bc * Blockchain ) MarshalJSON () ([]byte , error ) {
88
122
return json .Marshal (struct {
89
123
Blocks []* Block `json:"chains"`
@@ -96,6 +130,13 @@ func (bc *Blockchain) CreateBlock(nonce int, previousHash [32]byte) *Block {
96
130
b := NewBlock (nonce , previousHash , bc .transactionPool )
97
131
bc .chain = append (bc .chain , b )
98
132
bc .transactionPool = []* Transaction {}
133
+ for _ , n := range bc .neighbors {
134
+ endpoint := fmt .Sprintf ("http://%s/transactions" , n )
135
+ client := & http.Client {}
136
+ req , _ := http .NewRequest ("DELETE" , endpoint , nil )
137
+ resp , _ := client .Do (req )
138
+ log .Printf ("%v" , resp )
139
+ }
99
140
return b
100
141
}
101
142
@@ -115,6 +156,24 @@ func (bc *Blockchain) Print() {
115
156
func (bc * Blockchain ) CreateTransaction (sender string , recipient string , value float32 ,
116
157
senderPublicKey * ecdsa.PublicKey , s * utils.Signature ) bool {
117
158
isTransacted := bc .AddTransaction (sender , recipient , value , senderPublicKey , s )
159
+
160
+ if isTransacted {
161
+ for _ , n := range bc .neighbors {
162
+ publicKeyStr := fmt .Sprintf ("%064x%064x" , senderPublicKey .X .Bytes (), senderPublicKey .Y .Bytes ())
163
+ signatureStr := s .String ()
164
+ bt := & TransactionRequest {
165
+ & sender , & recipient , & publicKeyStr , & value , & signatureStr ,
166
+ }
167
+ m , _ := json .Marshal (bt )
168
+ buf := bytes .NewBuffer (m )
169
+ endpoint := fmt .Sprintf ("http://%s/transactions" , n )
170
+ client := & http.Client {}
171
+ req , _ := http .NewRequest ("PUT" , endpoint , buf )
172
+ resp , _ := client .Do (req )
173
+ log .Printf ("%v" , resp )
174
+ }
175
+ }
176
+
118
177
return isTransacted
119
178
}
120
179
0 commit comments