When a new block is mined, let everyone know

This commit is contained in:
Ivan Kuznetsov 2017-10-06 11:30:51 +07:00
parent 5c4340f47d
commit 64d1cc5569
2 changed files with 36 additions and 10 deletions

View File

@ -109,7 +109,18 @@ func sendBlock(addr string, b *Block) {
func sendData(addr string, data []byte) { func sendData(addr string, data []byte) {
conn, err := net.Dial(protocol, addr) conn, err := net.Dial(protocol, addr)
if err != nil { if err != nil {
log.Panic(err) fmt.Printf("%s is not available\n", addr)
var updatedNodes []string
for _, node := range knownNodes {
if node != addr {
updatedNodes = append(updatedNodes, node)
}
}
knownNodes = updatedNodes
return
} }
defer conn.Close() defer conn.Close()
@ -219,7 +230,7 @@ func handleInv(request []byte, bc *Blockchain) {
fmt.Printf("Recevied inventory with %d %s\n", len(payload.Items), payload.Type) fmt.Printf("Recevied inventory with %d %s\n", len(payload.Items), payload.Type)
if payload.Type == "blocks" { if payload.Type == "block" {
blocksInTransit = payload.Items blocksInTransit = payload.Items
blockHash := payload.Items[0] blockHash := payload.Items[0]
@ -255,7 +266,7 @@ func handleGetBlocks(request []byte, bc *Blockchain) {
} }
blocks := bc.GetBlockHashes() blocks := bc.GetBlockHashes()
sendInv(payload.AddrFrom, "blocks", blocks) sendInv(payload.AddrFrom, "block", blocks)
} }
func handleGetData(request []byte, bc *Blockchain) { func handleGetData(request []byte, bc *Blockchain) {
@ -319,6 +330,11 @@ func handleTx(request []byte, bc *Blockchain) {
} }
} }
if len(txs) == 0 {
fmt.Println("All transactions are invalid! Waiting for new ones...")
return
}
cbTx := NewCoinbaseTX(miningAddress, "") cbTx := NewCoinbaseTX(miningAddress, "")
txs = append(txs, cbTx) txs = append(txs, cbTx)
@ -326,10 +342,18 @@ func handleTx(request []byte, bc *Blockchain) {
UTXOSet := UTXOSet{bc} UTXOSet := UTXOSet{bc}
UTXOSet.Update(newBlock) UTXOSet.Update(newBlock)
fmt.Println("New block is mined!")
for _, tx := range txs { for _, tx := range txs {
txID := hex.EncodeToString(tx.ID) txID := hex.EncodeToString(tx.ID)
delete(mempool, txID) delete(mempool, txID)
} }
for _, node := range knownNodes {
if node != nodeAddress {
sendInv(node, "block", [][]byte{newBlock.Hash})
}
}
} }
} }
} }

View File

@ -7,12 +7,12 @@ import (
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"math/big" "math/big"
"strings"
"encoding/gob" "encoding/gob"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"log" "log"
"strings"
) )
const subsidy = 10 const subsidy = 10
@ -72,16 +72,17 @@ func (tx *Transaction) Sign(privKey ecdsa.PrivateKey, prevTXs map[string]Transac
prevTx := prevTXs[hex.EncodeToString(vin.Txid)] prevTx := prevTXs[hex.EncodeToString(vin.Txid)]
txCopy.Vin[inID].Signature = nil txCopy.Vin[inID].Signature = nil
txCopy.Vin[inID].PubKey = prevTx.Vout[vin.Vout].PubKeyHash txCopy.Vin[inID].PubKey = prevTx.Vout[vin.Vout].PubKeyHash
txCopy.ID = txCopy.Hash()
txCopy.Vin[inID].PubKey = nil
r, s, err := ecdsa.Sign(rand.Reader, &privKey, txCopy.ID) dataToSign := fmt.Sprintf("%x\n", txCopy)
r, s, err := ecdsa.Sign(rand.Reader, &privKey, []byte(dataToSign))
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
signature := append(r.Bytes(), s.Bytes()...) signature := append(r.Bytes(), s.Bytes()...)
tx.Vin[inID].Signature = signature tx.Vin[inID].Signature = signature
txCopy.Vin[inID].PubKey = nil
} }
} }
@ -146,8 +147,6 @@ func (tx *Transaction) Verify(prevTXs map[string]Transaction) bool {
prevTx := prevTXs[hex.EncodeToString(vin.Txid)] prevTx := prevTXs[hex.EncodeToString(vin.Txid)]
txCopy.Vin[inID].Signature = nil txCopy.Vin[inID].Signature = nil
txCopy.Vin[inID].PubKey = prevTx.Vout[vin.Vout].PubKeyHash txCopy.Vin[inID].PubKey = prevTx.Vout[vin.Vout].PubKeyHash
txCopy.ID = txCopy.Hash()
txCopy.Vin[inID].PubKey = nil
r := big.Int{} r := big.Int{}
s := big.Int{} s := big.Int{}
@ -161,10 +160,13 @@ func (tx *Transaction) Verify(prevTXs map[string]Transaction) bool {
x.SetBytes(vin.PubKey[:(keyLen / 2)]) x.SetBytes(vin.PubKey[:(keyLen / 2)])
y.SetBytes(vin.PubKey[(keyLen / 2):]) y.SetBytes(vin.PubKey[(keyLen / 2):])
dataToVerify := fmt.Sprintf("%x\n", txCopy)
rawPubKey := ecdsa.PublicKey{curve, &x, &y} rawPubKey := ecdsa.PublicKey{curve, &x, &y}
if ecdsa.Verify(&rawPubKey, txCopy.ID, &r, &s) == false { if ecdsa.Verify(&rawPubKey, []byte(dataToVerify), &r, &s) == false {
return false return false
} }
txCopy.Vin[inID].PubKey = nil
} }
return true return true