Implement 'tx' command (WIP)
This commit is contained in:
parent
c753df287a
commit
3cb93b5278
13
cli_send.go
13
cli_send.go
|
@ -25,9 +25,16 @@ func (cli *CLI) send(from, to string, amount int, nodeID string) {
|
||||||
|
|
||||||
tx := NewUTXOTransaction(&wallet, to, amount, &UTXOSet)
|
tx := NewUTXOTransaction(&wallet, to, amount, &UTXOSet)
|
||||||
cbTx := NewCoinbaseTX(from, "")
|
cbTx := NewCoinbaseTX(from, "")
|
||||||
txs := []*Transaction{cbTx, tx}
|
// txs := []*Transaction{cbTx, tx}
|
||||||
|
|
||||||
newBlock := bc.MineBlock(txs)
|
// var txHashes [][]byte
|
||||||
UTXOSet.Update(newBlock)
|
// txHashes = append(txHashes, tx.Hash())
|
||||||
|
// txHashes = append(txHashes, cbTx.Hash())
|
||||||
|
|
||||||
|
sendTx(knownNodes[0], tx)
|
||||||
|
sendTx(knownNodes[0], cbTx)
|
||||||
|
|
||||||
|
// newBlock := bc.MineBlock(txs)
|
||||||
|
// UTXOSet.Update(newBlock)
|
||||||
fmt.Println("Success!")
|
fmt.Println("Success!")
|
||||||
}
|
}
|
||||||
|
|
70
server.go
70
server.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -17,6 +18,7 @@ const commandLength = 12
|
||||||
var nodeAddress string
|
var nodeAddress string
|
||||||
var knownNodes = []string{"localhost:3000"}
|
var knownNodes = []string{"localhost:3000"}
|
||||||
var blocksInTransit = [][]byte{}
|
var blocksInTransit = [][]byte{}
|
||||||
|
var mempool = make(map[string]Transaction)
|
||||||
|
|
||||||
type addr struct {
|
type addr struct {
|
||||||
AddrList []string
|
AddrList []string
|
||||||
|
@ -43,6 +45,11 @@ type inv struct {
|
||||||
Items [][]byte
|
Items [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tx struct {
|
||||||
|
AddFrom string
|
||||||
|
Transaction []byte
|
||||||
|
}
|
||||||
|
|
||||||
type verzion struct {
|
type verzion struct {
|
||||||
Version int
|
Version int
|
||||||
BestHeight int
|
BestHeight int
|
||||||
|
@ -133,6 +140,14 @@ func sendGetData(address, kind string, id []byte) {
|
||||||
sendData(address, request)
|
sendData(address, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendTx(addr string, tnx *Transaction) {
|
||||||
|
data := tx{nodeAddress, tnx.Serialize()}
|
||||||
|
payload := gobEncode(data)
|
||||||
|
request := append(commandToBytes("tx"), payload...)
|
||||||
|
|
||||||
|
sendData(addr, request)
|
||||||
|
}
|
||||||
|
|
||||||
func sendVersion(addr string, bc *Blockchain) {
|
func sendVersion(addr string, bc *Blockchain) {
|
||||||
bestHeight := bc.GetBestHeight()
|
bestHeight := bc.GetBestHeight()
|
||||||
payload := gobEncode(verzion{nodeVersion, bestHeight, nodeAddress})
|
payload := gobEncode(verzion{nodeVersion, bestHeight, nodeAddress})
|
||||||
|
@ -213,6 +228,14 @@ func handleInv(request []byte, bc *Blockchain) {
|
||||||
}
|
}
|
||||||
blocksInTransit = newInTransit
|
blocksInTransit = newInTransit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if payload.Type == "tx" {
|
||||||
|
txID := payload.Items[0]
|
||||||
|
|
||||||
|
if mempool[hex.EncodeToString(txID)].ID == nil {
|
||||||
|
sendGetData(payload.AddrFrom, "tx", txID)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleGetBlocks(request []byte, bc *Blockchain) {
|
func handleGetBlocks(request []byte, bc *Blockchain) {
|
||||||
|
@ -249,6 +272,51 @@ func handleGetData(request []byte, bc *Blockchain) {
|
||||||
|
|
||||||
sendBlock(payload.AddrFrom, &block)
|
sendBlock(payload.AddrFrom, &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if payload.Type == "tx" {
|
||||||
|
txID := hex.EncodeToString(payload.ID)
|
||||||
|
tx := mempool[txID]
|
||||||
|
|
||||||
|
sendTx(payload.AddrFrom, &tx)
|
||||||
|
// delete(mempool, txID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleTx(request []byte, bc *Blockchain) {
|
||||||
|
var buff bytes.Buffer
|
||||||
|
var payload tx
|
||||||
|
|
||||||
|
buff.Write(request[commandLength:])
|
||||||
|
dec := gob.NewDecoder(&buff)
|
||||||
|
err := dec.Decode(&payload)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txData := payload.Transaction
|
||||||
|
tx := DeserializeTransaction(txData)
|
||||||
|
mempool[hex.EncodeToString(tx.ID)] = tx
|
||||||
|
|
||||||
|
if nodeAddress == knownNodes[0] {
|
||||||
|
for _, node := range knownNodes {
|
||||||
|
if node != nodeAddress {
|
||||||
|
sendInv(node, "tx", [][]byte{tx.ID})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(mempool) >= 2 {
|
||||||
|
var txs []*Transaction
|
||||||
|
|
||||||
|
for _, tx := range mempool {
|
||||||
|
txs = append(txs, &tx)
|
||||||
|
}
|
||||||
|
newBlock := bc.MineBlock(txs)
|
||||||
|
UTXOSet := UTXOSet{bc}
|
||||||
|
UTXOSet.Update(newBlock)
|
||||||
|
|
||||||
|
mempool = make(map[string]Transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleVersion(request []byte, bc *Blockchain) {
|
func handleVersion(request []byte, bc *Blockchain) {
|
||||||
|
@ -296,6 +364,8 @@ func handleConnection(conn net.Conn, bc *Blockchain) {
|
||||||
handleGetBlocks(request, bc)
|
handleGetBlocks(request, bc)
|
||||||
case "getdata":
|
case "getdata":
|
||||||
handleGetData(request, bc)
|
handleGetData(request, bc)
|
||||||
|
case "tx":
|
||||||
|
handleTx(request, bc)
|
||||||
case "version":
|
case "version":
|
||||||
handleVersion(request, bc)
|
handleVersion(request, bc)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -228,3 +228,16 @@ func NewUTXOTransaction(wallet *Wallet, to string, amount int, UTXOSet *UTXOSet)
|
||||||
|
|
||||||
return &tx
|
return &tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeserializeTransaction deserializes a transaction
|
||||||
|
func DeserializeTransaction(data []byte) Transaction {
|
||||||
|
var transaction Transaction
|
||||||
|
|
||||||
|
decoder := gob.NewDecoder(bytes.NewReader(data))
|
||||||
|
err := decoder.Decode(&transaction)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return transaction
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue