示例#1
0
        public static IPromise <TransactionBuilder> SetRequiredFees(TransactionBuilder builder, SpaceTypeId assetId = null)
        {
            if (builder.IsFinalized)
            {
                throw new InvalidOperationException("SetRequiredFees... Already finalized");
            }
            if (builder.operations.IsNullOrEmpty())
            {
                throw new InvalidOperationException("SetRequiredFees... Add operation first");
            }
            var ops = new OperationData[builder.operations.Count];

            for (var i = 0; i < builder.operations.Count; i++)
            {
                ops[i] = builder.operations[i].Clone();
            }
            var coreAssetId = SpaceTypeId.CreateOne(SpaceType.Asset);

            if (assetId.IsNull())
            {
                var firstFee = ops.First().Fee;
                if (!firstFee.IsNull() && !firstFee.AssetId.IsNullOrEmpty())
                {
                    assetId = firstFee.AssetId;
                }
                else
                {
                    assetId = coreAssetId;
                }
            }
            var isNotCoreAsset = !assetId.Equals(coreAssetId);
            var promises       = new List <IPromise <object> >();

            if (ops.Contains(op => op.Type.Equals(ChainTypes.Operation.ContractCall)))
            {
                promises.Add(EchoApiManager.Instance.Database.GetRequiredFees <FeeForCallContractData>(ops, assetId.ToUintId).Then <object>(feesData => feesData.Cast <IFeeAsset>()));
                if (isNotCoreAsset)
                {
                    promises.Add(EchoApiManager.Instance.Database.GetRequiredFees <FeeForCallContractData>(ops, coreAssetId.ToUintId).Then <object>(coreFeesData => coreFeesData.Cast <IFeeAsset>()));
                }
            }
            else
            if (ops.Contains(op => op.Type.Equals(ChainTypes.Operation.ContractCreate)))
            {
                promises.Add(EchoApiManager.Instance.Database.GetRequiredFees <FeeForCreateContractData>(ops, assetId.ToUintId).Then <object>(feesData => feesData.Cast <IFeeAsset>()));
                if (isNotCoreAsset)
                {
                    promises.Add(EchoApiManager.Instance.Database.GetRequiredFees <FeeForCreateContractData>(ops, coreAssetId.ToUintId).Then <object>(coreFeesData => coreFeesData.Cast <IFeeAsset>()));
                }
            }
            else
            {
                promises.Add(EchoApiManager.Instance.Database.GetRequiredFees <AssetData>(ops, assetId.ToUintId).Then <object>(feesData => feesData.Cast <IFeeAsset>()));
                if (isNotCoreAsset)
                {
                    promises.Add(EchoApiManager.Instance.Database.GetRequiredFees <AssetData>(ops, coreAssetId.ToUintId).Then <object>(coreFeesData => coreFeesData.Cast <IFeeAsset>()));
                }
            }

            if (isNotCoreAsset)
            {
                promises.Add(Repository.GetInPromise(assetId, () => EchoApiManager.Instance.Database.GetAsset(assetId.ToUintId)).Then <object>(assetObject => assetObject));
            }

            return(Promise <object> .All(promises.ToArray()).Then(results =>
            {
                var list = new List <object>(results).ToArray();

                var feesData = list.First() as IFeeAsset[];
                var coreFeesData = (list.Length > 1) ? (list[1] as IFeeAsset[]) : null;
                var assetObject = (list.Length > 2) ? (list[2] as AssetObject) : null;

                var dynamicPromise = isNotCoreAsset ? EchoApiManager.Instance.Database.GetObject <AssetDynamicDataObject>(assetObject.DynamicAssetData) : Promise <AssetDynamicDataObject> .Resolved(null);

                return dynamicPromise.Then(dynamicObject =>
                {
                    if (isNotCoreAsset)
                    {
                        var totalFees = 0L;
                        for (var j = 0; j < coreFeesData.Length; j++)
                        {
                            totalFees += coreFeesData[j].FeeAsset.Amount;
                        }
                        var feePool = dynamicObject.IsNull() ? 0L : dynamicObject.FeePool;
                        if (totalFees > feePool)
                        {
                            feesData = coreFeesData;
                        }
                    }
                    var flatAssets = GetFee(feesData.OrEmpty(), new List <AssetData>());
                    var assetIndex = 0;
                    for (var i = 0; i < builder.operations.Count; i++)
                    {
                        SetFee(builder.operations[i], ref assetIndex, flatAssets);
                    }
                });
            }).Then(() => Promise <TransactionBuilder> .Resolved(builder)));
        }