lnwallet/interface_test: add testCreateSimpleTx
This commit is contained in:
parent
306c0c8aab
commit
54f1f32e71
@ -2221,6 +2221,187 @@ func testLastUnusedAddr(miner *rpctest.Harness,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testCreateSimpleTx checks that a call to CreateSimpleTx will return a
|
||||||
|
// transaction that is equal to the one that is being created by SendOutputs in
|
||||||
|
// a subsequent call.
|
||||||
|
func testCreateSimpleTx(r *rpctest.Harness, w *lnwallet.LightningWallet,
|
||||||
|
_ *lnwallet.LightningWallet, t *testing.T) {
|
||||||
|
|
||||||
|
// Send some money from the miner to the wallet
|
||||||
|
err := loadTestCredits(r, w, 20, 4)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send money to lnwallet: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The test cases we will run through for all backends.
|
||||||
|
testCases := []struct {
|
||||||
|
outVals []int64
|
||||||
|
feeRate lnwallet.SatPerKWeight
|
||||||
|
valid bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
outVals: []int64{},
|
||||||
|
feeRate: 2500,
|
||||||
|
valid: false, // No outputs.
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
outVals: []int64{1e3},
|
||||||
|
feeRate: 2500,
|
||||||
|
valid: false, // Dust output.
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
outVals: []int64{1e8},
|
||||||
|
feeRate: 2500,
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
outVals: []int64{1e8, 2e8, 1e8, 2e7, 3e5},
|
||||||
|
feeRate: 2500,
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
outVals: []int64{1e8, 2e8, 1e8, 2e7, 3e5},
|
||||||
|
feeRate: 12500,
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
outVals: []int64{1e8, 2e8, 1e8, 2e7, 3e5},
|
||||||
|
feeRate: 50000,
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
outVals: []int64{1e8, 2e8, 1e8, 2e7, 3e5, 1e8, 2e8,
|
||||||
|
1e8, 2e7, 3e5},
|
||||||
|
feeRate: 44250,
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
feeRate := test.feeRate
|
||||||
|
|
||||||
|
// Grab some fresh addresses from the miner that we will send
|
||||||
|
// to.
|
||||||
|
outputs := make([]*wire.TxOut, len(test.outVals))
|
||||||
|
for i, outVal := range test.outVals {
|
||||||
|
minerAddr, err := r.NewAddress()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to generate address for "+
|
||||||
|
"miner: %v", err)
|
||||||
|
}
|
||||||
|
script, err := txscript.PayToAddrScript(minerAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create pay to addr "+
|
||||||
|
"script: %v", err)
|
||||||
|
}
|
||||||
|
output := &wire.TxOut{
|
||||||
|
Value: outVal,
|
||||||
|
PkScript: script,
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs[i] = output
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now try creating a tx spending to these outputs.
|
||||||
|
createTx, createErr := w.CreateSimpleTx(
|
||||||
|
outputs, feeRate, true,
|
||||||
|
)
|
||||||
|
if test.valid == (createErr != nil) {
|
||||||
|
fmt.Println(spew.Sdump(createTx.Tx))
|
||||||
|
t.Fatalf("got unexpected error when creating tx: %v",
|
||||||
|
createErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also send to these outputs. This should result in a tx
|
||||||
|
// _very_ similar to the one we just created being sent. The
|
||||||
|
// only difference is that the dry run tx is not signed, and
|
||||||
|
// that the change output position might be different.
|
||||||
|
tx, sendErr := w.SendOutputs(outputs, feeRate)
|
||||||
|
if test.valid == (sendErr != nil) {
|
||||||
|
t.Fatalf("got unexpected error when sending tx: %v",
|
||||||
|
sendErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We expected either both to not fail, or both to fail with
|
||||||
|
// the same error.
|
||||||
|
if createErr != sendErr {
|
||||||
|
t.Fatalf("error creating tx (%v) different "+
|
||||||
|
"from error sending outputs (%v)",
|
||||||
|
createErr, sendErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we expected the creation to fail, then this test is over.
|
||||||
|
if !test.valid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
txid := tx.TxHash()
|
||||||
|
err = waitForMempoolTx(r, &txid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tx not relayed to miner: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to check that the two txs are similar.
|
||||||
|
assertSimilarTx := func(a, b *wire.MsgTx) error {
|
||||||
|
if a.Version != b.Version {
|
||||||
|
return fmt.Errorf("different versions: "+
|
||||||
|
"%v vs %v", a.Version, b.Version)
|
||||||
|
}
|
||||||
|
if a.LockTime != b.LockTime {
|
||||||
|
return fmt.Errorf("different locktimes: "+
|
||||||
|
"%v vs %v", a.LockTime, b.LockTime)
|
||||||
|
}
|
||||||
|
if len(a.TxIn) != len(b.TxIn) {
|
||||||
|
return fmt.Errorf("different number of "+
|
||||||
|
"inputs: %v vs %v", len(a.TxIn),
|
||||||
|
len(b.TxIn))
|
||||||
|
}
|
||||||
|
if len(a.TxOut) != len(b.TxOut) {
|
||||||
|
return fmt.Errorf("different number of "+
|
||||||
|
"outputs: %v vs %v", len(a.TxOut),
|
||||||
|
len(b.TxOut))
|
||||||
|
}
|
||||||
|
|
||||||
|
// They should be spending the same inputs.
|
||||||
|
for i := range a.TxIn {
|
||||||
|
prevA := a.TxIn[i].PreviousOutPoint
|
||||||
|
prevB := b.TxIn[i].PreviousOutPoint
|
||||||
|
if prevA != prevB {
|
||||||
|
return fmt.Errorf("different inputs: "+
|
||||||
|
"%v vs %v", spew.Sdump(prevA),
|
||||||
|
spew.Sdump(prevB))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// They should have the same outputs. Since the change
|
||||||
|
// output position gets randomized, they are not
|
||||||
|
// guaranteed to be in the same order.
|
||||||
|
for _, outA := range a.TxOut {
|
||||||
|
found := false
|
||||||
|
for _, outB := range b.TxOut {
|
||||||
|
if reflect.DeepEqual(outA, outB) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return fmt.Errorf("did not find "+
|
||||||
|
"output %v", spew.Sdump(outA))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that our "template tx" was similar to the one that
|
||||||
|
// ended up being sent.
|
||||||
|
if err := assertSimilarTx(createTx.Tx, tx); err != nil {
|
||||||
|
t.Fatalf("transactions not similar: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type walletTestCase struct {
|
type walletTestCase struct {
|
||||||
name string
|
name string
|
||||||
test func(miner *rpctest.Harness, alice, bob *lnwallet.LightningWallet,
|
test func(miner *rpctest.Harness, alice, bob *lnwallet.LightningWallet,
|
||||||
@ -2283,6 +2464,10 @@ var walletTests = []walletTestCase{
|
|||||||
name: "reorg wallet balance",
|
name: "reorg wallet balance",
|
||||||
test: testReorgWalletBalance,
|
test: testReorgWalletBalance,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "create simple tx",
|
||||||
|
test: testCreateSimpleTx,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearWalletStates(a, b *lnwallet.LightningWallet) error {
|
func clearWalletStates(a, b *lnwallet.LightningWallet) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user