@@ -740,3 +740,160 @@ impl<'backend, 'config, B: Backend> MemoryStackState<'backend, 'config, B> {
740740 self . substate . deposit ( address, value, self . backend ) ;
741741 }
742742}
743+
744+ #[ cfg( test) ]
745+ mod tests {
746+ use crate :: backend:: { Backend , MemoryAccount , MemoryBackend , MemoryVicinity } ;
747+ use crate :: executor:: stack:: executor:: StackSubstateMetadata ;
748+ use crate :: executor:: stack:: memory:: MemoryStackState ;
749+ use crate :: executor:: stack:: StackState ;
750+ use crate :: prelude:: * ;
751+ use crate :: Config ;
752+ use primitive_types:: { H160 , U256 } ;
753+
754+ fn memory_vicinity ( ) -> MemoryVicinity {
755+ MemoryVicinity {
756+ gas_price : U256 :: from ( 1 ) ,
757+ effective_gas_price : Default :: default ( ) ,
758+ origin : H160 :: zero ( ) ,
759+ block_hashes : Vec :: new ( ) ,
760+ block_number : U256 :: zero ( ) ,
761+ block_coinbase : H160 :: zero ( ) ,
762+ block_timestamp : U256 :: zero ( ) ,
763+ block_difficulty : U256 :: zero ( ) ,
764+ block_randomness : None ,
765+ blob_gas_price : None ,
766+ block_gas_limit : U256 :: from ( 30_000_000 ) ,
767+ block_base_fee_per_gas : U256 :: from ( 1 ) ,
768+ chain_id : U256 :: from ( 1 ) ,
769+ blob_hashes : vec ! [ ] ,
770+ }
771+ }
772+
773+ #[ test]
774+ fn test_is_empty_catch_backend_only ( ) {
775+ let mut state = BTreeMap :: new ( ) ;
776+
777+ let addr1 = H160 :: from_low_u64_be ( 1 ) ;
778+ state. insert (
779+ addr1,
780+ MemoryAccount {
781+ balance : U256 :: one ( ) ,
782+ nonce : U256 :: zero ( ) ,
783+ storage : BTreeMap :: new ( ) ,
784+ code : Vec :: new ( ) ,
785+ } ,
786+ ) ;
787+
788+ let addr2 = H160 :: from_low_u64_be ( 2 ) ;
789+ state. insert (
790+ addr2,
791+ MemoryAccount {
792+ balance : U256 :: zero ( ) ,
793+ nonce : U256 :: one ( ) ,
794+ storage : BTreeMap :: new ( ) ,
795+ code : Vec :: new ( ) ,
796+ } ,
797+ ) ;
798+
799+ let addr3 = H160 :: from_low_u64_be ( 3 ) ;
800+ state. insert (
801+ addr3,
802+ MemoryAccount {
803+ balance : U256 :: zero ( ) ,
804+ nonce : U256 :: zero ( ) ,
805+ storage : BTreeMap :: new ( ) ,
806+ code : vec ! [ 0x42 ] ,
807+ } ,
808+ ) ;
809+
810+ let addr4 = H160 :: from_low_u64_be ( 4 ) ;
811+ state. insert (
812+ addr4,
813+ MemoryAccount {
814+ balance : U256 :: zero ( ) ,
815+ nonce : U256 :: zero ( ) ,
816+ storage : BTreeMap :: new ( ) ,
817+ code : Vec :: new ( ) ,
818+ } ,
819+ ) ;
820+
821+ let vicinity = memory_vicinity ( ) ;
822+ let backend = MemoryBackend :: new ( & vicinity, state) ;
823+ let config = Config :: osaka ( ) ;
824+ let metadata = StackSubstateMetadata :: new ( 0 , & config) ;
825+
826+ let stack_state = MemoryStackState :: new ( metadata, & backend) ;
827+
828+ assert ! ( !stack_state. is_empty( addr1) ) ;
829+ assert ! ( !stack_state. is_empty( addr2) ) ;
830+ assert ! ( !stack_state. is_empty( addr3) ) ;
831+ assert ! ( stack_state. is_empty( addr4) ) ;
832+ }
833+
834+ #[ test]
835+ fn test_is_empty_with_cached_account ( ) {
836+ let mut state = BTreeMap :: new ( ) ;
837+
838+ let addr1 = H160 :: from_low_u64_be ( 1 ) ;
839+ state. insert (
840+ addr1,
841+ MemoryAccount {
842+ balance : U256 :: zero ( ) ,
843+ nonce : U256 :: zero ( ) ,
844+ storage : BTreeMap :: new ( ) ,
845+ code : Vec :: new ( ) ,
846+ } ,
847+ ) ;
848+
849+ let addr2 = H160 :: from_low_u64_be ( 2 ) ;
850+ state. insert (
851+ addr2,
852+ MemoryAccount {
853+ balance : U256 :: zero ( ) ,
854+ nonce : U256 :: zero ( ) ,
855+ storage : BTreeMap :: new ( ) ,
856+ code : vec ! [ 0x42 ] ,
857+ } ,
858+ ) ;
859+
860+ let vicinity = memory_vicinity ( ) ;
861+ let backend = MemoryBackend :: new ( & vicinity, state) ;
862+ let config = Config :: osaka ( ) ;
863+ let metadata = StackSubstateMetadata :: new ( 0 , & config) ;
864+
865+ let mut stack_state = MemoryStackState :: new ( metadata, & backend) ;
866+ assert ! ( stack_state. is_empty( addr1) ) ;
867+ assert ! ( !stack_state. is_empty( addr2) ) ;
868+
869+ // Accounts cached
870+ stack_state. deposit ( addr1, U256 :: one ( ) ) ;
871+ stack_state. deposit ( addr2, U256 :: one ( ) ) ;
872+ // Cached account
873+ assert ! ( !stack_state. is_empty( addr1) ) ;
874+
875+ // Ensure that code will pass `is_some` check to catch data from backend.
876+ let acc1 = stack_state. substate . accounts . get ( & addr1) . unwrap ( ) ;
877+ let acc2 = stack_state. substate . accounts . get ( & addr2) . unwrap ( ) ;
878+ assert_eq ! ( acc1. basic. balance, U256 :: one( ) ) ;
879+ assert ! ( acc1. code. is_none( ) ) ;
880+ assert_eq ! ( acc2. basic. balance, U256 :: one( ) ) ;
881+ // NOTE: code is not cached
882+ assert ! ( acc2. code. is_none( ) ) ;
883+
884+ stack_state. reset_balance ( addr1) ;
885+ // Get from cache and code from backend.
886+ assert ! ( stack_state. is_empty( addr1) ) ;
887+ assert ! ( stack_state. code( addr1) . is_empty( ) ) ;
888+
889+ stack_state. reset_balance ( addr2) ;
890+ let acc2 = stack_state. substate . accounts . get ( & addr2) . unwrap ( ) ;
891+ assert_eq ! ( acc2. basic. balance, U256 :: zero( ) ) ;
892+ // NOTE: code is not cached
893+ assert ! ( acc2. code. is_none( ) ) ;
894+ // Get code from backend, but in backend code is not empty, so account is not empty.
895+ assert ! ( !stack_state. is_empty( addr2) ) ;
896+ // Get code from backend, but in backend code is not empty
897+ assert_eq ! ( stack_state. code( addr2) , vec![ 0x42 ] ) ;
898+ }
899+ }
0 commit comments