code.vegaprotocol.io/vega@v0.79.0/wallet/service/v1/policies.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package v1 17 18 import ( 19 "context" 20 "time" 21 22 commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1" 23 v1 "code.vegaprotocol.io/vega/protos/vega/wallet/v1" 24 ) 25 26 type ConsentConfirmation struct { 27 TxID string 28 Decision bool 29 } 30 31 type ConsentRequest struct { 32 TxID string 33 Tx *v1.SubmitTransactionRequest 34 ReceivedAt time.Time 35 Confirmation chan ConsentConfirmation 36 } 37 38 type SentTransaction struct { 39 TxHash string 40 TxID string 41 Tx *commandspb.Transaction 42 Error error 43 SentAt time.Time 44 } 45 46 type Policy interface { 47 Ask(tx *v1.SubmitTransactionRequest, txID string, receivedAt time.Time) (bool, error) 48 Report(tx SentTransaction) 49 } 50 51 type AutomaticConsentPolicy struct{} 52 53 func NewAutomaticConsentPolicy() Policy { 54 return &AutomaticConsentPolicy{} 55 } 56 57 func (p *AutomaticConsentPolicy) Ask(_ *v1.SubmitTransactionRequest, _ string, _ time.Time) (bool, error) { 58 return true, nil 59 } 60 61 func (p *AutomaticConsentPolicy) Report(_ SentTransaction) { 62 // Nothing to report as we expect this policy to be non-interactive. 63 } 64 65 type ExplicitConsentPolicy struct { 66 // ctx is used to interrupt the wait for consent confirmation 67 ctx context.Context 68 69 consentRequestsChan chan ConsentRequest 70 sentTransactionsChan chan SentTransaction 71 } 72 73 func NewExplicitConsentPolicy(ctx context.Context, consentRequests chan ConsentRequest, sentTransactions chan SentTransaction) Policy { 74 return &ExplicitConsentPolicy{ 75 ctx: ctx, 76 consentRequestsChan: consentRequests, 77 sentTransactionsChan: sentTransactions, 78 } 79 } 80 81 func (p *ExplicitConsentPolicy) Ask(tx *v1.SubmitTransactionRequest, txID string, receivedAt time.Time) (bool, error) { 82 confirmationChan := make(chan ConsentConfirmation, 1) 83 defer close(confirmationChan) 84 85 consentRequest := ConsentRequest{ 86 TxID: txID, 87 Tx: tx, 88 ReceivedAt: receivedAt, 89 Confirmation: confirmationChan, 90 } 91 92 if err := p.sendConsentRequest(consentRequest); err != nil { 93 return false, err 94 } 95 96 return p.receiveConsentConfirmation(consentRequest) 97 } 98 99 func (p *ExplicitConsentPolicy) receiveConsentConfirmation(consentRequest ConsentRequest) (bool, error) { 100 for { 101 select { 102 case <-p.ctx.Done(): 103 return false, ErrInterruptedConsentRequest 104 case decision := <-consentRequest.Confirmation: 105 return decision.Decision, nil 106 } 107 } 108 } 109 110 func (p *ExplicitConsentPolicy) sendConsentRequest(consentRequest ConsentRequest) error { 111 for { 112 select { 113 case <-p.ctx.Done(): 114 return ErrInterruptedConsentRequest 115 case p.consentRequestsChan <- consentRequest: 116 return nil 117 } 118 } 119 } 120 121 func (p *ExplicitConsentPolicy) Report(tx SentTransaction) { 122 p.sentTransactionsChan <- tx 123 }