The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/client/client.go

100 lines
2.8 KiB

package client
import (
"bytes"
"encoding/gob"
"fmt"
"harmony-benchmark/blockchain"
"harmony-benchmark/log"
"harmony-benchmark/p2p"
"sync"
)
// A client represent a entity/user which send transactions and receive responses from the harmony network
type Client struct {
PendingCrossTxs map[[32]byte]*blockchain.Transaction // map of TxId to pending cross shard txs
PendingCrossTxsMutex sync.Mutex
leaders *[]p2p.Peer
UpdateUtxoPool func(pool blockchain.UTXOPool) // func used to update utxo pool
UpdateUtxos func(txs []*blockchain.Transaction) // func used to update utxo pool with list of txs
log log.Logger // Log utility
}
func (client *Client) TransactionMessageHandler(msgPayload []byte) {
messageType := TransactionMessageType(msgPayload[0])
switch messageType {
case PROOF_OF_LOCK:
txDecoder := gob.NewDecoder(bytes.NewReader(msgPayload[1:])) // skip the PROOF_OF_LOCK messge type
proofList := new([]blockchain.CrossShardTxProof)
err := txDecoder.Decode(&proofList)
if err != nil {
client.log.Error("Failed deserializing cross transaction proof list")
}
txsToSend := []blockchain.Transaction{}
client.PendingCrossTxsMutex.Lock()
for _, proof := range *proofList {
txAndProofs, ok := client.PendingCrossTxs[proof.TxID]
readyToUnlock := true
if ok {
txAndProofs.Proofs = append(txAndProofs.Proofs, proof)
txInputs := make(map[blockchain.TXInput]bool)
for _, curProof := range txAndProofs.Proofs {
for _, txInput := range curProof.TxInput {
txInputs[txInput] = true
}
}
for _, txInput := range txAndProofs.TxInput {
val, ok := txInputs[txInput]
if !ok || !val {
readyToUnlock = false
}
}
} else {
readyToUnlock = false
}
if readyToUnlock {
txsToSend = append(txsToSend, *txAndProofs)
}
}
for _, txToSend := range txsToSend {
delete(client.PendingCrossTxs, txToSend.ID)
}
client.PendingCrossTxsMutex.Unlock()
if len(txsToSend) != 0 {
client.sendCrossShardTxUnlockMessage(&txsToSend)
tempList := []*blockchain.Transaction{}
for i, _ := range txsToSend {
tempList = append(tempList, &txsToSend[i])
}
client.UpdateUtxos(tempList)
}
}
}
func (client *Client) sendCrossShardTxUnlockMessage(txsToSend *[]blockchain.Transaction) {
// TODO: Send unlock message back to output shards
fmt.Println("SENDING UNLOCK MESSAGE")
//client.log.Debug("SENDING UNLOCK PROOFS TO LEADERS---", "txAndProof", (*txsToSend)[:10])
p2p.BroadcastMessage(*client.leaders, ConstructUnlockToCommitOrAbortMessage(*txsToSend))
}
// Create a new Node
func NewClient(leaders *[]p2p.Peer) *Client {
client := Client{}
client.PendingCrossTxs = make(map[[32]byte]*blockchain.Transaction)
client.leaders = leaders
// Logger
client.log = log.New()
return &client
}