From 4adf8d51d486825ebd0c7c1f4c23ca58e9d485a5 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Fri, 31 Oct 2025 17:50:54 +0100 Subject: [PATCH 1/3] multi: add fee and feerate fields to TrimmedTx and Tx API types This PR adds fee and feerate fields (in atoms) to apitypes.TrimmedTx and apitypes.Tx. These fields are now available across the api endpoints listed below: ```txt - GET /tx/{txid} - GET /tx/{txid}/trimmed - GET /tx/decoded/{txid} - POST /txs - POST /txs/trimmed ``` The new fields provide precise transaction fee information in atoms for both mempool and mined transactions. Signed-off-by: Philemon Ukane --- api/types/apitypes.go | 35 ++++++++++++++++++++--------------- db/dcrpg/pgblockchain.go | 3 +++ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/api/types/apitypes.go b/api/types/apitypes.go index d9cb9347e..2aff6c6ac 100644 --- a/api/types/apitypes.go +++ b/api/types/apitypes.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/decred/dcrd/dcrutil/v4" chainjson "github.com/decred/dcrd/rpc/jsonrpc/types/v4" "github.com/decred/dcrd/txscript/v4/stdscript" "github.com/decred/dcrdata/v8/db/dbtypes" @@ -93,15 +94,17 @@ type Vin = chainjson.Vin // TxShort models info about transaction TxID type TxShort struct { - TxID string `json:"txid"` - Size int32 `json:"size"` - Version int32 `json:"version"` - Locktime uint32 `json:"locktime"` - Expiry uint32 `json:"expiry"` - Vin []Vin `json:"vin"` - Vout []Vout `json:"vout"` - Tree int8 `json:"tree"` - Type string `json:"type"` + TxID string `json:"txid"` + Size int32 `json:"size"` + Version int32 `json:"version"` + Locktime uint32 `json:"locktime"` + Expiry uint32 `json:"expiry"` + Fee dcrutil.Amount `json:"fee"` + FeeRate dcrutil.Amount `json:"feerate"` + Vin []Vin `json:"vin"` + Vout []Vout `json:"vout"` + Tree int8 `json:"tree"` + Type string `json:"type"` } // AgendasInfo holds the high level details about an agenda. @@ -121,12 +124,14 @@ type AgendaAPIResponse struct { // TrimmedTx models data to resemble to result of the decoderawtransaction RPC. type TrimmedTx struct { - TxID string `json:"txid"` - Version int32 `json:"version"` - Locktime uint32 `json:"locktime"` - Expiry uint32 `json:"expiry"` - Vin []Vin `json:"vin"` - Vout []Vout `json:"vout"` + TxID string `json:"txid"` + Version int32 `json:"version"` + Locktime uint32 `json:"locktime"` + Expiry uint32 `json:"expiry"` + Fee dcrutil.Amount `json:"fee"` + FeeRate dcrutil.Amount `json:"feerate"` + Vin []Vin `json:"vin"` + Vout []Vout `json:"vout"` } // Txns models the multi transaction post data structure diff --git a/db/dcrpg/pgblockchain.go b/db/dcrpg/pgblockchain.go index e4f776a70..721dec779 100644 --- a/db/dcrpg/pgblockchain.go +++ b/db/dcrpg/pgblockchain.go @@ -4983,6 +4983,7 @@ func (pgb *ChainDB) GetAPITransaction(ctx context.Context, txid *chainhash.Hash) }, } + tx.Fee, tx.FeeRate = txhelpers.TxFeeRate(msgTx) copy(tx.Vin, txraw.Vin) for i := range txraw.Vout { @@ -5024,6 +5025,8 @@ func (pgb *ChainDB) GetTrimmedTransaction(ctx context.Context, txid *chainhash.H Expiry: tx.Expiry, Vin: tx.Vin, Vout: tx.Vout, + Fee: tx.Fee, + FeeRate: tx.FeeRate, } } From f071bc391a16cbe8d3eff74acb8f598535ed261d Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Fri, 31 Oct 2025 17:57:42 +0100 Subject: [PATCH 2/3] cmd/dcrdata: fix *appContext.getTransaction comment Signed-off-by: Philemon Ukane --- cmd/dcrdata/internal/api/apiroutes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/dcrdata/internal/api/apiroutes.go b/cmd/dcrdata/internal/api/apiroutes.go index 82dfd509e..54fdd6f1b 100644 --- a/cmd/dcrdata/internal/api/apiroutes.go +++ b/cmd/dcrdata/internal/api/apiroutes.go @@ -840,7 +840,7 @@ func (c *appContext) getTxSwapsInfo(w http.ResponseWriter, r *http.Request) { writeJSON(w, swapsInfo, m.GetIndentCtx(r)) } -// getTransactions handles the /txns POST API endpoint. +// getTransactions handles the /txs POST API endpoint. func (c *appContext) getTransactions(w http.ResponseWriter, r *http.Request) { ctx := r.Context() From 4ec17d9fbabe8f6d4f8ee705dcfae6c6ac827b7b Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Fri, 27 Feb 2026 14:27:07 +0100 Subject: [PATCH 3/3] review changes: Make /mempool tx col match /blocks tx col Signed-off-by: Philemon Ukane --- cmd/dcrdata/views/mempool.tmpl | 10 ++++++---- explorer/types/explorertypes.go | 11 +++++------ mempool/collector.go | 3 ++- mempool/monitor.go | 1 + 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cmd/dcrdata/views/mempool.tmpl b/cmd/dcrdata/views/mempool.tmpl index 3a53001ef..e92e4ff89 100644 --- a/cmd/dcrdata/views/mempool.tmpl +++ b/cmd/dcrdata/views/mempool.tmpl @@ -231,8 +231,8 @@ Transaction ID Total DCR - Size Fee Rate + Size Time in Mempool @@ -247,8 +247,8 @@ {{template "decimalParts" (float64AsDecimalParts .TotalOut 8 false)}} - {{.Size}} B {{printf "%.8f" (.FeeRate)}} DCR/kB + {{.Size}} B {{- end -}} @@ -307,8 +307,9 @@ Transaction ID Total DCR - Size + Fee Fee Rate + Size Time in Mempool @@ -323,8 +324,9 @@ {{template "decimalParts" (float64AsDecimalParts .TotalOut 8 false)}} + {{.Fee}} + {{dcrPerKbToAtomsPerByte .FeeRate}} atoms/B {{.Size}} B - {{printf "%.8f" (.FeeRate)}} DCR/kB {{- end -}} diff --git a/explorer/types/explorertypes.go b/explorer/types/explorertypes.go index f9d898331..7704769ba 100644 --- a/explorer/types/explorertypes.go +++ b/explorer/types/explorertypes.go @@ -988,12 +988,11 @@ type TicketPoolInfo struct { // MempoolTx models the tx basic data for the mempool page type MempoolTx struct { - TxID string `json:"txid"` - Version int32 `json:"version"` - Fees float64 `json:"fees"` - FeeRate float64 `json:"fee_rate"` - // Consider atom representation: - //FeeAmount int64 `json:"fee_amount"` + TxID string `json:"txid"` + Version int32 `json:"version"` + Fee dcrutil.Amount `json:"fee"` + Fees float64 `json:"fees"` + FeeRate float64 `json:"fee_rate"` VinCount int `json:"vin_count"` VoutCount int `json:"vout_count"` Vin []MempoolInput `json:"vin,omitempty"` diff --git a/mempool/collector.go b/mempool/collector.go index ed0018dc4..ee649bf63 100644 --- a/mempool/collector.go +++ b/mempool/collector.go @@ -135,12 +135,13 @@ func (t *DataCollector) mempoolTxns() ([]exptypes.MempoolTx, txhelpers.MempoolAd //fee, _ := txhelpers.TxFeeRate(msgTx) // log.Tracef("tx fee: GRM result = %f, msgTx = %f", tx.Fee, fee.ToCoin()) - _, feeRate := txhelpers.TxFeeRate(msgTx) + fee, feeRate := txhelpers.TxFeeRate(msgTx) txs = append(txs, exptypes.MempoolTx{ TxID: hashStr, Version: int32(msgTx.Version), Fees: tx.Fee, + Fee: fee, FeeRate: feeRate.ToCoin(), VinCount: len(msgTx.TxIn), VoutCount: len(msgTx.TxOut), diff --git a/mempool/monitor.go b/mempool/monitor.go index 871b84556..55f68f6af 100644 --- a/mempool/monitor.go +++ b/mempool/monitor.go @@ -244,6 +244,7 @@ func (p *MempoolMonitor) TxHandler(rawTx *chainjson.TxRawResult) error { tx := exptypes.MempoolTx{ TxID: hash, Version: rawTx.Version, + Fee: fee, Fees: fee.ToCoin(), FeeRate: feeRate.ToCoin(), VinCount: len(msgTx.TxIn),