Add scripthash variants of RPC handlers.

This commit is contained in:
Jonathan Moody 2022-09-02 16:46:35 -05:00
parent f5b8f2ce0d
commit 90afae7cd5

View file

@ -8,6 +8,7 @@ import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"github.com/lbryio/herald.go/internal"
"github.com/lbryio/lbcd/chaincfg"
@ -145,10 +146,19 @@ func (req *blockHeadersReq) Handle(s *Server) (*blockHeadersResp, error) {
return result, err
}
func hashX(scripthash string) []byte {
sh, _ := hex.DecodeString(scripthash)
func decodeScriptHash(scripthash string) ([]byte, error) {
sh, err := hex.DecodeString(scripthash)
if err != nil {
return nil, err
}
if len(sh) != chainhash.HashSize {
return nil, fmt.Errorf("invalid scripthash: %v (length %v)", scripthash, len(sh))
}
internal.ReverseBytesInPlace(sh)
return sh[:HASHX_LEN]
return sh, nil
}
func hashX(scripthash []byte) []byte {
return scripthash[:HASHX_LEN]
}
func hashXScript(script []byte, coin *chaincfg.Params) []byte {
@ -192,6 +202,28 @@ func (req *addressGetBalanceReq) Handle(s *Server) (*addressGetBalanceResp, erro
return &addressGetBalanceResp{confirmed, unconfirmed}, err
}
type scripthashGetBalanceReq struct {
ScriptHash string `json:"scripthash"`
}
type scripthashGetBalanceResp struct {
Confirmed uint64 `json:"confirmed"`
Unconfirmed uint64 `json:"unconfirmed"`
}
// 'blockchain.scripthash.get_balance'
func (req *scripthashGetBalanceReq) Handle(s *Server) (*scripthashGetBalanceResp, error) {
scripthash, err := decodeScriptHash(req.ScriptHash)
if err != nil {
return nil, err
}
hashX := hashX(scripthash)
confirmed, unconfirmed, err := s.DB.GetBalance(hashX)
if err != nil {
return nil, err
}
return &scripthashGetBalanceResp{confirmed, unconfirmed}, err
}
type addressGetHistoryReq struct {
Address string `json:"address"`
}
@ -220,6 +252,9 @@ func (req *addressGetHistoryReq) Handle(s *Server) (*addressGetHistoryResp, erro
}
hashX := hashXScript(script, s.Chain)
dbTXs, err := s.DB.GetHistory(hashX)
if err != nil {
return nil, err
}
confirmed := make([]TxInfo, 0, len(dbTXs))
for _, tx := range dbTXs {
confirmed = append(confirmed,
@ -235,6 +270,40 @@ func (req *addressGetHistoryReq) Handle(s *Server) (*addressGetHistoryResp, erro
return result, nil
}
type scripthashGetHistoryReq struct {
ScriptHash string `json:"scripthash"`
}
type scripthashGetHistoryResp struct {
Confirmed []TxInfo `json:"confirmed"`
Unconfirmed []TxInfoFee `json:"unconfirmed"`
}
// 'blockchain.scripthash.get_history'
func (req *scripthashGetHistoryReq) Handle(s *Server) (*scripthashGetHistoryResp, error) {
scripthash, err := decodeScriptHash(req.ScriptHash)
if err != nil {
return nil, err
}
hashX := hashX(scripthash)
dbTXs, err := s.DB.GetHistory(hashX)
if err != nil {
return nil, err
}
confirmed := make([]TxInfo, 0, len(dbTXs))
for _, tx := range dbTXs {
confirmed = append(confirmed,
TxInfo{
TxHash: tx.TxHash.String(),
Height: tx.Height,
})
}
result := &scripthashGetHistoryResp{
Confirmed: confirmed,
Unconfirmed: []TxInfoFee{}, // TODO
}
return result, nil
}
type addressGetMempoolReq struct {
Address string `json:"address"`
}
@ -258,6 +327,25 @@ func (req *addressGetMempoolReq) Handle(s *Server) (*addressGetMempoolResp, erro
return &result, nil
}
type scripthashGetMempoolReq struct {
ScriptHash string `json:"scripthash"`
}
type scripthashGetMempoolResp []TxInfoFee
// 'blockchain.scripthash.get_mempool'
func (req *scripthashGetMempoolReq) Handle(s *Server) (*scripthashGetMempoolResp, error) {
scripthash, err := decodeScriptHash(req.ScriptHash)
if err != nil {
return nil, err
}
hashX := hashX(scripthash)
// TODO...
internal.ReverseBytesInPlace(hashX)
unconfirmed := make([]TxInfoFee, 0, 100)
result := scripthashGetMempoolResp(unconfirmed)
return &result, nil
}
type addressListUnspentReq struct {
Address string `json:"address"`
}
@ -294,3 +382,30 @@ func (req *addressListUnspentReq) Handle(s *Server) (*addressListUnspentResp, er
result := addressListUnspentResp(unspent)
return &result, nil
}
type scripthashListUnspentReq struct {
ScriptHash string `json:"scripthash"`
}
type scripthashListUnspentResp []TXOInfo
// 'blockchain.scripthash.listunspent'
func (req *scripthashListUnspentReq) Handle(s *Server) (*scripthashListUnspentResp, error) {
scripthash, err := decodeScriptHash(req.ScriptHash)
if err != nil {
return nil, err
}
hashX := hashX(scripthash)
dbTXOs, err := s.DB.GetUnspent(hashX)
unspent := make([]TXOInfo, 0, len(dbTXOs))
for _, txo := range dbTXOs {
unspent = append(unspent,
TXOInfo{
TxHash: txo.TxHash.String(),
TxPos: txo.TxPos,
Height: txo.Height,
Value: txo.Value,
})
}
result := scripthashListUnspentResp(unspent)
return &result, nil
}