@@ -2,6 +2,7 @@ package state_test
22
33import (
44 "fmt"
5+ "math/big"
56 "testing"
67
78 gethCommon "github.com/ethereum/go-ethereum/common"
@@ -743,6 +744,245 @@ func TestDeltaView(t *testing.T) {
743744 emptyValue := gethCommon.Hash {}
744745 require .Equal (t , emptyValue , vret )
745746 })
747+
748+ t .Run ("test HasData for all combinations" , func (t * testing.T ) {
749+ view := state .NewDeltaView (
750+ & MockedReadOnlyView {
751+ GetRefundFunc : emptyRefund ,
752+ },
753+ )
754+ require .False (t , view .HasData ())
755+
756+ view = state .NewDeltaView (
757+ & MockedReadOnlyView {
758+ GetRefundFunc : emptyRefund ,
759+ IsCreatedFunc : func (a gethCommon.Address ) bool {
760+ return false
761+ },
762+ ExistFunc : func (a gethCommon.Address ) (bool , error ) {
763+ return false , nil
764+ },
765+ HasSelfDestructedFunc : func (a gethCommon.Address ) (bool , * uint256.Int ) {
766+ return false , new (uint256.Int )
767+ },
768+ },
769+ )
770+ // This will set the `dirtyAddresses` & `created` maps
771+ err := view .CreateAccount (gethCommon.Address {0x12 })
772+ require .NoError (t , err )
773+ require .True (t , len (view .DirtyAddresses ()) > 0 )
774+ require .True (t , view .IsCreated (gethCommon.Address {0x12 }))
775+ require .True (t , view .HasData ())
776+
777+ view = state .NewDeltaView (
778+ & MockedReadOnlyView {
779+ GetRefundFunc : emptyRefund ,
780+ },
781+ )
782+ // This will set the `newContract` map
783+ view .CreateContract (gethCommon.Address {0x10 })
784+ require .True (t , view .IsNewContract (gethCommon.Address {0x10 }))
785+ require .True (t , view .HasData ())
786+
787+ view = state .NewDeltaView (
788+ & MockedReadOnlyView {
789+ GetRefundFunc : emptyRefund ,
790+ ExistFunc : func (a gethCommon.Address ) (bool , error ) {
791+ return true , nil
792+ },
793+ HasSelfDestructedFunc : func (a gethCommon.Address ) (bool , * uint256.Int ) {
794+ return false , new (uint256.Int )
795+ },
796+ GetBalanceFunc : func (a gethCommon.Address ) (* uint256.Int , error ) {
797+ return uint256 .MustFromBig (big .NewInt (100 )), nil
798+ },
799+ },
800+ )
801+ // This will set the `toBeDestructed` map
802+ err = view .SelfDestruct (gethCommon.Address {0x12 })
803+ require .NoError (t , err )
804+ hasSelfDestructed , _ := view .HasSelfDestructed (gethCommon.Address {0x12 })
805+ require .True (t , hasSelfDestructed )
806+ require .True (t , view .HasData ())
807+
808+ view = state .NewDeltaView (
809+ & MockedReadOnlyView {
810+ GetRefundFunc : emptyRefund ,
811+ IsCreatedFunc : func (a gethCommon.Address ) bool {
812+ return false
813+ },
814+ ExistFunc : func (a gethCommon.Address ) (bool , error ) {
815+ return true , nil
816+ },
817+ HasSelfDestructedFunc : func (a gethCommon.Address ) (bool , * uint256.Int ) {
818+ return false , new (uint256.Int )
819+ },
820+ GetBalanceFunc : func (a gethCommon.Address ) (* uint256.Int , error ) {
821+ return uint256 .MustFromBig (big .NewInt (100 )), nil
822+ },
823+ },
824+ )
825+ // This will set the `recreated` map
826+ err = view .CreateAccount (gethCommon.Address {0x12 })
827+ require .NoError (t , err )
828+ require .True (t , view .HasData ())
829+
830+ view = state .NewDeltaView (
831+ & MockedReadOnlyView {
832+ GetRefundFunc : emptyRefund ,
833+ IsCreatedFunc : func (a gethCommon.Address ) bool {
834+ return false
835+ },
836+ ExistFunc : func (a gethCommon.Address ) (bool , error ) {
837+ return true , nil
838+ },
839+ HasSelfDestructedFunc : func (a gethCommon.Address ) (bool , * uint256.Int ) {
840+ return true , uint256 .MustFromBig (big .NewInt (100 ))
841+ },
842+ GetBalanceFunc : func (a gethCommon.Address ) (* uint256.Int , error ) {
843+ return uint256 .MustFromBig (big .NewInt (0 )), nil
844+ },
845+ },
846+ )
847+ // This will set the `balances` map
848+ err = view .AddBalance (gethCommon.Address {0x12 }, uint256 .MustFromBig (big .NewInt (100 )))
849+ require .NoError (t , err )
850+ require .True (t , view .HasData ())
851+
852+ view = state .NewDeltaView (
853+ & MockedReadOnlyView {
854+ GetRefundFunc : emptyRefund ,
855+ },
856+ )
857+ // This will set the `nonces` map
858+ err = view .SetNonce (gethCommon.Address {0x10 }, 3 )
859+ require .NoError (t , err )
860+ nonce , err := view .GetNonce (gethCommon.Address {0x10 })
861+ require .NoError (t , err )
862+ require .Equal (t , uint64 (3 ), nonce )
863+ require .True (t , view .HasData ())
864+
865+ view = state .NewDeltaView (
866+ & MockedReadOnlyView {
867+ GetRefundFunc : emptyRefund ,
868+ },
869+ )
870+ // This will set the `codes` & `codeHashes` map
871+ err = view .SetCode (gethCommon.Address {0x10 }, []byte {0x1 , 0x10 , 0x55 , 0x16 , 0x20 })
872+ require .NoError (t , err )
873+ code , err := view .GetCode (gethCommon.Address {0x10 })
874+ require .NoError (t , err )
875+ require .Equal (t , []byte {0x1 , 0x10 , 0x55 , 0x16 , 0x20 }, code )
876+ require .True (t , view .HasData ())
877+
878+ view = state .NewDeltaView (
879+ & MockedReadOnlyView {
880+ GetRefundFunc : emptyRefund ,
881+ GetStateFunc : func (sa types.SlotAddress ) (gethCommon.Hash , error ) {
882+ return gethCommon.Hash {}, nil
883+ },
884+ },
885+ )
886+ sk := types.SlotAddress {
887+ Address : gethCommon.Address {0x10 },
888+ Key : gethCommon.Hash {0x2 },
889+ }
890+ // This will set the `slots` map
891+ previousVal , err := view .SetState (sk , gethCommon.Hash {0x55 })
892+ require .NoError (t , err )
893+ require .Equal (t , gethCommon.Hash {}, previousVal )
894+ stateVal , err := view .GetState (sk )
895+ require .NoError (t , err )
896+ require .Equal (t , gethCommon.Hash {0x55 }, stateVal )
897+ require .True (t , view .HasData ())
898+
899+ view = state .NewDeltaView (
900+ & MockedReadOnlyView {
901+ GetRefundFunc : emptyRefund ,
902+ },
903+ )
904+ sk = types.SlotAddress {
905+ Address : gethCommon.Address {0x15 },
906+ Key : gethCommon.Hash {0x20 },
907+ }
908+ // This will set the `transient`
909+ view .SetTransientState (sk , gethCommon.Hash {0xfa })
910+ require .Equal (t , gethCommon.Hash {0xfa }, view .GetTransientState (sk ))
911+ require .True (t , view .HasData ())
912+ })
913+
914+ t .Run ("test get refund is carried over" , func (t * testing.T ) {
915+ ledger := testutils .GetSimpleValueStore ()
916+ rootView , err := state .NewBaseView (ledger , rootAddr )
917+ require .NoError (t , err )
918+ require .Equal (t , uint64 (0 ), rootView .GetRefund ())
919+
920+ view := state .NewDeltaView (rootView )
921+ refund := uint64 (100 )
922+ err = view .AddRefund (refund )
923+
924+ require .NoError (t , err )
925+ require .Equal (t , refund , view .GetRefund ())
926+ require .False (t , view .HasData ())
927+
928+ childView1 := state .NewDeltaView (view )
929+ childView2 := state .NewDeltaView (childView1 )
930+ childView3 := state .NewDeltaView (childView2 )
931+ childView4 := state .NewDeltaView (childView3 )
932+ childView5 := state .NewDeltaView (childView4 )
933+ childView6 := state .NewDeltaView (childView5 )
934+ childView7 := state .NewDeltaView (childView6 )
935+ childView8 := state .NewDeltaView (childView7 )
936+ childView9 := state .NewDeltaView (childView8 )
937+ childView10 := state .NewDeltaView (childView9 )
938+ childView11 := state .NewDeltaView (childView10 )
939+
940+ require .Equal (t , refund , childView11 .GetRefund ())
941+ })
942+
943+ t .Run ("test parent traversal" , func (t * testing.T ) {
944+ ledger := testutils .GetSimpleValueStore ()
945+ rootView , err := state .NewBaseView (ledger , rootAddr )
946+ require .NoError (t , err )
947+
948+ view := state .NewDeltaView (rootView )
949+ sk := types.SlotAddress {
950+ Address : gethCommon.Address {0x10 },
951+ Key : gethCommon.Hash {0x2 },
952+ }
953+ previousVal , err := view .SetState (sk , gethCommon.Hash {0x55 })
954+ require .NoError (t , err )
955+ require .Equal (t , gethCommon.Hash {}, previousVal )
956+ require .True (t , view .HasData ())
957+
958+ childView1 := state .NewDeltaView (view )
959+ childView2 := state .NewDeltaView (childView1 )
960+ childView3 := state .NewDeltaView (childView2 )
961+ childView4 := state .NewDeltaView (childView3 )
962+ childView5 := state .NewDeltaView (childView4 )
963+ childView6 := state .NewDeltaView (childView5 )
964+
965+ stateVal , err := childView6 .GetState (sk )
966+ require .NoError (t , err )
967+ require .False (t , childView6 .HasData ())
968+ require .Equal (t , gethCommon.Hash {0x55 }, stateVal )
969+
970+ previousVal , err = childView6 .SetState (sk , gethCommon.Hash {0x32 })
971+ require .NoError (t , err )
972+ require .Equal (t , stateVal , previousVal )
973+ require .True (t , childView6 .HasData ())
974+
975+ childView7 := state .NewDeltaView (childView6 )
976+ childView8 := state .NewDeltaView (childView7 )
977+ childView9 := state .NewDeltaView (childView8 )
978+ childView10 := state .NewDeltaView (childView9 )
979+ childView11 := state .NewDeltaView (childView10 )
980+
981+ stateVal , err = childView11 .GetState (sk )
982+ require .NoError (t , err )
983+ require .False (t , childView11 .HasData ())
984+ require .Equal (t , gethCommon.Hash {0x32 }, stateVal )
985+ })
746986}
747987
748988type MockedReadOnlyView struct {
0 commit comments