-
Notifications
You must be signed in to change notification settings - Fork 271
/
app.go
97 lines (83 loc) · 3.2 KB
/
app.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
package malicious
import (
"io"
"github.com/celestiaorg/celestia-app/app"
"github.com/celestiaorg/celestia-app/app/encoding"
"github.com/cosmos/cosmos-sdk/baseapp"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
)
const (
// BehaviorConfigKey is the key used to set the malicious config.
BehaviorConfigKey = "behavior_config"
// OutOfOrderHandlerKey is the key used to set the out of order prepare
// proposal handler.
OutOfOrderHandlerKey = "out_of_order"
)
// BehaviorConfig defines the malicious behavior for the application. It
// dictates the height at which the malicious behavior will start along with
// what type of malicious behavior will be performed.
type BehaviorConfig struct {
// HandlerName is the name of the malicious handler to use. All known
// handlers are defined in the PrepareProposalHandlerMap.
HandlerName string `json:"handler_name"`
// StartHeight is the height at which the malicious behavior will start.
StartHeight int64 `json:"start_height"`
}
type PrepareProposalHandler func(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal
// PrepareProposalHandlerMap is a map of all the known prepare proposal handlers.
func (a *App) PrepareProposalHandlerMap() map[string]PrepareProposalHandler {
return map[string]PrepareProposalHandler{
OutOfOrderHandlerKey: a.OutOfOrderPrepareProposal,
}
}
type App struct {
*app.App
maliciousStartHeight int64
malPreparePropsoalHandler PrepareProposalHandler
}
func New(
logger log.Logger,
db dbm.DB,
traceStore io.Writer,
loadLatest bool,
skipUpgradeHeights map[int64]bool,
homePath string,
invCheckPeriod uint,
encodingConfig encoding.Config,
appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp),
) *App {
goodApp := app.New(logger, db, traceStore, loadLatest, skipUpgradeHeights, homePath, invCheckPeriod, encodingConfig, appOpts, baseAppOptions...)
badApp := &App{App: goodApp}
// set the malicious prepare proposal handler if it is set in the app options
if malHanderName := appOpts.Get(BehaviorConfigKey); malHanderName != nil {
badApp.SetMaliciousBehavior(malHanderName.(BehaviorConfig))
}
return badApp
}
func (a *App) SetMaliciousBehavior(mcfg BehaviorConfig) {
// check if the handler is known
if _, ok := a.PrepareProposalHandlerMap()[mcfg.HandlerName]; !ok {
panic("unknown malicious prepare proposal handler")
}
a.malPreparePropsoalHandler = a.PrepareProposalHandlerMap()[mcfg.HandlerName]
a.maliciousStartHeight = mcfg.StartHeight
}
// PrepareProposal overwrites the default app's method to use the configured
// malicious behavior after a given height.
func (a *App) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
if a.LastBlockHeight()+1 >= a.maliciousStartHeight {
return a.malPreparePropsoalHandler(req)
}
return a.App.PrepareProposal(req)
}
// ProcessProposal overwrites the default app's method to auto accept any
// proposal.
func (a *App) ProcessProposal(_ abci.RequestProcessProposal) (resp abci.ResponseProcessProposal) {
return abci.ResponseProcessProposal{
Result: abci.ResponseProcessProposal_ACCEPT,
}
}