decred / dcrdata

Decred block explorer, with packages and apps for data collection and storage. Written in Go.
https://dcrdata.decred.org/
ISC License
129 stars 128 forks source link

api: missed tickets should name the block #1024

Closed chappjc closed 5 years ago

chappjc commented 5 years ago

Follow-up on the explorer change in https://github.com/decred/dcrdata/pull/1023

buck54321 commented 5 years ago

At /tx/{txid}?

chappjc commented 5 years ago

I think there's a TicketInfo field where that would be appropriate

buck54321 commented 5 years ago

The existing /tx/{txid}/ endpoints use apitypes.Tx, which is nearly identical to dcrjson.TxRawResult.

Should we add the missed ticket info to apitypes.Tx, or is there some reason to keep the type faithful to the dcrd type?

chappjc commented 5 years ago

For the sake of discussion, here is dcrjson.TxRawResult:

type TxRawResult struct {
    Hex           string `json:"hex"`
    Txid          string `json:"txid"`
    Version       int32  `json:"version"`
    LockTime      uint32 `json:"locktime"`
    Expiry        uint32 `json:"expiry"`
    Vin           []Vin  `json:"vin"`
    Vout          []Vout `json:"vout"`
    BlockHash     string `json:"blockhash,omitempty"`
    BlockHeight   int64  `json:"blockheight,omitempty"`
    BlockIndex    uint32 `json:"blockindex,omitempty"`
    Confirmations int64  `json:"confirmations,omitempty"`
    Time          int64  `json:"time,omitempty"`
    Blocktime     int64  `json:"blocktime,omitempty"`
}

type Vout struct {
    Value        float64            `json:"value"`
    N            uint32             `json:"n"`
    Version      uint16             `json:"version"`
    ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"`
}

Here is apitypes.Tx:

type Tx struct {
    TxShort
    Confirmations int64    `json:"confirmations"`
    Block         *BlockID `json:"block,omitempty"`
}

// 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      []dcrjson.Vin `json:"vin"`
    Vout     []Vout        `json:"vout"`
}

type Vout struct {
    Value               float64      `json:"value"`
    N                   uint32       `json:"n"`
    Version             uint16       `json:"version"`
    ScriptPubKeyDecoded ScriptPubKey `json:"scriptPubKey"`
    Spend               *TxInputID   `json:"spend,omitempty"`
}

// TxInputID specifies a transaction input as hash:vin_index.
type TxInputID struct {
    Hash  string `json:"hash"`
    Index uint32 `json:"vin_index"`
}

// BlockID models very basic info about a block
type BlockID struct {
    BlockHash   string `json:"blockhash"`
    BlockHeight int64  `json:"blockheight"`
    BlockIndex  uint32 `json:"blockindex"`
    Time        int64  `json:"time"`
    BlockTime   int64  `json:"blocktime"`
}
chappjc commented 5 years ago

The TicketInfo field was something in the explorer/types package, so that's not relevant.

I'm not entirely sure the /tx/{txid} endpoint is the right place for it, but if it is I would probably add a new field with omitempty in the tag so it's only shown for tickets. Alternatively, there could be a new endpoint like /tx/{txid}/tinfo (note that there is a /tx/{txid}/vinfo endpoint for vote info).

chappjc commented 5 years ago

@buck54321 Were you planning to hit this up (since you were asking about it)? All OK if not.

buck54321 commented 5 years ago

I've been going back and forth, but I'm leaning towards the /tinfo approach. I was thinking of a response structure something like

{
    "status": string,
    "purchase_block": {
        "height": int,
        "hash": string
    },
    "maturity_height": int,
    "expiration_height": int,
    "lottery_block": null || {
        "height": int,
        "hash": string,
    },
    "vote": null || string || omitempty,
    "revocation": null || string || omitempty
}
chappjc commented 5 years ago

I had the same thought about "lottery_block". That response structure you propose looks good to me. What valid "status" strings did you have in mind? There is the combination of spend status and ticket pool status.

https://github.com/decred/dcrdata/blob/12d31d2bd577210e57a211d253eadfa0991cd322/db/dbtypes/types.go#L150-L174

buck54321 commented 5 years ago

Probably break "unspent" into "immature" and "live", after which it will be "voted", or one of "expired" or "missed" until it is "revoked".

immature
live
voted
expired
missed
revoked

For a "revoked" ticket, you would then have to check whether the lottery block is null to see whether its previous state was "expired" or "missed".

chappjc commented 5 years ago

Perfect. So a "missed" ticket will always have "lottery_block" set, while "expired" will not. I suppose "expiration_height" will have omitempty on the tag then?

chappjc commented 5 years ago

It's no issue to have this in the 4.1 release that will follow shortly after 4.0. Changing milestone.