Esempio n. 1
0
 private static void CheckCandidate(StoreView snapshot, StorageKey key, CandidateState candidate)
 {
     if (!candidate.Registered && candidate.Votes.IsZero)
     {
         snapshot.Storages.Delete(key);
     }
 }
Esempio n. 2
0
        private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey)
        {
            if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
            {
                return(false);
            }
            StorageKey key = CreateStorageKey(Prefix_Candidate).Add(pubkey);

            if (engine.Snapshot.Storages.TryGet(key) is null)
            {
                return(true);
            }
            StorageItem    item  = engine.Snapshot.Storages.GetAndChange(key);
            CandidateState state = item.GetInteroperable <CandidateState>();

            if (state.Votes.IsZero)
            {
                engine.Snapshot.Storages.Delete(key);
            }
            else
            {
                state.Registered = false;
            }
            return(true);
        }
Esempio n. 3
0
    /// <summary>
    /// <para>
    /// Initializes a new instances of the <see cref="CandidateSet"/> class with the provided <paramref name="endpoints"/>,
    /// <paramref name="values"/>, and <paramref name="scores"/>.
    /// </para>
    /// <para>
    /// The constructor is provided to enable unit tests of implementations of <see cref="EndpointSelector"/>
    /// and <see cref="IEndpointSelectorPolicy"/>.
    /// </para>
    /// </summary>
    /// <param name="endpoints">The list of endpoints, sorted in descending priority order.</param>
    /// <param name="values">The list of <see cref="RouteValueDictionary"/> instances.</param>
    /// <param name="scores">The list of endpoint scores. <see cref="CandidateState.Score"/>.</param>
    public CandidateSet(Endpoint[] endpoints, RouteValueDictionary[] values, int[] scores)
    {
        if (endpoints == null)
        {
            throw new ArgumentNullException(nameof(endpoints));
        }

        if (values == null)
        {
            throw new ArgumentNullException(nameof(values));
        }

        if (scores == null)
        {
            throw new ArgumentNullException(nameof(scores));
        }

        if (endpoints.Length != values.Length || endpoints.Length != scores.Length)
        {
            throw new ArgumentException($"The provided {nameof(endpoints)}, {nameof(values)}, and {nameof(scores)} must have the same length.");
        }

        Candidates = new CandidateState[endpoints.Length];
        for (var i = 0; i < endpoints.Length; i++)
        {
            Candidates[i] = new CandidateState(endpoints[i], values[i], scores[i]);
        }
    }
Esempio n. 4
0
        public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            // The goal of this method is to perform the final matching:
            // Map between route values matched by the template and the ones we want to expose to the action for binding.
            // (tweaking the route values is fine here)
            // Invalidating the candidate if the key/function values are not valid/missing.
            // Perform overload resolution for functions by looking at the candidates and their metadata.
            for (var i = 0; i < candidates.Count; i++)
            {
                ref CandidateState candidate = ref candidates[i];
                if (!candidates.IsValidCandidate(i))
                {
                    continue;
                }

                IODataRoutingMetadata metadata = candidate.Endpoint.Metadata.OfType <IODataRoutingMetadata>().FirstOrDefault();
                if (metadata == null)
                {
                    continue;
                }

                IHttpMethodMetadata httpMetadata = candidate.Endpoint.Metadata.GetMetadata <IHttpMethodMetadata>();
                if (httpMetadata == null)
                {
                    // Check the http method
                    if (metadata.HttpMethods != null && !metadata.HttpMethods.Contains(httpContext.Request.Method))
                    {
                        candidates.SetValidity(i, false);
                        continue;
                    }
                }

                ODataTemplateTranslateContext translatorContext =
                    new ODataTemplateTranslateContext(httpContext, candidate.Values, metadata.Model);

                try
                {
                    ODataPath odataPath = _translator.Translate(metadata.Template, translatorContext);
                    if (odataPath != null)
                    {
                        IODataFeature odataFeature = httpContext.ODataFeature();
                        odataFeature.PrefixName = metadata.Prefix;
                        odataFeature.Model      = metadata.Model;
                        odataFeature.Path       = odataPath;
                    }
                    else
                    {
                        candidates.SetValidity(i, false);
                    }
                }
                catch (Exception)
                {
                    candidates.SetValidity(i, false);
                }
            }
