@@ -7,6 +7,7 @@ package blocksync
77
88import (
99 "context"
10+ "math/big"
1011 "testing"
1112 "time"
1213
@@ -18,6 +19,7 @@ import (
1819 "go.uber.org/mock/gomock"
1920 "google.golang.org/protobuf/proto"
2021
22+ "github.com/iotexproject/iotex-core/v2/action"
2123 "github.com/iotexproject/iotex-core/v2/action/protocol"
2224 "github.com/iotexproject/iotex-core/v2/action/protocol/account"
2325 accountutil "github.com/iotexproject/iotex-core/v2/action/protocol/account/util"
@@ -549,3 +551,102 @@ func TestDummyBlockSync(t *testing.T) {
549551 require .Zero (targetHeight )
550552 require .Empty (desc )
551553}
554+
555+ // TestBlockValidationWithBlacklistedSender tests that blocks containing actions
556+ // from blacklisted senders are rejected during validation
557+ func TestBlockValidationWithBlacklistedSender (t * testing.T ) {
558+ require := require .New (t )
559+ ctrl := gomock .NewController (t )
560+
561+ ctx := context .Background ()
562+
563+ // Use identity 27 as the producer and identity 28 as the blacklisted sender
564+ producerPriKey := identityset .PrivateKey (27 )
565+ blacklistedPriKey := identityset .PrivateKey (28 )
566+ blacklistedAddr := blacklistedPriKey .PublicKey ().Address ()
567+
568+ // Create a config with the blacklisted address
569+ cfg , err := newTestConfig ()
570+ require .NoError (err )
571+ cfg .ActPool .BlackList = []string {blacklistedAddr .String ()}
572+
573+ // Set up registry and protocols
574+ registry := protocol .NewRegistry ()
575+ acc := account .NewProtocol (rewarding .DepositGas )
576+ require .NoError (acc .Register (registry ))
577+ rp := rolldpos .NewProtocol (cfg .Genesis .NumCandidateDelegates , cfg .Genesis .NumDelegates , cfg .Genesis .NumSubEpochs )
578+ require .NoError (rp .Register (registry ))
579+
580+ // Initialize account balances for testing
581+ cfg .Genesis .InitBalanceMap = map [string ]string {
582+ identityset .Address (27 ).String (): "1000000000000000000000" ,
583+ blacklistedAddr .String (): "1000000000000000000000" ,
584+ }
585+
586+ // Create state factory
587+ factoryCfg := factory .GenerateConfig (cfg .Chain , cfg .Genesis )
588+ sf , err := factory .NewStateDB (factoryCfg , db .NewMemKVStore (), factory .RegistryStateDBOption (registry ))
589+ require .NoError (err )
590+
591+ // Create actpool with blacklist
592+ ap , err := actpool .NewActPool (cfg .Genesis , sf , cfg .ActPool )
593+ require .NotNil (ap )
594+ require .NoError (err )
595+ ap .AddActionEnvelopeValidators (protocol .NewGenericValidator (sf , accountutil .AccountState ))
596+
597+ // Create blockchain with actpool as validator
598+ store , err := filedao .NewFileDAOInMemForTest ()
599+ require .NoError (err )
600+ dao := blockdao .NewBlockDAOWithIndexersAndCache (store , []blockdao.BlockIndexer {sf }, 16 )
601+ chain := blockchain .NewBlockchain (
602+ cfg .Chain ,
603+ cfg .Genesis ,
604+ dao ,
605+ factory .NewMinter (sf , ap ),
606+ blockchain .BlockValidatorOption (block .NewValidator (sf , ap )),
607+ )
608+ require .NotNil (chain )
609+ require .NoError (chain .Start (ctx ))
610+
611+ // Create mock consensus
612+ cs := mock_consensus .NewMockConsensus (ctrl )
613+ cs .EXPECT ().ValidateBlockFooter (gomock .Any ()).Return (nil ).AnyTimes ()
614+
615+ defer func () {
616+ require .NoError (chain .Stop (ctx ))
617+ }()
618+
619+ // Create a transfer action from the blacklisted sender
620+ transfer , err := action .SignedTransfer (
621+ identityset .Address (27 ).String (),
622+ blacklistedPriKey ,
623+ 1 ,
624+ big .NewInt (100 ),
625+ nil ,
626+ 1000000 ,
627+ big .NewInt (1 ),
628+ )
629+ require .NoError (err )
630+
631+ // Get the tip info for creating the new block
632+ tipHeight := chain .TipHeight ()
633+ blkCtx , err := chain .Context (ctx )
634+ require .NoError (err )
635+ tip := protocol .MustGetBlockchainCtx (blkCtx ).Tip
636+
637+ // Create a properly signed block containing the blacklisted sender's action
638+ blk , err := block .NewTestingBuilder ().
639+ SetHeight (tipHeight + 1 ).
640+ SetPrevBlockHash (tip .Hash ).
641+ SetTimeStamp (testutil .TimestampNow ()).
642+ AddActions (transfer ).
643+ SignAndBuild (producerPriKey )
644+ require .NoError (err )
645+
646+ // The block validation should fail because the sender is blacklisted
647+ err = chain .ValidateBlock (& blk )
648+ require .Error (err )
649+ // The full error message should contain "blacklisted"
650+ // The error chain is: "failed to validate action: action source address is blacklisted: invalid address"
651+ require .Contains (err .Error (), "blacklisted" )
652+ }
0 commit comments