mirror of https://github.com/BTCPrivate/lnd.git
simplify boltdb ingest
This commit is contained in:
parent
a14b9a9e70
commit
df04a73e1a
56
shell.go
56
shell.go
|
@ -206,7 +206,7 @@ func Bal(args []string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var score int64
|
var score, confScore int64
|
||||||
for i, u := range allUtxos {
|
for i, u := range allUtxos {
|
||||||
fmt.Printf("\tutxo %d height %d %s key:%d amt %d",
|
fmt.Printf("\tutxo %d height %d %s key:%d amt %d",
|
||||||
i, u.AtHeight, u.Op.String(), u.KeyIdx, u.Value)
|
i, u.AtHeight, u.Op.String(), u.KeyIdx, u.Value)
|
||||||
|
@ -215,6 +215,9 @@ func Bal(args []string) error {
|
||||||
}
|
}
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
score += u.Value
|
score += u.Value
|
||||||
|
if u.AtHeight != 0 {
|
||||||
|
confScore += u.Value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
height, _ := SCon.TS.GetDBSyncHeight()
|
height, _ := SCon.TS.GetDBSyncHeight()
|
||||||
|
|
||||||
|
@ -228,7 +231,7 @@ func Bal(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Total known utxos: %d\n", len(allUtxos))
|
fmt.Printf("Total known utxos: %d\n", len(allUtxos))
|
||||||
fmt.Printf("Total spendable coin: %d\n", score)
|
fmt.Printf("Total coin: %d confirmed: %d\n", score, confScore)
|
||||||
fmt.Printf("DB sync height: %d\n", height)
|
fmt.Printf("DB sync height: %d\n", height)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -266,20 +269,22 @@ func Adr(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fan generates a bunch of fanout. Only for testing, can be expensive.
|
// Fan generates a bunch of fanout. Only for testing, can be expensive.
|
||||||
// syntax: fan numOutputs valOutputs witty
|
// syntax: fan adr numOutputs valOutputs witty
|
||||||
func Fan(args []string) error {
|
func Fan(args []string) error {
|
||||||
if len(args) < 3 {
|
if len(args) < 3 {
|
||||||
return fmt.Errorf("fan syntax: fan numOutputs valOutputs witty")
|
return fmt.Errorf("fan syntax: fan adr numOutputs valOutputs")
|
||||||
}
|
}
|
||||||
numOutputs, err := strconv.ParseInt(args[0], 10, 64)
|
|
||||||
|
adr, err := btcutil.DecodeAddress(args[0], SCon.TS.Param)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("error parsing %s as address\t", args[0])
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
numOutputs, err := strconv.ParseInt(args[1], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
valOutputs, err := strconv.ParseInt(args[1], 10, 64)
|
valOutputs, err := strconv.ParseInt(args[2], 10, 64)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
wittynum, err := strconv.ParseInt(args[2], 10, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -287,21 +292,8 @@ func Fan(args []string) error {
|
||||||
adrs := make([]btcutil.Address, numOutputs)
|
adrs := make([]btcutil.Address, numOutputs)
|
||||||
amts := make([]int64, numOutputs)
|
amts := make([]int64, numOutputs)
|
||||||
|
|
||||||
oAdr, err := SCon.TS.NewAdr()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for i := int64(0); i < numOutputs; i++ {
|
for i := int64(0); i < numOutputs; i++ {
|
||||||
if wittynum != 0 {
|
adrs[i] = adr
|
||||||
wAdr, err := btcutil.NewAddressWitnessPubKeyHash(
|
|
||||||
oAdr.ScriptAddress(), SCon.TS.Param)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
adrs[i] = wAdr
|
|
||||||
} else {
|
|
||||||
adrs[i] = oAdr
|
|
||||||
}
|
|
||||||
amts[i] = valOutputs + i
|
amts[i] = valOutputs + i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,21 +323,21 @@ func Send(args []string) error {
|
||||||
}
|
}
|
||||||
// need args, fail
|
// need args, fail
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
return fmt.Errorf("need args: ssend amount(satoshis) address wit?")
|
return fmt.Errorf("need args: ssend address amount(satoshis) wit?")
|
||||||
}
|
}
|
||||||
|
adr, err := btcutil.DecodeAddress(args[0], SCon.TS.Param)
|
||||||
amt, err := strconv.ParseInt(args[0], 10, 64)
|
if err != nil {
|
||||||
|
fmt.Printf("error parsing %s as address\t", args[0])
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
amt, err := strconv.ParseInt(args[1], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if amt < 1000 {
|
if amt < 1000 {
|
||||||
return fmt.Errorf("can't send %d, too small", amt)
|
return fmt.Errorf("can't send %d, too small", amt)
|
||||||
}
|
}
|
||||||
adr, err := btcutil.DecodeAddress(args[1], SCon.TS.Param)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("error parsing %s as address\t", args[1])
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("send %d to address: %s \n",
|
fmt.Printf("send %d to address: %s \n",
|
||||||
amt, adr.String())
|
amt, adr.String())
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ func (s *SPVCon) Rebroadcast() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// make utxo slices sortable
|
// make utxo slices sortable -- same as txsort
|
||||||
type utxoSlice []Utxo
|
type utxoSlice []Utxo
|
||||||
|
|
||||||
// Sort utxos just like txins -- Len, Less, Swap
|
// Sort utxos just like txins -- Len, Less, Swap
|
||||||
|
@ -68,6 +68,13 @@ func (s utxoSlice) Less(i, j int) bool {
|
||||||
return bytes.Compare(ihash[:], jhash[:]) == -1
|
return bytes.Compare(ihash[:], jhash[:]) == -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type utxoByAmt []Utxo
|
||||||
|
|
||||||
|
// utxoByAmts get sorted by utxo value
|
||||||
|
func (s utxoByAmt) Len() int { return len(s) }
|
||||||
|
func (s utxoByAmt) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
func (s utxoByAmt) Less(i, j int) bool { return s[i].Value < s[j].Value }
|
||||||
|
|
||||||
func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error {
|
func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error {
|
||||||
txid := tx.TxSha()
|
txid := tx.TxSha()
|
||||||
// assign height of zero for txs we create
|
// assign height of zero for txs we create
|
||||||
|
@ -99,14 +106,22 @@ func (s *SPVCon) SendCoins(adrs []btcutil.Address, sendAmts []int64) error {
|
||||||
var err error
|
var err error
|
||||||
var score, totalSend, fee int64
|
var score, totalSend, fee int64
|
||||||
dustCutoff := int64(20000) // below this amount, just give to miners
|
dustCutoff := int64(20000) // below this amount, just give to miners
|
||||||
satPerByte := int64(30) // satoshis per byte fee; have as arg later
|
satPerByte := int64(80) // satoshis per byte fee; have as arg later
|
||||||
allUtxos, err := s.TS.GetAllUtxos()
|
rawUtxos, err := s.TS.GetAllUtxos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
var allUtxos utxoByAmt
|
||||||
|
// start with utxos sorted by value.
|
||||||
|
|
||||||
for _, utxo := range allUtxos {
|
for _, utxo := range rawUtxos {
|
||||||
score += utxo.Value
|
score += utxo.Value
|
||||||
|
allUtxos = append(allUtxos, *utxo)
|
||||||
|
}
|
||||||
|
sort.Sort(sort.Reverse(allUtxos))
|
||||||
|
// sort.Reverse(allUtxos)
|
||||||
|
for _, u := range allUtxos {
|
||||||
|
fmt.Printf("%d ", u.Value)
|
||||||
}
|
}
|
||||||
for _, amt := range sendAmts {
|
for _, amt := range sendAmts {
|
||||||
totalSend += amt
|
totalSend += amt
|
||||||
|
@ -136,8 +151,13 @@ func (s *SPVCon) SendCoins(adrs []btcutil.Address, sendAmts []int64) error {
|
||||||
// add utxos until we've had enough
|
// add utxos until we've had enough
|
||||||
nokori := totalSend // nokori is how much is needed on input side
|
nokori := totalSend // nokori is how much is needed on input side
|
||||||
for _, utxo := range allUtxos {
|
for _, utxo := range allUtxos {
|
||||||
|
// skip unconfirmed. Or de-prioritize?
|
||||||
|
// if utxo.AtHeight == 0 {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
// yeah, lets add this utxo!
|
// yeah, lets add this utxo!
|
||||||
ins = append(ins, *utxo)
|
ins = append(ins, utxo)
|
||||||
// as we add utxos, fill in sigscripts
|
// as we add utxos, fill in sigscripts
|
||||||
// generate previous pkscripts (subscritpt?) for all utxos
|
// generate previous pkscripts (subscritpt?) for all utxos
|
||||||
// then make txins with the utxo and prevpk, and insert them into the tx
|
// then make txins with the utxo and prevpk, and insert them into the tx
|
||||||
|
@ -205,6 +225,11 @@ func (s *SPVCon) SendCoins(adrs []btcutil.Address, sendAmts []int64) error {
|
||||||
// tx is ready for signing,
|
// tx is ready for signing,
|
||||||
sigStash := make([][]byte, len(ins))
|
sigStash := make([][]byte, len(ins))
|
||||||
witStash := make([][][]byte, len(ins))
|
witStash := make([][][]byte, len(ins))
|
||||||
|
|
||||||
|
// generate tx-wide hashCache for segwit stuff
|
||||||
|
// middle index number doesn't matter for sighashAll.
|
||||||
|
hCache := txscript.CalcHashCache(tx, 0, txscript.SigHashAll)
|
||||||
|
|
||||||
for i, txin := range tx.TxIn {
|
for i, txin := range tx.TxIn {
|
||||||
// pick key
|
// pick key
|
||||||
child, err := s.TS.rootPrivKey.Child(
|
child, err := s.TS.rootPrivKey.Child(
|
||||||
|
@ -221,7 +246,7 @@ func (s *SPVCon) SendCoins(adrs []btcutil.Address, sendAmts []int64) error {
|
||||||
// sign into stash
|
// sign into stash
|
||||||
if ins[i].IsWit {
|
if ins[i].IsWit {
|
||||||
witStash[i], err = txscript.WitnessScript(
|
witStash[i], err = txscript.WitnessScript(
|
||||||
tx, i, ins[i].Value, txin.SignatureScript,
|
tx, hCache, i, ins[i].Value, txin.SignatureScript,
|
||||||
txscript.SigHashAll, priv, true)
|
txscript.SigHashAll, priv, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -368,16 +368,14 @@ func (ts *TxStore) Ingest(tx *wire.MsgTx, height int32) (uint32, error) {
|
||||||
spentOPs := make([][]byte, len(tx.TxIn))
|
spentOPs := make([][]byte, len(tx.TxIn))
|
||||||
// before entering into db, serialize all inputs of the ingested tx
|
// before entering into db, serialize all inputs of the ingested tx
|
||||||
for i, txin := range tx.TxIn {
|
for i, txin := range tx.TxIn {
|
||||||
nOP, err := outPointToBytes(&txin.PreviousOutPoint)
|
spentOPs[i], err = outPointToBytes(&txin.PreviousOutPoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hits, err
|
return hits, err
|
||||||
}
|
}
|
||||||
spentOPs[i] = nOP
|
|
||||||
}
|
}
|
||||||
// also generate PKscripts for all addresses (maybe keep storing these?)
|
// also generate PKscripts for all addresses (maybe keep storing these?)
|
||||||
for _, adr := range ts.Adrs {
|
for _, adr := range ts.Adrs {
|
||||||
// iterate through all our addresses
|
// iterate through all our addresses
|
||||||
|
|
||||||
// convert regular address to witness address. (split adrs later)
|
// convert regular address to witness address. (split adrs later)
|
||||||
wa, err := btcutil.NewAddressWitnessPubKeyHash(
|
wa, err := btcutil.NewAddressWitnessPubKeyHash(
|
||||||
adr.PkhAdr.ScriptAddress(), ts.Param)
|
adr.PkhAdr.ScriptAddress(), ts.Param)
|
||||||
|
@ -437,23 +435,15 @@ func (ts *TxStore) Ingest(tx *wire.MsgTx, height int32) (uint32, error) {
|
||||||
// first see if we lose utxos
|
// first see if we lose utxos
|
||||||
// iterate through duffel bag and look for matches
|
// iterate through duffel bag and look for matches
|
||||||
// this makes us lose money, which is regrettable, but we need to know.
|
// this makes us lose money, which is regrettable, but we need to know.
|
||||||
|
// var delOPs [][]byte
|
||||||
var delOPs [][]byte
|
|
||||||
// fmt.Printf("%d nOP to iterate over\n", len(spentOPs))
|
|
||||||
for _, nOP := range spentOPs {
|
for _, nOP := range spentOPs {
|
||||||
duf.ForEach(func(k, v []byte) error {
|
v := duf.Get(nOP)
|
||||||
if bytes.Equal(k, nOP) { // matched, we lost utxo
|
if v != nil {
|
||||||
fmt.Printf("will delete point %x\n", k)
|
|
||||||
hits++
|
hits++
|
||||||
// do all this just to figure out value we lost
|
// do all this just to figure out value we lost
|
||||||
x := make([]byte, len(k)+len(v))
|
x := make([]byte, len(nOP)+len(v))
|
||||||
copy(x, k)
|
copy(x, nOP)
|
||||||
y := make([]byte, len(k))
|
copy(x[len(nOP):], v)
|
||||||
// mark utxo for deletion
|
|
||||||
copy(y, k)
|
|
||||||
delOPs = append(delOPs, y)
|
|
||||||
|
|
||||||
copy(x[len(k):], v)
|
|
||||||
lostTxo, err := UtxoFromBytes(x)
|
lostTxo, err := UtxoFromBytes(x)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -468,7 +458,7 @@ func (ts *TxStore) Ingest(tx *wire.MsgTx, height int32) (uint32, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = old.Put(k, stxb) // write k:v outpoint:stxo bytes
|
err = old.Put(nOP, stxb) // write nOP:v outpoint:stxo bytes
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -480,16 +470,14 @@ func (ts *TxStore) Ingest(tx *wire.MsgTx, height int32) (uint32, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// stash for deletion
|
||||||
|
// delOPs = append(delOPs, nOP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil // matched utxo k, won't match another
|
//delete everything even if it doesn't exist!
|
||||||
}
|
for _, dOP := range spentOPs {
|
||||||
return nil // no match
|
err = duf.Delete(dOP)
|
||||||
})
|
|
||||||
// delete after done with foreach
|
|
||||||
}
|
|
||||||
for _, y := range delOPs {
|
|
||||||
fmt.Printf("deleting outpoint %x\n", y)
|
|
||||||
err = duf.Delete(y)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue