-
Notifications
You must be signed in to change notification settings - Fork 2
/
register_genesis_currency.go
144 lines (116 loc) · 3.85 KB
/
register_genesis_currency.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
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
135
136
137
138
139
140
141
142
143
144
package currency
import (
"github.com/ProtoconNet/mitum-currency/v3/common"
"github.com/ProtoconNet/mitum-currency/v3/types"
"github.com/ProtoconNet/mitum2/base"
"github.com/ProtoconNet/mitum2/util"
"github.com/ProtoconNet/mitum2/util/hint"
"github.com/ProtoconNet/mitum2/util/valuehash"
"github.com/pkg/errors"
)
var (
RegisterGenesisCurrencyFactHint = hint.MustNewHint("mitum-currency-register-genesis-currency-operation-fact-v0.0.1")
RegisterGenesisCurrencyHint = hint.MustNewHint("mitum-currency-register-genesis-currency-operation-v0.0.1")
)
type RegisterGenesisCurrencyFact struct {
base.BaseFact
genesisNodeKey base.Publickey
keys types.AccountKeys
cs []types.CurrencyDesign
}
func NewRegisterGenesisCurrencyFact(
token []byte,
genesisNodeKey base.Publickey,
keys types.AccountKeys,
cs []types.CurrencyDesign,
) RegisterGenesisCurrencyFact {
fact := RegisterGenesisCurrencyFact{
BaseFact: base.NewBaseFact(RegisterGenesisCurrencyFactHint, token),
genesisNodeKey: genesisNodeKey,
keys: keys,
cs: cs,
}
fact.SetHash(fact.GenerateHash())
return fact
}
func (fact RegisterGenesisCurrencyFact) Hash() util.Hash {
return fact.BaseFact.Hash()
}
func (fact RegisterGenesisCurrencyFact) Bytes() []byte {
bs := make([][]byte, len(fact.cs)+3)
bs[0] = fact.Token()
bs[1] = []byte(fact.genesisNodeKey.String())
bs[2] = fact.keys.Bytes()
for i := range fact.cs {
bs[i+3] = fact.cs[i].Bytes()
}
return util.ConcatBytesSlice(bs...)
}
func (fact RegisterGenesisCurrencyFact) IsValid(b []byte) error {
if err := fact.BaseHinter.IsValid(nil); err != nil {
return common.ErrFactInvalid.Wrap(err)
}
if len(fact.cs) < 1 {
return common.ErrFactInvalid.Wrap(common.ErrValOOR.Wrap(errors.Errorf("empty GenesisCurrency for RegisterGenesisCurrencyFact")))
}
if err := util.CheckIsValiders(nil, false, fact.genesisNodeKey, fact.keys); err != nil {
return common.ErrFactInvalid.Wrap(err)
}
founds := map[types.CurrencyID]struct{}{}
for i := range fact.cs {
c := fact.cs[i]
if err := c.IsValid(nil); err != nil {
return common.ErrFactInvalid.Wrap(err)
} else if _, found := founds[c.Currency()]; found {
return common.ErrFactInvalid.Wrap(common.ErrDupVal.Wrap(errors.Errorf("currency id, %v", c.Currency())))
} else {
founds[c.Currency()] = struct{}{}
}
}
if err := common.IsValidOperationFact(fact, b); err != nil {
return common.ErrFactInvalid.Wrap(err)
}
return nil
}
func (fact RegisterGenesisCurrencyFact) GenerateHash() util.Hash {
return valuehash.NewSHA256(fact.Bytes())
}
func (fact RegisterGenesisCurrencyFact) Token() base.Token {
return fact.BaseFact.Token()
}
func (fact RegisterGenesisCurrencyFact) GenesisNodeKey() base.Publickey {
return fact.genesisNodeKey
}
func (fact RegisterGenesisCurrencyFact) Keys() types.AccountKeys {
return fact.keys
}
func (fact RegisterGenesisCurrencyFact) Address() (base.Address, error) {
return types.NewAddressFromKeys(fact.keys)
}
func (fact RegisterGenesisCurrencyFact) Currencies() []types.CurrencyDesign {
return fact.cs
}
type RegisterGenesisCurrency struct {
common.BaseOperation
}
func NewRegisterGenesisCurrency(
fact RegisterGenesisCurrencyFact,
) RegisterGenesisCurrency {
return RegisterGenesisCurrency{BaseOperation: common.NewBaseOperation(RegisterGenesisCurrencyHint, fact)}
}
func (op RegisterGenesisCurrency) IsValid(networkID []byte) error {
if err := op.BaseOperation.IsValid(networkID); err != nil {
return err
}
if len(op.Signs()) != 1 {
return util.ErrInvalid.Errorf("Genesis currencies should be signed only by genesis node key")
}
fact, ok := op.Fact().(RegisterGenesisCurrencyFact)
if !ok {
return errors.Errorf("expected RegisterGenesisCurrencyFact, not %T", op.Fact())
}
if !fact.genesisNodeKey.Equal(op.Signs()[0].Signer()) {
return util.ErrInvalid.Errorf("Not signed by genesis node key")
}
return nil
}