mirror of
https://github.com/lightninglabs/pool.git
synced 2026-08-13 12:33:04 +02:00
poolscript: add RecoveryHelper
RecoveryHelper is a type that helps speed up account recovery by caching the tweaked trader and auctioneer keys for faster script lookups.
This commit is contained in:
parent
7f849b3248
commit
7ecc726b4e
1 changed files with 142 additions and 2 deletions
|
|
@ -91,12 +91,22 @@ func AccountWitnessScript(expiry uint32, traderKey, auctioneerKey,
|
|||
tweakedTraderKey := input.TweakPubKeyWithTweak(traderKey, traderKeyTweak)
|
||||
tweakedAuctioneerKey := input.TweakPubKey(auctioneerKey, tweakedTraderKey)
|
||||
|
||||
return accountWitnessScript(
|
||||
expiry, tweakedTraderKey.SerializeCompressed(),
|
||||
tweakedAuctioneerKey.SerializeCompressed(),
|
||||
)
|
||||
}
|
||||
|
||||
// accountWitnessScript returns the witness script of an account from the
|
||||
// tweaked and serialized trader and auctioneer key.
|
||||
func accountWitnessScript(expiry uint32, tweakedTraderKey,
|
||||
tweakedAuctioneerKey []byte) ([]byte, error) {
|
||||
builder := txscript.NewScriptBuilder()
|
||||
|
||||
builder.AddData(tweakedTraderKey.SerializeCompressed())
|
||||
builder.AddData(tweakedTraderKey)
|
||||
builder.AddOp(txscript.OP_CHECKSIGVERIFY)
|
||||
|
||||
builder.AddData(tweakedAuctioneerKey.SerializeCompressed())
|
||||
builder.AddData(tweakedAuctioneerKey)
|
||||
builder.AddOp(txscript.OP_CHECKSIG)
|
||||
|
||||
builder.AddOp(txscript.OP_IFDUP)
|
||||
|
|
@ -108,6 +118,104 @@ func AccountWitnessScript(expiry uint32, traderKey, auctioneerKey,
|
|||
return builder.Script()
|
||||
}
|
||||
|
||||
// RecoveryHelper is a type that helps speed up account recovery by caching the
|
||||
// tweaked trader and auctioneer keys for faster script lookups.
|
||||
type RecoveryHelper struct {
|
||||
// TraderKey is the trader's public key.
|
||||
TraderKey *btcec.PublicKey
|
||||
|
||||
// AuctioneerKey is the auctioneer's public key.
|
||||
AuctioneerKey *btcec.PublicKey
|
||||
|
||||
// BatchKey is the current batch key.
|
||||
BatchKey *btcec.PublicKey
|
||||
|
||||
// Secret is the shared secret between trader and auctioneer.
|
||||
Secret [32]byte
|
||||
|
||||
tweakedTraderKey []byte
|
||||
tweakedAuctioneerKey []byte
|
||||
}
|
||||
|
||||
// NextBatchKey increments the currently used batch key and re-calculates the
|
||||
// tweaked keys.
|
||||
func (r *RecoveryHelper) NextBatchKey() {
|
||||
r.BatchKey = IncrementKey(r.BatchKey)
|
||||
|
||||
r.tweakKeys()
|
||||
}
|
||||
|
||||
// NextAccount sets a fresh trader key and secret, then re-calculates the
|
||||
// tweaked keys.
|
||||
func (r *RecoveryHelper) NextAccount(traderKey *btcec.PublicKey,
|
||||
secret [32]byte) {
|
||||
|
||||
r.TraderKey = traderKey
|
||||
r.Secret = secret
|
||||
|
||||
r.tweakKeys()
|
||||
}
|
||||
|
||||
// tweakKeys caches the tweaked keys from the current values.
|
||||
func (r *RecoveryHelper) tweakKeys() {
|
||||
traderKeyTweak := TraderKeyTweak(r.BatchKey, r.Secret, r.TraderKey)
|
||||
tweakedTraderKey := input.TweakPubKeyWithTweak(
|
||||
r.TraderKey, traderKeyTweak,
|
||||
)
|
||||
tweakedAuctioneerKey := input.TweakPubKey(
|
||||
r.AuctioneerKey, tweakedTraderKey,
|
||||
)
|
||||
|
||||
r.tweakedTraderKey = tweakedTraderKey.SerializeCompressed()
|
||||
r.tweakedAuctioneerKey = tweakedAuctioneerKey.SerializeCompressed()
|
||||
}
|
||||
|
||||
// LocateOutput looks for an account output in the given transaction that
|
||||
// corresponds to a script derived with the current settings of the helper and
|
||||
// the given account expiry.
|
||||
func (r *RecoveryHelper) LocateOutput(expiry uint32, tx *wire.MsgTx) (uint32,
|
||||
bool, error) {
|
||||
|
||||
witnessScript, err := accountWitnessScript(
|
||||
expiry, r.tweakedTraderKey, r.tweakedAuctioneerKey,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
|
||||
scriptHash, err := input.WitnessScriptHash(witnessScript)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
|
||||
idx, ok := LocateOutputScript(tx, scriptHash)
|
||||
return idx, ok, nil
|
||||
}
|
||||
|
||||
// LocateAnyOutput looks for an account output in and of the given transactions
|
||||
// that corresponds to a script derived with the current settings of the helper
|
||||
// and the given account expiry.
|
||||
func (r *RecoveryHelper) LocateAnyOutput(expiry uint32,
|
||||
txns []*wire.MsgTx) (*wire.MsgTx, uint32, bool, error) {
|
||||
|
||||
for _, tx := range txns {
|
||||
// We shouldn't return a pointer to a loop iterator value, so
|
||||
// make a copy first.
|
||||
tx := tx
|
||||
|
||||
idx, ok, err := r.LocateOutput(expiry, tx)
|
||||
if err != nil {
|
||||
return nil, 0, false, err
|
||||
}
|
||||
|
||||
if ok {
|
||||
return tx, idx, true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, 0, false, nil
|
||||
}
|
||||
|
||||
// AccountScript returns the output script of an account on-chain.
|
||||
//
|
||||
// <trader_key> OP_CHECKSIGVERIFY
|
||||
|
|
@ -211,3 +319,35 @@ func LocateOutputScript(tx *wire.MsgTx, script []byte) (uint32, bool) {
|
|||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// MatchPreviousOutPoint determines whether or not a PreviousOutPoint appears
|
||||
// in anye of the provided transactions.
|
||||
func MatchPreviousOutPoint(op wire.OutPoint, txs []*wire.MsgTx) (*wire.MsgTx,
|
||||
bool) {
|
||||
|
||||
for _, tx := range txs {
|
||||
tx := tx
|
||||
if IncludesPreviousOutPoint(tx, op) {
|
||||
return tx, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// IncludesPreviousOutPoint determines whether a transaction includes a
|
||||
// given OutPoint as a txIn PreviousOutpoint.
|
||||
func IncludesPreviousOutPoint(tx *wire.MsgTx, output wire.OutPoint) bool {
|
||||
for _, txIn := range tx.TxIn {
|
||||
if txIn.PreviousOutPoint.Index != output.Index {
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(txIn.PreviousOutPoint.Hash[:], output.Hash[:]) {
|
||||
continue
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue