This repository has been archived by the owner on May 10, 2023. It is now read-only.
/
policies.go
108 lines (88 loc) · 2.58 KB
/
policies.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package service
import (
"context"
"time"
commandspb "code.vegaprotocol.io/protos/vega/commands/v1"
v1 "code.vegaprotocol.io/protos/vega/wallet/v1"
)
type ConsentConfirmation struct {
TxID string
Decision bool
}
type ConsentRequest struct {
TxID string
Tx *v1.SubmitTransactionRequest
ReceivedAt time.Time
Confirmation chan ConsentConfirmation
}
type SentTransaction struct {
TxHash string
TxID string
Tx *commandspb.Transaction
Error error
SentAt time.Time
}
type Policy interface {
Ask(tx *v1.SubmitTransactionRequest, txID string, receivedAt time.Time) (bool, error)
Report(tx SentTransaction)
}
type AutomaticConsentPolicy struct{}
func NewAutomaticConsentPolicy() Policy {
return &AutomaticConsentPolicy{}
}
func (p *AutomaticConsentPolicy) Ask(_ *v1.SubmitTransactionRequest, _ string, _ time.Time) (bool, error) {
return true, nil
}
func (p *AutomaticConsentPolicy) Report(_ SentTransaction) {
// Nothing to report as we expect this policy to be non-interactive.
}
type ExplicitConsentPolicy struct {
// ctx is used to interrupt the wait for consent confirmation
ctx context.Context
consentRequestsChan chan ConsentRequest
sentTransactionsChan chan SentTransaction
}
func NewExplicitConsentPolicy(ctx context.Context, consentRequests chan ConsentRequest, sentTransactions chan SentTransaction) Policy {
return &ExplicitConsentPolicy{
ctx: ctx,
consentRequestsChan: consentRequests,
sentTransactionsChan: sentTransactions,
}
}
func (p *ExplicitConsentPolicy) Ask(tx *v1.SubmitTransactionRequest, txID string, receivedAt time.Time) (bool, error) {
confirmationChan := make(chan ConsentConfirmation, 1)
defer close(confirmationChan)
consentRequest := ConsentRequest{
TxID: txID,
Tx: tx,
ReceivedAt: receivedAt,
Confirmation: confirmationChan,
}
if err := p.sendConsentRequest(consentRequest); err != nil {
return false, err
}
return p.receiveConsentConfirmation(consentRequest)
}
func (p *ExplicitConsentPolicy) receiveConsentConfirmation(consentRequest ConsentRequest) (bool, error) {
for {
select {
case <-p.ctx.Done():
return false, ErrInterruptedConsentRequest
case decision := <-consentRequest.Confirmation:
return decision.Decision, nil
}
}
}
func (p *ExplicitConsentPolicy) sendConsentRequest(consentRequest ConsentRequest) error {
for {
select {
case <-p.ctx.Done():
return ErrInterruptedConsentRequest
case p.consentRequestsChan <- consentRequest:
return nil
}
}
}
func (p *ExplicitConsentPolicy) Report(tx SentTransaction) {
p.sentTransactionsChan <- tx
}