diff --git a/docs/json_rpc_api.mediawiki b/docs/json_rpc_api.mediawiki
index f545a37ae3..8c1a1784f2 100644
--- a/docs/json_rpc_api.mediawiki
+++ b/docs/json_rpc_api.mediawiki
@@ -272,9 +272,9 @@ the method name for further details such as parameter and return information.
|Y
|Returns a mix message and its message type by its hash if it is accepted by and currently in the mixpool.
|-
-|[[#getmixpairrequests|getmixpairrequests]]
+|[[#getmixpoolinfo|getmixpoolinfo]]
|Y
-|Returns the current set of mixing pair request messages from the mixpool. WARNING: This is experimental and will very likely be removed in the next version. Do not use!
+|Returns the current state of the mixpool including timing of the next mix epoch and pending pair requests.
|-
|[[#getnettotals|getnettotals]]
|Y
@@ -1549,24 +1549,50 @@ of the best block.
----
-====getmixpairrequests====
+====getmixpoolinfo====
{|
!Method
-|getmixpairrequests
+|getmixpoolinfo
|-
!Parameters
|None
|-
!Description
|
-: Returns the current set of mixing pair request messages from the mixpool.
-: WARNING: This is experimental and will very likely be removed in the next version. Do not use!
+: Returns the current state of the mixpool including timing of the next mix epoch and pending pair requests.
|-
!Returns
-|(json array of string) hex-encoded mixing pair request messages.
+|(json object)
+: epoch: (numeric) Duration between mix epochs, in seconds.
+: nextepoch: (numeric) Unix timestamp of the next mix epoch.
+: pairings: (json array of object) Pending pair requests grouped by mixing compatibility.
+:: mixamount: (numeric) Amount of each mixed output, in DCR.
+:: scriptclass: (string) Script class of the mixed outputs.
+:: txversion: (numeric) Transaction version of the mix transaction.
+:: locktime: (numeric) Lock time of the mix transaction.
+:: pairingflags: (numeric) Pairing flags of the pair request.
+:: pairrequests: (json array of object) The pair requests matching these mixing parameters.
+::: hash: (string) Hash of the pair request message.
+::: identity: (string) Participant ephemeral public key identity as a hex string.
+::: messagecount: (numeric) Number of mixed outputs, each of value mixamount, the pair request is creating.
+::: inputvalue: (numeric) Total value of inputs contributed by the pair request, in DCR.
+::: utxos: (json array of object) Unspent transaction outputs contributed by the pair request.
+:::: txid: (string) The hash of the origin transaction.
+:::: vout: (numeric) The index of the output being contributed.
+:::: tree: (numeric) The tree of the output being contributed.
+:::: amountin: (numeric) The amount of the output, in DCR.
+:::: blockheight: (numeric) The height of the block containing the origin transaction.
+:::: scriptPubKey: (json object) The public key script used to pay coins.
+::::: asm: (string) Disassembly of the script.
+::::: hex: (string) Hex-encoded bytes of the script.
+::::: reqSigs: (numeric) The number of required signatures.
+::::: type: (string) The type of the script (e.g. 'pubkeyhash').
+::::: addresses: (json array of string) The Decred addresses associated with this output.
+::::: version: (numeric) The script version.
+::: expiry: (numeric) Block height at which the pair request expires.
|-
!Example Return
-|["a1d1d8c6ffc20a51ad9a5aa093c31bdeb06a0f627af95...",...]
+|{"epoch":600,"nextepoch":1751049600,"pairings":[{"mixamount":1,"scriptclass":"P2PKH-secp256k1-v0","txversion":1,"locktime":0,"pairingflags":1,"pairrequests":[{"hash":"a1d1d8c6...","identity":"02d1a...","messagecount":1,"inputvalue":1.2,"utxos":[{"txid":"a1d1d8c6...","vout":0,"tree":0,"amountin":1.2,"blockheight":987000,"scriptPubKey":{"asm":"OP_DUP OP_HASH160 2da3aaa402b110247f08c3ea2300a0567de77a5b OP_EQUALVERIFY OP_CHECKSIG","hex":"76a9142da3aaa402b110247f08c3ea2300a0567de77a5b88ac","reqSigs":1,"type":"pubkeyhash","addresses":["DsV8DxpEUFyZtcAwpWfejmWRpR5FEsrM6Yo"],"version":0}}],"expiry":987654}]}]}
|}
----
diff --git a/internal/rpcserver/interface.go b/internal/rpcserver/interface.go
index 64c9443b84..0db36e6ce6 100644
--- a/internal/rpcserver/interface.go
+++ b/internal/rpcserver/interface.go
@@ -665,6 +665,9 @@ type MixPooler interface {
// Message searches the mixing pool for a message by its hash.
Message(query *chainhash.Hash) (mixing.Message, error)
+
+ // Epoch returns the duration between mix epochs.
+ Epoch() time.Duration
}
// TxIndexer provides an interface for retrieving details for a given
diff --git a/internal/rpcserver/rpcserver.go b/internal/rpcserver/rpcserver.go
index 5a3013bc18..e7fdf97067 100644
--- a/internal/rpcserver/rpcserver.go
+++ b/internal/rpcserver/rpcserver.go
@@ -62,8 +62,8 @@ import (
// API version constants.
const (
- jsonrpcSemverMajor = 8
- jsonrpcSemverMinor = 3
+ jsonrpcSemverMajor = 9
+ jsonrpcSemverMinor = 0
jsonrpcSemverPatch = 0
)
@@ -210,7 +210,7 @@ var rpcHandlersBeforeInit = map[types.Method]commandHandler{
"getmempoolinfo": handleGetMempoolInfo,
"getmininginfo": handleGetMiningInfo,
"getmixmessage": handleGetMixMessage,
- "getmixpairrequests": handleGetMixPairRequests,
+ "getmixpoolinfo": handleGetMixpoolInfo,
"getnettotals": handleGetNetTotals,
"getnetworkhashps": handleGetNetworkHashPS,
"getnetworkinfo": handleGetNetworkInfo,
@@ -380,7 +380,7 @@ var rpcLimited = map[string]struct{}{
"getheaders": {},
"getinfo": {},
"getmixmessage": {},
- "getmixpairrequests": {},
+ "getmixpoolinfo": {},
"getnettotals": {},
"getnetworkhashps": {},
"getnetworkinfo": {},
@@ -1266,6 +1266,38 @@ func createVinList(mtx *wire.MsgTx, isTreasuryEnabled bool) []types.Vin {
return vinList
}
+// createScriptPubKeyResult returns a JSON object describing the passed public
+// key script information.
+func createScriptPubKeyResult(scriptVersion uint16, pkScript []byte,
+ chainParams *chaincfg.Params) types.ScriptPubKeyResult {
+
+ // Disassemble script into single line printable format. The disassembled
+ // string will contain [error] inline if the script doesn't fully parse, so
+ // ignore the error here.
+ script := pkScript
+ disbuf, _ := txscript.DisasmString(script)
+
+ // Attempt to extract known addresses associated with the script.
+ scriptType, addrs := stdscript.ExtractAddrs(scriptVersion, script,
+ chainParams)
+ addresses := make([]string, len(addrs))
+ for i, addr := range addrs {
+ addresses[i] = addr.String()
+ }
+
+ // Determine the number of required signatures for known standard types.
+ reqSigs := stdscript.DetermineRequiredSigs(scriptVersion, script)
+
+ return types.ScriptPubKeyResult{
+ Asm: disbuf,
+ Hex: hex.EncodeToString(script),
+ ReqSigs: int32(reqSigs),
+ Type: scriptType.String(),
+ Addresses: addresses,
+ Version: scriptVersion,
+ }
+}
+
// createVoutList returns a slice of JSON objects for the outputs of the passed
// transaction.
func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params,
@@ -2666,27 +2698,82 @@ func handleGetMixMessage(_ context.Context, s *Server, cmd any) (any, error) {
return &result, nil
}
-// handleGetMixPairRequests implements the getmixpairrequests command,
-// returning all current mixing pair requests messages from mixpool.
-func handleGetMixPairRequests(_ context.Context, s *Server, _ any) (any, error) {
+// handleGetMixpoolInfo implements the getmixpoolinfo command, returning the
+// timing of the next mix epoch and the pending pair requests grouped by pairing
+// description.
+func handleGetMixpoolInfo(_ context.Context, s *Server, _ any) (any, error) {
mp := s.cfg.MixPooler
-
prs := mp.MixPRs()
- buf := new(strings.Builder)
- res := make([]string, 0, len(prs))
-
- const pver = wire.MixVersion
+ // Use a map to group PRs by their pairing description. This is converted to
+ // a slice for JSON marshalling later.
+ groups := make(map[string]*types.Pairing)
for _, pr := range prs {
- err := pr.BtcEncode(hex.NewEncoder(buf), pver)
+ pairing, err := pr.Pairing()
if err != nil {
- return nil, err
+ return nil, rpcInternalErr(err, "Failed to generate PR pairing")
}
- res = append(res, buf.String())
- buf.Reset()
+
+ key := string(pairing)
+ group, ok := groups[key]
+ if !ok {
+ group = &types.Pairing{
+ MixAmount: dcrutil.Amount(pr.MixAmount).ToCoin(),
+ ScriptClass: pr.ScriptClass,
+ TxVersion: pr.TxVersion,
+ LockTime: pr.LockTime,
+ PairingFlags: pr.PairingFlags,
+ PairRequests: make([]types.PairRequest, 0, min(len(prs), mixing.MaxPeers)),
+ }
+ groups[key] = group
+ }
+
+ // The pair request only provides the hash, index and tree of the UTXO,
+ // so amountIn, blockHeight and scriptPubKey are retrieved from the
+ // local UTXO set.
+ utxos := make([]types.PairRequestUTXO, len(pr.UTXOs))
+ for i := range pr.UTXOs {
+ op := pr.UTXOs[i].OutPoint
+
+ entry, err := s.cfg.Chain.FetchUtxoEntry(op)
+ if entry == nil || err != nil {
+ return nil, rpcNoTxInfoError(&op.Hash)
+ }
+
+ utxos[i].Txid = op.Hash.String()
+ utxos[i].Vout = op.Index
+ utxos[i].Tree = op.Tree
+ utxos[i].AmountIn = dcrutil.Amount(entry.Amount()).ToCoin()
+ utxos[i].BlockHeight = uint32(entry.BlockHeight())
+ utxos[i].ScriptPubKey = createScriptPubKeyResult(
+ entry.ScriptVersion(), entry.PkScript(), s.cfg.ChainParams)
+ }
+
+ group.PairRequests = append(group.PairRequests, types.PairRequest{
+ Hash: pr.Hash().String(),
+ Identity: hex.EncodeToString(pr.Identity[:]),
+ MessageCount: pr.MessageCount,
+ InputValue: dcrutil.Amount(pr.InputValue).ToCoin(),
+ UTXOs: utxos,
+ Expiry: pr.Expiry,
+ })
}
- return res, nil
+ // Convert map to slice for JSON marshalling.
+ pairings := make([]types.Pairing, 0, len(groups))
+ for _, group := range groups {
+ pairings = append(pairings, *group)
+ }
+
+ epoch := mp.Epoch()
+ nextEpoch := s.cfg.Clock.Now().Truncate(epoch).Add(epoch)
+
+ result := types.GetMixpoolInfoResult{
+ Epoch: int64(epoch.Seconds()),
+ NextEpoch: nextEpoch.Unix(),
+ Pairings: pairings,
+ }
+ return &result, nil
}
// handleGetNetTotals implements the getnettotals command.
@@ -3752,35 +3839,12 @@ func handleGetTxOut(_ context.Context, s *Server, cmd any) (any, error) {
isCoinbase = entry.IsCoinBase()
}
- // Disassemble script into single line printable format. The
- // disassembled string will contain [error] inline if the script
- // doesn't fully parse, so ignore the error here.
- script := pkScript
- disbuf, _ := txscript.DisasmString(script)
-
- // Attempt to extract known addresses associated with the script.
- scriptType, addrs := stdscript.ExtractAddrs(scriptVersion, script,
- s.cfg.ChainParams)
- addresses := make([]string, len(addrs))
- for i, addr := range addrs {
- addresses[i] = addr.String()
- }
-
- // Determine the number of required signatures for known standard types.
- reqSigs := stdscript.DetermineRequiredSigs(scriptVersion, script)
-
txOutReply := &types.GetTxOutResult{
BestBlock: bestBlockHash,
Confirmations: confirmations,
Value: dcrutil.Amount(value).ToUnit(dcrutil.AmountCoin),
- ScriptPubKey: types.ScriptPubKeyResult{
- Asm: disbuf,
- Hex: hex.EncodeToString(pkScript),
- ReqSigs: int32(reqSigs),
- Type: scriptType.String(),
- Addresses: addresses,
- Version: scriptVersion,
- },
+ ScriptPubKey: createScriptPubKeyResult(scriptVersion, pkScript,
+ s.cfg.ChainParams),
Coinbase: isCoinbase,
}
return txOutReply, nil
diff --git a/internal/rpcserver/rpcserverhandlers_test.go b/internal/rpcserver/rpcserverhandlers_test.go
index fbd8716fee..e26e90b197 100644
--- a/internal/rpcserver/rpcserverhandlers_test.go
+++ b/internal/rpcserver/rpcserverhandlers_test.go
@@ -1184,6 +1184,7 @@ type testMixPooler struct {
mixPRs []*wire.MsgMixPairReq
message mixing.Message
messageErr error
+ epoch time.Duration
}
// MixPRs returns a mocked slice of MixPR messages.
@@ -1196,6 +1197,11 @@ func (mp *testMixPooler) Message(query *chainhash.Hash) (mixing.Message, error)
return mp.message, mp.messageErr
}
+// Epoch returns a mocked duration between mix epochs.
+func (mp *testMixPooler) Epoch() time.Duration {
+ return mp.epoch
+}
+
// testNtfnManager provides a mock notification manager by implementing the
// NtfnManager interface.
type testNtfnManager struct {
@@ -4606,6 +4612,188 @@ func TestHandleGetMempoolInfo(t *testing.T) {
}})
}
+func TestHandleGetMixpoolInfo(t *testing.T) {
+ t.Parallel()
+
+ epoch := 10 * time.Minute
+ now := time.Unix(1700000000, 0)
+
+ // Construct the mock UtxoEntry which will be returned by FetchUtxoEntry.
+ script := hexToBytes("76a9142da3aaa402b110247f08c3ea2300a0567de77a5b88ac")
+ const scriptVersion = uint16(0)
+ mockUtxo := &testRPCUtxoEntry{
+ amount: 500000000,
+ height: 12345,
+ pkScript: script,
+ scriptVersion: scriptVersion,
+ }
+
+ // Construct the representation of the script expected to be returned by the
+ // RPC.
+ disbuf, _ := txscript.DisasmString(script)
+ scriptType, addrs := stdscript.ExtractAddrs(scriptVersion, script,
+ defaultChainParams)
+ addresses := make([]string, len(addrs))
+ for i, addr := range addrs {
+ addresses[i] = addr.String()
+ }
+ reqSigs := stdscript.DetermineRequiredSigs(scriptVersion, script)
+ scriptPubKey := types.ScriptPubKeyResult{
+ Asm: disbuf,
+ Hex: hex.EncodeToString(script),
+ ReqSigs: int32(reqSigs),
+ Type: scriptType.String(),
+ Addresses: addresses,
+ Version: scriptVersion,
+ }
+
+ // Construct two UTXOs for use in the pair requests, and the representation
+ // of them expected to be returned by the RPC.
+ utxo1 := wire.OutPoint{Hash: chainhash.Hash{0x01}, Index: 2, Tree: 0}
+ utxo1Result := types.PairRequestUTXO{
+ Txid: "0000000000000000000000000000000000000000000000000000000000000001",
+ Vout: 2,
+ Tree: 0,
+ AmountIn: 5.00,
+ BlockHeight: 12345,
+ ScriptPubKey: scriptPubKey,
+ }
+
+ utxo2 := wire.OutPoint{Hash: chainhash.Hash{0x02}, Index: 3, Tree: 1}
+ utxo2Result := types.PairRequestUTXO{
+ Txid: "0000000000000000000000000000000000000000000000000000000000000002",
+ Vout: 3,
+ Tree: 1,
+ AmountIn: 5.00,
+ BlockHeight: 12345,
+ ScriptPubKey: scriptPubKey,
+ }
+
+ // Construct two pair requests each contributing a distinct UTXO, and
+ // sharing the same pairing description so they are grouped together.
+ pr1 := &wire.MsgMixPairReq{
+ Identity: [33]byte{0x02, 0xaa},
+ Expiry: 100,
+ MixAmount: 1000000,
+ ScriptClass: string(mixing.ScriptClassP2PKHv0),
+ TxVersion: 1,
+ MessageCount: 2,
+ InputValue: 2500000,
+ UTXOs: []wire.MixPairReqUTXO{{OutPoint: utxo1}},
+ PairingFlags: 2,
+ }
+ pr2 := &wire.MsgMixPairReq{
+ Identity: [33]byte{0x03, 0xbb},
+ Expiry: 200,
+ MixAmount: 1000000,
+ ScriptClass: string(mixing.ScriptClassP2PKHv0),
+ TxVersion: 1,
+ MessageCount: 1,
+ InputValue: 1500000,
+ UTXOs: []wire.MixPairReqUTXO{{OutPoint: utxo2}},
+ PairingFlags: 2,
+ }
+
+ hasher := blake256.NewHasher256()
+ pr1.WriteHash(hasher)
+ pr2.WriteHash(hasher)
+
+ testRPCServerHandler(t, []rpcTest{{
+ name: "handleGetMixpoolInfo: no pending pair requests",
+ handler: handleGetMixpoolInfo,
+ cmd: &types.GetMixpoolInfoCmd{},
+ mockClock: &testClock{now: now},
+ mockMixPooler: func() *testMixPooler {
+ mp := defaultMockMixPooler()
+ mp.epoch = epoch
+ return mp
+ }(),
+ result: &types.GetMixpoolInfoResult{
+ Epoch: 600, // 10 minutes
+ NextEpoch: 1700000400,
+ Pairings: []types.Pairing{},
+ },
+ }, {
+ name: "handleGetMixpoolInfo: pending pair requests grouped by pairing",
+ handler: handleGetMixpoolInfo,
+ cmd: &types.GetMixpoolInfoCmd{},
+ mockClock: &testClock{now: now},
+ mockChain: func() *testRPCChain {
+ chain := defaultMockRPCChain()
+ chain.fetchUtxoEntry = mockUtxo
+ return chain
+ }(),
+ mockMixPooler: func() *testMixPooler {
+ mp := defaultMockMixPooler()
+ mp.epoch = epoch
+ mp.mixPRs = []*wire.MsgMixPairReq{pr1, pr2}
+ return mp
+ }(),
+ result: &types.GetMixpoolInfoResult{
+ Epoch: 600, // 10 minutes
+ NextEpoch: 1700000400,
+ Pairings: []types.Pairing{{
+ MixAmount: 0.01,
+ ScriptClass: string(mixing.ScriptClassP2PKHv0),
+ TxVersion: 1,
+ LockTime: 0,
+ PairingFlags: 2,
+ PairRequests: []types.PairRequest{{
+ Hash: pr1.Hash().String(),
+ Identity: hex.EncodeToString(pr1.Identity[:]),
+ MessageCount: 2,
+ InputValue: 0.025,
+ UTXOs: []types.PairRequestUTXO{utxo1Result},
+ Expiry: 100,
+ }, {
+ Hash: pr2.Hash().String(),
+ Identity: hex.EncodeToString(pr2.Identity[:]),
+ MessageCount: 1,
+ InputValue: 0.015,
+ UTXOs: []types.PairRequestUTXO{utxo2Result},
+ Expiry: 200,
+ }},
+ }},
+ },
+ }, {
+ name: "handleGetMixpoolInfo: utxo not found in the utxo set",
+ handler: handleGetMixpoolInfo,
+ cmd: &types.GetMixpoolInfoCmd{},
+ mockClock: &testClock{now: now},
+ mockChain: func() *testRPCChain {
+ chain := defaultMockRPCChain()
+ chain.fetchUtxoEntry = nil
+ return chain
+ }(),
+ mockMixPooler: func() *testMixPooler {
+ mp := defaultMockMixPooler()
+ mp.epoch = epoch
+ mp.mixPRs = []*wire.MsgMixPairReq{pr1}
+ return mp
+ }(),
+ wantErr: true,
+ errCode: dcrjson.ErrRPCNoTxInfo,
+ }, {
+ name: "handleGetMixpoolInfo: utxo set lookup failure",
+ handler: handleGetMixpoolInfo,
+ cmd: &types.GetMixpoolInfoCmd{},
+ mockClock: &testClock{now: now},
+ mockChain: func() *testRPCChain {
+ chain := defaultMockRPCChain()
+ chain.fetchUtxoEntryErr = errors.New("utxo entry error")
+ return chain
+ }(),
+ mockMixPooler: func() *testMixPooler {
+ mp := defaultMockMixPooler()
+ mp.epoch = epoch
+ mp.mixPRs = []*wire.MsgMixPairReq{pr1}
+ return mp
+ }(),
+ wantErr: true,
+ errCode: dcrjson.ErrRPCNoTxInfo,
+ }})
+}
+
func TestHandleGetMiningInfo(t *testing.T) {
t.Parallel()
diff --git a/internal/rpcserver/rpcserverhelp.go b/internal/rpcserver/rpcserverhelp.go
index b3a1f9b8ad..0925408323 100644
--- a/internal/rpcserver/rpcserverhelp.go
+++ b/internal/rpcserver/rpcserverhelp.go
@@ -1,5 +1,5 @@
// Copyright (c) 2015 The btcsuite developers
-// Copyright (c) 2015-2025 The Decred developers
+// Copyright (c) 2015-2026 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@@ -522,9 +522,38 @@ var helpDescsEnUS = map[string]string{
"getmixmessageresult-type": "Command type of the message",
"getmixmessageresult-message": "Serialized message in hex encoding",
- // GetMixPairRequests help.
- "getmixpairrequests--synopsis": "Returns current set of mixing pair request messages from mixpool.",
- "getmixpairrequests--result0": "JSON array of hex-encoded mixing pair request messages.",
+ // GetMixpoolInfo help.
+ "getmixpoolinfo--synopsis": "Returns the current state of the mixpool including timing of the next mix epoch and pending pair requests.",
+ "getmixpoolinfo--result0": "JSON object describing current mixpool state.",
+
+ // GetMixpoolInfoResult help.
+ "getmixpoolinforesult-epoch": "Duration between mix epochs, in seconds",
+ "getmixpoolinforesult-nextepoch": "Unix timestamp of the next mix epoch",
+ "getmixpoolinforesult-pairings": "Pending pair requests grouped by mixing compatibility",
+
+ // Pairing help.
+ "pairing-mixamount": "Amount of each mixed output, in DCR",
+ "pairing-scriptclass": "Script class of the mixed outputs",
+ "pairing-txversion": "Transaction version of the mix transaction",
+ "pairing-locktime": "Lock time of the mix transaction",
+ "pairing-pairingflags": "Pairing flags",
+ "pairing-pairrequests": "The pair requests matching these mixing parameters",
+
+ // PairRequest help.
+ "pairrequest-hash": "Hash of the pair request message",
+ "pairrequest-identity": "Participant ephemeral public key identity as a hex string",
+ "pairrequest-messagecount": "Number of mixed outputs, each of value mixamount, the pair request is creating",
+ "pairrequest-inputvalue": "Total value of inputs contributed by the pair request, in DCR",
+ "pairrequest-utxos": "Unspent transaction outputs contributed by the pair request",
+ "pairrequest-expiry": "Block height at which the pair request expires",
+
+ // PairRequestUTXO help.
+ "pairrequestutxo-txid": "The hash of the origin transaction",
+ "pairrequestutxo-vout": "The index of the output being contributed",
+ "pairrequestutxo-tree": "The tree of the output being contributed",
+ "pairrequestutxo-amountin": "The amount of the output, in DCR",
+ "pairrequestutxo-blockheight": "The height of the block containing the origin transaction",
+ "pairrequestutxo-scriptPubKey": "The public key script used to pay coins as a JSON object",
// GetNetworkHashPSCmd help.
"getnetworkhashps--synopsis": "Returns the estimated network hashes per second for the block heights provided by the parameters.",
@@ -993,7 +1022,7 @@ var rpcResultTypes = map[types.Method][]any{
"getmempoolinfo": {(*types.GetMempoolInfoResult)(nil)},
"getmininginfo": {(*types.GetMiningInfoResult)(nil)},
"getmixmessage": {(*types.GetMixMessageResult)(nil)},
- "getmixpairrequests": {(*[]string)(nil)},
+ "getmixpoolinfo": {(*types.GetMixpoolInfoResult)(nil)},
"getnettotals": {(*types.GetNetTotalsResult)(nil)},
"getnetworkhashps": {(*int64)(nil)},
"getnetworkinfo": {(*[]types.GetNetworkInfoResult)(nil)},
diff --git a/rpc/jsonrpc/types/chainsvrcmds.go b/rpc/jsonrpc/types/chainsvrcmds.go
index 276f939264..e4bfc25ee3 100644
--- a/rpc/jsonrpc/types/chainsvrcmds.go
+++ b/rpc/jsonrpc/types/chainsvrcmds.go
@@ -565,13 +565,13 @@ func NewGetMixMessageCmd(hash string) *GetMixMessageCmd {
}
}
-// GetMixPairRequestsCmd defines the getmixpairrequests JSON-RPC command.
-type GetMixPairRequestsCmd struct{}
+// GetMixpoolInfoCmd defines the getmixpoolinfo JSON-RPC command.
+type GetMixpoolInfoCmd struct{}
-// NewGetMixPairRequestsCmd returns a new instance which can be used to issue a
-// getmixpairrequests JSON-RPC command.
-func NewGetMixPairRequestsCmd() *GetMixPairRequestsCmd {
- return &GetMixPairRequestsCmd{}
+// NewGetMixpoolInfoCmd returns a new instance which can be used to issue a
+// getmixpoolinfo JSON-RPC command.
+func NewGetMixpoolInfoCmd() *GetMixpoolInfoCmd {
+ return &GetMixpoolInfoCmd{}
}
// GetNetworkInfoCmd defines the getnetworkinfo JSON-RPC command.
@@ -1184,7 +1184,7 @@ func init() {
dcrjson.MustRegister(Method("getmempoolinfo"), (*GetMempoolInfoCmd)(nil), flags)
dcrjson.MustRegister(Method("getmininginfo"), (*GetMiningInfoCmd)(nil), flags)
dcrjson.MustRegister(Method("getmixmessage"), (*GetMixMessageCmd)(nil), flags)
- dcrjson.MustRegister(Method("getmixpairrequests"), (*GetMixPairRequestsCmd)(nil), flags)
+ dcrjson.MustRegister(Method("getmixpoolinfo"), (*GetMixpoolInfoCmd)(nil), flags)
dcrjson.MustRegister(Method("getnetworkinfo"), (*GetNetworkInfoCmd)(nil), flags)
dcrjson.MustRegister(Method("getnettotals"), (*GetNetTotalsCmd)(nil), flags)
dcrjson.MustRegister(Method("getnetworkhashps"), (*GetNetworkHashPSCmd)(nil), flags)
diff --git a/rpc/jsonrpc/types/chainsvrcmds_test.go b/rpc/jsonrpc/types/chainsvrcmds_test.go
index a33f15869c..36af5a3dc7 100644
--- a/rpc/jsonrpc/types/chainsvrcmds_test.go
+++ b/rpc/jsonrpc/types/chainsvrcmds_test.go
@@ -465,15 +465,15 @@ func TestChainSvrCmds(t *testing.T) {
unmarshalled: &GetMixMessageCmd{Hash: "123"},
},
{
- name: "getmixpairrequests",
+ name: "getmixpoolinfo",
newCmd: func() (interface{}, error) {
- return dcrjson.NewCmd(Method("getmixpairrequests"))
+ return dcrjson.NewCmd(Method("getmixpoolinfo"))
},
staticCmd: func() interface{} {
- return NewGetMixPairRequestsCmd()
+ return NewGetMixpoolInfoCmd()
},
- marshalled: `{"jsonrpc":"1.0","method":"getmixpairrequests","params":[],"id":1}`,
- unmarshalled: &GetMixPairRequestsCmd{},
+ marshalled: `{"jsonrpc":"1.0","method":"getmixpoolinfo","params":[],"id":1}`,
+ unmarshalled: &GetMixpoolInfoCmd{},
},
{
name: "getnetworkinfo",
diff --git a/rpc/jsonrpc/types/chainsvrresults.go b/rpc/jsonrpc/types/chainsvrresults.go
index d18f9a6804..10a2d39355 100644
--- a/rpc/jsonrpc/types/chainsvrresults.go
+++ b/rpc/jsonrpc/types/chainsvrresults.go
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The btcsuite developers
-// Copyright (c) 2015-2024 The Decred developers
+// Copyright (c) 2015-2026 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@@ -240,6 +240,46 @@ type GetMixMessageResult struct {
Message string `json:"message"`
}
+// GetMixpoolInfoResult models the data from the getmixpoolinfo command.
+type GetMixpoolInfoResult struct {
+ Epoch int64 `json:"epoch"`
+ NextEpoch int64 `json:"nextepoch"`
+ Pairings []Pairing `json:"pairings"`
+}
+
+// Pairing models a group of pair requests which share the same mix parameters
+// (i.e. MixAmount, ScriptClass, TxVersion, LockTime, and PairingFlags) and are
+// thus compatible to mix together.
+type Pairing struct {
+ MixAmount float64 `json:"mixamount"`
+ ScriptClass string `json:"scriptclass"`
+ TxVersion uint16 `json:"txversion"`
+ LockTime uint32 `json:"locktime"`
+ PairingFlags uint8 `json:"pairingflags"`
+ PairRequests []PairRequest `json:"pairrequests"`
+}
+
+// PairRequest models a single pair request.
+type PairRequest struct {
+ Hash string `json:"hash"`
+ Identity string `json:"identity"`
+ MessageCount uint32 `json:"messagecount"`
+ InputValue float64 `json:"inputvalue"`
+ UTXOs []PairRequestUTXO `json:"utxos"`
+ Expiry uint32 `json:"expiry"`
+}
+
+// PairRequestUTXO models an unspent transaction output contributed to a mixing
+// pair request.
+type PairRequestUTXO struct {
+ Txid string `json:"txid"`
+ Vout uint32 `json:"vout"`
+ Tree int8 `json:"tree"`
+ AmountIn float64 `json:"amountin"`
+ BlockHeight uint32 `json:"blockheight"`
+ ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"`
+}
+
// LocalAddressesResult models the localaddresses data from the getnetworkinfo
// command.
type LocalAddressesResult struct {