Пример #1
0
        /// <summary>
        ///     Helper method. Convert a value to a key value
        /// </summary>
        /// <param name="value"> </param>
        /// <param name="info"> </param>
        /// <returns> </returns>
        public static KeyValue ValueToKeyValue(object value, KeyInfo info)
        {
            //check if directly assignable to int
            if (info.KeyDataType == KeyDataType.IntKey)
            {
                // default behavior for nullable values (works fine for dates)
                if (value == null)
                {
                    return(new KeyValue(0, info));
                }

                var propertyType = value.GetType();

                //integer types
                if (propertyType == typeof(int) || propertyType == typeof(short) || propertyType == typeof(long) ||
                    propertyType == typeof(byte) || propertyType == typeof(char) || propertyType == typeof(bool) ||
                    propertyType == typeof(IntPtr))
                {
                    var longVal = Convert.ToInt64(value);
                    return(new KeyValue(longVal, info));
                }

                if (propertyType.IsEnum)
                {
                    var longVal = Convert.ToInt64(value);
                    return(new KeyValue(longVal, info));
                }


                //other types. Can be used as keys if a key converter is provided
                var converter = KeyConverters.GetIfAvailable(propertyType);
                if (converter != null)
                {
                    //prefer conversion to long if available
                    if (converter.CanConvertToLong)
                    {
                        return(new KeyValue(converter.GetAsLong(value), info));
                    }

                    if (converter.CanConvertToString)
                    {
                        return(new KeyValue(converter.GetAsString(value), info));
                    }

                    Dbg.CheckThat(false, "trying to use an invalid key converter");
                }
            }
            else
            {
                if (value != null)
                {
                    return(new KeyValue(value.ToString(), info));
                }
                return(new KeyValue(null, info));
            }


            throw new InvalidOperationException($"Can not compute key value for object {value}");
        }
        public void ExecuteActions()
        {
            (var addresses, Transaction <DumbAction>[] txs) =
                MakeFixturesForAppendTests();
            var genesis = _blockChain.Genesis;

            Block <DumbAction> block1 = MineNext(
                genesis,
                _policy.GetHashAlgorithm,
                txs,
                miner: _fx.Miner.PublicKey,
                difficulty: _policy.GetNextBlockDifficulty(_blockChain)
                ).Evaluate(_fx.Miner, _blockChain);

            _blockChain.Append(
                block1,
                evaluateActions: false,
                renderBlocks: true,
                renderActions: false
                );

            var minerAddress = genesis.Miner;

            var expectedStates = new Dictionary <Address, IValue>
            {
                { addresses[0], (Text)"foo" },
                { addresses[1], (Text)"bar" },
                { addresses[2], (Text)"baz" },
                { addresses[3], (Text)"qux" },
                { minerAddress, (Integer)2 },
                { MinerReward.RewardRecordAddress, (Text)$"{minerAddress},{minerAddress}" },
            };

            _blockChain.ExecuteActions(block1);
            foreach (KeyValuePair <Address, IValue> pair in expectedStates)
            {
                AssertBencodexEqual(
                    pair.Value,
                    _fx.StateStore.GetStates(
                        block1.StateRootHash,
                        new[] { KeyConverters.ToStateKey(pair.Key) }
                        )[0]
                    );
            }
        }
Пример #3
0
        public TxWithContext Sign(PrivateKey signer, params Arithmetic[] actions)
        {
            Address signerAddress       = signer.ToAddress();
            string  rawStateKey         = KeyConverters.ToStateKey(signerAddress);
            long    nonce               = Chain.GetNextTxNonce(signerAddress);
            Transaction <Arithmetic> tx =
                Transaction <Arithmetic> .Create(nonce, signer, Genesis.Hash, actions);

            BigInteger prevState = Chain.GetState(signerAddress) is Bencodex.Types.Integer i
                ? i.Value
                : 0;
            HashDigest <SHA256> prevStateRootHash = Chain.Tip.StateRootHash;
            ITrie prevTrie = GetTrie(Chain.Tip.Hash);

            (BigInteger, HashDigest <SHA256>)prevPair     = (prevState, prevStateRootHash);
            (BigInteger, HashDigest <SHA256>)stagedStates = Chain.ListStagedTransactions()
                                                            .Where(t => t.Signer.Equals(signerAddress))
                                                            .OrderBy(t => t.Nonce)
                                                            .SelectMany(t => t.Actions)
                                                            .TakeWhile(a => a.Error is null)
                                                            .Aggregate(prevPair, (prev, act) =>
            {
                BigInteger nextState = act.Operator.ToFunc()(prev.Item1, act.Operand);
                var updatedRawStates = ImmutableDictionary <string, IValue> .Empty
                                       .Add(rawStateKey, (Bencodex.Types.Integer)nextState);
                HashDigest <SHA256> nextRootHash =
                    prevTrie.Set(updatedRawStates).Commit().Hash;
                return(nextState, nextRootHash);
            });
            Chain.StageTransaction(tx);
            ImmutableArray <(BigInteger, HashDigest <SHA256>)> expectedDelta = tx.Actions
                                                                               .Take(tx.Actions.TakeWhile(a => a.Error is null).Count() + 1)
                                                                               .Aggregate(
                ImmutableArray.Create(stagedStates),
                (delta, act) =>
            {
                BigInteger nextState =
                    act.Operator.ToFunc()(delta[delta.Length - 1].Item1, act.Operand);
                var updatedRawStates = ImmutableDictionary <string, IValue> .Empty
                                       .Add(rawStateKey, (Bencodex.Types.Integer)nextState);
                HashDigest <SHA256> nextRootHash =
                    prevTrie.Set(updatedRawStates).Commit().Hash;
                return(delta.Add((nextState, nextRootHash)));
            }