Skip to content

Commit

Permalink
[PLA-1878] Mutation support for v1010 (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardocustodio authored Jul 5, 2024
1 parent 96c5f07 commit 39e08ee
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 91 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
name: Run Tests
name: Unit & Functional Tests

on:
pull_request:
paths-ignore:
- "**.md"
push:
paths-ignore:
- "**.md"
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/sast.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Static Application Security Testing

on:
pull_request:
push:
paths-ignore:
- "**.md"

jobs:
test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8
env:
MYSQL_DATABASE: platform
MYSQL_ROOT_PASSWORD: password
ports:
- 33306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
redis:
image: redis:7
ports:
- 6379:6379
options: --entrypoint redis-server
strategy:
fail-fast: true
matrix:
php: [8.2]

name: PHP ${{ matrix.php }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, gmp, intl, json, mysql, readline, sodium, bcmath, pcov
tools: composer:v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Setup problem matchers
run: |
echo "::add-matcher::${{ runner.tool_cache }}/php.json"
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- name: Install dependencies
run: |
composer install --no-interaction --no-progress
composer dump-autoload
- name: Run Rector
run: |
./vendor/bin/rector process --dry-run
2 changes: 0 additions & 2 deletions .github/workflows/security_checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: Dependencies Security Checker

on:
pull_request:
paths-ignore:
- '**.md'
push:
paths-ignore:
- '**.md'
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
}
],
"require": {
"php": "^8.2",
"php": "^8.2|^8.3",
"ext-bcmath": "*",
"ext-json": "*",
"ext-openssl": "*",
Expand All @@ -41,6 +41,7 @@
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/php-code-coverage": "^10.0",
"phpunit/phpunit": "^10.0",
"rector/rector": "^1.0",
"roave/security-advisories": "dev-latest"
},
"autoload": {
Expand All @@ -60,7 +61,8 @@
"scripts": {
"build-sr25519": "cd vendor/gmajor/sr25519-bindings/go && go build -buildmode=c-shared -o sr25519.so . && mv sr25519.so ../src/Crypto/sr25519.so",
"analyse": "vendor/bin/phpstan analyse",
"fix": "vendor/bin/pint",
"dry-fix": "vendor/bin/rector process --dry-run && vendor/bin/pint --test --config ./pint.json",
"fix": "vendor/bin/rector process && vendor/bin/pint --config ./pint.json",
"test": "vendor/bin/phpunit",
"test-coverage": "vendor/bin/phpunit --coverage-html ../../temp/coverage",
"post-autoload-dump": [
Expand Down
17 changes: 17 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;

return RectorConfig::configure()
->withPaths([
__DIR__ . '/config',
__DIR__ . '/lang',
__DIR__ . '/src',
__DIR__ . '/tests',
])
->withPhpSets(php82: true)
->withPreparedSets(deadCode: true)
->withRules([Spatie\Ray\Rector\RemoveRayCallRector::class])
->withTypeCoverageLevel(0);
25 changes: 21 additions & 4 deletions src/GraphQL/Mutations/CreateListingMutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ public function args(): array
'type' => GraphQL::type('String'),
'description' => __('enjin-platform-marketplace::type.marketplace_listing.field.salt'),
],
// TODO: We should remove `auctionData` and replace it with `listingData`
// listingData = FixedPrice, Auction, Offer
// FixedPrice => null,
// Auction => { startBlock, endBlock },
// Offer => { expiration }
'auctionData' => [
'type' => GraphQL::type('AuctionDataInputType'),
'description' => __('enjin-platform-marketplace::input_type.auction_data.description'),
Expand All @@ -106,7 +111,8 @@ public function resolve(
ResolveInfo $resolveInfo,
Closure $getSelectFields,
) {
$encodedData = TransactionSerializer::encode($this->getMutationName(), static::getEncodableParams(
$method = isRunningLatest() ? $this->getMutationName() . 'V1010' : $this->getMutationName();
$encodedData = TransactionSerializer::encode($method, static::getEncodableParams(
makeAssetId: new MultiTokensTokenAssetIdParams(
Arr::get($args, 'makeAssetId.collectionId'),
$this->encodeTokenId(Arr::get($args, 'makeAssetId'))
Expand Down Expand Up @@ -136,15 +142,26 @@ public static function getEncodableParams(...$params): array
$amount = Arr::get($params, 'amount', 0);
$price = Arr::get($params, 'price', 0);
$salt = Arr::get($params, 'salt', Str::random(10));
$auctionData = Arr::get($params, 'auctionData', null);
$auctionData = Arr::get($params, 'auctionData');

$extra = isRunningLatest() ? [
'listingData' => $auctionData ? [
'Auction' => $auctionData->toEncodable(),
] : [
'FixedPrice' => null,
],
] : [
'auctionData' => $auctionData?->toEncodable(),
];

return [
'makeAssetId' => $makeAsset->toEncodable(),
'takeAssetId' => $takeAsset->toEncodable(),
'amount' => gmp_init($amount),
'price' => gmp_init($price),
'salt' => HexConverter::stringToHexPrefixed($salt),
'auctionData' => $auctionData?->toEncodable(),
...$extra,
'depositor' => null,
];
}

Expand All @@ -158,7 +175,7 @@ protected function makeOrTakeRuleExist(?string $collectionId = null, ?bool $isMa
'required_with:' . $makeOrTake . '.tokenId',
new MinBigInt(),
new MaxBigInt(Hex::MAX_UINT128),
function (string $attribute, mixed $value, Closure $fail) {
function (string $attribute, mixed $value, Closure $fail): void {
if (!Collection::where('collection_chain_id', $value)->exists()) {
$fail('validation.exists')->translate();
}
Expand Down
60 changes: 26 additions & 34 deletions src/GraphQL/Types/MarketplaceListingType.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,21 @@ public function fields(): array
'makeAssetId' => [
'type' => GraphQL::type('Asset!'),
'description' => __('enjin-platform-marketplace::type.marketplace_listing.field.makeAssetId'),
'resolve' => function ($listing) {
return [
'collectionId' => $listing->make_collection_chain_id,
'tokenId' => $listing->make_token_chain_id,
];
},
'resolve' => fn ($listing) => [
'collectionId' => $listing->make_collection_chain_id,
'tokenId' => $listing->make_token_chain_id,
],
'is_relation' => false,
'selectable' => false,
'always' => ['make_collection_chain_id', 'make_token_chain_id'],
],
'takeAssetId' => [
'type' => GraphQL::type('Asset!'),
'description' => __('enjin-platform-marketplace::type.marketplace_listing.field.takeAssetId'),
'resolve' => function ($listing) {
return [
'collectionId' => $listing->take_collection_chain_id,
'tokenId' => $listing->take_token_chain_id,
];
},
'resolve' => fn ($listing) => [
'collectionId' => $listing->take_collection_chain_id,
'tokenId' => $listing->take_token_chain_id,
],
'is_relation' => false,
'selectable' => false,
'always' => ['take_collection_chain_id', 'take_token_chain_id'],
Expand Down Expand Up @@ -120,34 +116,30 @@ public function fields(): array
'description' => __('enjin-platform-marketplace::type.marketplace_sale.description'),
'args' => ConnectionInput::args(),
'is_relation' => true,
'resolve' => function ($listing, $args) {
return [
'items' => new CursorPaginator(
$listing?->sales,
$args['first'],
Arr::get($args, 'after') ? Cursor::fromEncoded($args['after']) : null,
['parameters' => ['id']]
),
'total' => (int) $listing?->sales_count,
];
},
'resolve' => fn ($listing, $args) => [
'items' => new CursorPaginator(
$listing?->sales,
$args['first'],
Arr::get($args, 'after') ? Cursor::fromEncoded($args['after']) : null,
['parameters' => ['id']]
),
'total' => (int) $listing?->sales_count,
],
],
'bids' => [
'type' => GraphQL::paginate('MarketplaceBid', 'MarketplaceBidConnection'),
'description' => __('enjin-platform-marketplace::type.marketplace_bid.description'),
'args' => ConnectionInput::args(),
'is_relation' => true,
'resolve' => function ($listing, $args) {
return [
'items' => new CursorPaginator(
$listing?->bids,
$args['first'],
Arr::get($args, 'after') ? Cursor::fromEncoded($args['after']) : null,
['parameters' => ['id']]
),
'total' => (int) $listing?->bids_count,
];
},
'resolve' => fn ($listing, $args) => [
'items' => new CursorPaginator(
$listing?->bids,
$args['first'],
Arr::get($args, 'after') ? Cursor::fromEncoded($args['after']) : null,
['parameters' => ['id']]
),
'total' => (int) $listing?->bids_count,
],
],
'states' => [
'type' => GraphQL::type('[MarketplaceState!]'),
Expand Down
65 changes: 27 additions & 38 deletions src/Models/Laravel/Traits/EagerLoadSelectFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,30 @@ public static function selectFields(ResolveInfo $resolveInfo, string $query): ar
static::$query = $query;
$queryPlan = $resolveInfo->lookAhead()->queryPlan();

switch ($query) {
case 'GetListings':
case 'GetListing':
[$select, $with, $withCount] = static::loadListings(
$queryPlan,
$query == 'GetListings' ? 'edges.fields.node.fields' : '',
[],
null,
true
);

break;
case 'GetBids':
case 'GetBid':
[$select, $with, $withCount] = static::loadBids(
$queryPlan,
$query == 'GetBids' ? 'edges.fields.node.fields' : '',
[],
null,
true
);

break;
case 'GetSales':
case 'GetSale':
[$select, $with, $withCount] = static::loadSales(
$queryPlan,
$query == 'GetSales' ? 'edges.fields.node.fields' : '',
[],
null,
true
);

break;
}
[$select, $with, $withCount] = match ($query) {
'GetListings', 'GetListing' => static::loadListings(
$queryPlan,
$query == 'GetListings' ? 'edges.fields.node.fields' : '',
[],
null,
true
),
'GetBids', 'GetBid' => static::loadBids(
$queryPlan,
$query == 'GetBids' ? 'edges.fields.node.fields' : '',
[],
null,
true
),
'GetSales', 'GetSale' => static::loadSales(
$queryPlan,
$query == 'GetSales' ? 'edges.fields.node.fields' : '',
[],
null,
true
),
default => [$select, $with, $withCount],
};


return [$select, $with, $withCount];
Expand Down Expand Up @@ -97,7 +86,7 @@ public static function loadListings(

if (!$isParent) {
$with = [
$key => function ($query) use ($select, $args) {
$key => function ($query) use ($select, $args): void {
$query->select(array_unique($select))
->when($cursor = Cursor::fromEncoded(Arr::get($args, 'after')), fn ($q) => $q->where('id', '>', $cursor->parameter('id')))
->orderBy('marketplace_listings.id');
Expand Down Expand Up @@ -155,7 +144,7 @@ public static function loadBids(

if (!$isParent) {
$with = [
$key => function ($query) use ($select, $args) {
$key => function ($query) use ($select, $args): void {
$query->select(array_unique($select))
->when($cursor = Cursor::fromEncoded(Arr::get($args, 'after')), fn ($q) => $q->where('id', '>', $cursor->parameter('id')))
->orderBy('marketplace_bids.id');
Expand Down Expand Up @@ -206,7 +195,7 @@ public static function loadSales(

if (!$isParent) {
$with = [
$key => function ($query) use ($select, $args) {
$key => function ($query) use ($select, $args): void {
$query->select(array_unique($select))
->when($cursor = Cursor::fromEncoded(Arr::get($args, 'after')), fn ($q) => $q->where('id', '>', $cursor->parameter('id')))
->orderBy('marketplace_sales.id');
Expand Down
2 changes: 1 addition & 1 deletion src/Rules/MinimumPrice.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
$listing?->highestBid?->price ?? $listing?->price,
1.05
);
if (bccomp($value, $price) < 0) {
if (bccomp((string) $value, $price) < 0) {
$fail('enjin-platform-marketplace::validation.minimum_price')->translate(['price' => $price]);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Services/Processor/Substrate/Codec/Encoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Encoder extends BaseEncoder
{
protected static array $callIndexKeys = [
'CreateListing' => 'Marketplace.create_listing',
'CreateListingV1010' => 'Marketplace.create_listing',
'CancelListing' => 'Marketplace.cancel_listing',
'FillListing' => 'Marketplace.fill_listing',
'FinalizeAuction' => 'Marketplace.finalize_auction',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ abstract class MarketplaceSubstrateEvent extends SubstrateEvent
protected function getListing(string $listingId): Model
{
if (!$listing = MarketplaceListing::where(['listing_chain_id' => $listingId])->first()) {
throw new PlatformException(__('enjin-platform::traits.query_data_or_fail.unable_to_find_listing', ['class' => __CLASS__, 'listingId' => $listingId]));
throw new PlatformException(__('enjin-platform::traits.query_data_or_fail.unable_to_find_listing', ['class' => self::class, 'listingId' => $listingId]));
}

return $listing;
Expand Down
Loading

0 comments on commit 39e08ee

Please sign in to comment.