Skip to content

Commit 25f0aba

Browse files
committed
tapdb: add unit test for proof delivery confirmation
This commit introduces a unit test for the `SetTransferOutputProofDeliveryStatus` functionality to ensure proof delivery confirmation.
1 parent d8c49b0 commit 25f0aba

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

tapdb/assets_store_test.go

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"crypto/sha256"
7+
"database/sql"
78
"math/rand"
89
"sort"
910
"testing"
@@ -1897,3 +1898,241 @@ func TestFetchGroupedAssets(t *testing.T) {
18971898
equalityCheck(allAssets[2].Asset, groupedAssets[1])
18981899
equalityCheck(allAssets[3].Asset, groupedAssets[2])
18991900
}
1901+
1902+
// TestTransferOutputProofDeliveryStatus tests that we can properly set the
1903+
// proof delivery status of a transfer output.
1904+
func TestTransferOutputProofDeliveryStatus(t *testing.T) {
1905+
t.Parallel()
1906+
1907+
// First, we'll create a new assets store. We'll use this to store the
1908+
// asset and the outbound parcel in the database.
1909+
_, assetsStore, db := newAssetStore(t)
1910+
ctx := context.Background()
1911+
1912+
// Generate a single asset.
1913+
targetScriptKey := asset.NewScriptKeyBip86(keychain.KeyDescriptor{
1914+
PubKey: test.RandPubKey(t),
1915+
KeyLocator: keychain.KeyLocator{
1916+
Family: test.RandInt[keychain.KeyFamily](),
1917+
Index: uint32(test.RandInt[int32]()),
1918+
},
1919+
})
1920+
1921+
assetVersionV0 := asset.V0
1922+
1923+
const numAssets = 1
1924+
assetGen := newAssetGenerator(t, numAssets, 1)
1925+
assetGen.genAssets(t, assetsStore, []assetDesc{
1926+
{
1927+
assetGen: assetGen.assetGens[0],
1928+
anchorPoint: assetGen.anchorPoints[0],
1929+
1930+
// This is the script key of the asset we'll be
1931+
// modifying.
1932+
scriptKey: &targetScriptKey,
1933+
1934+
amt: 16,
1935+
assetVersion: &assetVersionV0,
1936+
},
1937+
})
1938+
1939+
// Formulate a spend delta outbound parcel. This parcel will be stored
1940+
// in the database. We will then manipulate the proof delivery status
1941+
// of the first transfer output.
1942+
//
1943+
// First, we'll generate a new anchor transaction for use in the parcel.
1944+
newAnchorTx := wire.NewMsgTx(2)
1945+
newAnchorTx.AddTxIn(&wire.TxIn{})
1946+
newAnchorTx.TxIn[0].SignatureScript = []byte{}
1947+
newAnchorTx.AddTxOut(&wire.TxOut{
1948+
PkScript: bytes.Repeat([]byte{0x01}, 34),
1949+
Value: 1000,
1950+
})
1951+
anchorTxHash := newAnchorTx.TxHash()
1952+
1953+
// Next, we'll generate script keys for the two transfer outputs.
1954+
newScriptKey := asset.NewScriptKeyBip86(keychain.KeyDescriptor{
1955+
PubKey: test.RandPubKey(t),
1956+
KeyLocator: keychain.KeyLocator{
1957+
Index: uint32(rand.Int31()),
1958+
Family: keychain.KeyFamily(rand.Int31()),
1959+
},
1960+
})
1961+
1962+
newScriptKey2 := asset.NewScriptKeyBip86(keychain.KeyDescriptor{
1963+
PubKey: test.RandPubKey(t),
1964+
KeyLocator: keychain.KeyLocator{
1965+
Index: uint32(rand.Int31()),
1966+
Family: keychain.KeyFamily(rand.Int31()),
1967+
},
1968+
})
1969+
1970+
// The outbound parcel will split the asset into two outputs. The first
1971+
// will have an amount of 9, and the second will have the remainder of
1972+
// the asset amount.
1973+
newAmt := 9
1974+
1975+
senderBlob := bytes.Repeat([]byte{0x01}, 100)
1976+
receiverBlob := bytes.Repeat([]byte{0x02}, 100)
1977+
1978+
newWitness := asset.Witness{
1979+
PrevID: &asset.PrevID{},
1980+
TxWitness: [][]byte{{0x01}, {0x02}},
1981+
SplitCommitment: nil,
1982+
}
1983+
1984+
// Mock proof courier address.
1985+
proofCourierAddrBytes := []byte("universerpc://localhost:10009")
1986+
1987+
// Fetch the asset that was previously generated.
1988+
allAssets, err := assetsStore.FetchAllAssets(ctx, true, false, nil)
1989+
require.NoError(t, err)
1990+
require.Len(t, allAssets, numAssets)
1991+
1992+
inputAsset := allAssets[0]
1993+
1994+
// Construct the outbound parcel that will be stored in the database.
1995+
spendDelta := &tapfreighter.OutboundParcel{
1996+
AnchorTx: newAnchorTx,
1997+
AnchorTxHeightHint: 1450,
1998+
ChainFees: int64(100),
1999+
Inputs: []tapfreighter.TransferInput{{
2000+
PrevID: asset.PrevID{
2001+
OutPoint: wire.OutPoint{
2002+
Hash: assetGen.anchorTxs[0].TxHash(),
2003+
Index: 0,
2004+
},
2005+
ID: inputAsset.ID(),
2006+
ScriptKey: asset.ToSerialized(
2007+
inputAsset.ScriptKey.PubKey,
2008+
),
2009+
},
2010+
Amount: inputAsset.Amount,
2011+
}},
2012+
Outputs: []tapfreighter.TransferOutput{{
2013+
Anchor: tapfreighter.Anchor{
2014+
Value: 1000,
2015+
OutPoint: wire.OutPoint{
2016+
Hash: anchorTxHash,
2017+
Index: 0,
2018+
},
2019+
InternalKey: keychain.KeyDescriptor{
2020+
PubKey: test.RandPubKey(t),
2021+
KeyLocator: keychain.KeyLocator{
2022+
Family: keychain.KeyFamily(
2023+
rand.Int31(),
2024+
),
2025+
Index: uint32(
2026+
test.RandInt[int32](),
2027+
),
2028+
},
2029+
},
2030+
TaprootAssetRoot: bytes.Repeat([]byte{0x1}, 32),
2031+
MerkleRoot: bytes.Repeat([]byte{0x1}, 32),
2032+
},
2033+
ScriptKey: newScriptKey,
2034+
ScriptKeyLocal: false,
2035+
Amount: uint64(newAmt),
2036+
LockTime: 1337,
2037+
RelativeLockTime: 31337,
2038+
WitnessData: []asset.Witness{newWitness},
2039+
SplitCommitmentRoot: nil,
2040+
AssetVersion: asset.V0,
2041+
ProofSuffix: receiverBlob,
2042+
ProofCourierAddr: proofCourierAddrBytes,
2043+
ProofDeliveryComplete: fn.Some[bool](false),
2044+
Position: 0,
2045+
}, {
2046+
Anchor: tapfreighter.Anchor{
2047+
Value: 1000,
2048+
OutPoint: wire.OutPoint{
2049+
Hash: anchorTxHash,
2050+
Index: 1,
2051+
},
2052+
InternalKey: keychain.KeyDescriptor{
2053+
PubKey: test.RandPubKey(t),
2054+
KeyLocator: keychain.KeyLocator{
2055+
Family: keychain.KeyFamily(
2056+
rand.Int31(),
2057+
),
2058+
Index: uint32(
2059+
test.RandInt[int32](),
2060+
),
2061+
},
2062+
},
2063+
TaprootAssetRoot: bytes.Repeat([]byte{0x1}, 32),
2064+
MerkleRoot: bytes.Repeat([]byte{0x1}, 32),
2065+
},
2066+
ScriptKey: newScriptKey2,
2067+
ScriptKeyLocal: true,
2068+
Amount: inputAsset.Amount - uint64(newAmt),
2069+
WitnessData: []asset.Witness{newWitness},
2070+
SplitCommitmentRoot: nil,
2071+
AssetVersion: asset.V1,
2072+
ProofSuffix: senderBlob,
2073+
Position: 1,
2074+
}},
2075+
}
2076+
2077+
// Store the outbound parcel in the database.
2078+
leaseOwner := fn.ToArray[[32]byte](test.RandBytes(32))
2079+
leaseExpiry := time.Now().Add(time.Hour)
2080+
require.NoError(t, assetsStore.LogPendingParcel(
2081+
ctx, spendDelta, leaseOwner, leaseExpiry,
2082+
))
2083+
2084+
// At this point, we should be able to query for the log parcel, by
2085+
// looking for all unconfirmed transfers.
2086+
assetTransfers, err := db.QueryAssetTransfers(ctx, TransferQuery{})
2087+
require.NoError(t, err)
2088+
require.Len(t, assetTransfers, 1)
2089+
2090+
// We should also be able to find the transfer outputs.
2091+
transferOutputs, err := db.FetchTransferOutputs(
2092+
ctx, assetTransfers[0].ID,
2093+
)
2094+
require.NoError(t, err)
2095+
require.Len(t, transferOutputs, 2)
2096+
2097+
// Let's confirm that the proof has not been delivered for the first
2098+
// transfer output and that the proof delivery status for the second
2099+
// transfer output is still unset.
2100+
require.Equal(
2101+
t, sqlBool(false), transferOutputs[0].ProofDeliveryComplete,
2102+
)
2103+
require.Equal(
2104+
t, sql.NullBool{}, transferOutputs[1].ProofDeliveryComplete,
2105+
)
2106+
2107+
// We will now set the status of the transfer output proof to
2108+
// "delivered".
2109+
//
2110+
// nolint: lll
2111+
err = db.SetTransferOutputProofDeliveryStatus(
2112+
ctx, OutputProofDeliveryStatus{
2113+
DeliveryComplete: sqlBool(true),
2114+
SerializedAnchorOutpoint: transferOutputs[0].AnchorOutpoint,
2115+
Position: transferOutputs[0].Position,
2116+
},
2117+
)
2118+
require.NoError(t, err)
2119+
2120+
// We will check to ensure that the transfer output proof delivery
2121+
// status has been updated correctly.
2122+
transferOutputs, err = db.FetchTransferOutputs(
2123+
ctx, assetTransfers[0].ID,
2124+
)
2125+
require.NoError(t, err)
2126+
require.Len(t, transferOutputs, 2)
2127+
2128+
// The proof delivery status of the first output should be set to
2129+
// delivered (true).
2130+
require.Equal(
2131+
t, sqlBool(true), transferOutputs[0].ProofDeliveryComplete,
2132+
)
2133+
2134+
// The proof delivery status of the second output should be unset.
2135+
require.Equal(
2136+
t, sql.NullBool{}, transferOutputs[1].ProofDeliveryComplete,
2137+
)
2138+
}

0 commit comments

Comments
 (0)