Skip to content

Commit

Permalink
Add action source address blacklist in actpool (#1017)
Browse files Browse the repository at this point in the history
  • Loading branch information
lizhefeng authored Apr 15, 2019
1 parent 303347e commit 5029d8c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 7 deletions.
17 changes: 17 additions & 0 deletions actpool/actpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,24 @@ type actPool struct {
validators []protocol.ActionValidator
timerFactory *prometheustimer.TimerFactory
enableExperimentalActions bool
senderBlackList map[string]bool
}

// NewActPool constructs a new actpool
func NewActPool(bc blockchain.Blockchain, cfg config.ActPool, opts ...Option) (ActPool, error) {
if bc == nil {
return nil, errors.New("Try to attach a nil blockchain")
}

senderBlackList := make(map[string]bool)
for _, bannedSender := range cfg.BlackList{
senderBlackList[bannedSender] = true
}

ap := &actPool{
cfg: cfg,
bc: bc,
senderBlackList: senderBlackList,
accountActs: make(map[string]ActQueue),
allActions: make(map[hash.Hash256]action.SealedEnvelope),
}
Expand Down Expand Up @@ -150,6 +158,15 @@ func (ap *actPool) Add(act action.SealedEnvelope) error {
if !ap.enableExperimentalActions && action.IsExperimentalAction(act.Action()) {
return errors.New("Experimental action is not enabled")
}
// Reject action if action source address is blacklisted
pubKeyHash := act.SrcPubkey().Hash()
srcAddr, err := address.FromBytes(pubKeyHash)
if err != nil {
return errors.Wrap(err, "failed to get address from bytes")
}
if _, ok := ap.senderBlackList[srcAddr.String()]; ok {
return errors.Wrap(action.ErrAddress, "action source address is blacklisted")
}
// Reject action if pool space is full
if uint64(len(ap.allActions)) >= ap.cfg.MaxNumActsPerPool {
return errors.Wrap(action.ErrActPool, "insufficient space for action")
Expand Down
22 changes: 15 additions & 7 deletions actpool/actpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ var (
priKey4 = testaddress.Keyinfo["delta"].PriKey
addr5 = testaddress.Addrinfo["echo"].String()
priKey5 = testaddress.Keyinfo["echo"].PriKey
addr6 = testaddress.Addrinfo["foxtrot"].String()
priKey6 = testaddress.Keyinfo["foxtrot"].PriKey
)

func TestActPool_validateGenericAction(t *testing.T) {
Expand Down Expand Up @@ -202,12 +204,17 @@ func TestActPool_AddActs(t *testing.T) {
pNonce2, _ = ap.getPendingNonce(addr2)
require.Equal(uint64(4), pNonce2)
// Error Case Handling
// Case I: Action already exists in pool
// Case I: Action source address is blacklisted
bannedTsf, err := testutil.SignedTransfer(addr6, priKey6, uint64(1), big.NewInt(0), []byte{}, uint64(100000), big.NewInt(0))
require.NoError(err)
err = ap.Add(bannedTsf)
require.True(strings.Contains(err.Error(), "action source address is blacklisted"))
// Case II: Action already exists in pool
err = ap.Add(tsf1)
require.Error(err)
err = ap.Add(vote4)
require.Error(err)
// Case II: Pool space/gas space is full
// Case III: Pool space/gas space is full
mockBC := mock_blockchain.NewMockBlockchain(ctrl)
Ap2, err := NewActPool(mockBC, apConfig, EnableExperimentalActions())
require.NoError(err)
Expand Down Expand Up @@ -241,7 +248,7 @@ func TestActPool_AddActs(t *testing.T) {
err = ap3.Add(tsf10)
require.True(strings.Contains(err.Error(), "insufficient gas space for action"))

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

err = ap.Add(selp)
require.Equal(action.ErrNonce, errors.Cause(err))
// Case IV: Nonce is too large
// Case V: Nonce is too large
outOfBoundsTsf, err := testutil.SignedTransfer(addr1, priKey1, ap.cfg.MaxNumActsPerAcct+1, big.NewInt(1), []byte{}, uint64(100000), big.NewInt(0))
require.NoError(err)
err = ap.Add(outOfBoundsTsf)
require.Equal(action.ErrNonce, errors.Cause(err))
// Case V: Insufficient balance
// Case VI: Insufficient balance
overBalTsf, err := testutil.SignedTransfer(addr2, priKey2, uint64(4), big.NewInt(20), []byte{}, uint64(100000), big.NewInt(0))
require.NoError(err)
err = ap.Add(overBalTsf)
require.Equal(action.ErrBalance, errors.Cause(err))
// Case VI: over gas limit
// Case VII: over gas limit
creationExecution, err := action.NewExecution(
action.EmptyAddress,
uint64(5),
Expand All @@ -290,7 +297,7 @@ func TestActPool_AddActs(t *testing.T) {

err = ap.Add(selp)
require.Equal(action.ErrGasHigherThanLimit, errors.Cause(err))
// Case VII: insufficient gas
// Case VIII: insufficient gas
tmpData := [1234]byte{}
creationExecution, err = action.NewExecution(
action.EmptyAddress,
Expand Down Expand Up @@ -1136,6 +1143,7 @@ func getActPoolCfg() config.ActPool {
MaxGasLimitPerPool: maxGasLimitPerPool,
MaxNumActsPerAcct: maxNumActsPerAcct,
MinGasPriceStr: "0",
BlackList: []string{addr6},
}
}

Expand Down
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ var (
MaxNumActsPerAcct: 2000,
ActionExpiry: 10 * time.Minute,
MinGasPriceStr: big.NewInt(unit.Qev).String(),
BlackList: []string{},
},
Consensus: Consensus{
Scheme: StandaloneScheme,
Expand Down Expand Up @@ -346,6 +347,8 @@ type (
ActionExpiry time.Duration `yaml:"actionExpiry"`
// MinGasPriceStr defines the minimal gas price the delegate will accept for an action
MinGasPriceStr string `yaml:"minGasPrice"`
// BlackList lists the account address that are banned from initiating actions
BlackList []string `yaml:"blackList"`
}

// DB is the config for database
Expand Down

0 comments on commit 5029d8c

Please sign in to comment.