/
model.go
92 lines (82 loc) · 2.84 KB
/
model.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
package paychan
import (
"github.com/iov-one/weave"
"github.com/iov-one/weave/errors"
"github.com/iov-one/weave/orm"
)
var _ orm.CloneableData = (*PaymentChannel)(nil)
// Validate ensures the payment channel is valid.
func (pc *PaymentChannel) Validate() error {
if pc.Src == nil {
return errors.Wrap(errors.ErrInvalidModel, "missing source")
}
if pc.SenderPubkey == nil {
return errors.Wrap(errors.ErrInvalidModel, "missing sender public key")
}
if pc.Recipient == nil {
return errors.Wrap(errors.ErrInvalidModel, "missing recipient")
}
if pc.Timeout <= 0 {
return errors.Wrap(errors.ErrInvalidModel, "timeout in the past")
}
if pc.Total == nil || !pc.Total.IsPositive() {
return errors.Wrap(errors.ErrInvalidModel, "negative total")
}
if len(pc.Memo) > 128 {
return errors.Wrap(errors.ErrInvalidModel, "memo too long")
}
// Transfer value must not be greater than the Total value represented
// by the PaymentChannel.
if pc.Transferred == nil || !pc.Transferred.IsNonNegative() || pc.Transferred.Compare(*pc.Total) > 0 {
return errors.Wrap(errors.ErrInvalidModel, "invalid transferred value")
}
return nil
}
// Copy returns a shallow copy of this PaymentChannel.
func (pc PaymentChannel) Copy() orm.CloneableData {
return &pc
}
// PaymentChannelBucket is a wrapper over orm.Bucket that ensures that only
// PaymentChannel entities can be persisted.
type PaymentChannelBucket struct {
orm.Bucket
idSeq orm.Sequence
}
// NewPaymentChannelBucket returns a bucket for storing PaymentChannel state.
func NewPaymentChannelBucket() PaymentChannelBucket {
b := orm.NewBucket("paychan", orm.NewSimpleObj(nil, &PaymentChannel{}))
return PaymentChannelBucket{
Bucket: b,
idSeq: b.Sequence("id"),
}
}
// Create adds given payment store entity to the store and returns the ID of
// the newly inserted entity.
func (b *PaymentChannelBucket) Create(db weave.KVStore, pc *PaymentChannel) (orm.Object, error) {
key := b.idSeq.NextVal(db)
obj := orm.NewSimpleObj(key, pc)
return obj, b.Bucket.Save(db, obj)
}
// Save updates the state of given PaymentChannel entity in the store.
func (b *PaymentChannelBucket) Save(db weave.KVStore, obj orm.Object) error {
if _, ok := obj.Value().(*PaymentChannel); !ok {
return errors.WithType(errors.ErrInvalidModel, obj.Value())
}
return b.Bucket.Save(db, obj)
}
// GetPaymentChannel returns a payment channel instance with given ID or
// returns an error.
func (b *PaymentChannelBucket) GetPaymentChannel(db weave.KVStore, paymentChannelID []byte) (*PaymentChannel, error) {
obj, err := b.Get(db, paymentChannelID)
if err != nil {
return nil, err
}
if obj == nil || obj.Value() == nil {
return nil, errors.Wrap(errors.ErrNotFound, "payment channel not found")
}
pc, ok := obj.Value().(*PaymentChannel)
if !ok {
return nil, errors.Wrap(errors.ErrNotFound, "payment channel not found")
}
return pc, nil
}