@@ -501,7 +501,7 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
501501
502502 // Apply transaction
503503 var usedGas uint64
504- _ , _ , _ , err = ApplyTransactionWithEVM (msg , gasPool , statedb , blockNumber , blockHash , signedTx , & usedGas , evm , big .NewInt (0 ), common. Address {} )
504+ _ , _ , _ , err = ApplyTransactionWithEVM (msg , gasPool , statedb , blockNumber , blockHash , signedTx , & usedGas , evm , big .NewInt (0 ))
505505 // NOTE: Some special transactions (like BlockSignersBinary or XDCXAddrBinary)
506506 // may fail in test environment due to missing configuration or state, but
507507 // the tracer should still be called at the beginning of ApplyTransactionWithEVM.
@@ -589,7 +589,7 @@ func TestApplyTransactionWithEVMStateChangeHooks(t *testing.T) {
589589
590590 gasPool := new (GasPool ).AddGas (1000000 )
591591 var usedGas uint64
592- _ , _ , _ , err = ApplyTransactionWithEVM (msg , gasPool , statedb , big .NewInt (1 ), genesis .Hash (), signedTx , & usedGas , evmenv , nil , common. Address {} )
592+ _ , _ , _ , err = ApplyTransactionWithEVM (msg , gasPool , statedb , big .NewInt (1 ), genesis .Hash (), signedTx , & usedGas , evmenv , nil )
593593 if err != nil {
594594 t .Fatalf ("ApplyTransactionWithEVM failed: %v" , err )
595595 }
@@ -598,6 +598,158 @@ func TestApplyTransactionWithEVMStateChangeHooks(t *testing.T) {
598598 }
599599}
600600
601+ func TestProcessReReadsCoinbaseOwnerPerTransaction (t * testing.T ) {
602+ var (
603+ config = & params.ChainConfig {
604+ ChainID : big .NewInt (1 ),
605+ HomesteadBlock : big .NewInt (0 ),
606+ EIP150Block : big .NewInt (0 ),
607+ EIP155Block : big .NewInt (0 ),
608+ EIP158Block : big .NewInt (0 ),
609+ ByzantiumBlock : big .NewInt (0 ),
610+ ConstantinopleBlock : big .NewInt (0 ),
611+ PetersburgBlock : big .NewInt (0 ),
612+ IstanbulBlock : big .NewInt (0 ),
613+ BerlinBlock : big .NewInt (0 ),
614+ LondonBlock : big .NewInt (0 ),
615+ Eip1559Block : big .NewInt (0 ),
616+ Ethash : new (params.EthashConfig ),
617+ }
618+ chainEngine = ethash .NewFaker ()
619+ engine = noOpFinalizeEngine {Engine : chainEngine }
620+ signer = types .LatestSigner (config )
621+ testKey , _ = crypto .HexToECDSA ("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" )
622+ sender = crypto .PubkeyToAddress (testKey .PublicKey )
623+ coinbase = common .HexToAddress ("0x00000000000000000000000000000000000000c0" )
624+ owner1 = common .HexToAddress ("0x00000000000000000000000000000000000000a1" )
625+ owner2 = common .HexToAddress ("0x00000000000000000000000000000000000000a2" )
626+ tokenAddr = common .HexToAddress ("0x00000000000000000000000000000000000000b0" )
627+ blockNumber = new (big.Int ).Add (common .TIPTRC21Fee , common .Big1 )
628+ gasTipCap = new (big.Int ).Set (common .BaseFee )
629+ gasFeeCap = new (big.Int ).Mul (new (big.Int ).Set (common .BaseFee ), big .NewInt (2 ))
630+ )
631+
632+ db := rawdb .NewMemoryDatabase ()
633+ gspec := & Genesis {
634+ Config : config ,
635+ Alloc : types.GenesisAlloc {
636+ sender : {
637+ Balance : big .NewInt (1000000000000000000 ),
638+ Nonce : 0 ,
639+ },
640+ },
641+ }
642+ genesis := gspec .MustCommit (db )
643+ blockchain , _ := NewBlockChain (db , nil , gspec , chainEngine , vm.Config {})
644+ defer blockchain .Stop ()
645+
646+ statedb , err := blockchain .State ()
647+ if err != nil {
648+ t .Fatalf ("Failed to get state: %v" , err )
649+ }
650+ setCoinbaseOwner (statedb , coinbase , owner1 )
651+
652+ tx1 , err := types .SignTx (types .NewTx (& types.DynamicFeeTx {
653+ Nonce : 0 ,
654+ GasTipCap : gasTipCap ,
655+ GasFeeCap : gasFeeCap ,
656+ Gas : 21000 ,
657+ To : & tokenAddr ,
658+ Value : big .NewInt (0 ),
659+ }), signer , testKey )
660+ if err != nil {
661+ t .Fatalf ("Failed to sign first tx: %v" , err )
662+ }
663+ tx2 , err := types .SignTx (types .NewTx (& types.DynamicFeeTx {
664+ Nonce : 1 ,
665+ GasTipCap : gasTipCap ,
666+ GasFeeCap : gasFeeCap ,
667+ Gas : 21068 ,
668+ To : & tokenAddr ,
669+ Value : big .NewInt (0 ),
670+ Data : []byte {0x01 },
671+ }), signer , testKey )
672+ if err != nil {
673+ t .Fatalf ("Failed to sign second tx: %v" , err )
674+ }
675+
676+ header := & types.Header {
677+ ParentHash : genesis .Hash (),
678+ Coinbase : coinbase ,
679+ Difficulty : big .NewInt (0 ),
680+ GasLimit : 1000000 ,
681+ Number : blockNumber ,
682+ Time : genesis .Time () + 10 ,
683+ UncleHash : types .EmptyUncleHash ,
684+ BaseFee : new (big.Int ).Set (common .BaseFee ),
685+ }
686+ block := types .NewBlock (header , & types.Body {Transactions : types.Transactions {tx1 , tx2 }}, nil , trie .NewStackTrie (nil ))
687+
688+ txEndCalls := 0
689+ cfg := vm.Config {Tracer : & tracing.Hooks {
690+ OnTxEnd : func (receipt * types.Receipt , err error ) {
691+ txEndCalls ++
692+ if txEndCalls == 1 {
693+ setCoinbaseOwner (statedb , coinbase , owner2 )
694+ }
695+ },
696+ }}
697+ tokensFee := map [common.Address ]* big.Int {
698+ tokenAddr : new (big.Int ).Exp (big .NewInt (10 ), big .NewInt (18 ), nil ),
699+ }
700+
701+ processor := NewStateProcessor (config , blockchain , engine )
702+ receipts , _ , _ , err := processor .Process (block , statedb , nil , cfg , tokensFee )
703+ if err != nil {
704+ t .Fatalf ("Process failed: %v" , err )
705+ }
706+ if len (receipts ) != 2 {
707+ t .Fatalf ("expected 2 receipts, got %d" , len (receipts ))
708+ }
709+ if txEndCalls != 2 {
710+ t .Fatalf ("expected 2 OnTxEnd calls, got %d" , txEndCalls )
711+ }
712+
713+ owner1Balance := statedb .GetBalance (owner1 )
714+ owner2Balance := statedb .GetBalance (owner2 )
715+ if owner1Balance .Sign () <= 0 {
716+ t .Fatalf ("expected initial owner to receive first tx fee credit, have %v" , owner1Balance )
717+ }
718+ if owner2Balance .Sign () <= 0 {
719+ t .Fatalf ("expected updated owner to receive second tx fee credit, have %v" , owner2Balance )
720+ }
721+ expectedOwner1 := common .GetGasFee (blockNumber .Uint64 (), receipts [0 ].GasUsed )
722+ expectedOwner2 := common .GetGasFee (blockNumber .Uint64 (), receipts [1 ].GasUsed )
723+ if owner1Balance .Cmp (expectedOwner1 ) != 0 {
724+ t .Fatalf ("unexpected first owner fee credit: got %v want %v" , owner1Balance , expectedOwner1 )
725+ }
726+ if owner2Balance .Cmp (expectedOwner2 ) != 0 {
727+ t .Fatalf ("unexpected updated owner fee credit: got %v want %v" , owner2Balance , expectedOwner2 )
728+ }
729+
730+ totalCredited := new (big.Int ).Add (new (big.Int ).Set (owner1Balance ), owner2Balance )
731+ expectedTotal := new (big.Int ).Add (expectedOwner1 , expectedOwner2 )
732+ if totalCredited .Cmp (expectedTotal ) != 0 {
733+ t .Fatalf ("unexpected total fee credit: got %v want %v" , totalCredited , expectedTotal )
734+ }
735+ if owner1Balance .Cmp (expectedTotal ) == 0 {
736+ t .Fatalf ("all fee credit stayed with original owner, updated owner balance %v" , owner2Balance )
737+ }
738+ }
739+
740+ func setCoinbaseOwner (statedb * state.StateDB , coinbase common.Address , owner common.Address ) {
741+ ownerSlot := state .GetLocMappingAtKey (coinbase .Hash (), 1 )
742+ statedb .SetState (common .MasternodeVotingSMCBinary , common .BigToHash (ownerSlot ), owner .Hash ())
743+ }
744+
745+ type noOpFinalizeEngine struct {
746+ consensus.Engine
747+ }
748+
749+ func (e noOpFinalizeEngine ) Finalize (chain consensus.ChainReader , header * types.Header , state vm.StateDB , parentState * state.StateDB , txs []* types.Transaction , uncles []* types.Header , receipts []* types.Receipt ) (* types.Block , error ) {
750+ return nil , nil
751+ }
752+
601753func TestProcessParentBlockHash (t * testing.T ) {
602754 var (
603755 chainConfig = params .MergedTestChainConfig
0 commit comments