Skip to content

Commit 5029d8c

Browse files
authored
Add action source address blacklist in actpool (iotexproject#1017)
1 parent 303347e commit 5029d8c

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

actpool/actpool.go

+17
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,24 @@ type actPool struct {
7474
validators []protocol.ActionValidator
7575
timerFactory *prometheustimer.TimerFactory
7676
enableExperimentalActions bool
77+
senderBlackList map[string]bool
7778
}
7879

7980
// NewActPool constructs a new actpool
8081
func NewActPool(bc blockchain.Blockchain, cfg config.ActPool, opts ...Option) (ActPool, error) {
8182
if bc == nil {
8283
return nil, errors.New("Try to attach a nil blockchain")
8384
}
85+
86+
senderBlackList := make(map[string]bool)
87+
for _, bannedSender := range cfg.BlackList{
88+
senderBlackList[bannedSender] = true
89+
}
90+
8491
ap := &actPool{
8592
cfg: cfg,
8693
bc: bc,
94+
senderBlackList: senderBlackList,
8795
accountActs: make(map[string]ActQueue),
8896
allActions: make(map[hash.Hash256]action.SealedEnvelope),
8997
}
@@ -150,6 +158,15 @@ func (ap *actPool) Add(act action.SealedEnvelope) error {
150158
if !ap.enableExperimentalActions && action.IsExperimentalAction(act.Action()) {
151159
return errors.New("Experimental action is not enabled")
152160
}
161+
// Reject action if action source address is blacklisted
162+
pubKeyHash := act.SrcPubkey().Hash()
163+
srcAddr, err := address.FromBytes(pubKeyHash)
164+
if err != nil {
165+
return errors.Wrap(err, "failed to get address from bytes")
166+
}
167+
if _, ok := ap.senderBlackList[srcAddr.String()]; ok {
168+
return errors.Wrap(action.ErrAddress, "action source address is blacklisted")
169+
}
153170
// Reject action if pool space is full
154171
if uint64(len(ap.allActions)) >= ap.cfg.MaxNumActsPerPool {
155172
return errors.Wrap(action.ErrActPool, "insufficient space for action")

actpool/actpool_test.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ var (
5151
priKey4 = testaddress.Keyinfo["delta"].PriKey
5252
addr5 = testaddress.Addrinfo["echo"].String()
5353
priKey5 = testaddress.Keyinfo["echo"].PriKey
54+
addr6 = testaddress.Addrinfo["foxtrot"].String()
55+
priKey6 = testaddress.Keyinfo["foxtrot"].PriKey
5456
)
5557

5658
func TestActPool_validateGenericAction(t *testing.T) {
@@ -202,12 +204,17 @@ func TestActPool_AddActs(t *testing.T) {
202204
pNonce2, _ = ap.getPendingNonce(addr2)
203205
require.Equal(uint64(4), pNonce2)
204206
// Error Case Handling
205-
// Case I: Action already exists in pool
207+
// Case I: Action source address is blacklisted
208+
bannedTsf, err := testutil.SignedTransfer(addr6, priKey6, uint64(1), big.NewInt(0), []byte{}, uint64(100000), big.NewInt(0))
209+
require.NoError(err)
210+
err = ap.Add(bannedTsf)
211+
require.True(strings.Contains(err.Error(), "action source address is blacklisted"))
212+
// Case II: Action already exists in pool
206213
err = ap.Add(tsf1)
207214
require.Error(err)
208215
err = ap.Add(vote4)
209216
require.Error(err)
210-
// Case II: Pool space/gas space is full
217+
// Case III: Pool space/gas space is full
211218
mockBC := mock_blockchain.NewMockBlockchain(ctrl)
212219
Ap2, err := NewActPool(mockBC, apConfig, EnableExperimentalActions())
213220
require.NoError(err)
@@ -241,7 +248,7 @@ func TestActPool_AddActs(t *testing.T) {
241248
err = ap3.Add(tsf10)
242249
require.True(strings.Contains(err.Error(), "insufficient gas space for action"))
243250

244-
// Case III: Nonce already exists
251+
// Case IV: Nonce already exists
245252
replaceTsf, err := testutil.SignedTransfer(addr2, priKey1, uint64(1), big.NewInt(1), []byte{}, uint64(100000), big.NewInt(0))
246253
require.NoError(err)
247254
err = ap.Add(replaceTsf)
@@ -259,17 +266,17 @@ func TestActPool_AddActs(t *testing.T) {
259266

260267
err = ap.Add(selp)
261268
require.Equal(action.ErrNonce, errors.Cause(err))
262-
// Case IV: Nonce is too large
269+
// Case V: Nonce is too large
263270
outOfBoundsTsf, err := testutil.SignedTransfer(addr1, priKey1, ap.cfg.MaxNumActsPerAcct+1, big.NewInt(1), []byte{}, uint64(100000), big.NewInt(0))
264271
require.NoError(err)
265272
err = ap.Add(outOfBoundsTsf)
266273
require.Equal(action.ErrNonce, errors.Cause(err))
267-
// Case V: Insufficient balance
274+
// Case VI: Insufficient balance
268275
overBalTsf, err := testutil.SignedTransfer(addr2, priKey2, uint64(4), big.NewInt(20), []byte{}, uint64(100000), big.NewInt(0))
269276
require.NoError(err)
270277
err = ap.Add(overBalTsf)
271278
require.Equal(action.ErrBalance, errors.Cause(err))
272-
// Case VI: over gas limit
279+
// Case VII: over gas limit
273280
creationExecution, err := action.NewExecution(
274281
action.EmptyAddress,
275282
uint64(5),
@@ -290,7 +297,7 @@ func TestActPool_AddActs(t *testing.T) {
290297

291298
err = ap.Add(selp)
292299
require.Equal(action.ErrGasHigherThanLimit, errors.Cause(err))
293-
// Case VII: insufficient gas
300+
// Case VIII: insufficient gas
294301
tmpData := [1234]byte{}
295302
creationExecution, err = action.NewExecution(
296303
action.EmptyAddress,
@@ -1136,6 +1143,7 @@ func getActPoolCfg() config.ActPool {
11361143
MaxGasLimitPerPool: maxGasLimitPerPool,
11371144
MaxNumActsPerAcct: maxNumActsPerAcct,
11381145
MinGasPriceStr: "0",
1146+
BlackList: []string{addr6},
11391147
}
11401148
}
11411149

config/config.go

+3
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ var (
121121
MaxNumActsPerAcct: 2000,
122122
ActionExpiry: 10 * time.Minute,
123123
MinGasPriceStr: big.NewInt(unit.Qev).String(),
124+
BlackList: []string{},
124125
},
125126
Consensus: Consensus{
126127
Scheme: StandaloneScheme,
@@ -346,6 +347,8 @@ type (
346347
ActionExpiry time.Duration `yaml:"actionExpiry"`
347348
// MinGasPriceStr defines the minimal gas price the delegate will accept for an action
348349
MinGasPriceStr string `yaml:"minGasPrice"`
350+
// BlackList lists the account address that are banned from initiating actions
351+
BlackList []string `yaml:"blackList"`
349352
}
350353

351354
// DB is the config for database

0 commit comments

Comments
 (0)