Skip to content

Commit

Permalink
[PLA-1440] Update probabilities format (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
enjinabner authored Nov 22, 2023
1 parent d6349cc commit 22ecd91
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 38 deletions.
108 changes: 88 additions & 20 deletions src/Support/ClaimProbabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Enjin\Platform\Beam\Support;

use Closure;
use Enjin\Platform\Beam\Enums\PlatformBeamCache;
use Enjin\Platform\Beam\Models\Laravel\BeamClaim;
use Enjin\Platform\Beam\Rules\Traits\IntegerRange;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
Expand All @@ -12,6 +14,8 @@ class ClaimProbabilities
{
use IntegerRange;

public const FORMAT_VERSION = 'v1';

/**
* Create or update the probabilities for a claim.
*/
Expand All @@ -31,15 +35,57 @@ public function createOrUpdateProbabilities(string $code, array $claims): void
*/
public static function hasProbabilities(string $code): bool
{
return Cache::has(PlatformBeamCache::CLAIM_PROBABILITIES->key($code));
return Cache::has(static::getCacheKey($code));
}

/**
* Get the cache key for the code.
*/
public static function getCacheKey(string $code): string
{
return PlatformBeamCache::CLAIM_PROBABILITIES->key($code, static::FORMAT_VERSION);
}

/**
* Get the probabilities for a code.
*/
public static function getProbabilities(string $code): array
{
return Cache::get(PlatformBeamCache::CLAIM_PROBABILITIES->key($code), []);
return Cache::get(
static::getCacheKey($code),
static::getProbabilitiesFromDB($code)
);
}

/**
* Get the probabilities from the database.
*/
public static function getProbabilitiesFromDB(string $code): Closure
{
return function () use ($code) {
$claims = BeamClaim::selectRaw('
token_chain_id,
quantity as tokenQuantityPerClaim,
count(*) as claimQuantity
')->hasCode($code)
->groupBy('token_chain_id', 'quantity')
->get()
->map(function ($claim) {
$claim->tokenIds = [$claim->token_chain_id];

return $claim;
})->toArray();

$instance = resolve(static::class);
$formatted = $instance->filterClaims($claims);
$instance->computeProbabilities(
$code,
$formatted['ft'],
$formatted['nft'],
);

return Cache::get(static::getCacheKey($code), []);
};
}

/**
Expand Down Expand Up @@ -68,6 +114,34 @@ public function removeTokens(string $code, array $tokenIds): void
}
}

/**
* Compute the probabilities for the items.
*/
public function computeProbabilities(string $code, array $fts, array $nfts): void
{
$total = collect($fts)->sum() + ($totalNft = collect($nfts)->sum());
if (!$total) {
return;
}

$probabilities = [
'ft' => collect($fts)->mapWithKeys(fn ($quantity, $key) => [$key => ($quantity / $total) * 100])->toArray(),
'nft' => ($totalNft / $total) * 100,
'ftTokenIds' => $this->extractTokenIds($fts, $total),
'nftTokenIds' => $this->extractTokenIds($nfts, $total),
];

$data = [
'tokens' => ['ft' => $fts, 'nft' => $nfts],
'probabilities' => $probabilities,
];

Cache::forever(
static::getCacheKey($code),
$data
);
}

/**
* Merge the tokens into the current tokens.
*/
Expand Down Expand Up @@ -116,28 +190,22 @@ protected function filterClaims(array $claims): array
}

/**
* Compute the probabilities for the items.
* Extract the token ids from the array.
*/
protected function computeProbabilities(string $code, array $fts, array $nfts): void
protected function extractTokenIds(array $tokenIds, int $total): array
{
$totalNft = collect($nfts)->sum();
$total = collect($fts)->sum() + $totalNft;
$probabilities = [];
if ($total > 0) {
foreach ($fts as $key => $quantity) {
$probabilities['ft'][$key] = ($quantity / $total) * 100;
$tokens = [];
foreach ($tokenIds as $key => $quantity) {
if (($range = $this->integerRange($key)) !== false) {
$count = $quantity / (($range[1] - $range[0]) + 1);
for ($i = $range[0]; $i <= $range[1]; $i++) {
$tokens[$i] = ($count / $total) * 100;
}
} else {
$tokens[$key] = ($quantity / $total) * 100;
}
$probabilities['nft'] = ($totalNft / $total) * 100;
}

$data = [
'tokens' => ['ft' => $fts, 'nft' => $nfts],
'probabilities' => $probabilities,
];

Cache::forever(
PlatformBeamCache::CLAIM_PROBABILITIES->key($code),
$data
);
return $tokens;
}
}
75 changes: 57 additions & 18 deletions tests/Unit/ClaimProbabilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,24 @@ public function test_it_can_create_probabilities()
$this->assertEquals(
[
'ft' => [
'41' => 10,
'42' => 20,
'43..45' => 30,
'7' => 10.0,
'8..10' => 60.0,
],
'nft' => 30.0,
'ftTokenIds' => [
'7' => 10.0,
'8' => 20.0,
'9' => 20.0,
'10' => 20.0,
],
'nftTokenIds' => [
'1' => 5.0,
'2' => 5.0,
'3' => 5.0,
'4' => 5.0,
'5' => 5.0,
'6' => 5.0,
],
'nft' => 40,
],
ClaimProbabilities::getProbabilities($this->beam->code)['probabilities']
);
Expand All @@ -46,20 +59,46 @@ public function test_it_can_remove_tokens()
$this->assertEquals(
[
'ft' => [
'41' => 10,
'42' => 20,
'43..45' => 30,
'7' => 10.0,
'8..10' => 60.0,
],
'nft' => 30.0,
'ftTokenIds' => [
'7' => 10.0,
'8' => 20.0,
'9' => 20.0,
'10' => 20.0,
],
'nftTokenIds' => [
'1' => 5.0,
'2' => 5.0,
'3' => 5.0,
'4' => 5.0,
'5' => 5.0,
'6' => 5.0,
],
'nft' => 40,
],
ClaimProbabilities::getProbabilities($this->beam->code)['probabilities']
);

$this->probabilities->removeTokens($this->beam->code, ['42', '43..45']);
$this->probabilities->removeTokens($this->beam->code, ['8..10']);
$this->assertEquals(
[
'ft' => ['41' => 20],
'nft' => 80,
'ft' => [
'7' => 25.0,
],
'nft' => 75.0,
'ftTokenIds' => [
'7' => 25.0,
],
'nftTokenIds' => [
'1' => 12.5,
'2' => 12.5,
'3' => 12.5,
'4' => 12.5,
'5' => 12.5,
'6' => 12.5,
],
],
ClaimProbabilities::getProbabilities($this->beam->code)['probabilities']
);
Expand All @@ -70,26 +109,26 @@ protected function generateTokens(): array
return [
[
'type' => BeamType::MINT_ON_DEMAND->name,
'tokenIds' => ['1..40'],
'tokenIds' => ['1..5'],
'claimQuantity' => 1,
'tokenQuantityPerClaim' => 1,
],
[
'type' => BeamType::MINT_ON_DEMAND->name,
'tokenIds' => ['41'],
'claimQuantity' => 10,
'tokenIds' => ['6'],
'claimQuantity' => 1,
'tokenQuantityPerClaim' => 1,
],
[
'type' => BeamType::MINT_ON_DEMAND->name,
'tokenIds' => ['42'],
'claimQuantity' => 20,
'tokenIds' => ['7'],
'claimQuantity' => 2,
'tokenQuantityPerClaim' => 1,
],
[
'type' => BeamType::MINT_ON_DEMAND->name,
'tokenIds' => ['43..45'],
'claimQuantity' => 10,
'tokenIds' => ['8..10'],
'claimQuantity' => 4,
'tokenQuantityPerClaim' => 1,
],
];
Expand Down

0 comments on commit 22ecd91

Please sign in to comment.