Documentation ¶
Index ¶
- Constants
- Variables
- func BlockOK(blk wire.MsgBlock) bool
- func CheckDoubleSpends(argTx *wire.MsgTx, txs []*wire.MsgTx) ([]*wire.ShaHash, error)
- func CheckHeader(r io.ReadSeeker, height int32, p *chaincfg.Params) bool
- func CheckRange(r io.ReadSeeker, first, last int32, p *chaincfg.Params) bool
- func EstFee(otx *wire.MsgTx, spB int64) int64
- func LoadKeyFromFileArg(filename string, pass []byte) (*[32]byte, error)
- func LoadKeyFromFileInteractive(filename string) (*[32]byte, error)
- func MakeMerkleParent(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash
- func OutPointsEqual(a, b wire.OutPoint) bool
- func ReadKeyFileToECPriv(filename string, p *chaincfg.Params) (*hdkeychain.ExtendedKey, error)
- func SaveKeyToFileArg(filename string, priv32 *[32]byte, pass []byte) error
- func SaveKeyToFileInteractive(filename string, priv32 *[32]byte) error
- func TxToString(tx *wire.MsgTx) string
- type HashAndHeight
- type MyAdr
- type SPVCon
- func (s *SPVCon) AskForBlocks() error
- func (s *SPVCon) AskForHeaders() error
- func (s *SPVCon) AskForOneBlock(h int32) error
- func (s *SPVCon) AskForTx(txid wire.ShaHash)
- func (s *SPVCon) GetDataHandler(m *wire.MsgGetData)
- func (s *SPVCon) HeaderHandler(m *wire.MsgHeaders)
- func (s *SPVCon) IngestBlock(m *wire.MsgBlock)
- func (s *SPVCon) IngestHeaders(m *wire.MsgHeaders) (bool, error)
- func (s *SPVCon) IngestMerkleBlock(m *wire.MsgMerkleBlock)
- func (s *SPVCon) InvHandler(m *wire.MsgInv)
- func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error
- func (s *SPVCon) PongBack(nonce uint64)
- func (s *SPVCon) Rebroadcast()
- func (s *SPVCon) RemoveHeaders(r int32) error
- func (s *SPVCon) SendCoins(adrs []btcutil.Address, sendAmts []int64) error
- func (s *SPVCon) SendFilter(f *bloom.Filter)
- func (s *SPVCon) SendOne(u Utxo, adr btcutil.Address) error
- func (s *SPVCon) TxHandler(m *wire.MsgTx)
- type SortableUtxoSlice
- type Stxo
- type TxStore
- func (t *TxStore) AddTxid(txid *wire.ShaHash, height int32) error
- func (ts *TxStore) GetAllStxos() ([]*Stxo, error)
- func (ts *TxStore) GetAllTxs() ([]*wire.MsgTx, error)
- func (ts *TxStore) GetAllUtxos() ([]*Utxo, error)
- func (ts *TxStore) GetDBSyncHeight() (int32, error)
- func (ts *TxStore) GetPendingInv() (*wire.MsgInv, error)
- func (ts *TxStore) GetTx(txid *wire.ShaHash) (*wire.MsgTx, error)
- func (t *TxStore) GimmeFilter() (*bloom.Filter, error)
- func (ts *TxStore) Ingest(tx *wire.MsgTx, height int32) (uint32, error)
- func (ts *TxStore) NewAdr() (btcutil.Address, error)
- func (ts *TxStore) OpenDB(filename string) error
- func (ts *TxStore) PopulateAdrs(lastKey uint32) error
- func (ts *TxStore) Refilter() error
- func (ts *TxStore) SetDBSyncHeight(n int32) error
- func (t *TxStore) SignThis(tx *wire.MsgTx) error
- type Utxo
Constants ¶
const ( // version hardcoded for now, probably ok...? // 70012 is for segnet... make this a init var? VERSION = 70012 )
Variables ¶
var ( BKTUtxos = []byte("DuffelBag") // leave the rest to collect interest BKTStxos = []byte("SpentTxs") // for bookkeeping BKTTxns = []byte("Txns") // all txs we care about, for replays BKTState = []byte("MiscState") // last state of DB // these are in the state bucket KEYNumKeys = []byte("NumKeys") // number of p2pkh keys used KEYTipHeight = []byte("TipHeight") // height synced to )
var (
WitMagicBytes = []byte{0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed}
)
Functions ¶
func BlockOK ¶
BlockRootOK checks for block self-consistency. If the block has no wintess txs, and no coinbase witness commitment, it only checks the tx merkle root. If either a witness commitment or any witnesses are detected, it also checks that as well. Returns false if anything goes wrong, true if everything is fine.
func CheckDoubleSpends ¶
GetDoubleSpends takes a transaction and compares it with all transactions in the db. It returns a slice of all txids in the db which are double spent by the received tx.
func CheckHeader ¶
func CheckRange ¶
checkrange verifies a range of headers. it checks their proof of work,
difficulty adjustments, and that they all link in to each other properly. This is the only blockchain technology in the whole code base. Returns false if anything bad happens. Returns true if the range checks out with no errors.
func EstFee ¶
EstFee gives a fee estimate based on a tx and a sat/Byte target. The TX should have all outputs, including the change address already populated (with potentially 0 amount. Also it should have all inputs populated, but inputs don't need to have sigscripts or witnesses (it'll guess the sizes of sigs/wits that arent' filled in).
func LoadKeyFromFileArg ¶
LoadKeyFromFileArg opens the file and returns the key. If the key is unencrypted it will ignore the password argument.
func LoadKeyFromFileInteractive ¶
LoadKeyFromFileInteractive opens the file 'filename' and presents a keyboard prompt for the passphrase to decrypt it. It returns the key if decryption works, or errors out.
func MakeMerkleParent ¶
func OutPointsEqual ¶
need this because before I was comparing pointers maybe? so they were the same outpoint but stored in 2 places so false negative?
func ReadKeyFileToECPriv ¶
func ReadKeyFileToECPriv( filename string, p *chaincfg.Params) (*hdkeychain.ExtendedKey, error)
ReadKeyFileToECPriv returns an extendedkey from a file. If there's no file there, it'll make one. If there's a password needed, it'll prompt for one. One stop function.
func SaveKeyToFileArg ¶
saves a 32 byte key to a file, encrypting with pass. if pass is nil or zero length, doesn't encrypt and just saves in hex.
func SaveKeyToFileInteractive ¶
saves a 32 byte key to file, prompting for passphrase. if user enters empty passphrase (hits enter twice), will be saved in the clear.
func TxToString ¶
TxToString prints out some info about a transaction. for testing / debugging
Types ¶
type HashAndHeight ¶
type HashAndHeight struct {
// contains filtered or unexported fields
}
HashAndHeight is needed instead of just height in case a fullnode responds abnormally (?) by sending out of order merkleblocks. we cache a merkleroot:height pair in the queue so we don't have to look them up from the disk. Also used when inv messages indicate blocks so we can add the header and parse the txs in one request instead of requesting headers first.
func NewRootAndHeight ¶
func NewRootAndHeight(b wire.ShaHash, h int32) (hah HashAndHeight)
NewRootAndHeight saves like 2 lines.
type SPVCon ¶
type SPVCon struct { // Enhanced SPV modes for users who have outgrown easy mode SPV // but have not yet graduated to full nodes. HardMode bool // hard mode doesn't use filters. Ironman bool // ironman only gets blocks, never requests txs. WBytes uint64 // total bytes written RBytes uint64 // total bytes read TS *TxStore // transaction store to write to // contains filtered or unexported fields }
func OpenSPV ¶
func OpenSPV(remoteNode string, hfn, dbfn string, inTs *TxStore, hard bool, iron bool, p *chaincfg.Params) (SPVCon, error)
OpenPV starts a
func (*SPVCon) AskForBlocks ¶
AskForMerkBlocks requests blocks from current to last right now this asks for 1 block per getData message. Maybe it's faster to ask for many in a each message?
func (*SPVCon) AskForHeaders ¶
func (*SPVCon) AskForOneBlock ¶
AskForOneBlock is for testing only, so you can ask for a specific block height and see what goes wrong
func (*SPVCon) AskForTx ¶
AskForTx requests a tx we heard about from an inv message. It's one at a time but should be fast enough. I don't like this function because SPV shouldn't even ask...
func (*SPVCon) GetDataHandler ¶
func (s *SPVCon) GetDataHandler(m *wire.MsgGetData)
GetDataHandler responds to requests for tx data, which happen after advertising our txs via an inv message
func (*SPVCon) HeaderHandler ¶
func (s *SPVCon) HeaderHandler(m *wire.MsgHeaders)
func (*SPVCon) IngestBlock ¶
IngestBlock is like IngestMerkleBlock but aralphic different enough that it's better to have 2 separate functions
func (*SPVCon) IngestHeaders ¶
func (s *SPVCon) IngestHeaders(m *wire.MsgHeaders) (bool, error)
IngestHeaders takes in a bunch of headers and appends them to the local header file, checking that they fit. If there's no headers, it assumes we're done and returns false. If it worked it assumes there's more to request and returns true.
func (*SPVCon) IngestMerkleBlock ¶
func (s *SPVCon) IngestMerkleBlock(m *wire.MsgMerkleBlock)
func (*SPVCon) InvHandler ¶
func (*SPVCon) Rebroadcast ¶
func (s *SPVCon) Rebroadcast()
Rebroadcast sends an inv message of all the unconfirmed txs the db is aware of. This is called after every sync. Only txids so hopefully not too annoying for nodes.
func (*SPVCon) RemoveHeaders ¶
func (*SPVCon) SendCoins ¶
SendCoins does send coins, but it's very rudimentary wit makes it into p2wpkh. Which is not yet spendable.
func (*SPVCon) SendFilter ¶
type SortableUtxoSlice ¶
type SortableUtxoSlice []Utxo
func (SortableUtxoSlice) Len ¶
func (s SortableUtxoSlice) Len() int
utxoByAmts get sorted by utxo value. also put unconfirmed last
func (SortableUtxoSlice) Less ¶
func (s SortableUtxoSlice) Less(i, j int) bool
height 0 means your lesser
func (SortableUtxoSlice) Swap ¶
func (s SortableUtxoSlice) Swap(i, j int)
type Stxo ¶
type Stxo struct { Utxo // when it used to be a utxo SpendHeight int32 // height at which it met its demise SpendTxid wire.ShaHash // the tx that consumed it }
Stxo is a utxo that has moved on.
func StxoFromBytes ¶
StxoFromBytes turns bytes into a Stxo. first take the first 53 bytes as a utxo, then the next 36 for how it's spent.
type TxStore ¶
type TxStore struct { OKTxids map[wire.ShaHash]int32 // known good txids and their heights OKMutex sync.Mutex Adrs []MyAdr // endeavouring to acquire capital StateDB *bolt.DB // place to write all this down // Params live here, not SCon Param *chaincfg.Params // network parameters (testnet3, testnetL) // contains filtered or unexported fields }
func NewTxStore ¶
func NewTxStore(rootkey *hdkeychain.ExtendedKey, p *chaincfg.Params) TxStore
func (*TxStore) GetAllStxos ¶
GetAllStxos returns a slice of all stxos known to the db. empty slice is OK.
func (*TxStore) GetAllUtxos ¶
GetAllUtxos returns a slice of all utxos known to the db. empty slice is OK.
func (*TxStore) GetDBSyncHeight ¶
SyncHeight returns the chain height to which the db has synced
func (*TxStore) GetPendingInv ¶
GetPendingInv returns an inv message containing all txs known to the db which are at height 0 (not known to be confirmed). This can be useful on startup or to rebroadcast unconfirmed txs.
func (*TxStore) GimmeFilter ¶
... or I'm gonna fade away
func (*TxStore) Ingest ¶
Ingest puts a tx into the DB atomically. This can result in a gain, a loss, or no result. Gain or loss in satoshis is returned.
func (*TxStore) NewAdr ¶
NewAdr creates a new, never before seen address, and increments the DB counter as well as putting it in the ram Adrs store, and returns it
func (*TxStore) PopulateAdrs ¶
PopulateAdrs just puts a bunch of adrs in ram; it doesn't touch the DB
func (*TxStore) SetDBSyncHeight ¶
SetDBSyncHeight sets sync height of the db, indicated the latest block of which it has ingested all the transactions.
type Utxo ¶
type Utxo struct { Op wire.OutPoint // where // all the info needed to spend AtHeight int32 // block height where this tx was confirmed, 0 for unconf KeyIdx uint32 // index for private key needed to sign / spend Value int64 // higher is better // IsCoinbase bool // can't spend for a while IsWit bool // true if p2wpkh output }
func UtxoFromBytes ¶
UtxoFromBytes turns bytes into a Utxo. Note it wants the txid and outindex in the first 36 bytes, which isn't stored that way in the boldDB, but can be easily appended.