13.9 处理客户端接收到的数据
/Users/qinjianquan/publicChain/Part78-Net-Conn
使用goroutine并行处理请求
/Users/qinjianquan/publicChain/Part78-Net-Conn/src/Server.go
func StartServer(nodeID string, mineAddress string) {
--
for {
//receive data from client
conn, err1 := ln.Accept()
if err != nil {
log.Panic(err1)
}
go HandleConnection(conn)
}
}
func HandleConnection(conn net.Conn) {
//read data from client
request, err := ioutil.ReadAll(conn)
if err != nil {
log.Panic(err)
}
fmt.Printf("received a message:%s\n", request[:COMMANDLENGTH])
}
配置handle方法
func handleAddr(request []byte, bc *Blockchain) {}
func handleVersion(request []byte, bc *Blockchain) {}
func handleBlock(request []byte, bc *Blockchain) {}
func handleInv(request []byte, bc *Blockchain) {}
func handleGetblocks(request []byte, bc *Blockchain) {}
func handleTx(request []byte, bc *Blockchain) {}
func handleGetData(request []byte, bc *Blockchain) {}
配置常量
const COMMAND_VERSION = "version"
const COMMAND_ADDR = "addr"
const COMMAND_BLOCK = "block"
const COMMAND_INV = "inv"
const COMMAND_GETBLOCKS = "getblocks"
const COMMAND_GETDATA = "getdata"
const COMMAND_TX = "tx"
编写case
func HandleConnection(conn net.Conn) {
//read data from client
request, err := ioutil.ReadAll(conn)
if err != nil {
log.Panic(err)
}
command := bytesToCommand(request[:COMMANDLENGTH])
fmt.Printf("received %s command\n", command)
bc := BlockChainObject("test")
switch command {
case COMMAND_VERSION:
handleVersion(request, bc)
case COMMAND_ADDR:
handleAddr(request, bc)
case COMMAND_BLOCK:
handleBlock(request, bc)
case COMMAND_GETBLOCKS:
handleGetblocks(request, bc)
case COMMAND_GETDATA:
handleGetData(request, bc)
case COMMAND_INV:
handleInv(request, bc)
case COMMAND_TX:
handleTx(request, bc)
default:
fmt.Println("Unknown command!")
}
defer conn.Close()
}
func handleVersion(request []byte, bc *Blockchain) {
var buff bytes.Buffer
var payload Version
dataBytes := request[COMMANDLENGTH:]
buff.Write(dataBytes)
dec := gob.NewDecoder(&buff)
err := dec.Decode(&payload)
if err != nil {
log.Panic(err)
}
bestHeight := bc.GetBestHeight()
foreignerBestHeight := payload.BestHeight
if bestHeight > foreignerBestHeight {
SendVersion(payload.AddrFrom, bc)
} else if bestHeight < foreignerBestHeight {
SendGetBlocks(payload.AddrFrom)
}
}
13.10 GetBlocks
/Users/qinjianquan/publicChain/Part80-Net-sendGetBlocks/src/Server_getBlocks.go
type GetBlocks struct {
AddFrom string
}
这里涉及多case的处理,代码过程请参考github本项目:https://github.com/jianquanqin/publicChain
13.11 master node/wallet node/miner node interaction logic
本项目中,master node 端口号设置为了3000;wallet node 端口号为 3001;miner node 端口号为 3002
1.master node
创建wallet -> 创建创世区块 ->备份数据库为创世区块数据库
2.wallet node
继续备份数据库wallet node数据库 -> 创建4个钱包地址 ->切换到master node向不同地址转两笔账 -> wallet node 查询余额
此时wallet node数据库中只有1个区块,我们先启动master code,接着启动wallet node,让wallet node同步主节点的数据,同步结束后wallet node数据库中应该有三个区块,余额也应该能够正常查询
3.miner node
在miner node中创建wallet address ->拷贝创世区块数据库->启动miner node ->数据同步 ->切换到wallet node 进行转两笔账(tx会发送给master node)->master node 将inv发送给miner node ->miner node若无该数据,则会存储,只有数据量达到规定数目的时候,miner node才会打包区块
13.12 区块同步
创建主节点
cd /Users/qinjianquan/publicChain/Part84-Net-validation
go build -o bc main.go
export NODE_ID=3000
./bc createWallet
./bc createBlockChain -address
备份数据库
cp blockChain_3000.db blockChain_genesis.db
创建wallet node
打开一个新的终端
cd /Users/qinjianquan/publicChain/Part84-Net-validation
export NODE_ID=3001
备份数据库
cp blockChain_genesis.db blockChain_3001.db
创建四个钱包
./bc createWallet
./bc createWallet
./bc createWallet
./bc createWallet
查看钱包
./bc getAddressList
NODE_ID:3001
Address list:
19nkshsC71LkTWkqXHKSm6NsdzCwTaCy2r
122sTFRy9kxUFbvhHMkzENcfs52odyvHny
1G6bg8U2wiqXhyY3K9tKeJrTKGJz6UwisZ
1NTeiYo2b4J9wD6Wg6aujKoz1v4XeBprvj
在主节点中向wallet node中前两个钱包转账
./bc transfer -from '["18UmevN8CW6Fm2h5dt6DixbrXTH42VWDxE"]' -to '["19nkshsC71LkTWkqXHKSm6NsdzCwTaCy2r"]' -amount '["8"]' -mine
./bc transfer -from '["18UmevN8CW6Fm2h5dt6DixbrXTH42VWDxE"]' -to '["122sTFRy9kxUFbvhHMkzENcfs52odyvHny"]' -amount '["6"]' -mine
查看余额
./bc getBalance -address 18UmevN8CW6Fm2h5dt6DixbrXTH42VWDxE
./bc getBalance -address 19nkshsC71LkTWkqXHKSm6NsdzCwTaCy2r
./bc getBalance -address 122sTFRy9kxUFbvhHMkzENcfs52odyvHny
启动主节点
./bc startNode
启动wallet node
./bc startNode
./bc startNode
NODE_ID:3000
start the server, localhost:3000
received version command
version
the client sends message to the server...
received getBlocks command
getBlocks
the client sends message to the server...
received getData command
getData
the client sends message to the server...
received getData command
getData
the client sends message to the server...
received getData command
getData
the client sends message to the server...
./bc startNode
NODE_ID:3001
start the server, localhost:3001
the client sends message to the server...
received version command
version
the client sends message to the server...
received inv command
inv
the client sends message to the server...
received block command
block
the client sends message to the server...
received block command
block
此时关闭进程,重制数据库就可以查到余额了,这说明节点数据已经同步好了
122sTFRy9kxUFbvhHMkzENcfs52odyvHny has 6 token
qinjianquan@MacBook-Pro-10 Part84-Net-validation % ./bc getBalance -address 19nkshsC71LkTWkqXHKSm6NsdzCwTaCy2r
NODE_ID:3001
19nkshsC71LkTWkqXHKSm6NsdzCwTaCy2r has 8 token
qinjianquan@MacBook-Pro-10 Part84-Net-validation % ./bc getBalance -address 18UmevN8CW6Fm2h5dt6DixbrXTH42VWDxE
NODE_ID:3001
18UmevN8CW6Fm2h5dt6DixbrXTH42VWDxE has 16 token