PHP WebShell

Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@iota/iota-sdk/dist/esm/transactions/executor

Просмотр файла: parallel.js

var __typeError = (msg) => {
  throw TypeError(msg);
};
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
var __privateWrapper = (obj, member, setter, getter) => ({
  set _(value) {
    __privateSet(obj, member, value, setter);
  },
  get _() {
    return __privateGet(obj, member, getter);
  }
});
var _signer, _client, _coinBatchSize, _initialCoinBalance, _minimumCoinBalance, _epochBoundaryWindow, _defaultGasBudget, _maxPoolSize, _sourceCoins, _coinPool, _cache, _objectIdQueues, _buildQueue, _executeQueue, _lastDigest, _cacheLock, _pendingTransactions, _gasPrice, _ParallelTransactionExecutor_instances, getUsedObjects_fn, execute_fn, updateCache_fn, waitForLastDigest_fn, getGasCoin_fn, getGasPrice_fn, refillCoinPool_fn;
import { toBase64 } from "@iota/bcs";
import { bcs } from "../../bcs/index.js";
import { Transaction } from "../Transaction.js";
import { TransactionDataBuilder } from "../TransactionData.js";
import { CachingTransactionExecutor } from "./caching.js";
import { ParallelQueue, SerialQueue } from "./queue.js";
import { getGasCoinFromEffects } from "./serial.js";
const PARALLEL_EXECUTOR_DEFAULTS = {
  coinBatchSize: 20,
  initialCoinBalance: 200000000n,
  minimumCoinBalance: 50000000n,
  maxPoolSize: 50,
  epochBoundaryWindow: 1e3
};
class ParallelTransactionExecutor {
  constructor(options) {
    __privateAdd(this, _ParallelTransactionExecutor_instances);
    __privateAdd(this, _signer);
    __privateAdd(this, _client);
    __privateAdd(this, _coinBatchSize);
    __privateAdd(this, _initialCoinBalance);
    __privateAdd(this, _minimumCoinBalance);
    __privateAdd(this, _epochBoundaryWindow);
    __privateAdd(this, _defaultGasBudget);
    __privateAdd(this, _maxPoolSize);
    __privateAdd(this, _sourceCoins);
    __privateAdd(this, _coinPool, []);
    __privateAdd(this, _cache);
    __privateAdd(this, _objectIdQueues, /* @__PURE__ */ new Map());
    __privateAdd(this, _buildQueue, new SerialQueue());
    __privateAdd(this, _executeQueue);
    __privateAdd(this, _lastDigest, null);
    __privateAdd(this, _cacheLock, null);
    __privateAdd(this, _pendingTransactions, 0);
    __privateAdd(this, _gasPrice, null);
    __privateSet(this, _signer, options.signer);
    __privateSet(this, _client, options.client);
    __privateSet(this, _coinBatchSize, options.coinBatchSize ?? PARALLEL_EXECUTOR_DEFAULTS.coinBatchSize);
    __privateSet(this, _initialCoinBalance, options.initialCoinBalance ?? PARALLEL_EXECUTOR_DEFAULTS.initialCoinBalance);
    __privateSet(this, _minimumCoinBalance, options.minimumCoinBalance ?? PARALLEL_EXECUTOR_DEFAULTS.minimumCoinBalance);
    __privateSet(this, _defaultGasBudget, options.defaultGasBudget ?? __privateGet(this, _minimumCoinBalance));
    __privateSet(this, _epochBoundaryWindow, options.epochBoundaryWindow ?? PARALLEL_EXECUTOR_DEFAULTS.epochBoundaryWindow);
    __privateSet(this, _maxPoolSize, options.maxPoolSize ?? PARALLEL_EXECUTOR_DEFAULTS.maxPoolSize);
    __privateSet(this, _cache, new CachingTransactionExecutor({
      client: options.client,
      cache: options.cache
    }));
    __privateSet(this, _executeQueue, new ParallelQueue(__privateGet(this, _maxPoolSize)));
    __privateSet(this, _sourceCoins, options.sourceCoins ? new Map(options.sourceCoins.map((id) => [id, null])) : null);
  }
  resetCache() {
    __privateSet(this, _gasPrice, null);
    return __privateMethod(this, _ParallelTransactionExecutor_instances, updateCache_fn).call(this, () => __privateGet(this, _cache).reset());
  }
  async waitForLastTransaction() {
    await __privateMethod(this, _ParallelTransactionExecutor_instances, updateCache_fn).call(this, () => __privateMethod(this, _ParallelTransactionExecutor_instances, waitForLastDigest_fn).call(this));
  }
  async executeTransaction(transaction, options) {
    const { promise, resolve, reject } = promiseWithResolvers();
    const usedObjects = await __privateMethod(this, _ParallelTransactionExecutor_instances, getUsedObjects_fn).call(this, transaction);
    const execute = () => {
      __privateGet(this, _executeQueue).runTask(() => {
        const promise2 = __privateMethod(this, _ParallelTransactionExecutor_instances, execute_fn).call(this, transaction, usedObjects, options);
        return promise2.then(resolve, reject);
      });
    };
    const conflicts = /* @__PURE__ */ new Set();
    usedObjects.forEach((objectId) => {
      const queue = __privateGet(this, _objectIdQueues).get(objectId);
      if (queue) {
        conflicts.add(objectId);
        __privateGet(this, _objectIdQueues).get(objectId).push(() => {
          conflicts.delete(objectId);
          if (conflicts.size === 0) {
            execute();
          }
        });
      } else {
        __privateGet(this, _objectIdQueues).set(objectId, []);
      }
    });
    if (conflicts.size === 0) {
      execute();
    }
    return promise;
  }
}
_signer = new WeakMap();
_client = new WeakMap();
_coinBatchSize = new WeakMap();
_initialCoinBalance = new WeakMap();
_minimumCoinBalance = new WeakMap();
_epochBoundaryWindow = new WeakMap();
_defaultGasBudget = new WeakMap();
_maxPoolSize = new WeakMap();
_sourceCoins = new WeakMap();
_coinPool = new WeakMap();
_cache = new WeakMap();
_objectIdQueues = new WeakMap();
_buildQueue = new WeakMap();
_executeQueue = new WeakMap();
_lastDigest = new WeakMap();
_cacheLock = new WeakMap();
_pendingTransactions = new WeakMap();
_gasPrice = new WeakMap();
_ParallelTransactionExecutor_instances = new WeakSet();
getUsedObjects_fn = async function(transaction) {
  const usedObjects = /* @__PURE__ */ new Set();
  let serialized = false;
  transaction.addSerializationPlugin(async (blockData, _options, next) => {
    await next();
    if (serialized) {
      return;
    }
    serialized = true;
    blockData.inputs.forEach((input) => {
      if (input.Object?.ImmOrOwnedObject?.objectId) {
        usedObjects.add(input.Object.ImmOrOwnedObject.objectId);
      } else if (input.Object?.Receiving?.objectId) {
        usedObjects.add(input.Object.Receiving.objectId);
      } else if (input.UnresolvedObject?.objectId && !input.UnresolvedObject.initialSharedVersion) {
        usedObjects.add(input.UnresolvedObject.objectId);
      }
    });
  });
  await transaction.prepareForSerialization({ client: __privateGet(this, _client) });
  return usedObjects;
};
execute_fn = async function(transaction, usedObjects, options) {
  let gasCoin;
  try {
    transaction.setSenderIfNotSet(__privateGet(this, _signer).toIotaAddress());
    await __privateGet(this, _buildQueue).runTask(async () => {
      const data = transaction.getData();
      if (!data.gasData.price) {
        transaction.setGasPrice(await __privateMethod(this, _ParallelTransactionExecutor_instances, getGasPrice_fn).call(this));
      }
      transaction.setGasBudgetIfNotSet(__privateGet(this, _defaultGasBudget));
      await __privateMethod(this, _ParallelTransactionExecutor_instances, updateCache_fn).call(this);
      gasCoin = await __privateMethod(this, _ParallelTransactionExecutor_instances, getGasCoin_fn).call(this);
      __privateWrapper(this, _pendingTransactions)._++;
      transaction.setGasPayment([
        {
          objectId: gasCoin.id,
          version: gasCoin.version,
          digest: gasCoin.digest
        }
      ]);
      await __privateGet(this, _cache).buildTransaction({ transaction, onlyTransactionKind: true });
    });
    const bytes = await transaction.build({ client: __privateGet(this, _client) });
    const { signature } = await __privateGet(this, _signer).signTransaction(bytes);
    const results = await __privateGet(this, _cache).executeTransaction({
      transaction: bytes,
      signature,
      options: {
        ...options,
        showEffects: true
      }
    });
    const effectsBytes = Uint8Array.from(results.rawEffects);
    const effects = bcs.TransactionEffects.parse(effectsBytes);
    const gasResult = getGasCoinFromEffects(effects);
    const gasUsed = effects.V1?.gasUsed;
    if (gasCoin && gasUsed && gasResult.owner === __privateGet(this, _signer).toIotaAddress()) {
      const totalUsed = BigInt(gasUsed.computationCost) + BigInt(gasUsed.storageCost) + BigInt(gasUsed.storageCost) - BigInt(gasUsed.storageRebate);
      let usesGasCoin = false;
      new TransactionDataBuilder(transaction.getData()).mapArguments((arg) => {
        if (arg.$kind === "GasCoin") {
          usesGasCoin = true;
        }
        return arg;
      });
      if (!usesGasCoin && gasCoin.balance >= __privateGet(this, _minimumCoinBalance)) {
        __privateGet(this, _coinPool).push({
          id: gasResult.ref.objectId,
          version: gasResult.ref.version,
          digest: gasResult.ref.digest,
          balance: gasCoin.balance - totalUsed
        });
      } else {
        if (!__privateGet(this, _sourceCoins)) {
          __privateSet(this, _sourceCoins, /* @__PURE__ */ new Map());
        }
        __privateGet(this, _sourceCoins).set(gasResult.ref.objectId, gasResult.ref);
      }
    }
    __privateSet(this, _lastDigest, results.digest);
    return {
      digest: results.digest,
      effects: toBase64(effectsBytes),
      data: results
    };
  } catch (error) {
    if (gasCoin) {
      if (!__privateGet(this, _sourceCoins)) {
        __privateSet(this, _sourceCoins, /* @__PURE__ */ new Map());
      }
      __privateGet(this, _sourceCoins).set(gasCoin.id, null);
    }
    await __privateMethod(this, _ParallelTransactionExecutor_instances, updateCache_fn).call(this, async () => {
      await Promise.all([
        __privateGet(this, _cache).cache.deleteObjects([...usedObjects]),
        __privateMethod(this, _ParallelTransactionExecutor_instances, waitForLastDigest_fn).call(this)
      ]);
    });
    throw error;
  } finally {
    usedObjects.forEach((objectId) => {
      const queue = __privateGet(this, _objectIdQueues).get(objectId);
      if (queue && queue.length > 0) {
        queue.shift()();
      } else if (queue) {
        __privateGet(this, _objectIdQueues).delete(objectId);
      }
    });
    __privateWrapper(this, _pendingTransactions)._--;
  }
};
updateCache_fn = async function(fn) {
  if (__privateGet(this, _cacheLock)) {
    await __privateGet(this, _cacheLock);
  }
  __privateSet(this, _cacheLock, fn?.().then(
    () => {
      __privateSet(this, _cacheLock, null);
    },
    () => {
    }
  ) ?? null);
};
waitForLastDigest_fn = async function() {
  const digest = __privateGet(this, _lastDigest);
  if (digest) {
    __privateSet(this, _lastDigest, null);
    await __privateGet(this, _client).waitForTransaction({ digest });
  }
};
getGasCoin_fn = async function() {
  if (__privateGet(this, _coinPool).length === 0 && __privateGet(this, _pendingTransactions) <= __privateGet(this, _maxPoolSize)) {
    await __privateMethod(this, _ParallelTransactionExecutor_instances, refillCoinPool_fn).call(this);
  }
  if (__privateGet(this, _coinPool).length === 0) {
    throw new Error("No coins available");
  }
  const coin = __privateGet(this, _coinPool).shift();
  return coin;
};
getGasPrice_fn = async function() {
  const remaining = __privateGet(this, _gasPrice) ? __privateGet(this, _gasPrice).expiration - __privateGet(this, _epochBoundaryWindow) - Date.now() : 0;
  if (remaining > 0) {
    return __privateGet(this, _gasPrice).price;
  }
  if (__privateGet(this, _gasPrice)) {
    const timeToNextEpoch = Math.max(
      __privateGet(this, _gasPrice).expiration + __privateGet(this, _epochBoundaryWindow) - Date.now(),
      1e3
    );
    await new Promise((resolve) => setTimeout(resolve, timeToNextEpoch));
  }
  const state = await __privateGet(this, _client).getLatestIotaSystemState();
  __privateSet(this, _gasPrice, {
    price: BigInt(state.referenceGasPrice),
    expiration: Number.parseInt(state.epochStartTimestampMs, 10) + Number.parseInt(state.epochDurationMs, 10)
  });
  return __privateMethod(this, _ParallelTransactionExecutor_instances, getGasPrice_fn).call(this);
};
refillCoinPool_fn = async function() {
  const batchSize = Math.min(
    __privateGet(this, _coinBatchSize),
    __privateGet(this, _maxPoolSize) - (__privateGet(this, _coinPool).length + __privateGet(this, _pendingTransactions)) + 1
  );
  if (batchSize === 0) {
    return;
  }
  const txb = new Transaction();
  const address = __privateGet(this, _signer).toIotaAddress();
  txb.setSender(address);
  if (__privateGet(this, _sourceCoins)) {
    const refs = [];
    const ids = [];
    for (const [id, ref] of __privateGet(this, _sourceCoins)) {
      if (ref) {
        refs.push(ref);
      } else {
        ids.push(id);
      }
    }
    if (ids.length > 0) {
      const coins = await __privateGet(this, _client).multiGetObjects({
        ids
      });
      refs.push(
        ...coins.filter(
          (coin) => coin.data !== null
        ).map(({ data }) => ({
          objectId: data.objectId,
          version: data.version,
          digest: data.digest
        }))
      );
    }
    txb.setGasPayment(refs);
    __privateSet(this, _sourceCoins, /* @__PURE__ */ new Map());
  }
  const amounts = new Array(batchSize).fill(__privateGet(this, _initialCoinBalance));
  const results = txb.splitCoins(txb.gas, amounts);
  const coinResults = [];
  for (let i = 0; i < amounts.length; i++) {
    coinResults.push(results[i]);
  }
  txb.transferObjects(coinResults, address);
  await this.waitForLastTransaction();
  const result = await __privateGet(this, _client).signAndExecuteTransaction({
    transaction: txb,
    signer: __privateGet(this, _signer),
    options: {
      showRawEffects: true
    }
  });
  const effects = bcs.TransactionEffects.parse(Uint8Array.from(result.rawEffects));
  effects.V1?.changedObjects.forEach(([id, { outputState }], i) => {
    if (i === effects.V1?.gasObjectIndex || !outputState.ObjectWrite) {
      return;
    }
    __privateGet(this, _coinPool).push({
      id,
      version: effects.V1.lamportVersion,
      digest: outputState.ObjectWrite[0],
      balance: BigInt(__privateGet(this, _initialCoinBalance))
    });
  });
  if (!__privateGet(this, _sourceCoins)) {
    __privateSet(this, _sourceCoins, /* @__PURE__ */ new Map());
  }
  const gasObject = getGasCoinFromEffects(effects).ref;
  __privateGet(this, _sourceCoins).set(gasObject.objectId, gasObject);
  await __privateGet(this, _client).waitForTransaction({ digest: result.digest });
};
function promiseWithResolvers() {
  let resolve;
  let reject;
  const promise = new Promise((_resolve, _reject) => {
    resolve = _resolve;
    reject = _reject;
  });
  return { promise, resolve, reject };
}
export {
  ParallelTransactionExecutor
};
//# sourceMappingURL=parallel.js.map

Выполнить команду


Для локальной разработки. Не используйте в интернете!