Esempio n. 5
0
        private void RegisterCandidateInternal(StoreView snapshot, ECPoint pubkey)
        {
            StorageKey     key   = CreateStorageKey(Prefix_Candidate).Add(pubkey);
            StorageItem    item  = snapshot.Storages.GetAndChange(key, () => new StorageItem(new CandidateState()));
            CandidateState state = item.GetInteroperable <CandidateState>();

            state.Registered = true;
        }
Esempio n. 6
0
 // Used in tests.
 internal CandidateSet(Candidate[] candidates)
 {
     Candidates = new CandidateState[candidates.Length];
     for (var i = 0; i < candidates.Length; i++)
     {
         Candidates[i] = new CandidateState(candidates[i].Endpoint, candidates[i].Score);
     }
 }
Esempio n. 7
0
        private bool Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo)
        {
            if (!engine.CheckWitnessInternal(account))
            {
                return(false);
            }
            NeoAccountState state_account = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Account).Add(account))?.GetInteroperable <NeoAccountState>();

            if (state_account is null)
            {
                return(false);
            }
            CandidateState validator_new = null;

            if (voteTo != null)
            {
                validator_new = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Candidate).Add(voteTo))?.GetInteroperable <CandidateState>();
                if (validator_new is null)
                {
                    return(false);
                }
                if (!validator_new.Registered)
                {
                    return(false);
                }
            }
            if (state_account.VoteTo is null ^ voteTo is null)
            {
                StorageItem item = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_VotersCount));
                if (state_account.VoteTo is null)
                {
                    item.Add(state_account.Balance);
                }
                else
                {
                    item.Add(-state_account.Balance);
                }
            }
            if (state_account.VoteTo != null)
            {
                StorageKey     key = CreateStorageKey(Prefix_Candidate).Add(state_account.VoteTo);
                StorageItem    storage_validator = engine.Snapshot.Storages.GetAndChange(key);
                CandidateState state_validator   = storage_validator.GetInteroperable <CandidateState>();
                state_validator.Votes -= state_account.Balance;
                if (!state_validator.Registered && state_validator.Votes.IsZero)
                {
                    engine.Snapshot.Storages.Delete(key);
                }
            }
            state_account.VoteTo = voteTo;
            if (validator_new != null)
            {
                validator_new.Votes += state_account.Balance;
            }
            return(true);
        }
Esempio n. 8
0
        private async ContractTask <bool> Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo)
        {
            if (!engine.CheckWitnessInternal(account))
            {
                return(false);
            }
            VauthAccountState state_account = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Account).Add(account))?.GetInteroperable <VauthAccountState>();

            if (state_account is null)
            {
                return(false);
            }
            CandidateState validator_new = null;

            if (voteTo != null)
            {
                validator_new = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Candidate).Add(voteTo))?.GetInteroperable <CandidateState>();
                if (validator_new is null)
                {
                    return(false);
                }
                if (!validator_new.Registered)
                {
                    return(false);
                }
            }
            if (state_account.VoteTo is null ^ voteTo is null)
            {
                StorageItem item = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_VotersCount));
                if (state_account.VoteTo is null)
                {
                    item.Add(state_account.Balance);
                }
                else
                {
                    item.Add(-state_account.Balance);
                }
            }
            await DistributeValt(engine, account, state_account);

            if (state_account.VoteTo != null)
            {
                StorageKey     key = CreateStorageKey(Prefix_Candidate).Add(state_account.VoteTo);
                StorageItem    storage_validator = engine.Snapshot.GetAndChange(key);
                CandidateState state_validator   = storage_validator.GetInteroperable <CandidateState>();
                state_validator.Votes -= state_account.Balance;
                CheckCandidate(engine.Snapshot, state_account.VoteTo, state_validator);
            }
            state_account.VoteTo = voteTo;
            if (validator_new != null)
            {
                validator_new.Votes += state_account.Balance;
            }
            return(true);
        }
Esempio n. 9
0
 private void CheckCandidate(DataCache snapshot, ECPoint pubkey, CandidateState candidate)
 {
     if (!candidate.Registered && candidate.Votes.IsZero)
     {
         foreach (var(rewardKey, _) in snapshot.Find(CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(pubkey).ToArray()).ToArray())
         {
             snapshot.Delete(rewardKey);
         }
         snapshot.Delete(CreateStorageKey(Prefix_Candidate).Add(pubkey));
     }
 }
Esempio n. 10
0
        private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey)
        {
            if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
            {
                return(false);
            }
            StorageKey     key   = CreateStorageKey(Prefix_Candidate).Add(pubkey);
            StorageItem    item  = engine.Snapshot.Storages.GetAndChange(key, () => new StorageItem(new CandidateState()));
            CandidateState state = item.GetInteroperable <CandidateState>();

            state.Registered = true;
            return(true);
        }
