Skip to content

Commit

Permalink
[PLA-1770] Adds Balances.Teleport + LimitedTeleportAssets method. (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardocustodio authored May 20, 2024
1 parent d7c2a44 commit 4653bd2
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 25 deletions.
71 changes: 47 additions & 24 deletions src/Commands/RelayWatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
use Enjin\Platform\Enums\Global\TransactionState;
use Enjin\Platform\Enums\Substrate\StorageKey;
use Enjin\Platform\Enums\Substrate\SystemEventType;
use Enjin\Platform\Enums\Substrate\XcmOutcome;
use Enjin\Platform\Events\Global\TransactionCreated;
use Enjin\Platform\Events\Substrate\Balances\Teleport;
use Enjin\Platform\Models\Transaction;
use Enjin\Platform\Models\Wallet;
use Enjin\Platform\Services\Blockchain\Implementations\Substrate;
use Enjin\Platform\Services\Processor\Substrate\Codec\Codec;
use Enjin\Platform\Services\Processor\Substrate\Codec\Polkadart\Events\System\ExtrinsicFailed;
use Enjin\Platform\Services\Processor\Substrate\Codec\Polkadart\Events\System\ExtrinsicSuccess;
use Enjin\Platform\Services\Processor\Substrate\DecoderService;
use Enjin\Platform\Support\Account;
use Enjin\Platform\Support\JSON;
Expand Down Expand Up @@ -125,11 +125,13 @@ protected function fetchExtrinsics(string $blockHash, $blockNumber): void
'wallet_public_key' => $signer,
]);

$tx->transaction_chain_id = $blockNumber . '-' . $i;
$tx->state = TransactionState::FINALIZED->name;
$tx->save();
if ($tx) {
$tx->transaction_chain_id = $blockNumber . '-' . $i;
$tx->state = TransactionState::FINALIZED->name;
$tx->save();

$this->updateExtrinsicResult($blockHash, $i, $tx->id, null);
$this->updateExtrinsicResult($blockNumber, $i, $tx->id, null);
}
}
}
}
Expand All @@ -146,9 +148,11 @@ protected function getEvents($data): void

