-
Notifications
You must be signed in to change notification settings - Fork 2
/
p_proposal_maker.go
155 lines (131 loc) · 3.89 KB
/
p_proposal_maker.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
145
146
147
148
149
150
151
152
153
154
155
package cmds
import (
"context"
"github.com/ProtoconNet/mitum2/launch"
"github.com/pkg/errors"
"time"
"github.com/ProtoconNet/mitum2/base"
"github.com/ProtoconNet/mitum2/isaac"
isaacdatabase "github.com/ProtoconNet/mitum2/isaac/database"
isaacoperation "github.com/ProtoconNet/mitum2/isaac/operation"
"github.com/ProtoconNet/mitum2/util"
"github.com/ProtoconNet/mitum2/util/localtime"
"github.com/ProtoconNet/mitum2/util/logging"
)
func PProposalMaker(pctx context.Context) (context.Context, error) {
e := util.StringError("prepare proposal maker")
var log *logging.Logging
var local base.LocalNode
var isaacparams *isaac.Params
var pool *isaacdatabase.TempPool
var db isaac.Database
if err := util.LoadFromContextOK(pctx,
launch.LoggingContextKey, &log,
launch.LocalContextKey, &local,
launch.ISAACParamsContextKey, &isaacparams,
launch.PoolDatabaseContextKey, &pool,
launch.CenterDatabaseContextKey, &db,
); err != nil {
return pctx, e.Wrap(err)
}
opf, err := proposalMakderGetOperationsFunc(pctx)
if err != nil {
return pctx, e.Wrap(err)
}
pm := isaac.NewProposalMaker(
local,
isaacparams.NetworkID(),
opf,
pool,
db.LastBlockMap,
)
_ = pm.SetLogging(log)
return context.WithValue(pctx, launch.ProposalMakerContextKey, pm), nil
}
func proposalMakderGetOperationsFunc(pctx context.Context) (
func(context.Context, base.Height) ([][2]util.Hash, error),
error,
) {
var log *logging.Logging
var local base.LocalNode
var params *launch.LocalParams
var db isaac.Database
var pool *isaacdatabase.TempPool
var f ProposalOperationFactHintFunc
if err := util.LoadFromContextOK(pctx,
launch.LoggingContextKey, &log,
launch.LocalContextKey, &local,
launch.LocalParamsContextKey, ¶ms,
launch.CenterDatabaseContextKey, &db,
launch.PoolDatabaseContextKey, &pool,
ProposalOperationFactHintContextKey, &f,
); err != nil {
return nil, err
}
operationfilterf := f()
return func(ctx context.Context, height base.Height) ([][2]util.Hash, error) {
policy := db.LastNetworkPolicy()
if policy == nil { // NOTE Usually it means empty block data
return nil, nil
}
n := policy.MaxOperationsInProposal()
if n < 1 {
return nil, nil
}
hs, err := pool.OperationHashes(
ctx,
height,
n,
func(meta isaac.PoolOperationRecordMeta) (bool, error) {
// NOTE filter genesis operations
if !operationfilterf(meta.Hint()) {
return false, errors.Errorf("Not supported operation")
}
switch found, err := db.ExistsKnownOperation(meta.Operation()); {
case err != nil:
return false, err
case found:
log.Log().Trace().
Stringer("operation", meta.Operation()).
Msg("already processed; known operation")
return false, nil
}
switch found, err := db.ExistsInStateOperation(meta.Fact()); {
case err != nil:
return false, err
case found:
log.Log().Trace().Stringer("operation", meta.Fact()).Msg("already processed; in state")
return false, nil
}
// NOTE if bad operation and it is failed to be processed;
// it can be included in next proposal; it should be
// excluded.
// NOTE if operation has not enough fact signs, it will
// ignored. It must be filtered for not this kind of
// operations.
switch found, err := db.ExistsInStateOperation(meta.Fact()); {
case err != nil:
return false, err
case found:
return false, nil
}
var expire time.Duration
switch ht := meta.Hint(); {
case ht.Type() == isaacoperation.SuffrageCandidateFactHint.Type(),
ht.Type() == isaacoperation.SuffrageJoinFactHint.Type():
expire = params.MISC.ValidProposalSuffrageOperationsExpire()
default:
expire = params.MISC.ValidProposalOperationExpire()
}
if localtime.Now().UTC().After(meta.AddedAt().Add(expire)) {
return false, nil
}
return true, nil
},
)
if err != nil {
return nil, err
}
return hs, nil
}, nil
}