Implement 'getblocks' command
This commit is contained in:
parent
0c59d8cd52
commit
9adb5fc139
|
@ -169,6 +169,24 @@ func (bc *Blockchain) Iterator() *BlockchainIterator {
|
||||||
return bci
|
return bci
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlockHashes returns a list of hashes of all the blocks in the chain
|
||||||
|
func (bc *Blockchain) GetBlockHashes() [][]byte {
|
||||||
|
var blocks [][]byte
|
||||||
|
bci := bc.Iterator()
|
||||||
|
|
||||||
|
for {
|
||||||
|
block := bci.Next()
|
||||||
|
|
||||||
|
blocks = append(blocks, block.Hash)
|
||||||
|
|
||||||
|
if len(block.PrevBlockHash) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks
|
||||||
|
}
|
||||||
|
|
||||||
// MineBlock mines a new block with the provided transactions
|
// MineBlock mines a new block with the provided transactions
|
||||||
func (bc *Blockchain) MineBlock(transactions []*Transaction) *Block {
|
func (bc *Blockchain) MineBlock(transactions []*Transaction) *Block {
|
||||||
var lastHash []byte
|
var lastHash []byte
|
||||||
|
|
64
server.go
64
server.go
|
@ -22,6 +22,15 @@ type addr struct {
|
||||||
AddrList []string
|
AddrList []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type getblocks struct {
|
||||||
|
AddrFrom string
|
||||||
|
}
|
||||||
|
|
||||||
|
type inv struct {
|
||||||
|
Type string
|
||||||
|
Items [][]byte
|
||||||
|
}
|
||||||
|
|
||||||
type verack struct {
|
type verack struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +66,12 @@ func extractCommand(request []byte) []byte {
|
||||||
return request[:commandLength]
|
return request[:commandLength]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func requestBlocks() {
|
||||||
|
for _, node := range knownNodes {
|
||||||
|
sendGetBlocks(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func sendAddr(address string) {
|
func sendAddr(address string) {
|
||||||
nodes := addr{knownNodes}
|
nodes := addr{knownNodes}
|
||||||
nodes.AddrList = append(nodes.AddrList, nodeAddress)
|
nodes.AddrList = append(nodes.AddrList, nodeAddress)
|
||||||
|
@ -79,6 +94,21 @@ func sendData(addr string, data []byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendInv(address, kind string, items [][]byte) {
|
||||||
|
inventory := inv{kind, items}
|
||||||
|
payload := gobEncode(inventory)
|
||||||
|
request := append(commandToBytes("inv"), payload...)
|
||||||
|
|
||||||
|
sendData(address, request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendGetBlocks(address string) {
|
||||||
|
payload := gobEncode(getblocks{nodeAddress})
|
||||||
|
request := append(commandToBytes("getblocks"), payload...)
|
||||||
|
|
||||||
|
sendData(address, request)
|
||||||
|
}
|
||||||
|
|
||||||
func sendVersion(addr string) {
|
func sendVersion(addr string) {
|
||||||
payload := gobEncode(verzion{nodeVersion, nodeAddress})
|
payload := gobEncode(verzion{nodeVersion, nodeAddress})
|
||||||
|
|
||||||
|
@ -108,6 +138,36 @@ func handleAddr(request []byte) {
|
||||||
|
|
||||||
knownNodes = append(knownNodes, payload.AddrList...)
|
knownNodes = append(knownNodes, payload.AddrList...)
|
||||||
fmt.Printf("There are %d known nodes now!\n", len(knownNodes))
|
fmt.Printf("There are %d known nodes now!\n", len(knownNodes))
|
||||||
|
requestBlocks()
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleInv(request []byte) {
|
||||||
|
var buff bytes.Buffer
|
||||||
|
var payload inv
|
||||||
|
|
||||||
|
buff.Write(request[commandLength:])
|
||||||
|
dec := gob.NewDecoder(&buff)
|
||||||
|
err := dec.Decode(&payload)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Recevied %d %s\n", len(payload.Items), payload.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleGetBlocks(request []byte, bc *Blockchain) {
|
||||||
|
var buff bytes.Buffer
|
||||||
|
var payload getblocks
|
||||||
|
|
||||||
|
buff.Write(request[commandLength:])
|
||||||
|
dec := gob.NewDecoder(&buff)
|
||||||
|
err := dec.Decode(&payload)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks := bc.GetBlockHashes()
|
||||||
|
sendInv(payload.AddrFrom, "blocks", blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleVersion(request []byte) {
|
func handleVersion(request []byte) {
|
||||||
|
@ -137,6 +197,10 @@ func handleConnection(conn net.Conn, bc *Blockchain) {
|
||||||
switch command {
|
switch command {
|
||||||
case "addr":
|
case "addr":
|
||||||
handleAddr(request)
|
handleAddr(request)
|
||||||
|
case "inv":
|
||||||
|
handleInv(request)
|
||||||
|
case "getblocks":
|
||||||
|
handleGetBlocks(request, bc)
|
||||||
case "version":
|
case "version":
|
||||||
handleVersion(request)
|
handleVersion(request)
|
||||||
case "verack":
|
case "verack":
|
||||||
|
|
Loading…
Reference in New Issue