Пример #1
0
        protected Task ValidateDoubleEndorsing(RawDoubleEndorsingEvidenceContent de, RawBlock rawBlock)
        {
            if (de.Op1.Operations.Kind != "endorsement" || de.Op2.Operations.Kind != "endorsement")
            {
                throw new ValidationException("inconsistent double endorsing operations kind");
            }

            if (de.Op1.Operations.Level != de.Op2.Operations.Level)
            {
                throw new ValidationException("inconsistent double endorsing levels");
            }

            var rewardUpdate = de.Metadata.BalanceUpdates.FirstOrDefault(x => x.Change > 0) as RewardsUpdate
                               ?? throw new ValidationException("double endorsing reward is missed");

            if (rewardUpdate.Delegate != rawBlock.Metadata.Baker)
            {
                throw new ValidationException("invalid double endorsing reward recipient");
            }

            var lostDepositsUpdate = de.Metadata.BalanceUpdates.FirstOrDefault(x => x is DepositsUpdate && x.Change < 0) as DepositsUpdate;
            var lostRewardsUpdate  = de.Metadata.BalanceUpdates.FirstOrDefault(x => x is RewardsUpdate && x.Change < 0) as RewardsUpdate;
            var lostFeesUpdate     = de.Metadata.BalanceUpdates.FirstOrDefault(x => x is FeesUpdate && x.Change < 0) as FeesUpdate;

            var offender = lostDepositsUpdate?.Delegate ?? lostRewardsUpdate?.Delegate ?? lostFeesUpdate?.Delegate;

            if (!Cache.Accounts.DelegateExists(offender))
            {
                throw new ValidationException("invalid double endorsing offender");
            }

            if ((lostDepositsUpdate?.Delegate ?? offender) != offender ||
                (lostRewardsUpdate?.Delegate ?? offender) != offender ||
                (lostFeesUpdate?.Delegate ?? offender) != offender)
            {
                throw new ValidationException("invalid double endorsing offender updates");
            }

            if (rewardUpdate.Change != -((lostDepositsUpdate?.Change ?? 0) + (lostFeesUpdate?.Change ?? 0)) / 2)
            {
                throw new ValidationException("invalid double endorsing reward amount");
            }

            var accusedCycle = (de.Op1.Operations.Level - 1) / Protocol.BlocksPerCycle;

            if ((lostDepositsUpdate?.Cycle ?? accusedCycle) != accusedCycle ||
                (lostRewardsUpdate?.Cycle ?? accusedCycle) != accusedCycle ||
                (lostFeesUpdate?.Cycle ?? accusedCycle) != accusedCycle)
            {
                throw new ValidationException("invalid double endorsing freezer level");
            }

            return(Task.CompletedTask);
        }
Пример #2
0
        public Task Init(Block block, RawOperation op, RawDoubleEndorsingEvidenceContent content)
        {
            DoubleEndorsing = new DoubleEndorsingOperation
            {
                Id        = Cache.AppState.NextOperationId(),
                Block     = block,
                Level     = block.Level,
                Timestamp = block.Timestamp,
                OpHash    = op.Hash,

                AccusedLevel = content.Op1.Operations.Level,
                Accuser      = block.Baker,
                Offender     = Cache.Accounts.GetDelegate(content.Metadata.BalanceUpdates.First(x => x.Change < 0).Target),

                AccuserReward       = content.Metadata.BalanceUpdates.Where(x => x.Change > 0).Sum(x => x.Change),
                OffenderLostDeposit = content.Metadata.BalanceUpdates.Where(x => x.Change < 0 && x is DepositsUpdate).Sum(x => - x.Change),
                OffenderLostReward  = content.Metadata.BalanceUpdates.Where(x => x.Change < 0 && x is RewardsUpdate).Sum(x => - x.Change),
                OffenderLostFee     = content.Metadata.BalanceUpdates.Where(x => x.Change < 0 && x is FeesUpdate).Sum(x => - x.Change)
            };

            return(Task.CompletedTask);
        }
Пример #3
0
        public static async Task <DoubleEndorsingCommit> Apply(ProtocolHandler proto, Block block, RawOperation op, RawDoubleEndorsingEvidenceContent content)
        {
            var commit = new DoubleEndorsingCommit(proto);
            await commit.Init(block, op, content);

            await commit.Apply();

            return(commit);
        }