@@ -532,8 +532,8 @@ func newCommitBlobAndLeaves(pendingFunding *pendingAssetFunding,
532532// desc. This is the final step in the modified funding process, as after this,
533533// both sides are able to construct the funding output, and will be able to
534534// store the appropriate funding blobs.
535- func (p * pendingAssetFunding ) toAuxFundingDesc (
536- req * bindFundingReq ) (* lnwallet.AuxFundingDesc , error ) {
535+ func (p * pendingAssetFunding ) toAuxFundingDesc (req * bindFundingReq ,
536+ decimalDisplay uint8 ) (* lnwallet.AuxFundingDesc , error ) {
537537
538538 // First, we'll map all the assets into asset outputs that'll be stored
539539 // in the open channel struct on the lnd side.
@@ -1732,13 +1732,28 @@ func (f *FundingController) chanFunder() {
17321732 continue
17331733 }
17341734
1735- fundingDesc , err := fundingFlow .toAuxFundingDesc (req )
1735+ // We'll want to store the decimal display of the asset
1736+ // in the funding blob, so let's determine it now.
1737+ decimalDisplay , err := f .fundingAssetDecimalDisplay (
1738+ ctxc , fundingFlow .assetOutputs (),
1739+ )
1740+ if err != nil {
1741+ fErr := fmt .Errorf ("unable to determine " +
1742+ "decimal display: %w" , err )
1743+ f .cfg .ErrReporter .ReportError (
1744+ ctxc , fundingFlow .peerPub , pid , fErr ,
1745+ )
1746+ continue
1747+ }
1748+
1749+ fundingDesc , err := fundingFlow .toAuxFundingDesc (
1750+ req , decimalDisplay ,
1751+ )
17361752 if err != nil {
17371753 fErr := fmt .Errorf ("unable to create aux " +
17381754 "funding desc: %w" , err )
17391755 f .cfg .ErrReporter .ReportError (
1740- ctxc , fundingFlow .peerPub , pid ,
1741- fErr ,
1756+ ctxc , fundingFlow .peerPub , pid , fErr ,
17421757 )
17431758 continue
17441759 }
@@ -1771,6 +1786,62 @@ func (f *FundingController) chanFunder() {
17711786 }
17721787}
17731788
1789+ // fundingAssetDecimalDisplay determines the decimal display of the funding
1790+ // asset(s). If no specific decimal display value was chosen for the asset, then
1791+ // the default value of 0 is returned.
1792+ func (f * FundingController ) fundingAssetDecimalDisplay (ctx context.Context ,
1793+ assetOutputs []* cmsg.AssetOutput ) (uint8 , error ) {
1794+
1795+ // We now check the decimal display of each funding asset, to make sure
1796+ // we know the meta information for each asset. And we also verify that
1797+ // each asset tranche has the same decimal display (which should've been
1798+ // verified during the minting process already).
1799+ var decimalDisplay uint8
1800+ for idx , a := range assetOutputs {
1801+ meta , err := f .cfg .AssetSyncer .FetchAssetMetaForAsset (
1802+ ctx , a .AssetID .Val ,
1803+ )
1804+ if err != nil {
1805+ return 0 , fmt .Errorf ("unable to fetch asset meta: %w" ,
1806+ err )
1807+ }
1808+
1809+ decDisplayOpt , err := meta .DecDisplayOption ()
1810+ if err != nil {
1811+ return 0 , fmt .Errorf ("unable to get decimal display " +
1812+ "option: %w" , err )
1813+ }
1814+
1815+ var thisAssetDecDisplay uint8
1816+ decDisplayOpt .WhenSome (func (decDisplay uint32 ) {
1817+ // We limit the decimal display value to a maximum of
1818+ // 12, so it should easily fit into an uint8.
1819+ thisAssetDecDisplay = uint8 (decDisplay )
1820+ })
1821+
1822+ // If this is the first asset we're looking at, we just use the
1823+ // decimal display. Every other asset should have the same
1824+ // decimal display. The value of 0 is a valid decimal display,
1825+ // and we use that if the meta information didn't contain a
1826+ // specific decimal display value, assuming it's either a
1827+ // non-JSON meta information or the value just wasn't set.
1828+ if idx == 0 {
1829+ decimalDisplay = thisAssetDecDisplay
1830+ continue
1831+ }
1832+
1833+ // Make sure every subsequent asset has the same decimal display
1834+ // as the first asset.
1835+ if decimalDisplay != thisAssetDecDisplay {
1836+ return 0 , fmt .Errorf ("decimal display mismatch: " +
1837+ "expected %v, got %v" , decimalDisplay ,
1838+ thisAssetDecDisplay )
1839+ }
1840+ }
1841+
1842+ return decimalDisplay , nil
1843+ }
1844+
17741845// channelAcceptor is a callback that's called by the lnd client when a new
17751846// channel is proposed. This function is responsible for deciding whether to
17761847// accept the channel based on the channel parameters, and to also set some
0 commit comments