@@ -174,17 +174,10 @@ type (
174
174
// BlockHashByBlockHeight returns block hash by block height
175
175
BlockHashByBlockHeight (blkHeight uint64 ) (hash.Hash256 , error )
176
176
// TraceTransaction returns the trace result of a transaction
177
- TraceTransaction (ctx context.Context , actHash string , config * tracers.TraceConfig ) ([]byte , * action.Receipt , any , error )
177
+ TraceTransaction (context.Context , string , * tracers.TraceConfig ) ([]byte , * action.Receipt , any , error )
178
178
// TraceCall returns the trace result of a call
179
- TraceCall (ctx context.Context ,
180
- callerAddr address.Address ,
181
- blkNumOrHash any ,
182
- contractAddress string ,
183
- nonce uint64 ,
184
- amount * big.Int ,
185
- gasLimit uint64 ,
186
- data []byte ,
187
- config * tracers.TraceConfig ) ([]byte , * action.Receipt , any , error )
179
+ TraceCall (context.Context , address.Address , string , uint64 , * big.Int , uint64 , []byte ,
180
+ * tracers.TraceConfig ) ([]byte , * action.Receipt , any , error )
188
181
189
182
// Track tracks the api call
190
183
Track (ctx context.Context , start time.Time , method string , size int64 , success bool )
@@ -1873,6 +1866,9 @@ func (core *coreService) SyncingProgress() (uint64, uint64, uint64) {
1873
1866
1874
1867
// TraceTransaction returns the trace result of transaction
1875
1868
func (core * coreService ) TraceTransaction (ctx context.Context , actHash string , config * tracers.TraceConfig ) ([]byte , * action.Receipt , any , error ) {
1869
+ if ! core .archiveSupported {
1870
+ return nil , nil , nil , ErrArchiveNotSupported
1871
+ }
1876
1872
actInfo , err := core .Action (util .Remove0xPrefix (actHash ), false )
1877
1873
if err != nil {
1878
1874
return nil , nil , nil , err
@@ -1884,16 +1880,73 @@ func (core *coreService) TraceTransaction(ctx context.Context, actHash string, c
1884
1880
if _ , ok := act .Action ().(* action.Execution ); ! ok {
1885
1881
return nil , nil , nil , errors .New ("the type of action is not supported" )
1886
1882
}
1887
- addr , _ := address .FromString (address .ZeroAddress )
1883
+ blk , err := core .dao .GetBlockByHeight (actInfo .BlkHeight )
1884
+ if err != nil {
1885
+ return nil , nil , nil , err
1886
+ }
1887
+ var (
1888
+ preActs = make ([]* action.SealedEnvelope , 0 )
1889
+ actExist bool
1890
+ )
1891
+ hash , err := act .Hash ()
1892
+ if err != nil {
1893
+ return nil , nil , nil , status .Error (codes .Internal , err .Error ())
1894
+ }
1895
+ for i := range blk .Actions {
1896
+ shash , err := blk .Actions [i ].Hash ()
1897
+ if err != nil {
1898
+ return nil , nil , nil , status .Error (codes .Internal , err .Error ())
1899
+ }
1900
+ if bytes .Equal (shash [:], hash [:]) {
1901
+ actExist = true
1902
+ break
1903
+ }
1904
+ preActs = append (preActs , blk .Actions [i ])
1905
+ }
1906
+ if ! actExist {
1907
+ return nil , nil , nil , status .Errorf (codes .InvalidArgument , "action %s does not exist in block %d" , actHash , actInfo .BlkHeight )
1908
+ }
1909
+ // generate the working set just before the target action
1910
+ ctx , err = core .bc .ContextAtHeight (ctx , actInfo .BlkHeight - 1 )
1911
+ if err != nil {
1912
+ return nil , nil , nil , status .Error (codes .Internal , err .Error ())
1913
+ }
1914
+ ws , err := core .sf .WorkingSetAtHeight (ctx , actInfo .BlkHeight , preActs ... )
1915
+ if err != nil {
1916
+ return nil , nil , nil , status .Error (codes .Internal , err .Error ())
1917
+ }
1918
+ g := core .bc .Genesis ()
1919
+ ctx = protocol .WithBlockCtx (protocol .WithRegistry (ctx , core .registry ), protocol.BlockCtx {
1920
+ BlockHeight : blk .Height (),
1921
+ BlockTimeStamp : blk .Timestamp (),
1922
+ GasLimit : g .BlockGasLimitByHeight (actInfo .BlkHeight ),
1923
+ Producer : blk .PublicKey ().Address (),
1924
+ })
1925
+ intrinsicGas , err := act .IntrinsicGas ()
1926
+ if err != nil {
1927
+ return nil , nil , nil , status .Error (codes .Internal , err .Error ())
1928
+ }
1929
+ ctx = protocol .WithFeatureCtx (protocol .WithActionCtx (ctx ,
1930
+ protocol.ActionCtx {
1931
+ Caller : act .SenderAddress (),
1932
+ ActionHash : hash ,
1933
+ GasPrice : act .GasPrice (),
1934
+ IntrinsicGas : intrinsicGas ,
1935
+ Nonce : act .Nonce (),
1936
+ }))
1888
1937
return core .traceTx (ctx , new (tracers.Context ), config , func (ctx context.Context ) ([]byte , * action.Receipt , error ) {
1889
- return core .simulateExecution (ctx , core .bc .TipHeight (), false , addr , act .Envelope )
1938
+ ctx = evm .WithHelperCtx (ctx , evm.HelperContext {
1939
+ GetBlockHash : core .dao .GetBlockHash ,
1940
+ GetBlockTime : core .getBlockTime ,
1941
+ DepositGasFunc : rewarding .DepositGas ,
1942
+ })
1943
+ return evm .ExecuteContract (ctx , ws , act .Envelope )
1890
1944
})
1891
1945
}
1892
1946
1893
1947
// TraceCall returns the trace result of call
1894
1948
func (core * coreService ) TraceCall (ctx context.Context ,
1895
1949
callerAddr address.Address ,
1896
- blkNumOrHash any ,
1897
1950
contractAddress string ,
1898
1951
nonce uint64 ,
1899
1952
amount * big.Int ,
0 commit comments