Esempio n. 11
0
 protected override void OnBalanceChanging(ApplicationEngine engine, UInt160 account, NeoAccountState state, BigInteger amount)
 {
     DistributeGas(engine, account, state);
     if (amount.IsZero)
     {
         return;
     }
     if (state.VoteTo != null)
     {
         StorageItem    storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Candidate, state.VoteTo.ToArray()));
         CandidateState state_validator   = storage_validator.GetInteroperable <CandidateState>();
         state_validator.Votes += amount;
     }
 }
Esempio n. 12
0
        protected override void OnBalanceChanging(ApplicationEngine engine, UInt160 account, NeoAccountState state, BigInteger amount)
        {
            DistributeGas(engine, account, state);
            if (amount.IsZero)
            {
                return;
            }
            if (state.VoteTo is null)
            {
                return;
            }
            engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_VotersCount)).Add(amount);
            StorageKey     key       = CreateStorageKey(Prefix_Candidate).Add(state.VoteTo);
            CandidateState candidate = engine.Snapshot.Storages.GetAndChange(key).GetInteroperable <CandidateState>();

            candidate.Votes += amount;
            CheckCandidate(engine.Snapshot, key, candidate);
        }
Esempio n. 13
0
        internal override async ContractTask OnBalanceChanging(ApplicationEngine engine, UInt160 account, VauthAccountState state, BigInteger amount)
        {
            await DistributeValt(engine, account, state);

            if (amount.IsZero)
            {
                return;
            }
            if (state.VoteTo is null)
            {
                return;
            }
            engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_VotersCount)).Add(amount);
            StorageKey     key       = CreateStorageKey(Prefix_Candidate).Add(state.VoteTo);
            CandidateState candidate = engine.Snapshot.GetAndChange(key).GetInteroperable <CandidateState>();

            candidate.Votes += amount;
            CheckCandidate(engine.Snapshot, state.VoteTo, candidate);
        }
Esempio n. 14
0
        private bool UnregisterCandidate(StoreView snapshot, ECPoint pubkey)
        {
            StorageKey key = CreateStorageKey(Prefix_Candidate, pubkey);

            if (snapshot.Storages.TryGet(key) is null)
            {
                return(true);
            }
            StorageItem    item  = snapshot.Storages.GetAndChange(key);
            CandidateState state = item.GetInteroperable <CandidateState>();

            if (state.Votes.IsZero)
            {
                snapshot.Storages.Delete(key);
            }
            else
            {
                state.Registered = false;
            }
            return(true);
        }
Esempio n. 15
0
        private bool Vote(StoreView snapshot, UInt160 account, ECPoint voteTo)
        {
            StorageKey key_account = CreateAccountKey(account);

            if (snapshot.Storages.TryGet(key_account) is null)
            {
                return(false);
            }
            StorageItem     storage_account = snapshot.Storages.GetAndChange(key_account);
            NeoAccountState state_account   = storage_account.GetInteroperable <NeoAccountState>();

            if (state_account.VoteTo != null)
            {
                StorageKey     key = CreateStorageKey(Prefix_Candidate, state_account.VoteTo.ToArray());
                StorageItem    storage_validator = snapshot.Storages.GetAndChange(key);
                CandidateState state_validator   = storage_validator.GetInteroperable <CandidateState>();
                state_validator.Votes -= state_account.Balance;
                if (!state_validator.Registered && state_validator.Votes.IsZero)
                {
                    snapshot.Storages.Delete(key);
                }
            }
            state_account.VoteTo = voteTo;
            if (voteTo != null)
            {
                StorageKey key = CreateStorageKey(Prefix_Candidate, voteTo.ToArray());
                if (snapshot.Storages.TryGet(key) is null)
                {
                    return(false);
                }
                StorageItem    storage_validator = snapshot.Storages.GetAndChange(key);
                CandidateState state_validator   = storage_validator.GetInteroperable <CandidateState>();
                if (!state_validator.Registered)
                {
                    return(false);
                }
                state_validator.Votes += state_account.Balance;
            }
            return(true);
        }
        internal void Select(HttpContext httpContext, CandidateSet candidateSet)
        {
            IODataFeature    odataFeature     = httpContext.ODataFeature();
            ActionDescriptor actionDescriptor = odataFeature.ActionDescriptor;

            if (actionDescriptor != null)
            {
                int count = candidateSet.Count;
                for (int i = 0; i < count; i++)
                {
                    CandidateState   candidate = candidateSet[i];
                    ActionDescriptor action    = candidate.Endpoint.Metadata.GetMetadata <ActionDescriptor>();

                    // Noted: we simple use the "ReferenceEquals" to compare the action descriptor.
                    // So far, i don't know the risk, i need .NET team help me to verify it?
                    if (object.ReferenceEquals(action, actionDescriptor))
                    {
                        httpContext.SetEndpoint(candidate.Endpoint);
                        httpContext.Request.RouteValues = candidate.Values;
                        return;
                    }
                }
            }
        }
