dc4bc/main.go

152 lines
3.8 KiB
Go
Raw Normal View History

2020-07-22 04:53:06 -07:00
package main
import (
2020-08-09 14:37:53 -07:00
"context"
2020-08-19 09:04:41 -07:00
"crypto/ed25519"
"crypto/md5"
2020-08-20 08:37:13 -07:00
"encoding/hex"
2020-08-19 09:04:41 -07:00
"encoding/json"
2020-07-23 06:29:20 -07:00
"fmt"
"github.com/depools/dc4bc/airgapped"
2020-07-22 04:53:06 -07:00
_ "image/jpeg"
"log"
2020-07-23 06:29:20 -07:00
"sync"
2020-08-19 09:04:41 -07:00
"time"
spf "github.com/depools/dc4bc/fsm/state_machines/signature_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests"
"github.com/google/uuid"
2020-07-22 04:53:06 -07:00
2020-08-09 14:37:53 -07:00
"github.com/depools/dc4bc/qr"
"github.com/depools/dc4bc/storage"
2020-07-30 03:29:47 -07:00
2020-08-09 14:37:53 -07:00
"github.com/depools/dc4bc/client"
2020-07-22 04:53:06 -07:00
_ "image/gif"
_ "image/png"
_ "golang.org/x/image/bmp"
_ "golang.org/x/image/tiff"
_ "golang.org/x/image/webp"
)
2020-07-23 06:29:20 -07:00
type Transport struct {
2020-08-09 14:37:53 -07:00
nodes []*client.Client
2020-07-23 08:39:56 -07:00
}
2020-08-19 09:04:41 -07:00
type node struct {
client *client.Client
keyPair *client.KeyPair
}
2020-07-22 04:53:06 -07:00
func main() {
2020-07-23 06:29:20 -07:00
var numNodes = 4
2020-08-19 09:04:41 -07:00
var threshold = 3
var storagePath = "/tmp/dc4bc_storage"
var nodes = make([]*node, 4)
2020-08-09 14:37:53 -07:00
for nodeID := 0; nodeID < numNodes; nodeID++ {
var ctx = context.Background()
2020-08-14 05:34:15 -07:00
var userName = fmt.Sprintf("node_%d", nodeID)
2020-08-09 14:37:53 -07:00
var state, err = client.NewLevelDBState(fmt.Sprintf("/tmp/dc4bc_node_%d_state", nodeID))
if err != nil {
log.Fatalf("node %d failed to init state: %v\n", nodeID, err)
2020-07-22 04:53:06 -07:00
}
2020-08-19 09:04:41 -07:00
stg, err := storage.NewFileStorage(storagePath)
2020-07-23 08:39:56 -07:00
if err != nil {
2020-08-09 14:37:53 -07:00
log.Fatalf("node %d failed to init storage: %v\n", nodeID, err)
2020-07-23 08:39:56 -07:00
}
2020-08-14 05:34:15 -07:00
keyStore, err := client.NewLevelDBKeyStore(userName, fmt.Sprintf("/tmp/dc4bc_node_%d_key_store", nodeID))
if err != nil {
log.Fatalf("Failed to init key store: %v", err)
}
2020-08-19 09:04:41 -07:00
keyPair := client.NewKeyPair()
if err := keyStore.PutKeys(userName, keyPair); err != nil {
log.Fatalf("Failed to PutKeys: %v\n", err)
}
airgappedMachine, err := airgapped.NewAirgappedMachine(fmt.Sprintf("/tmp/dc4bc_node_%d_airgapped_db", nodeID))
if err != nil {
log.Fatalf("Failed to create airgapped machine: %v", err)
}
2020-08-09 14:37:53 -07:00
clt, err := client.NewClient(
ctx,
2020-08-14 05:34:15 -07:00
userName,
2020-08-09 14:37:53 -07:00
state,
stg,
2020-08-14 05:34:15 -07:00
keyStore,
2020-08-09 14:37:53 -07:00
qr.NewCameraProcessor(),
airgappedMachine,
2020-08-09 14:37:53 -07:00
)
2020-07-23 08:39:56 -07:00
if err != nil {
2020-08-09 14:37:53 -07:00
log.Fatalf("node %d failed to init client: %v\n", nodeID, err)
2020-07-23 08:39:56 -07:00
}
2020-08-21 09:25:09 -07:00
clt.Airgapped.SetAddress(clt.GetAddr())
2020-07-23 08:39:56 -07:00
2020-08-19 09:04:41 -07:00
nodes[nodeID] = &node{
client: clt,
keyPair: keyPair,
}
}
2020-07-23 08:39:56 -07:00
2020-08-19 09:04:41 -07:00
// Each node starts to Poll().
for nodeID, node := range nodes {
2020-08-09 14:37:53 -07:00
go func(nodeID int, node *client.Client) {
if err := node.Poll(); err != nil {
log.Fatalf("client %d poller failed: %v\n", nodeID, err)
}
2020-08-19 09:04:41 -07:00
}(nodeID, node.client)
2020-07-22 04:53:06 -07:00
2020-08-09 14:37:53 -07:00
log.Printf("client %d started...\n", nodeID)
2020-07-23 06:29:20 -07:00
}
2020-08-09 14:37:53 -07:00
2020-08-19 09:04:41 -07:00
stg, err := storage.NewFileStorage(storagePath)
if err != nil {
log.Fatalf("main namespace failed to init storage: %v\n", err)
}
// Node1 tells other participants to start DKG.
var participants []*requests.SignatureProposalParticipantsEntry
for _, node := range nodes {
2020-08-21 09:25:09 -07:00
dkgPubKey, err := node.client.Airgapped.GetPubKey().MarshalBinary()
if err != nil {
log.Fatalln("failed to get DKG pubKey:", err.Error())
}
2020-08-19 09:04:41 -07:00
participants = append(participants, &requests.SignatureProposalParticipantsEntry{
Addr: node.client.GetAddr(),
PubKey: node.client.GetPubKey(),
2020-08-21 09:25:09 -07:00
DkgPubKey: dkgPubKey, // TODO: Use a real one.
2020-08-19 09:04:41 -07:00
})
}
messageData := requests.SignatureProposalParticipantsListRequest{
Participants: participants,
SigningThreshold: threshold,
CreatedAt: time.Now(),
}
messageDataBz, err := json.Marshal(messageData)
if err != nil {
log.Fatalf("failed to marshal SignatureProposalParticipantsListRequest: %v\n", err)
}
dkgRoundID := md5.Sum(messageDataBz)
message := storage.Message{
ID: uuid.New().String(),
2020-08-20 08:37:13 -07:00
DkgRoundID: hex.EncodeToString(dkgRoundID[:]),
2020-08-19 09:04:41 -07:00
Event: string(spf.EventInitProposal),
Data: messageDataBz,
SenderAddr: nodes[0].client.GetAddr(),
}
message.Signature = ed25519.Sign(nodes[0].keyPair.Priv, message.Bytes())
if _, err := stg.Send(message); err != nil {
log.Fatalf("Failed to send %+v to storage: %v\n", message, err)
}
2020-08-09 14:37:53 -07:00
var wg = sync.WaitGroup{}
wg.Add(1)
2020-07-23 06:29:20 -07:00
wg.Wait()
2020-07-22 04:53:06 -07:00
}