forked from LFDT-Panurus/panurus
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauditor.go
More file actions
134 lines (109 loc) · 4.41 KB
/
Copy pathauditor.go
File metadata and controls
134 lines (109 loc) · 4.41 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package views
import (
"encoding/json"
"math/big"
"time"
"github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/assert"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
"github.com/hyperledger-labs/fabric-token-sdk/token"
"github.com/hyperledger-labs/fabric-token-sdk/token/services/interop/hashescrow"
"github.com/hyperledger-labs/fabric-token-sdk/token/services/interop/htlc"
"github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx"
)
const (
Limit int64 = 50
)
type AuditView struct{}
func (a *AuditView) Call(context view.Context) (interface{}, error) {
tx, err := ttx.ReceiveTransaction(context)
assert.NoError(err, "failed receiving transaction")
assert.NoError(tx.IsValid(context.Context()), "failed verifying transaction")
w := ttx.MyAuditorWallet(context, token.WithTMSID(tx.TokenService().ID()))
assert.NotNil(w, "failed getting default auditor wallet")
auditor, err := ttx.NewAuditor(context, w)
assert.NoError(err, "failed to get auditor instance")
assert.NoError(auditor.Validate(tx), "failed auditing verification")
// Check limits
// extract inputs and outputs
inputs, outputs, err := auditor.Audit(context.Context(), tx)
assert.NoError(err, "failed retrieving inputs and outputs")
defer auditor.Release(context.Context(), tx)
// For example, all payments of an amount less than or equal to payment limit is valid
eIDs := inputs.EnrollmentIDs()
tokenTypes := inputs.TokenTypes()
logger.Debugf("Limits on inputs [%v][%v]", eIDs, tokenTypes)
for _, eID := range eIDs {
assert.NotEmpty(eID, "enrollment id should not be empty")
for _, tokenType := range tokenTypes {
// compute the payment done in the transaction
sent := inputs.ByEnrollmentID(eID).ByType(tokenType).Sum()
received := outputs.ByEnrollmentID(eID).ByType(tokenType).Sum()
logger.Debugf("Payment Limit: [%s] Sent [%d], Received [%d], type [%s]", eID, sent.Int64(), received.Int64(), tokenType)
diff := big.NewInt(0).Sub(sent, received)
if diff.Cmp(big.NewInt(0)) <= 0 {
continue
}
logger.Debugf("Payment Limit: [%s] Diff [%d], type [%s]", eID, diff.Int64(), tokenType)
assert.True(diff.Cmp(big.NewInt(Limit)) <= 0, "payment limit reached [%s][%s][%s]", eID, tokenType, diff.Text(10))
}
}
for i := range inputs.Count() {
input, err := htlc.ToInput(inputs.At(i))
assert.NoError(err, "cannot get htlc input wrapper")
if input.IsHTLC() {
// check script details, for example make sure the hash is set
script, err := input.Script()
assert.NoError(err, "cannot get htlc script from input")
assert.True(len(script.HashInfo.Hash) > 0, "hash is not set")
}
hashEscrowInput, err := hashescrow.ToInput(inputs.At(i))
assert.NoError(err, "cannot get hash escrow input wrapper")
if hashEscrowInput.IsHashEscrow() {
hashEscrowScript, err := hashEscrowInput.Script()
assert.NoError(err, "cannot get hash escrow script from input")
assert.NoError(hashEscrowScript.Validate(), "hash escrow script is not valid")
}
}
now := time.Now()
for i := range outputs.Count() {
output, err := htlc.ToOutput(outputs.At(i))
assert.NoError(err, "cannot get htlc output wrapper")
if output.IsHTLC() {
// check script details
script, err := output.Script()
assert.NoError(err, "cannot get htlc script from output")
assert.NoError(script.Validate(now), "script is not valid")
}
hashEscrowOutput, err := hashescrow.ToOutput(outputs.At(i))
assert.NoError(err, "cannot get hash escrow output wrapper")
if hashEscrowOutput.IsHashEscrow() {
hashEscrowScript, err := hashEscrowOutput.Script()
assert.NoError(err, "cannot get hash escrow script from output")
assert.NoError(hashEscrowScript.Validate(), "hash escrow script is not valid")
}
}
return context.RunView(ttx.NewAuditApproveView(w, tx))
}
type RegisterAuditor struct {
TMSID token.TMSID
}
type RegisterAuditorView struct {
*RegisterAuditor
}
func (r *RegisterAuditorView) Call(context view.Context) (interface{}, error) {
return context.RunView(ttx.NewRegisterAuditorView(
&AuditView{},
token.WithTMSID(r.TMSID),
))
}
type RegisterAuditorViewFactory struct{}
func (p *RegisterAuditorViewFactory) NewView(in []byte) (view.View, error) {
f := &RegisterAuditorView{RegisterAuditor: &RegisterAuditor{}}
err := json.Unmarshal(in, f.RegisterAuditor)
assert.NoError(err, "failed unmarshalling input")
return f, nil
}