Esempio n. 17
0
        internal override void OnBalanceChanging(ApplicationEngine engine, UInt160 account, NeoAccountState state, BigInteger amount)
        {
            GasDistribution distribution = DistributeGas(engine, account, state);

            if (distribution is not null)
            {
                var list = engine.CurrentContext.GetState <List <GasDistribution> >();
                list.Add(distribution);
            }
            if (amount.IsZero)
            {
                return;
            }
            if (state.VoteTo is null)
            {
                return;
            }
            engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_VotersCount)).Add(amount);
            StorageKey     key       = CreateStorageKey(Prefix_Candidate).Add(state.VoteTo);
            CandidateState candidate = engine.Snapshot.GetAndChange(key).GetInteroperable <CandidateState>();

            candidate.Votes += amount;
            CheckCandidate(engine.Snapshot, state.VoteTo, candidate);
        }
        /// <summary>
        /// Applies the policy to the CandidateSet.
        /// </summary>
        /// <param name="httpContext">The context associated with the current request.</param>
        /// <param name="candidates">The CandidateSet.</param>
        /// <returns>The task.</returns>
        public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
        {
            if (httpContext == null)
            {
                throw Error.ArgumentNull(nameof(httpContext));
            }

            IODataFeature odataFeature = httpContext.ODataFeature();

            if (odataFeature.Path != null)
            {
                // If we have the OData path setting, it means there's some Policy working.
                // Let's skip this default OData matcher policy.
                return(Task.CompletedTask);
            }

            // The goal of this method is to perform the final matching:
            // Map between route values matched by the template and the ones we want to expose to the action for binding.
            // (tweaking the route values is fine here)
            // Invalidating the candidate if the key/function values are not valid/missing.
            // Perform overload resolution for functions by looking at the candidates and their metadata.
            for (var i = 0; i < candidates.Count; i++)
            {
                ref CandidateState candidate = ref candidates[i];
                if (!candidates.IsValidCandidate(i))
                {
                    continue;
                }

                IODataRoutingMetadata metadata = candidate.Endpoint.Metadata.OfType <IODataRoutingMetadata>().FirstOrDefault();
                if (metadata == null)
                {
                    continue;
                }

                if (odataFeature.Path != null)
                {
                    // If it's odata endpoint, and we have a path set, let other odata endpoints invalid.
                    candidates.SetValidity(i, false);
                    continue;
                }

                ODataTemplateTranslateContext translatorContext =
                    new ODataTemplateTranslateContext(httpContext, candidate.Endpoint, candidate.Values, metadata.Model);

                ODataPath odataPath = _translator.Translate(metadata.Template, translatorContext);
                if (odataPath != null)
                {
                    odataFeature.RoutePrefix = metadata.Prefix;
                    odataFeature.Model       = metadata.Model;
                    odataFeature.Path        = odataPath;

                    MergeRouteValues(translatorContext.UpdatedValues, candidate.Values);

                    // Shall we break the remaining candidates?
                    // So far the answer is no. Because we can use this matcher to obsolete the unmatched endpoint.
                    // break;
                }
                else
                {
                    candidates.SetValidity(i, false);
                }
            }
Esempio n. 19
0
 public void addVotesForCandidates(CandidateState cs)
 {
     Votes.Add(cs.ID, cs);
     TotalNumberOfVotes += cs.numberOfVotes;
 }
Esempio n. 20
0
 internal static bool IsValidCandidate(ref CandidateState candidate)
 {
     return(candidate.Score >= 0);
 }
        public void Check_UnregisterCandidate()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot();

            var keyCount = snapshot.Storages.GetChangeSet().Count();
            var point    = Blockchain.StandbyValidators[0].EncodePoint(true);

            //without register
            var ret = Check_UnregisterCandidate(snapshot, point);

            ret.State.Should().BeTrue();
            ret.Result.Should().BeTrue();
            snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount);

            //register and then unregister
            ret = Check_RegisterValidator(snapshot, point);
            StorageItem item = snapshot.Storages.GetAndChange(CreateStorageKey(33, point));

            ret.State.Should().BeTrue();
            ret.Result.Should().BeTrue();

            var members = NativeContract.NEO.GetCandidates(snapshot);

            Assert.AreEqual(1, members.Length);
            snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount + 1);
            StorageKey key = CreateStorageKey(33, point);

            snapshot.Storages.TryGet(key).Should().NotBeNull();

            ret = Check_UnregisterCandidate(snapshot, point);
            ret.State.Should().BeTrue();
            ret.Result.Should().BeTrue();
            snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount);

            members = NativeContract.NEO.GetCandidates(snapshot);
            Assert.AreEqual(0, members.Length);
            snapshot.Storages.TryGet(key).Should().BeNull();

            //register with votes, then unregister
            ret = Check_RegisterValidator(snapshot, point);
            var G_Account = Contract.CreateSignatureContract(ECCurve.Secp256r1.G).ScriptHash.ToArray();

            snapshot.Storages.Add(CreateStorageKey(20, G_Account), new StorageItem(new NeoAccountState()));
            var accountState = snapshot.Storages.TryGet(CreateStorageKey(20, G_Account)).GetInteroperable <NeoAccountState>();

            accountState.Balance = 100;
            Check_Vote(snapshot, G_Account, Blockchain.StandbyValidators[0].ToArray(), true);
            ret = Check_UnregisterCandidate(snapshot, point);
            ret.State.Should().BeTrue();
            ret.Result.Should().BeTrue();
            snapshot.Storages.TryGet(key).Should().NotBeNull();
            StorageItem    pointItem  = snapshot.Storages.TryGet(key);
            CandidateState pointState = pointItem.GetInteroperable <CandidateState>();

            pointState.Registered.Should().BeFalse();
            pointState.Votes.Should().Be(100);

            //vote fail
            ret = Check_Vote(snapshot, G_Account, Blockchain.StandbyValidators[0].ToArray(), true);
            ret.State.Should().BeTrue();
            ret.Result.Should().BeFalse();
            accountState.VoteTo.Should().Be(Blockchain.StandbyValidators[0]);
        }
