This repository has been archived by the owner on May 13, 2022. It is now read-only.
/
proposals.go
127 lines (108 loc) · 2.77 KB
/
proposals.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
package proposals
import (
"fmt"
"strings"
"time"
"github.com/hyperledger/burrow/deploy/def"
"github.com/hyperledger/burrow/logging"
"github.com/hyperledger/burrow/txs"
"github.com/hyperledger/burrow/txs/payload"
)
type ProposalState int
const (
ALL ProposalState = 1 + iota
FAILED
EXECUTED
EXPIRED
PROPOSED
)
func (p *ProposalState) String() string {
switch *p {
case ALL:
return "ALL"
case FAILED:
return "FAILED"
case EXECUTED:
return "EXECUTED"
case EXPIRED:
return "EXPIRED"
case PROPOSED:
return "PROPOSED"
default:
panic(fmt.Sprintf("unknown propopsal state %d", *p))
}
}
func ProposalStateFromString(s string) (ProposalState, error) {
if strings.EqualFold(s, "all") {
return ALL, nil
}
if strings.EqualFold(s, "failed") {
return FAILED, nil
}
if strings.EqualFold(s, "executed") {
return EXECUTED, nil
}
if strings.EqualFold(s, "expired") {
return EXPIRED, nil
}
if strings.EqualFold(s, "proposed") {
return PROPOSED, nil
}
return ALL, fmt.Errorf("Unknown proposal state %s", s)
}
func ListProposals(args *def.DeployArgs, reqState ProposalState, logger *logging.Logger) error {
client := def.NewClient(args.Chain, args.KeysService, args.MempoolSign, time.Duration(args.Timeout)*time.Second)
props, err := client.ListProposals(reqState == PROPOSED, logger)
if err != nil {
return err
}
for _, prop := range props {
var state string
switch prop.Ballot.ProposalState {
case payload.Ballot_FAILED:
state = "FAILED"
case payload.Ballot_EXECUTED:
state = "EXECUTED"
case payload.Ballot_PROPOSED:
if ProposalExpired(prop.Ballot.Proposal, client, logger) != nil {
state = "EXPIRED"
} else {
state = "PROPOSED"
}
}
if !strings.EqualFold(state, reqState.String()) && reqState != ALL {
continue
}
logger.InfoMsg("Proposal",
"ProposalHash", fmt.Sprintf("%x", prop.Hash),
"Name", prop.Ballot.Proposal.Name,
"Description", prop.Ballot.Proposal.Description,
"State", state,
"Votes", len(prop.Ballot.GetVotes()))
}
return nil
}
func ProposalExpired(proposal *payload.Proposal, client *def.Client, logger *logging.Logger) error {
for _, input := range proposal.BatchTx.Inputs {
acc, err := client.GetAccount(input.Address)
if err != nil {
return err
}
if input.Sequence != acc.Sequence+1 {
return fmt.Errorf("Proposal has expired, account %s is out of sequence", input.Address.String())
}
}
for i, step := range proposal.BatchTx.Txs {
txEnv := txs.EnvelopeFromAny("", step)
for _, input := range txEnv.Tx.GetInputs() {
acc, err := client.GetAccount(input.Address)
if err != nil {
return err
}
if input.Sequence != acc.Sequence+1 {
return fmt.Errorf("Proposal has expired, account %s at step %d is expired", input.Address.String(), i)
}
}
}
return nil
}