can sync with segnet in hard mode
lots of changes but they seem to work
This commit is contained in:
parent
a955a428a7
commit
0d3639435f
@ -86,7 +86,7 @@ func newLightningChannel(wallet *LightningWallet, events chainntnfs.ChainNotifie
|
||||
return nil, err
|
||||
}
|
||||
_, multiSigIndex := findScriptOutputIndex(state.FundingTx, fundingPkScript)
|
||||
lc.fundingTxIn = wire.NewTxIn(wire.NewOutPoint(&fundingTxId, multiSigIndex), nil)
|
||||
lc.fundingTxIn = wire.NewTxIn(wire.NewOutPoint(&fundingTxId, multiSigIndex), nil, nil)
|
||||
lc.fundingP2SH = fundingPkScript
|
||||
|
||||
return lc, nil
|
||||
|
@ -529,7 +529,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
|
||||
// Empty sig script, we'll actually sign if this reservation is
|
||||
// queued up to be completed (the other side accepts).
|
||||
outPoint := wire.NewOutPoint(coin.Hash(), coin.Index())
|
||||
ourContribution.Inputs[i] = wire.NewTxIn(outPoint, nil)
|
||||
ourContribution.Inputs[i] = wire.NewTxIn(outPoint, nil, nil)
|
||||
}
|
||||
|
||||
l.coinSelectMtx.Unlock()
|
||||
@ -794,7 +794,7 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
|
||||
// since the outputs are cannonically sorted.
|
||||
fundingNTxid := fundingTx.TxSha() // NOTE: assumes testnet-L
|
||||
_, multiSigIndex := findScriptOutputIndex(fundingTx, multiSigOut.PkScript)
|
||||
fundingTxIn := wire.NewTxIn(wire.NewOutPoint(&fundingNTxid, multiSigIndex), nil)
|
||||
fundingTxIn := wire.NewTxIn(wire.NewOutPoint(&fundingNTxid, multiSigIndex), nil, nil)
|
||||
|
||||
// With the funding tx complete, create both commitment transactions.
|
||||
initialBalance := ourContribution.FundingAmount
|
||||
|
@ -4,11 +4,12 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
var MAX_SLICE_LENGTH = 65535
|
||||
@ -557,7 +558,7 @@ func readElement(r io.Reader, element interface{}) error {
|
||||
var txins []*wire.TxIn
|
||||
for i := uint8(0); i < numScripts; i++ {
|
||||
outpoint := new(wire.OutPoint)
|
||||
txin := wire.NewTxIn(outpoint, nil)
|
||||
txin := wire.NewTxIn(outpoint, nil, nil)
|
||||
err = readElement(r, &txin)
|
||||
if err != nil {
|
||||
return err
|
||||
|
2
shell.go
2
shell.go
@ -314,7 +314,7 @@ func SendCoins(s uspv.SPVCon, adr btcutil.Address, sendAmt int64) error {
|
||||
return err
|
||||
}
|
||||
// make new input from this utxo
|
||||
thisInput := wire.NewTxIn(&utxo.Op, prevPKscript)
|
||||
thisInput := wire.NewTxIn(&utxo.Op, prevPKscript, nil)
|
||||
tx.AddTxIn(thisInput)
|
||||
nokori -= utxo.Value
|
||||
if nokori < -10000 { // minimum overage / fee is 1K now
|
||||
|
133
uspv/hardmode.go
133
uspv/hardmode.go
@ -9,41 +9,128 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
||||
// BlockRootOK checks that all the txs in the block match the merkle root.
|
||||
// Only checks merkle root; it doesn't look at txs themselves.
|
||||
func BlockRootOK(blk wire.MsgBlock) bool {
|
||||
var shas []*wire.ShaHash
|
||||
for _, tx := range blk.Transactions { // make slice of txids
|
||||
nSha := tx.TxSha()
|
||||
shas = append(shas, &nSha)
|
||||
var (
|
||||
WitMagicBytes = []byte{0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed}
|
||||
)
|
||||
|
||||
// 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 BlockOK(blk wire.MsgBlock) bool {
|
||||
var txids, wtxids []*wire.ShaHash // txids and wtxids
|
||||
// witMode true if any tx has a wintess OR coinbase has wit commit
|
||||
var witMode bool
|
||||
|
||||
for _, tx := range blk.Transactions { // make slice of (w)/txids
|
||||
txid := tx.TxSha()
|
||||
wtxid := tx.WTxSha()
|
||||
if !witMode && !txid.IsEqual(&wtxid) {
|
||||
witMode = true
|
||||
}
|
||||
txids = append(txids, &txid)
|
||||
wtxids = append(wtxids, &wtxid)
|
||||
}
|
||||
neededLen := int(nextPowerOfTwo(uint32(len(shas)))) // kindof ugly
|
||||
for len(shas) < neededLen {
|
||||
shas = append(shas, nil) // pad out tx slice to get the full tree base
|
||||
|
||||
var commitBytes []byte
|
||||
// try to extract coinbase witness commitment (even if !witMode)
|
||||
cb := blk.Transactions[0] // get coinbase tx
|
||||
for i := len(cb.TxOut) - 1; i >= 0; i-- { // start at the last txout
|
||||
if bytes.HasPrefix(cb.TxOut[i].PkScript, WitMagicBytes) &&
|
||||
len(cb.TxOut[i].PkScript) > 37 {
|
||||
// 38 bytes or more, and starts with WitMagicBytes is a hit
|
||||
commitBytes = cb.TxOut[i].PkScript[6:38]
|
||||
witMode = true // it there is a wit commit it must be valid
|
||||
}
|
||||
}
|
||||
for len(shas) > 1 { // calculate merkle root. Terse, eh?
|
||||
shas = append(shas[2:], MakeMerkleParent(shas[0], shas[1]))
|
||||
} // auto recognizes coinbase-only blocks
|
||||
fmt.Printf("MRs calcd %s given %s\n",
|
||||
shas[0].String(), blk.Header.MerkleRoot.String())
|
||||
return blk.Header.MerkleRoot.IsEqual(shas[0])
|
||||
|
||||
if witMode { // witmode, so check witness tree
|
||||
// first find ways witMode can be disqualified
|
||||
if len(commitBytes) != 32 {
|
||||
// witness in block but didn't find a wintess commitment; fail
|
||||
log.Printf("block %s has witness but no witcommit",
|
||||
blk.BlockSha().String())
|
||||
return false
|
||||
}
|
||||
if len(cb.TxIn) != 1 {
|
||||
log.Printf("block %s coinbase tx has %d txins (must be 1)",
|
||||
blk.BlockSha().String(), len(cb.TxIn))
|
||||
return false
|
||||
}
|
||||
if len(cb.TxIn[0].Witness) != 1 {
|
||||
log.Printf("block %s coinbase has %d witnesses (must be 1)",
|
||||
blk.BlockSha().String(), len(cb.TxIn[0].Witness))
|
||||
return false
|
||||
}
|
||||
|
||||
if len(cb.TxIn[0].Witness[0]) != 32 {
|
||||
log.Printf("block %s coinbase has %d byte witness nonce (not 32)",
|
||||
blk.BlockSha().String(), len(cb.TxIn[0].Witness[0]))
|
||||
return false
|
||||
}
|
||||
// witness nonce is the cb's witness, subject to above constraints
|
||||
witNonce, err := wire.NewShaHash(cb.TxIn[0].Witness[0])
|
||||
if err != nil {
|
||||
log.Printf("Witness nonce error: %s", err.Error())
|
||||
return false // not sure why that'd happen but fail
|
||||
}
|
||||
|
||||
var empty [32]byte
|
||||
wtxids[0].SetBytes(empty[:]) // coinbase wtxid is 0x00...00
|
||||
|
||||
// witness root calculated from wtixds
|
||||
witRoot := calcRoot(wtxids)
|
||||
|
||||
calcWitCommit := wire.DoubleSha256SH(
|
||||
append(witRoot.Bytes(), witNonce.Bytes()...))
|
||||
|
||||
// witness root given in coinbase op_return
|
||||
givenWitCommit, err := wire.NewShaHash(commitBytes)
|
||||
if err != nil {
|
||||
log.Printf("Witness root error: %s", err.Error())
|
||||
return false // not sure why that'd happen but fail
|
||||
}
|
||||
// they should be the same. If not, fail.
|
||||
if !calcWitCommit.IsEqual(givenWitCommit) {
|
||||
log.Printf("Block %s witRoot error: calc %s given %s",
|
||||
blk.BlockSha().String(),
|
||||
calcWitCommit.String(), givenWitCommit.String())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// got through witMode check so that should be OK;
|
||||
// check regular txid merkleroot. Which is, like, trivial.
|
||||
return blk.Header.MerkleRoot.IsEqual(calcRoot(txids))
|
||||
}
|
||||
|
||||
// calcRoot calculates the merkle root of a slice of hashes.
|
||||
func calcRoot(hashes []*wire.ShaHash) *wire.ShaHash {
|
||||
for len(hashes) < int(nextPowerOfTwo(uint32(len(hashes)))) {
|
||||
hashes = append(hashes, nil) // pad out hash slice to get the full base
|
||||
}
|
||||
for len(hashes) > 1 { // calculate merkle root. Terse, eh?
|
||||
hashes = append(hashes[2:], MakeMerkleParent(hashes[0], hashes[1]))
|
||||
}
|
||||
return hashes[0]
|
||||
}
|
||||
|
||||
// IngestBlock is like IngestMerkleBlock but aralphic
|
||||
// different enough that it's better to have 2 separate functions
|
||||
func (s *SPVCon) IngestBlock(m *wire.MsgBlock) {
|
||||
var err error
|
||||
var buf bytes.Buffer
|
||||
m.SerializeWitness(&buf)
|
||||
fmt.Printf("block hex %x\n", buf.Bytes())
|
||||
for i, tx := range m.Transactions {
|
||||
// var buf bytes.Buffer
|
||||
// m.SerializeWitness(&buf)
|
||||
// fmt.Printf("block hex %x\n", buf.Bytes())
|
||||
for _, tx := range m.Transactions {
|
||||
// if i > 0 {
|
||||
fmt.Printf("wtxid: %s\n", tx.WTxSha())
|
||||
fmt.Printf(" txid: %s\n", tx.TxSha())
|
||||
fmt.Printf("%d %s", i, TxToString(tx))
|
||||
// fmt.Printf("%d %s", i, TxToString(tx))
|
||||
// }
|
||||
}
|
||||
ok := BlockRootOK(*m) // check block self-consistency
|
||||
ok := BlockOK(*m) // check block self-consistency
|
||||
if !ok {
|
||||
fmt.Printf("block %s not OK!!11\n", m.BlockSha().String())
|
||||
return
|
||||
@ -71,6 +158,7 @@ func (s *SPVCon) IngestBlock(m *wire.MsgBlock) {
|
||||
wg.Add(len(m.Transactions))
|
||||
for i, tx := range m.Transactions {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
hits, err := s.TS.Ingest(tx, hah.height)
|
||||
if err != nil {
|
||||
log.Printf("Incoming Tx error: %s\n", err.Error())
|
||||
@ -80,7 +168,6 @@ func (s *SPVCon) IngestBlock(m *wire.MsgBlock) {
|
||||
log.Printf("block %d tx %d %s ingested and matches %d utxo/adrs.",
|
||||
hah.height, i, tx.TxSha().String(), hits)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
|
@ -88,10 +88,19 @@ func (s *SPVCon) fPositiveHandler() {
|
||||
// send filter
|
||||
s.SendFilter(filt)
|
||||
fmt.Printf("sent filter %x\n", filt.MsgFilterLoad().Filter)
|
||||
|
||||
// clear the channel
|
||||
for len(s.fPositives) != 0 {
|
||||
fpAccumulator += <-s.fPositives
|
||||
finClear:
|
||||
for {
|
||||
select {
|
||||
case x := <-s.fPositives:
|
||||
fpAccumulator += x
|
||||
|
||||
default:
|
||||
break finClear
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("reset %d false positives\n", fpAccumulator)
|
||||
// reset accumulator
|
||||
fpAccumulator = 0
|
||||
|
@ -139,6 +139,10 @@ func TxToString(tx *wire.MsgTx) string {
|
||||
for i, in := range tx.TxIn {
|
||||
str += fmt.Sprintf("Input %d: %s\n", i, in.PreviousOutPoint.String())
|
||||
str += fmt.Sprintf("SigScript for input %d: %x\n", i, in.SignatureScript)
|
||||
for j, wit := range in.Witness {
|
||||
str += fmt.Sprintf("witness %d: %x\t", j, wit)
|
||||
}
|
||||
str += fmt.Sprintf("\n")
|
||||
}
|
||||
for i, out := range tx.TxOut {
|
||||
if out != nil {
|
||||
@ -148,12 +152,6 @@ func TxToString(tx *wire.MsgTx) string {
|
||||
str += fmt.Sprintf("output %d nil (WARNING)\n", i)
|
||||
}
|
||||
}
|
||||
for i, wit := range tx.TxWitness {
|
||||
if wit != nil {
|
||||
str += fmt.Sprintf("Witness %d: %x\n", i, wit.ScriptWitness)
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user