mirror of https://github.com/certusone/dc4bc.git
WIP: nodes interaction through HTTP
This commit is contained in:
parent
132f31861d
commit
16053f3a54
|
@ -264,10 +264,10 @@ func (c *Client) ReadProcessedOperation() error {
|
|||
return fmt.Errorf("failed to unmarshal processed operation")
|
||||
}
|
||||
|
||||
return c.HandleProcessedOperation(operation)
|
||||
return c.handleProcessedOperation(operation)
|
||||
}
|
||||
|
||||
func (c *Client) HandleProcessedOperation(operation types.Operation) error {
|
||||
func (c *Client) handleProcessedOperation(operation types.Operation) error {
|
||||
storedOperation, err := c.state.GetOperationByID(operation.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find matching operation: %w", err)
|
||||
|
|
|
@ -66,6 +66,7 @@ func (c *Client) StartHTTPServer(listenAddr string) error {
|
|||
|
||||
mux.HandleFunc("/readProcessedOperation", c.readProcessedOperationFromBodyHandler)
|
||||
mux.HandleFunc("/getOperationQR", c.getOperationQRToBodyHandler)
|
||||
mux.HandleFunc("/handleProcessedOperationJSON", c.handleJSONOperationHandler)
|
||||
|
||||
mux.HandleFunc("/startDKG", c.startDKGHandler)
|
||||
mux.HandleFunc("/proposeSignMessage", c.proposeSignDataHandler)
|
||||
|
@ -204,7 +205,7 @@ func (c *Client) readProcessedOperationFromBodyHandler(w http.ResponseWriter, r
|
|||
fmt.Sprintf("failed to unmarshal processed operation: %v", err))
|
||||
return
|
||||
}
|
||||
if err := c.HandleProcessedOperation(operation); err != nil {
|
||||
if err := c.handleProcessedOperation(operation); err != nil {
|
||||
errorResponse(w, http.StatusInternalServerError, fmt.Sprintf("failed to handle an operation: %v", err))
|
||||
return
|
||||
}
|
||||
|
@ -266,6 +267,32 @@ func (c *Client) proposeSignDataHandler(w http.ResponseWriter, r *http.Request)
|
|||
successResponse(w, "ok")
|
||||
}
|
||||
|
||||
func (c *Client) handleJSONOperationHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
errorResponse(w, http.StatusBadRequest, "Wrong HTTP method")
|
||||
return
|
||||
}
|
||||
reqBody, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
errorResponse(w, http.StatusInternalServerError, fmt.Sprintf("failed to read body: %v", err))
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
var req types.Operation
|
||||
if err = json.Unmarshal(reqBody, &req); err != nil {
|
||||
errorResponse(w, http.StatusInternalServerError, fmt.Sprintf("failed to umarshal request: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
if err = c.handleProcessedOperation(req); err != nil {
|
||||
errorResponse(w, http.StatusInternalServerError, fmt.Sprintf("failed to handle processed operation: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
successResponse(w, "ok")
|
||||
}
|
||||
|
||||
func (c *Client) buildMessage(dkgRoundID string, event fsm.Event, data []byte) (*storage.Message, error) {
|
||||
message := storage.Message{
|
||||
ID: uuid.New().String(),
|
||||
|
|
81
main.go
81
main.go
|
@ -6,7 +6,9 @@ import (
|
|||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/depools/dc4bc/client/types"
|
||||
_ "image/jpeg"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
@ -20,18 +22,67 @@ import (
|
|||
)
|
||||
|
||||
type node struct {
|
||||
client *client.Client
|
||||
keyPair *client.KeyPair
|
||||
air *airgapped.AirgappedMachine
|
||||
client *client.Client
|
||||
keyPair *client.KeyPair
|
||||
air *airgapped.AirgappedMachine
|
||||
listenAddr string
|
||||
}
|
||||
|
||||
type OperationsResponse struct {
|
||||
Result map[string]*types.Operation `json:"result"`
|
||||
}
|
||||
|
||||
func getOperations(url string) (*OperationsResponse, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get operations for node %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
responseBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read body %v", err)
|
||||
}
|
||||
|
||||
var response OperationsResponse
|
||||
if err = json.Unmarshal(responseBody, &response); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal response: %v", err)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func handleProcessedOperation(url string, operation types.Operation) error {
|
||||
operationBz, err := json.Marshal(operation)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal operation: %w", err)
|
||||
}
|
||||
resp, err := http.Post(url, "application/json", bytes.NewReader(operationBz))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to handle processed operation %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
responseBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read body %v", err)
|
||||
}
|
||||
|
||||
var response client.Response
|
||||
if err = json.Unmarshal(responseBody, &response); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal response: %w", err)
|
||||
}
|
||||
if response.ErrorMessage != "" {
|
||||
return fmt.Errorf("failed to handle processed operation: %s", response.ErrorMessage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *node) run() {
|
||||
for {
|
||||
operations, err := n.client.GetOperations()
|
||||
operationsResponse, err := getOperations(fmt.Sprintf("http://%s/getOperations", n.listenAddr))
|
||||
if err != nil {
|
||||
n.client.Logger.Log("Failed to get operations: %v", err)
|
||||
log.Fatalf("failed to get operations: %v", err)
|
||||
}
|
||||
|
||||
operations := operationsResponse.Result
|
||||
if len(operations) == 0 {
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
|
@ -48,11 +99,14 @@ func (n *node) run() {
|
|||
n.client.Logger.Log("Got %d Processed Operations from Airgapped", len(operations))
|
||||
n.client.Logger.Log("Operation %s handled in airgapped, result event is %s",
|
||||
operation.Event, processedOperation.Event)
|
||||
if err = n.client.HandleProcessedOperation(processedOperation); err != nil {
|
||||
|
||||
if err = handleProcessedOperation(fmt.Sprintf("http://%s/handleProcessedOperationJSON", n.listenAddr),
|
||||
processedOperation); err != nil {
|
||||
n.client.Logger.Log("Failed to handle processed operation: %v", err)
|
||||
} else {
|
||||
n.client.Logger.Log("Successfully handled processed operation %s", processedOperation.Event)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,20 +159,21 @@ func main() {
|
|||
airgappedMachine.SetAddress(clt.GetAddr())
|
||||
|
||||
nodes[nodeID] = &node{
|
||||
client: clt,
|
||||
keyPair: keyPair,
|
||||
air: airgappedMachine,
|
||||
client: clt,
|
||||
keyPair: keyPair,
|
||||
air: airgappedMachine,
|
||||
listenAddr: fmt.Sprintf("localhost:%d", startingPort),
|
||||
}
|
||||
startingPort++
|
||||
}
|
||||
|
||||
// Each node starts to Poll().
|
||||
for nodeID, n := range nodes {
|
||||
go func(nodeID int, node *node, port int) {
|
||||
if err := node.client.StartHTTPServer(fmt.Sprintf(":%d", port)); err != nil {
|
||||
go func(nodeID int, node *node) {
|
||||
if err := node.client.StartHTTPServer(node.listenAddr); err != nil {
|
||||
log.Fatalf("failed to start HTTP server for nodeID #%d: %v\n", nodeID, err)
|
||||
}
|
||||
}(nodeID, n, startingPort)
|
||||
startingPort++
|
||||
}(nodeID, n)
|
||||
go nodes[nodeID].run()
|
||||
|
||||
go func(nodeID int, node *client.Client) {
|
||||
|
|
Loading…
Reference in New Issue