diff --git a/client/client.go b/client/client.go index 815a1b6..718f5f5 100644 --- a/client/client.go +++ b/client/client.go @@ -997,3 +997,7 @@ func (ec *SDKClient) GetNativeTransferGasLimit(ctx context.Context, toAddress st func (ec *SDKClient) GetL1DataFee(ctx context.Context, ethTxBytes []byte) (*big.Int, error) { return nil, errors.New("GetL1DataFee not implemented") } + +func (ec *SDKClient) GetCustomizedBlockBody(raw json.RawMessage, body *RPCBlock) error { + return errors.New("GetCustomizedBlockBody not implemented") +} diff --git a/configuration/configuration.go b/configuration/configuration.go index 848e74b..6d09842 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -118,6 +118,9 @@ type RosettaConfig struct { // CustomizedTraceConfig is the blockchain customized trace config CustomizedTraceConfig interface{} + + // SupportCustomizedBlockBody indicates if the blockchain supports customized block body + SupportCustomizedBlockBody bool } type Token struct { diff --git a/mocks/services/client.go b/mocks/services/client.go index 91a357a..76d4b56 100644 --- a/mocks/services/client.go +++ b/mocks/services/client.go @@ -291,6 +291,24 @@ func (_m *Client) GetContractCurrency(addr common.Address, erc20 bool) (*client. return r0, r1 } +// GetCustomizedBlockBody provides a mock function with given fields: raw, body +func (_m *Client) GetCustomizedBlockBody(raw json.RawMessage, body *client.RPCBlock) error { + ret := _m.Called(raw, body) + + if len(ret) == 0 { + panic("no return value specified for GetCustomizedBlockBody") + } + + var r0 error + if rf, ok := ret.Get(0).(func(json.RawMessage, *client.RPCBlock) error); ok { + r0 = rf(raw, body) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // GetErc20TransferGasLimit provides a mock function with given fields: ctx, toAddress, fromAddress, value, currency func (_m *Client) GetErc20TransferGasLimit(ctx context.Context, toAddress string, fromAddress string, value *big.Int, currency *types.Currency) (uint64, error) { ret := _m.Called(ctx, toAddress, fromAddress, value, currency) diff --git a/services/block_service.go b/services/block_service.go index a142a48..cfd9c52 100644 --- a/services/block_service.go +++ b/services/block_service.go @@ -157,14 +157,28 @@ func (s *BlockAPIService) PopulateTransaction( traceList = append(traceList, traceMap) } + var gasLimit uint64 + if tx.Receipt != nil && tx.Receipt.GasUsed != nil { + gasLimit = tx.Receipt.GasUsed.Uint64() + } else { + gasLimit = tx.Transaction.Gas() + } + + var gasPrice *big.Int + if tx.Receipt != nil && tx.Receipt.GasPrice != nil { + gasPrice = tx.Receipt.GasPrice + } else { + gasPrice = tx.Transaction.GasPrice() + } + populatedTransaction := &RosettaTypes.Transaction{ TransactionIdentifier: &RosettaTypes.TransactionIdentifier{ Hash: tx.TxHash.String(), }, Operations: ops, Metadata: map[string]interface{}{ - "gas_limit": hexutil.EncodeUint64(tx.Transaction.Gas()), - "gas_price": hexutil.EncodeBig(tx.Transaction.GasPrice()), + "gas_limit": hexutil.EncodeUint64(gasLimit), + "gas_price": hexutil.EncodeBig(gasPrice), "receipt": receiptMap, "trace": traceList, }, @@ -217,9 +231,17 @@ func (s *BlockAPIService) GetBlock( if err := json.Unmarshal(raw, &head); err != nil { return nil, nil, nil, err } - if err := json.Unmarshal(raw, &body); err != nil { - return nil, nil, nil, err + if s.config.RosettaCfg.SupportCustomizedBlockBody { + err = s.client.GetCustomizedBlockBody(raw, &body) + if err != nil { + return nil, nil, nil, err + } + } else { + if err := json.Unmarshal(raw, &body); err != nil { + return nil, nil, nil, err + } } + // Note: We need a full node to return a complete RPCBlock, // otherwise, only body.Hash is populated. body.Transactions is empty. // TODO(xiaying): log warn if len(body.Hash) > 1 && len(body.txs) == 0 diff --git a/services/construction/types.go b/services/construction/types.go index 23c7275..543b30e 100644 --- a/services/construction/types.go +++ b/services/construction/types.go @@ -78,6 +78,9 @@ type Client interface { // SkipTxReceiptParsing determines if the tx receipt parsing can be skipped for specific contract address SkipTxReceiptParsing(contractAddress string) bool + // GetCustomizedBlockBody returns the customized block body + GetCustomizedBlockBody(raw json.RawMessage, body *evmClient.RPCBlock) error + // TraceBlockByHash returns all traces for each transaction in the block // by calling geth debug_traceBlockByHash JSON RPC. // The output is map which key is transaction hash, and the value is list of