Skip to content

Commit

Permalink
byte hashes
Browse files Browse the repository at this point in the history
pkscript bytes
  • Loading branch information
chappjc committed Aug 30, 2023
1 parent 1fdcc52 commit 43381d8
Show file tree
Hide file tree
Showing 54 changed files with 2,069 additions and 1,571 deletions.
42 changes: 31 additions & 11 deletions api/types/insightapitypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package types

import (
"encoding/hex"
"encoding/json"

"github.com/decred/dcrdata/v8/db/dbtypes"
Expand Down Expand Up @@ -80,19 +81,38 @@ type InsightPagination struct {
IsToday string `json:"isToday,omitempty"`
}

var _ json.Unmarshaler = (*HexBytes)(nil)
var _ json.Marshaler = HexBytes{}

type HexBytes []byte

func (hb HexBytes) MarshalJSON() ([]byte, error) {
return []byte(`"` + hex.EncodeToString(hb) + `"`), nil // json.Marshal(hex.EncodeToString(hb)) but not absurdly inefficient
}

func (hb *HexBytes) UnmarshalJSON(b []byte) error {
var str string
err := json.Unmarshal(b, &str)
if err != nil {
return err
}
*hb, err = hex.DecodeString(str)
return err
}

// AddressTxnOutput models an address transaction outputs.
type AddressTxnOutput struct {
Address string `json:"address"`
TxnID string `json:"txid"`
Vout uint32 `json:"vout"`
BlockTime int64 `json:"ts,omitempty"`
ScriptPubKey string `json:"scriptPubKey"`
Height int64 `json:"height,omitempty"`
BlockHash string `json:"block_hash,omitempty"`
Amount float64 `json:"amount,omitempty"`
Atoms int64 `json:"atoms,omitempty"` // Not Required per Insight spec
Satoshis int64 `json:"satoshis,omitempty"`
Confirmations int64 `json:"confirmations"`
Address string `json:"address"`
TxnID string `json:"txid"`
Vout uint32 `json:"vout"`
BlockTime int64 `json:"ts,omitempty"`
ScriptPubKey HexBytes `json:"scriptPubKey"`
Height int64 `json:"height,omitempty"`
BlockHash string `json:"block_hash,omitempty"`
Amount float64 `json:"amount,omitempty"`
Atoms int64 `json:"atoms,omitempty"` // Not Required per Insight spec
Satoshis int64 `json:"satoshis,omitempty"`
Confirmations int64 `json:"confirmations"`
}

// TxOutFromDB converts a dbtypes.AddressTxnOutput to a api/types.AddressTxnOutput.
Expand Down
18 changes: 18 additions & 0 deletions api/types/insightapitypes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package types

import (
"fmt"
"testing"
)

func TestHexBytes_UnmarshalJSON(t *testing.T) {
in := []byte(`"deadbeef"`)
var hb HexBytes
err := hb.UnmarshalJSON(in)
if err != nil {
t.Fatal(err)
}
fmt.Printf("%x\n", []byte(hb))
out, _ := hb.MarshalJSON()
fmt.Println(string(out))
}
6 changes: 3 additions & 3 deletions cmd/dcrdata/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/decred/dcrdata/cmd/dcrdata

go 1.18
go 1.21

replace (
github.com/decred/dcrdata/db/dcrpg/v8 => ../../db/dcrpg/
Expand Down Expand Up @@ -35,8 +35,8 @@ require (
github.com/jessevdk/go-flags v1.5.0
github.com/jrick/logrotate v1.0.0
github.com/rs/cors v1.8.2
golang.org/x/net v0.8.0
golang.org/x/text v0.8.0
golang.org/x/net v0.14.0
golang.org/x/text v0.12.0
)

require (
Expand Down
4 changes: 2 additions & 2 deletions cmd/dcrdata/internal/api/apiroutes.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type DataSource interface {
GetBlockHash(idx int64) (string, error)
GetBlockHeight(hash string) (int64, error)
GetBlockByHash(string) (*wire.MsgBlock, error)
SpendingTransaction(fundingTx string, vout uint32) (string, uint32, int8, error)
SpendingTransaction(fundingTx string, vout uint32) (string, uint32, error)
SpendingTransactions(fundingTxID string) ([]string, []uint32, []uint32, error)
AddressHistory(address string, N, offset int64, txnType dbtypes.AddrTxnViewType) ([]*dbtypes.AddressRow, *dbtypes.AddressBalance, error)
FillAddressTransactions(addrInfo *dbtypes.AddressInfo) error
Expand All @@ -80,7 +80,7 @@ type DataSource interface {
GetStakeInfoExtendedByHash(hash string) *apitypes.StakeInfoExtended
GetStakeInfoExtendedByHeight(idx int) *apitypes.StakeInfoExtended
GetPoolInfo(idx int) *apitypes.TicketPoolInfo
GetPoolInfoByHash(hash string) *apitypes.TicketPoolInfo
// GetPoolInfoByHash(hash string) *apitypes.TicketPoolInfo
GetPoolInfoRange(idx0, idx1 int) []apitypes.TicketPoolInfo
GetPoolValAndSizeRange(idx0, idx1 int) ([]float64, []uint32)
GetPool(idx int64) ([]string, error)
Expand Down
10 changes: 5 additions & 5 deletions cmd/dcrdata/internal/api/insight/apiroutes.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (

type BlockDataSource interface {
AddressBalance(address string) (bal *dbtypes.AddressBalance, cacheUpdated bool, err error)
AddressIDsByOutpoint(txHash string, voutIndex uint32) ([]uint64, []string, int64, error)
OutpointAddresses(txHash string, voutIndex uint32) ([]string, int64, error)
AddressUTXO(address string) ([]*dbtypes.AddressTxnOutput, bool, error)
BlockSummaryTimeRange(min, max int64, limit int) ([]dbtypes.BlockDataBasic, error)
GetBlockHash(idx int64) (string, error)
Expand Down Expand Up @@ -130,7 +130,7 @@ func writeJSON(w http.ResponseWriter, thing interface{}, indent string) {
func writeInsightError(w http.ResponseWriter, str string) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, str)
io.WriteString(w, str) //nolint:errcheck
}

// Insight API response for an item NOT FOUND. This means the request was valid
Expand All @@ -140,7 +140,7 @@ func writeInsightError(w http.ResponseWriter, str string) {
func writeInsightNotFound(w http.ResponseWriter, str string) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusNotFound)
io.WriteString(w, str)
io.WriteString(w, str) //nolint:errcheck
}

func (iapi *InsightApi) getTransaction(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -459,7 +459,7 @@ func (iapi *InsightApi) getAddressesTxnOutput(w http.ResponseWriter, r *http.Req
// need to do one more search on utxo and do not add if this is
// already in the list as a confirmed tx.
for _, utxo := range confirmedTxnOutputs {
if utxo.Vout == f.Index && utxo.TxHash == f.Hash {
if utxo.Vout == f.Index && utxo.TxHash == dbtypes.ChainHash(f.Hash) {
continue FUNDING_TX_DUPLICATE_CHECK
}
}
Expand All @@ -473,7 +473,7 @@ func (iapi *InsightApi) getAddressesTxnOutput(w http.ResponseWriter, r *http.Req
TxnID: fundingTx.Hash().String(),
Vout: f.Index,
BlockTime: fundingTx.MemPoolTime,
ScriptPubKey: hex.EncodeToString(txOut.PkScript),
ScriptPubKey: txOut.PkScript,
Amount: dcrutil.Amount(txOut.Value).ToCoin(),
Satoshis: txOut.Value,
Confirmations: 0,
Expand Down
2 changes: 1 addition & 1 deletion cmd/dcrdata/internal/api/insight/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (iapi *InsightApi) DcrToInsightTxns(txs []*chainjson.TxRawResult, noAsm, no
// work if the funding transaction is confirmed. Otherwise use RPC
// to get the funding transaction outpoint addresses.
if !vinGenerated {
_, addresses, _, err := iapi.BlockData.AddressIDsByOutpoint(vin.Txid, vin.Vout)
addresses, _, err := iapi.BlockData.OutpointAddresses(vin.Txid, vin.Vout)
if err == nil && len(addresses) > 0 {
InsightVin.Addr = addresses[0]
} else {
Expand Down
4 changes: 3 additions & 1 deletion cmd/dcrdata/internal/api/insight/socket.io.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ func NewSocketServer(params *chaincfg.Params, txGetter txhelpers.RawTransactionG

apiLog.Infof("Started Insight socket.io server.")

go server.Serve()
go func() {
apiLog.Warnf("SocketServer.Serve: %v", server.Serve())
}()
return server, nil
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/dcrdata/internal/explorer/explorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type explorerDataSource interface {
Height() int64
HeightDB() (int64, error)
BlockHash(height int64) (string, error)
SpendingTransaction(fundingTx string, vout uint32) (string, uint32, int8, error)
SpendingTransaction(fundingTx string, vout uint32) (string, uint32, error)
SpendingTransactions(fundingTxID string) ([]string, []uint32, []uint32, error)
PoolStatusForTicket(txid string) (dbtypes.TicketSpendType, dbtypes.TicketPoolStatus, error)
TreasuryBalance() (*dbtypes.TreasuryBalance, error)
Expand All @@ -89,7 +89,7 @@ type explorerDataSource interface {
TicketPoolVisualization(interval dbtypes.TimeBasedGrouping) (*dbtypes.PoolTicketsData, *dbtypes.PoolTicketsData, *dbtypes.PoolTicketsData, int64, error)
TransactionBlocks(hash string) ([]*dbtypes.BlockStatus, []uint32, error)
Transaction(txHash string) ([]*dbtypes.Tx, error)
VinsForTx(*dbtypes.Tx) (vins []dbtypes.VinTxProperty, prevPkScripts []string, scriptVersions []uint16, err error)
VinsForTx(*dbtypes.Tx) (vins []dbtypes.VinTxProperty, err error)
VoutsForTx(*dbtypes.Tx) ([]dbtypes.Vout, error)
PosIntervals(limit, offset uint64) ([]*dbtypes.BlocksGroupedInfo, error)
TimeBasedIntervals(timeGrouping dbtypes.TimeBasedGrouping, limit, offset uint64) ([]*dbtypes.BlocksGroupedInfo, error)
Expand Down
68 changes: 35 additions & 33 deletions cmd/dcrdata/internal/explorer/explorerroutes.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func (exp *explorerUI) Home(w http.ResponseWriter, r *http.Request) {
}
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
io.WriteString(w, str)
io.WriteString(w, str) //nolint:errcheck
}

// SideChains is the page handler for the "/side" path.
Expand Down Expand Up @@ -275,7 +275,7 @@ func (exp *explorerUI) SideChains(w http.ResponseWriter, r *http.Request) {
}
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
io.WriteString(w, str)
io.WriteString(w, str) //nolint:errcheck
}

// InsightRootPage is the page for the "/insight" path.
Expand All @@ -293,7 +293,7 @@ func (exp *explorerUI) InsightRootPage(w http.ResponseWriter, r *http.Request) {
}
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
io.WriteString(w, str)
io.WriteString(w, str) //nolint:errcheck
}

// DisapprovedBlocks is the page handler for the "/disapproved" path.
Expand Down Expand Up @@ -324,7 +324,7 @@ func (exp *explorerUI) DisapprovedBlocks(w http.ResponseWriter, r *http.Request)
}
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
io.WriteString(w, str)
io.WriteString(w, str) //nolint:errcheck
}

// VisualBlocks is the page handler for the "/visualblocks" path.
Expand Down Expand Up @@ -746,7 +746,7 @@ func (exp *explorerUI) Block(w http.ResponseWriter, r *http.Request) {
log.Warnf("Unable to retrieve chain status for block %s: %v", hash, err)
}
for i, block := range altBlocks {
if block.Hash == hash {
if block.Hash.String() == hash {
data.Valid = block.IsValid
data.MainChain = block.IsMainchain
altBlocks = append(altBlocks[:i], altBlocks[i+1:]...)
Expand Down Expand Up @@ -852,7 +852,9 @@ func (exp *explorerUI) TxPage(w http.ResponseWriter, r *http.Request) {

tx := exp.dataSource.GetExplorerTx(hash)
// If dcrd has no information about the transaction, pull the transaction
// details from the auxiliary DB database.
// details from the auxiliary DB database. Several pieces of information may
// be missing, namely the pkScripts and various information, including the
// prevout addresses.
if tx == nil {
log.Warnf("No transaction information for %v. Trying tables in case this is an orphaned txn.", hash)
// Search for occurrences of the transaction in the database.
Expand Down Expand Up @@ -897,9 +899,9 @@ func (exp *explorerUI) TxPage(w http.ResponseWriter, r *http.Request) {
// Vouts - looked-up in vouts table
BlockHeight: dbTx0.BlockHeight,
BlockIndex: dbTx0.BlockIndex,
BlockHash: dbTx0.BlockHash,
BlockHash: dbTx0.BlockHash.String(),
Confirmations: exp.Height() - dbTx0.BlockHeight + 1,
Time: types.TimeDef(dbTx0.Time),
Time: types.TimeDef(dbTx0.BlockTime),
}

// Coinbase transactions are regular, but call them coinbase for the page.
Expand All @@ -924,17 +926,17 @@ func (exp *explorerUI) TxPage(w http.ResponseWriter, r *http.Request) {
// Convert to explorer.Vout, getting spending information from DB.
for iv := range vouts {
// Check pkScript for OP_RETURN and OP_TADD.
pkScript := vouts[iv].ScriptPubKey
opTAdd := len(pkScript) > 0 && pkScript[0] == txscript.OP_TADD
var opReturn string
if !opTAdd {
asm, _ := txscript.DisasmString(pkScript)
if strings.HasPrefix(asm, "OP_RETURN") {
opReturn = asm
}
}
// pkScript := vouts[iv].ScriptPubKey
// opTAdd := len(pkScript) > 0 && pkScript[0] == txscript.OP_TADD
// var opReturn string
// if !opTAdd {
// asm, _ := txscript.DisasmString(pkScript)
// if strings.HasPrefix(asm, "OP_RETURN") {
// opReturn = asm
// }
// }
// Determine if the outpoint is spent
spendingTx, _, _, err := exp.dataSource.SpendingTransaction(hash, vouts[iv].TxIndex)
spendingTx, _, err := exp.dataSource.SpendingTransaction(hash, vouts[iv].TxIndex)
if exp.timeoutErrorPage(w, err, "SpendingTransaction") {
return
}
Expand All @@ -949,15 +951,15 @@ func (exp *explorerUI) TxPage(w http.ResponseWriter, r *http.Request) {
FormattedAmount: humanize.Commaf(amount),
Type: vouts[iv].ScriptPubKeyData.Type.String(),
Spent: spendingTx != "",
OP_RETURN: opReturn,
OP_TADD: opTAdd,
Index: vouts[iv].TxIndex,
Version: vouts[iv].Version,
// OP_RETURN: opReturn,
// OP_TADD: opTAdd,
Index: vouts[iv].TxIndex,
Version: vouts[iv].Version,
})
}

// Retrieve vins from DB.
vins, prevPkScripts, scriptVersions, err := exp.dataSource.VinsForTx(dbTx0)
vins, err := exp.dataSource.VinsForTx(dbTx0)
if exp.timeoutErrorPage(w, err, "VinsForTx") {
return
}
Expand All @@ -971,15 +973,15 @@ func (exp *explorerUI) TxPage(w http.ResponseWriter, r *http.Request) {
// Convert to explorer.Vin from dbtypes.VinTxProperty.
for iv := range vins {
// Decode all addresses from previous outpoint's pkScript.
var addresses []string
pkScriptsStr, err := hex.DecodeString(prevPkScripts[iv])
if err != nil {
log.Errorf("Failed to decode pkScript: %v", err)
}
_, scrAddrs := stdscript.ExtractAddrs(scriptVersions[iv], pkScriptsStr, exp.ChainParams)
for ia := range scrAddrs {
addresses = append(addresses, scrAddrs[ia].String())
}
// var addresses []string
// pkScriptsStr, err := hex.DecodeString(prevPkScripts[iv])
// if err != nil {
// log.Errorf("Failed to decode pkScript: %v", err)
// }
// _, scrAddrs := stdscript.ExtractAddrs(scriptVersions[iv], pkScriptsStr, exp.ChainParams)
// for ia := range scrAddrs {
// addresses = append(addresses, scrAddrs[ia].String())
// }

// If the scriptsig does not decode or disassemble, oh well.
asm, _ := txscript.DisasmString(vins[iv].ScriptSig)
Expand Down Expand Up @@ -1017,7 +1019,7 @@ func (exp *explorerUI) TxPage(w http.ResponseWriter, r *http.Request) {
Hex: hex.EncodeToString(vins[iv].ScriptSig),
},
},
Addresses: addresses,
Addresses: []string{"unknown"}, // addresses,
FormattedAmount: humanize.Commaf(amount),
Index: txIndex,
})
Expand Down
15 changes: 4 additions & 11 deletions cmd/dcrdata/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -886,25 +886,18 @@ func _main(ctx context.Context) error {
sideChainsStored++

// Collect and store data for each block in this side chain.
for _, hash := range sideChain.Hashes {
// Validate the block hash.
blockHash, err := chainhash.NewHashFromStr(hash)
if err != nil {
log.Errorf("Invalid block hash %s: %v.", hash, err)
continue
}

for _, blockHash := range sideChain.Hashes {
// Collect block data.
_, msgBlock, err := collector.CollectHash(blockHash)
_, msgBlock, err := collector.CollectHash(&blockHash)
if err != nil {
// Do not quit if unable to collect side chain block data.
log.Errorf("Unable to collect data for side chain block %s: %v.",
hash, err)
blockHash, err)
continue
}

// Get the chainwork
chainWork, err := rpcutils.GetChainWork(chainDB.Client, blockHash)
chainWork, err := rpcutils.GetChainWork(chainDB.Client, &blockHash)
if err != nil {
log.Errorf("GetChainWork failed (%s): %v", blockHash, err)
continue
Expand Down
2 changes: 1 addition & 1 deletion cmd/swapscan-btc/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/decred/dcrdata/cmd/swapscan-btc

go 1.18
go 1.21

require (
github.com/btcsuite/btcd v0.23.3
Expand Down
Loading

0 comments on commit 43381d8

Please sign in to comment.