Skip to content

Commit

Permalink
checkpoint. cleaned up BTCCloneCFG
Browse files Browse the repository at this point in the history
  • Loading branch information
buck54321 committed Oct 3, 2023
1 parent 1db4ed9 commit 86c4c3d
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 502 deletions.
139 changes: 38 additions & 101 deletions client/asset/btc/btc.go

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions client/asset/btc/electrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,12 @@ func ElectrumWallet(cfg *BTCCloneCFG) (*ExchangeWalletElectrum, error) {
ewc := electrum.NewWalletClient(rpcCfg.RPCUser, rpcCfg.RPCPass,
"http://"+rpcCfg.RPCBind, rpcCfg.WalletName)
ew := newElectrumWallet(ewc, &electrumWalletConfig{
params: cfg.ChainParams,
log: cfg.Logger.SubLogger("ELECTRUM"),
addrDecoder: cfg.AddressDecoder,
addrStringer: cfg.AddressStringer,
txDeserializer: cfg.TxDeserializer,
txSerializer: cfg.TxSerializer,
segwit: cfg.Segwit,
rpcCfg: rpcCfg,
params: cfg.ChainParams,
log: cfg.Logger.SubLogger("ELECTRUM"),
addrDecoder: cfg.AddressDecoder,
addrStringer: cfg.AddressStringer,
segwit: cfg.Segwit,
rpcCfg: rpcCfg,
})
btc.setNode(ew)

Expand Down
67 changes: 26 additions & 41 deletions client/asset/btc/electrum_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,14 @@ type electrumNetworkClient interface {
}

type electrumWallet struct {
log dex.Logger
chainParams *chaincfg.Params
decodeAddr dexbtc.AddressDecoder
stringAddr dexbtc.AddressStringer
deserializeTx func([]byte) (*wire.MsgTx, error)
serializeTx func(*wire.MsgTx) ([]byte, error)
rpcCfg *RPCConfig // supports live reconfigure check
wallet electrumWalletClient
chainV atomic.Value // electrumNetworkClient
segwit bool
log dex.Logger
chainParams *chaincfg.Params
decodeAddr dexbtc.AddressDecoder
stringAddr dexbtc.AddressStringer
rpcCfg *RPCConfig // supports live reconfigure check
wallet electrumWalletClient
chainV atomic.Value // electrumNetworkClient
segwit bool

// ctx is set on connect, and used in asset.Wallet and btc.Wallet interface
// method implementations that have no ctx arg yet (refactoring TODO).
Expand All @@ -101,14 +99,12 @@ func (ew *electrumWallet) resetChain(cl electrumNetworkClient) {
}

type electrumWalletConfig struct {
params *chaincfg.Params
log dex.Logger
addrDecoder dexbtc.AddressDecoder
addrStringer dexbtc.AddressStringer
txDeserializer func([]byte) (*wire.MsgTx, error)
txSerializer func(*wire.MsgTx) ([]byte, error)
segwit bool // indicates if segwit addresses are expected from requests
rpcCfg *RPCConfig
params *chaincfg.Params
log dex.Logger
addrDecoder dexbtc.AddressDecoder
addrStringer dexbtc.AddressStringer
segwit bool // indicates if segwit addresses are expected from requests
rpcCfg *RPCConfig
}

func newElectrumWallet(ew electrumWalletClient, cfg *electrumWalletConfig) *electrumWallet {
Expand All @@ -124,24 +120,13 @@ func newElectrumWallet(ew electrumWalletClient, cfg *electrumWalletConfig) *elec
}
}

txDeserializer := cfg.txDeserializer
if txDeserializer == nil {
txDeserializer = msgTxFromBytes
}
txSerializer := cfg.txSerializer
if txSerializer == nil {
txSerializer = serializeMsgTx
}

return &electrumWallet{
log: cfg.log,
chainParams: cfg.params,
decodeAddr: addrDecoder,
stringAddr: addrStringer,
deserializeTx: txDeserializer,
serializeTx: txSerializer,
wallet: ew,
segwit: cfg.segwit,
log: cfg.log,
chainParams: cfg.params,
decodeAddr: addrDecoder,
stringAddr: addrStringer,
wallet: ew,
segwit: cfg.segwit,
// TODO: remove this when all interface methods are given a Context. In
// the meantime, init with a valid sentry context until connect().
ctx: context.TODO(),
Expand Down Expand Up @@ -376,7 +361,7 @@ func (ew *electrumWallet) reconfigure(cfg *asset.WalletConfig, currentAddress st

// part of btc.Wallet interface
func (ew *electrumWallet) sendRawTransaction(tx *wire.MsgTx) (*chainhash.Hash, error) {
b, err := ew.serializeTx(tx)
b, err := serializeMsgTx(tx)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -464,7 +449,7 @@ func (ew *electrumWallet) getTxOutput(ctx context.Context, txHash *chainhash.Has
}
}

msgTx, err := ew.deserializeTx(txRaw)
msgTx, err := msgTxFromBytes(txRaw)
if err != nil {
return nil, 0, err
}
Expand Down Expand Up @@ -819,7 +804,7 @@ func (ew *electrumWallet) signTx(inTx *wire.MsgTx) (*wire.MsgTx, error) {
if err != nil {
return nil, err
}
return ew.deserializeTx(signedB)
return msgTxFromBytes(signedB)
}

type hash160er interface {
Expand Down Expand Up @@ -1053,7 +1038,7 @@ func (ew *electrumWallet) swapConfirmations(txHash *chainhash.Hash, vout uint32,
// Try the wallet first in case this is a wallet transaction (own swap).
txRaw, confs, err := ew.checkWalletTx(txid)
if err == nil {
msgTx, err := ew.deserializeTx(txRaw)
msgTx, err := msgTxFromBytes(txRaw)
if err != nil {
return 0, false, err
}
Expand Down Expand Up @@ -1104,7 +1089,7 @@ func (ew *electrumWallet) outPointAddress(ctx context.Context, txid string, vout
if err != nil {
return "", err
}
msgTx, err := ew.deserializeTx(txRaw)
msgTx, err := msgTxFromBytes(txRaw)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -1158,7 +1143,7 @@ func (ew *electrumWallet) findOutputSpender(ctx context.Context, txHash *chainha
io.TxHash, addr, err)
continue
}
msgTx, err := ew.deserializeTx(txRaw)
msgTx, err := msgTxFromBytes(txRaw)
if err != nil {
ew.log.Warnf("Unable to decode transaction %v for address %v: %v",
io.TxHash, addr, err)
Expand Down
4 changes: 2 additions & 2 deletions client/asset/btc/electrum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func TestElectrumExchangeWallet(t *testing.T) {
// contractHash, _ := hex.DecodeString("2b00eaeab6fc2f23bd96fc20fdc2b73a9e7510e03e8c7c66712c6a3f086c5e99")
contractHash := sha256.Sum256(contract)
wantSecret, _ := hex.DecodeString("aa8e04bb335da65d362b89ec0630dc76fd02ffaca783ae58cb712a2820f504ce")
foundTxHash, foundVin, secret, err := eew.findRedemption(ctx, newOutPoint(swapTxHash, swapVout), contractHash[:])
foundTxHash, foundVin, secret, err := eew.findRedemption(ctx, NewOutPoint(swapTxHash, swapVout), contractHash[:])
if err != nil {
t.Fatal(err)
}
Expand All @@ -121,7 +121,7 @@ func TestElectrumExchangeWallet(t *testing.T) {
}

// FindRedemption
redeemCoin, secretBytes, err := eew.FindRedemption(ctx, toCoinID(swapTxHash, swapVout), contract)
redeemCoin, secretBytes, err := eew.FindRedemption(ctx, ToCoinID(swapTxHash, swapVout), contract)
if err != nil {
t.Fatal(err)
}
Expand Down
94 changes: 21 additions & 73 deletions client/asset/btc/rpcclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,8 @@ type rpcCore struct {
legacySignTx bool
booleanGetBlock bool
unlockSpends bool
deserializeTx func([]byte) (*wire.MsgTx, error)
serializeTx func(*wire.MsgTx) ([]byte, error)
deserializeBlock func([]byte) (*wire.MsgBlock, error)
hashTx func(*wire.MsgTx) *chainhash.Hash
numericGetRawTxRPC bool
legacyValidateAddressRPC bool
omitRPCOptionsArg bool
addrFunc func() (btcutil.Address, error)
connectFunc func() error
privKeyFunc func(addr string) (*btcec.PrivateKey, error)
}

Expand Down Expand Up @@ -190,11 +183,6 @@ func (wc *rpcClient) connect(ctx context.Context, _ *sync.WaitGroup) error {
}
wc.log.Debug("Using a descriptor wallet.")
}
if wc.connectFunc != nil {
if err := wc.connectFunc(); err != nil {
return err
}
}
return nil
}

Expand Down Expand Up @@ -226,10 +214,6 @@ func (wc *rpcClient) reconfigure(cfg *asset.WalletConfig, currentAddress string)
// If the RPC configuration has changed, try to update the client.
oldCfg := wc.rpcConfig
if *newCfg != *oldCfg {
if wc.connectFunc != nil {
return true, nil // this asset needs a new rpcClient, then connect
}

cl, err := newRPCConnection(parsedCfg, wc.cloneParams.SingularWallet)
if err != nil {
return false, fmt.Errorf("error creating RPC client with new credentials: %v", err)
Expand Down Expand Up @@ -286,7 +270,7 @@ func estimateSmartFee(ctx context.Context, rr RawRequester, confTarget uint64, m
// SendRawTransactionLegacy broadcasts the transaction with an additional legacy
// boolean `allowhighfees` argument set to false.
func (wc *rpcClient) SendRawTransactionLegacy(tx *wire.MsgTx) (*chainhash.Hash, error) {
txBytes, err := wc.serializeTx(tx)
txBytes, err := serializeMsgTx(tx)
if err != nil {
return nil, err
}
Expand All @@ -296,7 +280,7 @@ func (wc *rpcClient) SendRawTransactionLegacy(tx *wire.MsgTx) (*chainhash.Hash,

// SendRawTransaction broadcasts the transaction.
func (wc *rpcClient) SendRawTransaction(tx *wire.MsgTx) (*chainhash.Hash, error) {
b, err := wc.serializeTx(tx)
b, err := serializeMsgTx(tx)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -466,16 +450,12 @@ func (wc *rpcClient) GetRawMempool() ([]*chainhash.Hash, error) {
// GetRawTransaction retrieves the MsgTx.
func (wc *rpcClient) GetRawTransaction(txHash *chainhash.Hash) (*wire.MsgTx, error) {
var txB dex.Bytes
args := anylist{txHash.String(), false}
if wc.numericGetRawTxRPC {
args[1] = 0
}
err := wc.call(methodGetRawTransaction, args, &txB)
err := wc.call(methodGetRawTransaction, anylist{txHash.String(), false}, &txB)
if err != nil {
return nil, err
}

return wc.deserializeTx(txB)
return msgTxFromBytes(txB)
}

// balances retrieves a wallet's balance details.
Expand Down Expand Up @@ -560,8 +540,6 @@ func (wc *rpcClient) changeAddress() (btcutil.Address, error) {
var addrStr string
var err error
switch {
case wc.addrFunc != nil:
return wc.addrFunc()
case wc.omitAddressType:
err = wc.call(methodChangeAddress, nil, &addrStr)
case wc.segwit:
Expand All @@ -576,9 +554,6 @@ func (wc *rpcClient) changeAddress() (btcutil.Address, error) {
}

func (wc *rpcClient) externalAddress() (btcutil.Address, error) {
if wc.addrFunc != nil {
return wc.addrFunc()
}
if wc.segwit {
return wc.address("bech32")
}
Expand All @@ -602,7 +577,7 @@ func (wc *rpcClient) address(aType string) (btcutil.Address, error) {

// signTx attempts to have the wallet sign the transaction inputs.
func (wc *rpcClient) signTx(inTx *wire.MsgTx) (*wire.MsgTx, error) {
txBytes, err := wc.serializeTx(inTx)
txBytes, err := serializeMsgTx(inTx)
if err != nil {
return nil, fmt.Errorf("tx serialization error: %w", err)
}
Expand All @@ -625,7 +600,7 @@ func (wc *rpcClient) signTx(inTx *wire.MsgTx) (*wire.MsgTx, error) {
}
return nil, fmt.Errorf("signing incomplete. %d signing errors encountered: %s", len(res.Errors), errMsg)
}
outTx, err := wc.deserializeTx(res.Hex)
outTx, err := msgTxFromBytes(res.Hex)
if err != nil {
return nil, fmt.Errorf("error deserializing transaction response: %w", err)
}
Expand Down Expand Up @@ -850,59 +825,32 @@ func (wc *rpcClient) locked() bool {
// sendTxFeeEstimator returns the fee required to send tx using the provided
// feeRate.
func (wc *rpcClient) estimateSendTxFee(tx *wire.MsgTx, feeRate uint64, subtract bool) (txfee uint64, err error) {
txBytes, err := wc.serializeTx(tx)
txBytes, err := serializeMsgTx(tx)
if err != nil {
return 0, fmt.Errorf("tx serialization error: %w", err)
}
args := anylist{hex.EncodeToString(txBytes)}

// 1e-5 = 1e-8 for satoshis * 1000 for kB.
feeRateOption := float64(feeRate) / 1e5
if wc.omitRPCOptionsArg {
var success bool
err := wc.call(methodSetTxFee, anylist{feeRateOption}, &success)
if err != nil {
return 0, fmt.Errorf("error setting transaction fee: %w", err)
}
if !success {
return 0, fmt.Errorf("failed to set transaction fee")
}
} else {
options := &btcjson.FundRawTransactionOpts{
FeeRate: &feeRateOption,
}
if !wc.omitAddressType {
if wc.segwit {
options.ChangeType = &btcjson.ChangeTypeBech32
} else {
options.ChangeType = &btcjson.ChangeTypeLegacy
}
}
if subtract {
options.SubtractFeeFromOutputs = []int{0}
options := &btcjson.FundRawTransactionOpts{
FeeRate: &feeRateOption,
}
if !wc.omitAddressType {
if wc.segwit {
options.ChangeType = &btcjson.ChangeTypeBech32
} else {
options.ChangeType = &btcjson.ChangeTypeLegacy
}
args = append(args, options)
}
if subtract {
options.SubtractFeeFromOutputs = []int{0}
}
args = append(args, options)

res := &btcjson.FundRawTransactionResult{}
err = wc.call(methodFundRawTransaction, args, &res)
if err != nil {
// This is a work around for ZEC wallet, which does not support options
// argument for fundrawtransaction.
if wc.omitRPCOptionsArg {
var sendAmount uint64
for _, txOut := range tx.TxOut {
sendAmount += uint64(txOut.Value)
}
var bal uint64
// args: "(dummy)" minconf includeWatchonly inZat
if err := wc.call(methodGetBalance, anylist{"", 0, false, true}, &bal); err != nil {
return 0, err
}
if subtract && sendAmount <= bal {
return 0, errors.New("wallet does not support options")
}
}
return 0, fmt.Errorf("error calculating transaction fee: %w", err)
}
return toSatoshi(res.Fee.ToBTC()), nil
Expand Down Expand Up @@ -1050,7 +998,7 @@ func (wc *rpcClient) getVersion() (uint64, uint64, error) {
// findRedemptionsInMempool attempts to find spending info for the specified
// contracts by searching every input of all txs in the mempool.
func (wc *rpcClient) findRedemptionsInMempool(ctx context.Context, reqs map[OutPoint]*FindRedemptionReq) (discovered map[OutPoint]*FindRedemptionResult) {
return FindRedemptionsInMempool(ctx, wc.log, reqs, wc.GetRawMempool, wc.GetRawTransaction, wc.segwit, wc.hashTx, wc.chainParams)
return FindRedemptionsInMempool(ctx, wc.log, reqs, wc.GetRawMempool, wc.GetRawTransaction, wc.segwit, hashTx, wc.chainParams)
}

func FindRedemptionsInMempool(
Expand Down Expand Up @@ -1114,7 +1062,7 @@ func (wc *rpcClient) searchBlockForRedemptions(ctx context.Context, reqs map[Out
wc.log.Errorf("RPC GetBlock error: %v", err)
return
}
return SearchBlockForRedemptions(ctx, reqs, msgBlock, wc.segwit, wc.hashTx, wc.chainParams)
return SearchBlockForRedemptions(ctx, reqs, msgBlock, wc.segwit, hashTx, wc.chainParams)
}

func SearchBlockForRedemptions(
Expand Down
Loading

0 comments on commit 86c4c3d

Please sign in to comment.