Skip to content

Commit

Permalink
Add function to compute an ideal batch size from a number of inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
KtorZ committed Oct 18, 2019
1 parent 63a18b4 commit 9f8a886
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
21 changes: 20 additions & 1 deletion lib/core/src/Cardano/Wallet/Primitive/CoinSelection/Migration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@

module Cardano.Wallet.Primitive.CoinSelection.Migration
( selectCoinsForMigration
, idealBatchSize
) where

import Prelude

import Cardano.Wallet.Primitive.CoinSelection
( CoinSelection (..), changeBalance, inputBalance )
( CoinSelection (..)
, CoinSelectionOptions (..)
, changeBalance
, inputBalance
)
import Cardano.Wallet.Primitive.Fee
( Fee (..), FeeOptions (..) )
import Cardano.Wallet.Primitive.Types
Expand Down Expand Up @@ -122,3 +127,17 @@ selectCoinsForMigration feeOpts batchSize utxo =
let (batch, rest) = splitAt (fromIntegral batchSize) xs
put rest
pure batch

-- | Try to find a fix "ideal" number of input transactions that would generate
-- rather balanced transactions.
idealBatchSize :: CoinSelectionOptions e -> Int
idealBatchSize coinselOpts = fromIntegral (fixPoint 1)
where
fixPoint :: Word8 -> Word8
fixPoint !n
| maxN n <= n = n
| n == maxBound = n
| otherwise = fixPoint (n + 1)
where
maxN :: Word8 -> Word8
maxN = maximumNumberOfInputs coinselOpts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Prelude
import Cardano.Wallet.Primitive.CoinSelection
( CoinSelection (..), changeBalance, inputBalance )
import Cardano.Wallet.Primitive.CoinSelection.Migration
( selectCoinsForMigration )
( idealBatchSize, selectCoinsForMigration )
import Cardano.Wallet.Primitive.CoinSelectionSpec
()
import Cardano.Wallet.Primitive.Fee
Expand All @@ -21,15 +21,21 @@ import Cardano.Wallet.Primitive.Types
import Test.Hspec
( Spec, describe, it, shouldSatisfy )
import Test.QuickCheck
( conjoin, counterexample, property, withMaxSuccess, (===) )
( conjoin, counterexample, label, property, withMaxSuccess, (===) )

import qualified Data.Map as Map
import qualified Data.Set as Set

spec :: Spec
spec = do

describe "Coin selection for migration PATATE" $ do
describe "idealBatchSize" $ do
it "Eventually converge for decreasing functions" $ do
property $ \coinselOpts -> do
let batchSize = idealBatchSize coinselOpts
label (show batchSize) True

describe "selectCoinsForMigration" $ do

it "No coin selection has ouputs" $
property $ withMaxSuccess 1000 $ \feeOpts batchSize utxo -> do
Expand Down
17 changes: 17 additions & 0 deletions lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelectionSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import Test.QuickCheck
, checkCoverageWith
, choose
, cover
, elements
, generate
, oneof
, scale
Expand Down Expand Up @@ -206,6 +207,22 @@ coinSelectionUnitTest run lbl expected (CoinSelectionFixture n fn utxoF outsF) =

deriving instance Arbitrary a => Arbitrary (ShowFmt a)

instance Arbitrary (CoinSelectionOptions e) where
arbitrary = do
-- NOTE Functions have to be decreasing functions
fn <- elements
[ (maxBound -)
, \x ->
if x > maxBound `div` 2
then maxBound
else maxBound - (2 * x)
, const 42
]
pure $ CoinSelectionOptions fn (const (pure ()))

instance Show (CoinSelectionOptions e) where
show _ = "CoinSelectionOptions"

instance Arbitrary a => Arbitrary (NonEmpty a) where
shrink xs = catMaybes (NE.nonEmpty <$> shrink (NE.toList xs))
arbitrary = do
Expand Down

0 comments on commit 9f8a886

Please sign in to comment.