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"
|
|
|
|
"encoding/json"
|
2020-07-23 06:29:20 -07:00
|
|
|
"fmt"
|
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)
|
|
|
|
}
|
|
|
|
|
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(),
|
|
|
|
)
|
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-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 {
|
|
|
|
participants = append(participants, &requests.SignatureProposalParticipantsEntry{
|
|
|
|
Addr: node.client.GetAddr(),
|
|
|
|
PubKey: node.client.GetPubKey(),
|
|
|
|
DkgPubKey: make([]byte, 128), // TODO: Use a real one.
|
|
|
|
})
|
|
|
|
}
|
|
|
|
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(),
|
|
|
|
DkgRoundID: string(dkgRoundID[:]),
|
|
|
|
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
|
|
|
}
|