protected function findEndowedAccounts(array $events, string $blockHash): void
{
$blockNumber = $this->getBlockNumber($blockHash);

array_filter(
$events,
function ($event) use ($blockHash, $events) {
function ($event) use ($blockNumber) {
if ($event->module === 'Balances' && $event->name === 'Transfer') {
if (in_array($account = HexConverter::prefix($event->to), Account::managedPublicKeys())) {
$this->info(json_encode($event));
Expand All @@ -157,14 +161,12 @@ function ($event) use ($blockHash, $events) {
}

if ($event->module === 'XcmPallet' && $event->name === 'Attempted') {
$extrinsicIndex = $event->extrinsicIndex;
$successOrFailed = collect($events)->firstWhere(
fn ($event) => ($event instanceof ExtrinsicSuccess || $event instanceof ExtrinsicFailed)
&& $event->extrinsicIndex === $extrinsicIndex
);

$blockNumber = $this->getBlockNumber($blockHash);
$this->updateExtrinsicResult($blockNumber, $extrinsicIndex, null, $successOrFailed);
$successOrFailed = $event->outcome === XcmOutcome::COMPLETE;
$this->updateExtrinsicResult($blockNumber, $event->extrinsicIndex, null, $successOrFailed);
}

if ($event->module === 'System' && $event->name === 'ExtrinsicFailed') {
$this->updateExtrinsicResult($blockNumber, $event->extrinsicIndex, null, false);
}
}
);
Expand All @@ -186,18 +188,37 @@ protected function updateExtrinsicResult($blockNumber, $extrinsicIndex, $transac
{
$extrinsicIdentifier = Cache::remember(
PlatformCache::BLOCK_TRANSACTION->key($txId = $blockNumber . '-' . $extrinsicIndex),
now()->addMinute(),
fn () => $txId . ':' . $success->name,
now()->addMinutes(5),
fn () => $txId . ':' . $success,
);

if ($transactionId) {
$tx = Transaction::find($transactionId);
if ($transactionId != null) {
$tx = Transaction::firstWhere('id', $transactionId);
if (!$tx) {
return;
}

$explode = explode(':', $extrinsicIdentifier);
if ($tx->transaction_chain_id !== $explode[0]) {
return;
}

if ($explode[1]) {
$tx->result = SystemEventType::EXTRINSIC_SUCCESS->name;
Teleport::safeBroadcast(
$wallet = Wallet::firstWhere('public_key', $tx->wallet_public_key),
$wallet,
$tx->amount,
currentMatrix()->value,
$tx,
);
}

if ($tx->transaction_chain_id === $explode[0]) {
$tx->result = $explode[1] === 'ExtrinsicSuccess' ? SystemEventType::EXTRINSIC_SUCCESS->name : SystemEventType::EXTRINSIC_FAILED->name;
$tx->save();
if (!$explode[1]) {
$tx->result = SystemEventType::EXTRINSIC_FAILED->name;
}

$tx->save();
}
}

Expand All @@ -209,9 +230,11 @@ protected function createDaemonTransaction(string $account, string $amount): voi
'public_key' => $account,
]);

$amount = $this->codec->encoder()->compact($amount);
$transferableAmount = $this->codec->encoder()->compact(
gmp_strval(gmp_sub($amount, '100000000000000000'))
);
$call = '0x630903000100a10f0300010100' . HexConverter::unPrefix($managedWallet->public_key);
$call .= '030400000000' . HexConverter::unPrefix($amount);
$call .= '030400000000' . HexConverter::unPrefix($transferableAmount);
$call .= '0000000000';

$transaction = Transaction::create([
Expand Down
13 changes: 13 additions & 0 deletions src/Enums/Substrate/XcmOutcome.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Enjin\Platform\Enums\Substrate;

use Enjin\Platform\Traits\EnumExtensions;

enum XcmOutcome: string
{
use EnumExtensions;

case COMPLETE = 'Complete';
case INCOMPLETE = 'Incomplete';
}
34 changes: 34 additions & 0 deletions src/Events/Substrate/Balances/Teleport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Enjin\Platform\Events\Substrate\Balances;

use Enjin\Platform\Channels\PlatformAppChannel;
use Enjin\Platform\Events\PlatformBroadcastEvent;
use Illuminate\Broadcasting\Channel;
use Illuminate\Database\Eloquent\Model;

class Teleport extends PlatformBroadcastEvent
{
/**
* Create a new event instance.
*/
public function __construct(Model $from, Model $to, string $amount, string $destination, ?Model $transaction = null)
{
parent::__construct();

$this->broadcastData = [
'idempotencyKey' => $transaction?->idempotency_key,
'transactionHash' => $transaction?->transaction_chain_hash,
'from' => $from->address,
'to' => $to->address,
'amount' => $amount,
'destination' => $destination,
];

$this->broadcastChannels = [
new Channel($from->address),
new Channel($to->address),
new PlatformAppChannel(),
];
}
}
2 changes: 1 addition & 1 deletion src/GraphQL/Enums/TransactionMethodEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function attributes(): array
{
// TODO: Need to check the implications of removing:
// This '' causes an error on graphql
$mutationNames = collect([]);
$mutationNames = collect(['LimitedTeleportAssets']);
foreach (get_declared_classes() as $className) {
if (in_array(PlatformBlockchainTransaction::class, class_implements($className))) {
$mutationNames->add((new $className())->getMutationName());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Enjin\Platform\Services\Processor\Substrate\Codec\Polkadart\Events\XcmPallet;

use Enjin\Platform\Enums\Substrate\XcmOutcome;
use Enjin\Platform\Services\Processor\Substrate\Codec\Polkadart\Events\Event;
use Enjin\Platform\Services\Processor\Substrate\Codec\Polkadart\PolkadartEvent;
use Illuminate\Support\Arr;

class Attempted extends Event implements PolkadartEvent
{
public readonly ?string $extrinsicIndex;
public readonly string $module;
public readonly string $name;
public readonly XcmOutcome $outcome;

public static function fromChain(array $data): self
{
$self = new self();

$self->extrinsicIndex = Arr::get($data, 'phase.ApplyExtrinsic');
$self->module = array_key_first(Arr::get($data, 'event'));
$self->name = array_key_first(Arr::get($data, 'event.' . $self->module));
$self->outcome = XcmOutcome::tryFrom(array_key_first($self->getValue($data, ['xcm::latest::Outcome']))) ?? XcmOutcome::INCOMPLETE;

return $self;
}

public function getPallet(): string
{
return $this->module;
}

public function getParams(): array
{
return [
['type' => 'outcome', 'value' => $this->outcome],
];
}
}

// - Complete
// +extrinsicIndex: "2"
// +module: "XcmPallet"
// +name: "Attempted"
// +data: array:1 [▼
// "xcm::latest::Outcome" => array:1 [▼
// "Complete" => array:2 [▼
// "ref_time" => "450000000"
// "proof_size" => "3072"
// ]
// ]
// ]
// +outcome: "Complete"
//
//
// - Incomplete
// +extrinsicIndex: "2"
// +module: "XcmPallet"
// +name: "Attempted"
// +data: array:1 [▼
// "xcm::latest::Outcome" => array:1 [▼
// "Incomplete" => array:2 [▼
// 0 => array:2 [▼
// "ref_time" => "150000000"
// "proof_size" => "1024"
// ]
// 1 => array:1 [▼
// "FailedToTransactAsset" => null
// ]
// ]
// ]
// ]
// +outcome: "Incomplete"

0 comments on commit 4653bd2

Please sign in to comment.