Esempio n. 22
0
        public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            IODataFeature odataFeature = httpContext.ODataFeature();

            if (odataFeature.Path != null)
            {
                // If we have the OData path setting, it means there's some Policy working.
                // Let's skip this default OData matcher policy.
                return(Task.CompletedTask);
            }

            for (var i = 0; i < candidates.Count; i++)
            {
                ref CandidateState candidate = ref candidates[i];
                if (!candidates.IsValidCandidate(i))
                {
                    continue;
                }

                IODataRoutingMetadata metadata = candidate.Endpoint.Metadata.OfType <IODataRoutingMetadata>().FirstOrDefault();
                if (metadata == null)
                {
                    continue;
                }

                // Get api-version query from HttpRequest?
                QueryStringApiVersionReader reader = new QueryStringApiVersionReader("api-version");
                string apiVersionStr = reader.Read(httpContext.Request);
                if (apiVersionStr == null)
                {
                    candidates.SetValidity(i, false);
                    continue;
                }
                ApiVersion apiVersion = ApiVersion.Parse(apiVersionStr);

                IEdmModel model = GetEdmModel(apiVersion);
                if (model == null)
                {
                    candidates.SetValidity(i, false);
                    continue;
                }

                if (!IsApiVersionMatch(candidate.Endpoint.Metadata, apiVersion))
                {
                    candidates.SetValidity(i, false);
                    continue;
                }

                ODataTemplateTranslateContext translatorContext
                    = new ODataTemplateTranslateContext(httpContext, candidate.Endpoint, candidate.Values, model);

                try
                {
                    ODataPath odataPath = _translator.Translate(metadata.Template, translatorContext);
                    if (odataPath != null)
                    {
                        odataFeature.RoutePrefix = metadata.Prefix;
                        odataFeature.Model       = model;
                        odataFeature.Path        = odataPath;

                        ODataOptions options = new ODataOptions();
                        UpdateQuerySetting(options);
                        options.AddRouteComponents(model);
                        odataFeature.Services = options.GetRouteServices(string.Empty);

                        MergeRouteValues(translatorContext.UpdatedValues, candidate.Values);
                    }
                    else
                    {
                        candidates.SetValidity(i, false);
                    }
                }
                catch
                {
                    candidates.SetValidity(i, false);
                }
            }