WIP: blockchain.transaction.yyy JSON RPC implementations #78
3 changed files with 53 additions and 7 deletions
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-restruct/restruct"
|
"github.com/go-restruct/restruct"
|
||||||
|
"github.com/lbryio/herald.go/internal"
|
||||||
"github.com/lbryio/lbcd/chaincfg/chainhash"
|
"github.com/lbryio/lbcd/chaincfg/chainhash"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -59,6 +60,34 @@ func (kv *BlockTxsValue) Unpack(buf []byte, order binary.ByteOrder) ([]byte, err
|
||||||
return buf[offset:], nil
|
return buf[offset:], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Struct BigEndianChainHash is a chainhash.Hash stored in external
|
||||||
|
// byte-order (opposite of other 32 byte chainhash.Hash values). In order
|
||||||
|
// to reuse chainhash.Hash we need to correct the byte-order.
|
||||||
|
// Currently this type is used for field Genesis of DBStateValue.
|
||||||
|
|
||||||
|
func (kv *BigEndianChainHash) SizeOf() int {
|
||||||
|
return chainhash.HashSize
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kv *BigEndianChainHash) Pack(buf []byte, order binary.ByteOrder) ([]byte, error) {
|
||||||
|
offset := 0
|
||||||
|
hash := kv.CloneBytes()
|
||||||
|
// HACK: Instances of chainhash.Hash use the internal byte-order.
|
||||||
|
// Python scribe writes bytes of genesis hash in external byte-order.
|
||||||
|
internal.ReverseBytesInPlace(hash)
|
||||||
|
offset += copy(buf[offset:chainhash.HashSize], hash[:])
|
||||||
|
return buf[offset:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kv *BigEndianChainHash) Unpack(buf []byte, order binary.ByteOrder) ([]byte, error) {
|
||||||
|
offset := 0
|
||||||
|
offset += copy(kv.Hash[:], buf[offset:32])
|
||||||
|
// HACK: Instances of chainhash.Hash use the internal byte-order.
|
||||||
|
// Python scribe writes bytes of genesis hash in external byte-order.
|
||||||
|
internal.ReverseBytesInPlace(kv.Hash[:])
|
||||||
|
return buf[offset:], nil
|
||||||
|
}
|
||||||
|
|
||||||
func genericNew(prefix []byte, key bool) (interface{}, error) {
|
func genericNew(prefix []byte, key bool) (interface{}, error) {
|
||||||
t, ok := prefixRegistry[prefix[0]]
|
t, ok := prefixRegistry[prefix[0]]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -182,12 +182,25 @@ func NewLengthEncodedPartialClaimId(s string) LengthEncodedPartialClaimId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BigEndianChainHash struct {
|
||||||
|
chainhash.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBigEndianChainHash(hash *chainhash.Hash) BigEndianChainHash {
|
||||||
|
if hash != nil {
|
||||||
|
return BigEndianChainHash{
|
||||||
|
*hash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BigEndianChainHash{}
|
||||||
|
}
|
||||||
|
|
||||||
type DBStateKey struct {
|
type DBStateKey struct {
|
||||||
Prefix []byte `struct:"[1]byte" json:"prefix"`
|
Prefix []byte `struct:"[1]byte" json:"prefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DBStateValue struct {
|
type DBStateValue struct {
|
||||||
Genesis *chainhash.Hash
|
Genesis BigEndianChainHash
|
||||||
Height uint32
|
Height uint32
|
||||||
TxCount uint32
|
TxCount uint32
|
||||||
Tip *chainhash.Hash
|
Tip *chainhash.Hash
|
||||||
|
@ -203,7 +216,7 @@ type DBStateValue struct {
|
||||||
|
|
||||||
func NewDBStateValue() *DBStateValue {
|
func NewDBStateValue() *DBStateValue {
|
||||||
return &DBStateValue{
|
return &DBStateValue{
|
||||||
Genesis: new(chainhash.Hash),
|
Genesis: NewBigEndianChainHash(nil),
|
||||||
Height: 0,
|
Height: 0,
|
||||||
TxCount: 0,
|
TxCount: 0,
|
||||||
Tip: new(chainhash.Hash),
|
Tip: new(chainhash.Hash),
|
||||||
|
@ -237,7 +250,11 @@ func (v *DBStateValue) PackValue() []byte {
|
||||||
// b'>32sLL32sLLBBlllL'
|
// b'>32sLL32sLLBBlllL'
|
||||||
n := 32 + 4 + 4 + 32 + 4 + 4 + 1 + 1 + 4 + 4 + 4 + 4
|
n := 32 + 4 + 4 + 32 + 4 + 4 + 1 + 1 + 4 + 4 + 4 + 4
|
||||||
value := make([]byte, n)
|
value := make([]byte, n)
|
||||||
copy(value, v.Genesis[:32])
|
genesis := v.Genesis.CloneBytes()
|
||||||
|
// HACK: Instances of chainhash.Hash use the internal byte-order.
|
||||||
|
// Python scribe writes bytes of genesis hash in external byte-order.
|
||||||
|
internal.ReverseBytesInPlace(genesis)
|
||||||
|
copy(value, genesis[:32])
|
||||||
binary.BigEndian.PutUint32(value[32:], v.Height)
|
binary.BigEndian.PutUint32(value[32:], v.Height)
|
||||||
binary.BigEndian.PutUint32(value[32+4:], v.TxCount)
|
binary.BigEndian.PutUint32(value[32+4:], v.TxCount)
|
||||||
copy(value[32+4+4:], v.Tip[:32])
|
copy(value[32+4+4:], v.Tip[:32])
|
||||||
|
@ -286,7 +303,7 @@ func DBStateValueUnpack(value []byte) *DBStateValue {
|
||||||
// Instances of chainhash.Hash should use the internal byte-order.
|
// Instances of chainhash.Hash should use the internal byte-order.
|
||||||
internal.ReverseBytesInPlace(genesis[:])
|
internal.ReverseBytesInPlace(genesis[:])
|
||||||
x := &DBStateValue{
|
x := &DBStateValue{
|
||||||
Genesis: genesis,
|
Genesis: NewBigEndianChainHash(genesis),
|
||||||
Height: binary.BigEndian.Uint32(value[32:]),
|
Height: binary.BigEndian.Uint32(value[32:]),
|
||||||
TxCount: binary.BigEndian.Uint32(value[32+4:]),
|
TxCount: binary.BigEndian.Uint32(value[32+4:]),
|
||||||
Tip: tip,
|
Tip: tip,
|
||||||
|
@ -711,7 +728,7 @@ type BlockTxsKey struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockTxsValue struct {
|
type BlockTxsValue struct {
|
||||||
TxHashes []*chainhash.Hash `struct-while:"!_eof" json:"tx_hashes"`
|
TxHashes []*chainhash.Hash `struct:"*[32]byte" struct-while:"!_eof" json:"tx_hashes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *BlockTxsKey) NewBlockTxsKey(height uint32) *BlockTxsKey {
|
func (k *BlockTxsKey) NewBlockTxsKey(height uint32) *BlockTxsKey {
|
||||||
|
|
|
@ -277,9 +277,9 @@ func MakeHubServer(grp *stop.Group, args *Args) *Server {
|
||||||
|
|
||||||
// Determine which chain to use based on db and cli values
|
// Determine which chain to use based on db and cli values
|
||||||
dbChain := (*chaincfg.Params)(nil)
|
dbChain := (*chaincfg.Params)(nil)
|
||||||
if myDB != nil && myDB.LastState != nil && myDB.LastState.Genesis != nil {
|
if myDB != nil && myDB.LastState != nil {
|
||||||
// The chain params can be inferred from DBStateValue.
|
// The chain params can be inferred from DBStateValue.
|
||||||
switch *myDB.LastState.Genesis {
|
switch myDB.LastState.Genesis.Hash {
|
||||||
case *chaincfg.MainNetParams.GenesisHash:
|
case *chaincfg.MainNetParams.GenesisHash:
|
||||||
dbChain = &chaincfg.MainNetParams
|
dbChain = &chaincfg.MainNetParams
|
||||||
case *chaincfg.TestNet3Params.GenesisHash:
|
case *chaincfg.TestNet3Params.GenesisHash:
|
||||||
|
|
Loading…
Reference in a new issue