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/proto/node/node.go

182 lines
4.7 KiB

package node
import (
"bytes"
"encoding/gob"
"log"
"github.com/simple-rules/harmony-benchmark/blockchain"
"github.com/simple-rules/harmony-benchmark/p2p"
"github.com/simple-rules/harmony-benchmark/proto"
)
// The specific types of message under NODE category
type NodeMessageType byte
const (
TRANSACTION NodeMessageType = iota
BLOCK
CLIENT
CONTROL
BLOCKCHAIN_SYNC
// TODO: add more types
)
type BlockchainSyncMessage struct {
BlockHeight int
BlockHashes [][32]byte
}
type BlockchainSyncMessageType int
const (
DONE BlockchainSyncMessageType = iota
GET_LAST_BLOCK_HASHES
GET_BLOCK
)
// The types of messages used for NODE/TRANSACTION
type TransactionMessageType int
const (
SEND TransactionMessageType = iota
REQUEST
UNLOCK
)
// The types of messages used for NODE/BLOCK
type BlockMessageType int
const (
SYNC BlockMessageType = iota
)
// The types of messages used for NODE/BLOCK
type ClientMessageType int
const (
LOOKUP_UTXO ClientMessageType = iota
)
// The types of messages used for NODE/CONTROL
type ControlMessageType int
const (
STOP ControlMessageType = iota
)
// The wrapper struct FetchUtxoMessage sent from client wallet
type FetchUtxoMessage struct {
Addresses [][20]byte
Sender p2p.Peer
}
// Serialize serializes the block
func SerializeBlockchainSyncMessage(blockchainSyncMessage *BlockchainSyncMessage) []byte {
var result bytes.Buffer
encoder := gob.NewEncoder(&result)
err := encoder.Encode(blockchainSyncMessage)
if err != nil {
log.Panic(err)
}
return result.Bytes()
}
// DeserializeBlock deserializes a block
func DeserializeBlockchainSyncMessage(d []byte) (*BlockchainSyncMessage, error) {
var blockchainSyncMessage BlockchainSyncMessage
decoder := gob.NewDecoder(bytes.NewReader(d))
err := decoder.Decode(&blockchainSyncMessage)
if err != nil {
log.Panic(err)
}
return &blockchainSyncMessage, err
}
// [client] Constructs the unlock to commit or abort message that will be sent to leaders
func ConstructUnlockToCommitOrAbortMessage(txsAndProofs []*blockchain.Transaction) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(proto.NODE)})
byteBuffer.WriteByte(byte(TRANSACTION))
byteBuffer.WriteByte(byte(UNLOCK))
encoder := gob.NewEncoder(byteBuffer)
encoder.Encode(txsAndProofs)
return byteBuffer.Bytes()
}
// [client] Constructs the fetch utxo message that will be sent to Harmony network
func ConstructFetchUtxoMessage(sender p2p.Peer, addresses [][20]byte) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(proto.NODE)})
byteBuffer.WriteByte(byte(CLIENT))
byteBuffer.WriteByte(byte(LOOKUP_UTXO))
encoder := gob.NewEncoder(byteBuffer)
encoder.Encode(FetchUtxoMessage{Addresses: addresses, Sender: sender})
return byteBuffer.Bytes()
}
// Constructs serialized transactions
func ConstructTransactionListMessage(transactions []*blockchain.Transaction) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(proto.NODE)})
byteBuffer.WriteByte(byte(TRANSACTION))
byteBuffer.WriteByte(byte(SEND))
encoder := gob.NewEncoder(byteBuffer)
// Copy over the tx data
txs := make([]blockchain.Transaction, len(transactions))
for i := range txs {
txs[i] = *transactions[i]
}
err := encoder.Encode(txs)
if err != nil {
return []byte{} // TODO(RJ): better handle of the error
}
return byteBuffer.Bytes()
}
6 years ago
// Constructs Blockchain Sync Message.
func ConstructBlockchainSyncMessage(msgType BlockchainSyncMessageType, blockHash [32]byte) []byte {
6 years ago
byteBuffer := bytes.NewBuffer([]byte{byte(proto.NODE)})
byteBuffer.WriteByte(byte(BLOCKCHAIN_SYNC))
byteBuffer.WriteByte(byte(msgType))
if msgType != GET_LAST_BLOCK_HASHES {
byteBuffer.Write(blockHash[:])
}
6 years ago
return byteBuffer.Bytes()
}
func GenerateBlockchainSyncMessage(payload []byte) *BlockchainSyncMessage {
dec := gob.NewDecoder(bytes.NewBuffer(payload))
var res BlockchainSyncMessage
dec.Decode(&res)
return &res
}
// Constructs serialized transactions
func ConstructRequestTransactionsMessage(transactionIds [][]byte) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(proto.NODE)})
byteBuffer.WriteByte(byte(TRANSACTION))
byteBuffer.WriteByte(byte(REQUEST))
for _, txId := range transactionIds {
byteBuffer.Write(txId)
}
return byteBuffer.Bytes()
}
// Constructs STOP message for node to stop
func ConstructStopMessage() []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(proto.NODE)})
byteBuffer.WriteByte(byte(CONTROL))
byteBuffer.WriteByte(byte(STOP))
return byteBuffer.Bytes()
}
// Constructs blocks sync message to send blocks to other nodes
func ConstructBlocksSyncMessage(blocks []blockchain.Block) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(proto.NODE)})
byteBuffer.WriteByte(byte(BLOCK))
byteBuffer.WriteByte(byte(SYNC))
encoder := gob.NewEncoder(byteBuffer)
encoder.Encode(blocks)
return byteBuffer.Bytes()
}