@@ -754,3 +754,250 @@ func ExampleRevertErrorData() {
754754 // revert: 08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a75736572206572726f72
755755 // message: user error
756756}
757+
758+ func TestSimulateV1 (t * testing.T ) {
759+ backend , _ , err := newTestBackend (nil )
760+ if err != nil {
761+ t .Fatalf ("Failed to create test backend: %v" , err )
762+ }
763+ defer backend .Close ()
764+
765+ client := ethclient .NewClient (backend .Attach ())
766+ defer client .Close ()
767+
768+ ctx := context .Background ()
769+
770+ // Get current base fee
771+ header , err := client .HeaderByNumber (ctx , nil )
772+ if err != nil {
773+ t .Fatalf ("Failed to get header: %v" , err )
774+ }
775+
776+ // Simple test: transfer ETH from one account to another
777+ from := testAddr
778+ to := common .HexToAddress ("0x0000000000000000000000000000000000000001" )
779+ value := big .NewInt (100 )
780+ gas := uint64 (100000 )
781+ maxFeePerGas := new (big.Int ).Mul (header .BaseFee , big .NewInt (2 ))
782+
783+ opts := ethclient.SimulateOptions {
784+ BlockStateCalls : []ethclient.SimulateBlock {
785+ {
786+ Calls : []ethereum.CallMsg {
787+ {
788+ From : from ,
789+ To : & to ,
790+ Value : value ,
791+ Gas : gas ,
792+ GasFeeCap : maxFeePerGas ,
793+ },
794+ },
795+ },
796+ },
797+ Validation : true ,
798+ }
799+
800+ results , err := client .SimulateV1 (ctx , opts , nil )
801+ if err != nil {
802+ t .Fatalf ("SimulateV1 failed: %v" , err )
803+ }
804+
805+ if len (results ) != 1 {
806+ t .Fatalf ("expected 1 block result, got %d" , len (results ))
807+ }
808+
809+ if len (results [0 ].Calls ) != 1 {
810+ t .Fatalf ("expected 1 call result, got %d" , len (results [0 ].Calls ))
811+ }
812+
813+ // Check that the transaction succeeded
814+ if results [0 ].Calls [0 ].Status != 1 {
815+ t .Errorf ("expected status 1 (success), got %d" , results [0 ].Calls [0 ].Status )
816+ }
817+
818+ if results [0 ].Calls [0 ].Error != nil {
819+ t .Errorf ("expected no error, got %v" , results [0 ].Calls [0 ].Error )
820+ }
821+ }
822+
823+ func TestSimulateV1WithBlockOverrides (t * testing.T ) {
824+ backend , _ , err := newTestBackend (nil )
825+ if err != nil {
826+ t .Fatalf ("Failed to create test backend: %v" , err )
827+ }
828+ defer backend .Close ()
829+
830+ client := ethclient .NewClient (backend .Attach ())
831+ defer client .Close ()
832+
833+ ctx := context .Background ()
834+
835+ // Get current base fee
836+ header , err := client .HeaderByNumber (ctx , nil )
837+ if err != nil {
838+ t .Fatalf ("Failed to get header: %v" , err )
839+ }
840+
841+ from := testAddr
842+ to := common .HexToAddress ("0x0000000000000000000000000000000000000001" )
843+ value := big .NewInt (100 )
844+ gas := uint64 (100000 )
845+ maxFeePerGas := new (big.Int ).Mul (header .BaseFee , big .NewInt (2 ))
846+
847+ // Override timestamp only
848+ timestamp := uint64 (1234567890 )
849+
850+ opts := ethclient.SimulateOptions {
851+ BlockStateCalls : []ethclient.SimulateBlock {
852+ {
853+ BlockOverrides : & ethereum.BlockOverrides {
854+ Time : timestamp ,
855+ },
856+ Calls : []ethereum.CallMsg {
857+ {
858+ From : from ,
859+ To : & to ,
860+ Value : value ,
861+ Gas : gas ,
862+ GasFeeCap : maxFeePerGas ,
863+ },
864+ },
865+ },
866+ },
867+ Validation : true ,
868+ }
869+
870+ results , err := client .SimulateV1 (ctx , opts , nil )
871+ if err != nil {
872+ t .Fatalf ("SimulateV1 with block overrides failed: %v" , err )
873+ }
874+
875+ if len (results ) != 1 {
876+ t .Fatalf ("expected 1 block result, got %d" , len (results ))
877+ }
878+
879+ // Verify the timestamp was overridden
880+ if results [0 ].Timestamp != timestamp {
881+ t .Errorf ("expected timestamp %d, got %d" , timestamp , results [0 ].Timestamp )
882+ }
883+ }
884+
885+ func TestSimulateV1WithStateOverrides (t * testing.T ) {
886+ backend , _ , err := newTestBackend (nil )
887+ if err != nil {
888+ t .Fatalf ("Failed to create test backend: %v" , err )
889+ }
890+ defer backend .Close ()
891+
892+ client := ethclient .NewClient (backend .Attach ())
893+ defer client .Close ()
894+
895+ ctx := context .Background ()
896+
897+ // Get current base fee
898+ header , err := client .HeaderByNumber (ctx , nil )
899+ if err != nil {
900+ t .Fatalf ("Failed to get header: %v" , err )
901+ }
902+
903+ from := testAddr
904+ to := common .HexToAddress ("0x0000000000000000000000000000000000000001" )
905+ value := big .NewInt (1000000000000000000 ) // 1 ETH
906+ gas := uint64 (100000 )
907+ maxFeePerGas := new (big.Int ).Mul (header .BaseFee , big .NewInt (2 ))
908+
909+ // Override the balance of the 'from' address
910+ balanceStr := "1000000000000000000000"
911+ balance := new (big.Int )
912+ balance .SetString (balanceStr , 10 )
913+
914+ stateOverrides := map [common.Address ]ethereum.OverrideAccount {
915+ from : {
916+ Balance : balance ,
917+ },
918+ }
919+
920+ opts := ethclient.SimulateOptions {
921+ BlockStateCalls : []ethclient.SimulateBlock {
922+ {
923+ StateOverrides : stateOverrides ,
924+ Calls : []ethereum.CallMsg {
925+ {
926+ From : from ,
927+ To : & to ,
928+ Value : value ,
929+ Gas : gas ,
930+ GasFeeCap : maxFeePerGas ,
931+ },
932+ },
933+ },
934+ },
935+ Validation : true ,
936+ }
937+
938+ results , err := client .SimulateV1 (ctx , opts , nil )
939+ if err != nil {
940+ t .Fatalf ("SimulateV1 with state overrides failed: %v" , err )
941+ }
942+
943+ if len (results ) != 1 {
944+ t .Fatalf ("expected 1 block result, got %d" , len (results ))
945+ }
946+
947+ if results [0 ].Calls [0 ].Status != 1 {
948+ t .Errorf ("expected status 1 (success), got %d" , results [0 ].Calls [0 ].Status )
949+ }
950+ }
951+
952+ func TestSimulateV1WithBlockNumberOrHash (t * testing.T ) {
953+ backend , _ , err := newTestBackend (nil )
954+ if err != nil {
955+ t .Fatalf ("Failed to create test backend: %v" , err )
956+ }
957+ defer backend .Close ()
958+
959+ client := ethclient .NewClient (backend .Attach ())
960+ defer client .Close ()
961+
962+ ctx := context .Background ()
963+
964+ // Get current base fee
965+ header , err := client .HeaderByNumber (ctx , nil )
966+ if err != nil {
967+ t .Fatalf ("Failed to get header: %v" , err )
968+ }
969+
970+ from := testAddr
971+ to := common .HexToAddress ("0x0000000000000000000000000000000000000001" )
972+ value := big .NewInt (100 )
973+ gas := uint64 (100000 )
974+ maxFeePerGas := new (big.Int ).Mul (header .BaseFee , big .NewInt (2 ))
975+
976+ opts := ethclient.SimulateOptions {
977+ BlockStateCalls : []ethclient.SimulateBlock {
978+ {
979+ Calls : []ethereum.CallMsg {
980+ {
981+ From : from ,
982+ To : & to ,
983+ Value : value ,
984+ Gas : gas ,
985+ GasFeeCap : maxFeePerGas ,
986+ },
987+ },
988+ },
989+ },
990+ Validation : true ,
991+ }
992+
993+ // Simulate on the latest block
994+ latest := rpc .BlockNumberOrHashWithNumber (rpc .LatestBlockNumber )
995+ results , err := client .SimulateV1 (ctx , opts , & latest )
996+ if err != nil {
997+ t .Fatalf ("SimulateV1 with latest block failed: %v" , err )
998+ }
999+
1000+ if len (results ) != 1 {
1001+ t .Fatalf ("expected 1 block result, got %d" , len (results ))
1002+ }
1003+ }
0 commit comments