Example #1
0
        /*
         * protected bool Validate(SignedTransaction signed, MultiSignature declaration)
         * {
         *  MultiSignatureAddress multi;
         *  if (MultiSignatureManager.TryGetAddress(declaration.Address, out multi))
         *      return false;
         *  return true;
         * }
         */

        // validates the inputs are spending money that exists
        public bool ValidateBalance(ILedgerState state, IEnumerable <TxInput> inputs)
        {
            // we cannot have duplicate (account + currency). In fact we can since we use fees in input
            var amounts = new Dictionary <AddressCurrency, Amount>();

            foreach (var input in inputs)
            {
                var currency = input.Currency;
                var address  = input.Address;

                // no need to check we have enough balance if we are issuer
                if (LiveService.IssuerManager.IsIssuer(currency, address))
                {
                    continue;
                }

                if (!state.TryGetAccount(address, out var account))
                {
                    return(false);
                }

                // TODO looks not good
                var key    = new AddressCurrency(address, currency);
                var amount = amounts[key] = amounts.GetOrCreate(key, () => 0) + input.Amount;
                if (account.GetBalance(currency) < amount)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
 public override bool TryGetRequiredValidations(ILedgerState state, Address address, List <TxDeclaration> declarations, out TransactionRequiredValidation required)
 {
     switch (address.Type)
     {
     case AddressType.ECDSA:
         required = new AddressRequiredSignature(address);
         return(true);
     }
     required = null;
     return(false);
 }
        public static bool TryGetDeclaration <T>(this ILedgerState state, Address address, out T declaration) where T : TxAddressDeclaration
        {
            // if the account does exists in the state
            if (!state.TryGetAccount(address, out var account))
            {
                declaration = null;
                return(false);
            }

            // check the account has been declared
            declaration = account.GetDeclaration <T>();
            return(declaration != null);
        }
Example #4
0
        public static bool TryGetRequiredValidations(ILedgerState state, TransactionRequiredValidationFactory factory, Transaction transaction, out List <TransactionRequiredValidation> validations)
        {
            var dictionary = new Dictionary <Address, TransactionRequiredValidation>();

            foreach (var input in transaction.GetInputs())
            {
                var address = input.Address;
                if (!dictionary.ContainsKey(address))
                {
                    TransactionRequiredValidation validation;
                    if (!factory.TryGetRequiredValidations(state, input.Address, transaction.Declarations, out validation))
                    {
                        validations = new List <TransactionRequiredValidation>();
                        return(false);
                    }
                    dictionary.Add(address, validation);
                }
            }
            validations = dictionary.Values.ToList();
            return(true);
        }
Example #5
0
        private static bool TryGetRequiredSignatures(ILedgerState state, TransactionRequiredValidationFactory factory, Transaction transaction, out List <TransactionRequiredValidation> list)
        {
            var validations = new Dictionary <string, TransactionRequiredValidation>();

            foreach (var input in transaction.GetInputs())
            {
                if (!validations.ContainsKey(input.Address.Encoded))
                {
                    TransactionRequiredValidation required;
                    if (!factory.TryGetRequiredValidations(state, input.Address, transaction.Declarations, out required))
                    {
                        list = null;
                        return(false);
                    }
                    validations.Add(input.Address.Encoded, required);
                }
            }

            list = validations.Values.ToList();
            return(true);
        }
Example #6
0
        public static bool CheckSignatures(this SignedTransaction transaction, TransactionRequiredValidationFactory factory, Network network, long timestamp, ILedgerState state = null)
        {
            var hash = transaction.Hash;

            // get required signatures
            List <TransactionRequiredValidation> requireds;

            if (!TryGetRequiredValidations(state, factory, transaction.Transaction, out requireds))
            {
                return(false);
            }

            var signatures = transaction.Signatures.Select(signature => new SignatureRequired(signature)).ToList();

            // check required signatures and declarations are set
            foreach (var required in requireds)
            {
                if (!required.IsValid(signatures, transaction.Transaction, timestamp))
                {
                    return(false);
                }
            }

            // TODO we dont accept transactions with useless declarations

            // we try to optimize by checking signatures only at the end
            // verify signatures
            foreach (var signature in signatures)
            {
                // we dont accept transactions with useless signatures
                if (!signature.Required || !signature.Verify(hash, network))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #7
0
 public abstract bool TryGetRequiredValidations(ILedgerState state, Address address, List <TxDeclaration> declarations, out TransactionRequiredValidation required);
Example #8
0
        // returns false if over the limit
        private bool TryGetRequiredValidationsRecursive(ILedgerState state, Address address, List <TxDeclaration> declarations, out TransactionRequiredValidation required, int depth)
        {
            // we check max depth to limit computation
            if (depth >= MAX_DEPTH)
            {
                required = null;
                return(false);
            }

            // try get account
            switch (address.Type)
            {
            case AddressType.ECDSA:
                required = new AddressRequiredSignature(address);
                break;

            case AddressType.MultiSignatureECDSA:
                if (!state.TryGetDeclaration <MultiSignature>(address, out var multi))
                {
                    if (!TryGetMultiSigFromDeclarations(declarations, address, out multi))
                    {
                        required = NotDeclaredRequiredValidation.Instance;
                        break;
                    }
                }

                var list = new List <TransactionRequiredValidation>();
                foreach (var signer in multi.Signers)
                {
                    if (!TryGetRequiredValidationsRecursive(state, signer, declarations, out var required2, depth + 1))
                    {
                        required = null;
                        return(false);
                    }
                    list.Add(required2);
                }

                required = new MultiAddressRequiredSignature(multi, list);
                break;

            case AddressType.HashLock:
                if (!state.TryGetDeclaration <HashLock>(address, out var hashlock))
                {
                    if (!TryGetHashLockFromDeclarations(declarations, address, out hashlock))
                    {
                        required = NotDeclaredRequiredValidation.Instance;
                        break;
                    }
                }
                required = new HashLockRequiredSignature(hashlock);
                break;

            case AddressType.TimeLock:
                if (!state.TryGetDeclaration <TimeLock>(address, out var timelock))
                {
                    if (!TryGetTimeLockFromDeclarations(declarations, address, out timelock))
                    {
                        required = NotDeclaredRequiredValidation.Instance;
                        break;
                    }
                }

                required = new TimeLockRequiredSignature(timelock);
                //TODO
                break;

            case AddressType.VendingMachine:
                if (!state.TryGetDeclaration <VendingMachine>(address, out var machine))
                {
                    if (!TryGetVendingMachineFromDeclarations(declarations, address, out machine))
                    {
                        required = NotDeclaredRequiredValidation.Instance;
                        break;
                    }
                }

                required = new VendingMachineRequiredSignature(machine);
                //TODO
                break;

            default:
                required = null;
                return(false);
            }
            return(true);
        }
Example #9
0
 public override bool TryGetRequiredValidations(ILedgerState state, Address address, List <TxDeclaration> declarations, out TransactionRequiredValidation required)
 {
     return(TryGetRequiredValidationsRecursive(state, address, declarations, out required, 0));
 }