signatures.go 2.12 KB
Newer Older
1
2
3
4
package sign

import (
	"fmt"
5
	"time"
6
7

	cAPI "dfss/dfssc/api"
8
	"dfss/dfssc/common"
9
	"dfss/net"
10
11
)

12
13
// ExchangeAllSignatures creates and sends signatures to all the signers of the contract
func (m *SignatureManager) ExchangeAllSignatures() error {
14
	allReceived := make(chan error, chanBufferSize)
15
	go m.ReceiveAllSignatures(allReceived)
16

17
18
19
20
21
	myID, err := m.FindID()
	if err != nil {
		return err
	}

22
	// compute a set of all signers except me
23
	sendSet := common.GetAllButOne(m.sequence, myID)
24
	errorChan := make(chan error, chanBufferSize)
25
	for _, id := range sendSet {
26
		go func(id uint32) {
27
28
29
			signature, err2 := m.CreateSignature(myID, id)
			if err2 != nil {
				errorChan <- err2
30
31
				return
			}
32
			err2 = m.SendEvidence(nil, signature, id)
33
34
			if err2 != nil {
				errorChan <- err2
35
36
37
38
39
40
41
42
				return
			}
			errorChan <- nil
		}(id)
	}

	for range sendSet {
		err = <-errorChan
43
44
45
46
47
		if err != nil {
			return err
		}
	}

48
	return <-allReceived
49
50
51
52
53
}

// CreateSignature creates a signature from a sequence ID to another
// provided the specified sequence indexes are valid
func (m *SignatureManager) CreateSignature(from, to uint32) (*cAPI.Signature, error) {
54
	context, err := m.createContext(from, to)
55
	if err != nil {
56
		return nil, err
57
58
	}

59
60
61
62
	return &cAPI.Signature{
		Context: context,
		Payload: []byte{0x42},
	}, nil
63
64
}

65
66
// ReceiveAllSignatures receive all the signatures
func (m *SignatureManager) ReceiveAllSignatures(out chan error) {
67
68
	myID, err := m.FindID()
	if err != nil {
69
70
		out <- err
		return
71
72
	}

73
	// compute a set of all signers except me
74
75
76
	pendingSet := common.GetAllButOne(m.sequence, myID)

	for len(pendingSet) > 0 {
77
78
79
80
81
82
83
84
85
86
		select {
		// Waiting for signatures from grpc handler
		case signatureIface := <-m.cServerIface.incomingSignatures:
			signature := (signatureIface).(*cAPI.Signature)
			senderID, exist := m.hashToID[fmt.Sprintf("%x", signature.Context.SenderKeyHash)]
			if exist {
				pendingSet, _ = common.Remove(pendingSet, senderID)
				m.archives.receivedSignatures = append(m.archives.receivedSignatures, signature)
			}

87
		case <-time.After(net.DefaultTimeout):
88
89
			out <- fmt.Errorf("Signature reception timeout!")
			return
90
91
92
		}
	}

93
94
	out <- nil
	return
95
}