diff --git a/shared_model/interfaces/iroha_internal/transaction_sequence.cpp b/shared_model/interfaces/iroha_internal/transaction_sequence.cpp index 2f21609c48..04aaf8f682 100644 --- a/shared_model/interfaces/iroha_internal/transaction_sequence.cpp +++ b/shared_model/interfaces/iroha_internal/transaction_sequence.cpp @@ -4,14 +4,18 @@ */ #include "interfaces/iroha_internal/transaction_sequence.hpp" +#include "validators/field_validator.hpp" +#include "validators/transaction_validator.hpp" namespace shared_model { namespace interface { + template iroha::expected::Result TransactionSequence::createTransactionSequence( const types::TransactionsForwardCollectionType &transactions, - const validation::TransactionsCollectionValidator &validator) { + const validation::TransactionsCollectionValidator + &validator) { auto answer = validator.validate(transactions); if (answer.hasErrors()) { return iroha::expected::makeError(answer.reason()); @@ -19,6 +23,15 @@ namespace shared_model { return iroha::expected::makeValue(TransactionSequence(transactions)); } + template iroha::expected::Result + TransactionSequence::createTransactionSequence( + const types::TransactionsForwardCollectionType &transactions, + const validation::TransactionsCollectionValidator< + validation::TransactionValidator< + validation::FieldValidator, + validation::CommandValidatorVisitor< + validation::FieldValidator>>> &validator); + types::TransactionsForwardCollectionType TransactionSequence::transactions() { return transactions_; diff --git a/shared_model/interfaces/iroha_internal/transaction_sequence.hpp b/shared_model/interfaces/iroha_internal/transaction_sequence.hpp index 9c5a8fe0ed..43e3aa7f56 100644 --- a/shared_model/interfaces/iroha_internal/transaction_sequence.hpp +++ b/shared_model/interfaces/iroha_internal/transaction_sequence.hpp @@ -28,10 +28,12 @@ namespace shared_model { * @return Result containing transaction sequence if validation successful * and string message containing error otherwise */ + template static iroha::expected::Result createTransactionSequence( const types::TransactionsForwardCollectionType &transactions, - const validation::TransactionsCollectionValidator &validator); + const validation::TransactionsCollectionValidator< + TransactionValidator> &validator); /** * Get transactions collection diff --git a/shared_model/validators/block_validator.hpp b/shared_model/validators/block_validator.hpp index 31b1b95c8c..975b762b02 100644 --- a/shared_model/validators/block_validator.hpp +++ b/shared_model/validators/block_validator.hpp @@ -33,10 +33,14 @@ namespace shared_model { /** * Class that validates block */ - template - class BlockValidator : public ContainerValidator { + template + class BlockValidator + : public ContainerValidator { public: /** * Applies validation on block @@ -44,10 +48,11 @@ namespace shared_model { * @return Answer containing found error if any */ Answer validate(const interface::Block &block) const { - return ContainerValidator::validate(block, - "Block"); + return ContainerValidator< + interface::Block, + FieldValidator, + TransactionValidator, + TransactionsCollectionValidator>::validate(block, "Block"); } }; diff --git a/shared_model/validators/container_validator.hpp b/shared_model/validators/container_validator.hpp index afec679e87..79a7b5ecde 100644 --- a/shared_model/validators/container_validator.hpp +++ b/shared_model/validators/container_validator.hpp @@ -34,7 +34,8 @@ namespace shared_model { */ template + typename TransactionValidator, + typename TransactionsCollectionValidator> class ContainerValidator { protected: void validateTransaction( @@ -50,18 +51,25 @@ namespace shared_model { ReasonsGroupType &reason, const interface::types::TransactionsCollectionType &transactions) const { - for (const auto &tx : transactions) { - validateTransaction(reason, tx); + auto answer = transactions_collection_validator_.validate(transactions); + if (answer.hasErrors()) { + reason.second.push_back(answer.reason()); } } public: - ContainerValidator( + explicit ContainerValidator( + const TransactionsCollectionValidator + &transactions_collection_validator = + TransactionsCollectionValidator(), const TransactionValidator &transaction_validator = TransactionValidator(), const FieldValidator &field_validator = FieldValidator()) - : transaction_validator_(transaction_validator), + : transactions_collection_validator_( + transactions_collection_validator), + transaction_validator_(transaction_validator), field_validator_(field_validator) {} + Answer validate(const Iface &cont, std::string reason_name) const { Answer answer; ReasonsGroupType reason; @@ -76,6 +84,7 @@ namespace shared_model { } private: + TransactionsCollectionValidator transactions_collection_validator_; TransactionValidator transaction_validator_; protected: diff --git a/shared_model/validators/default_validator.hpp b/shared_model/validators/default_validator.hpp index 072d2043ad..a1055100a8 100644 --- a/shared_model/validators/default_validator.hpp +++ b/shared_model/validators/default_validator.hpp @@ -27,20 +27,29 @@ #include "validators/query_validator.hpp" #include "validators/signable_validator.hpp" #include "validators/transaction_validator.hpp" +#include "validators/transactions_collection/signed_transactions_collection_validator.hpp" +#include "validators/transactions_collection/unsigned_transactions_collection_validator.hpp" namespace shared_model { namespace validation { using DefaultTransactionValidator = TransactionValidator>; + using DefaultQueryValidator = QueryValidator>; + using DefaultBlocksQueryValidator = BlocksQueryValidator; - using DefaultProposalValidator = - ProposalValidator; - using DefaultBlockValidator = - BlockValidator; + using DefaultProposalValidator = ProposalValidator< + FieldValidator, + DefaultTransactionValidator, + UnsignedTransactionsCollectionValidator>; + + using DefaultBlockValidator = BlockValidator< + FieldValidator, + DefaultTransactionValidator, + SignedTransactionsCollectionValidator>; using DefaultEmptyBlockValidator = EmptyBlockValidator; @@ -57,11 +66,6 @@ namespace shared_model { const interface::Query &, FieldValidator>; - using DefaultSignableProposalValidator = - SignableModelValidator; - using DefaultSignableBlockValidator = SignableModelValidator - class ProposalValidator : public ContainerValidator { + template + class ProposalValidator + : public ContainerValidator { public: /** * Applies validation on proposal @@ -44,10 +48,11 @@ namespace shared_model { * @return Answer containing found error if any */ Answer validate(const interface::Proposal &prop) const { - return ContainerValidator::validate(prop, - "Proposal"); + return ContainerValidator< + interface::Proposal, + FieldValidator, + TransactionValidator, + TransactionsCollectionValidator>::validate(prop, "Proposal"); } }; diff --git a/shared_model/validators/transactions_collection/signed_transactions_collection_validator.cpp b/shared_model/validators/transactions_collection/signed_transactions_collection_validator.cpp index c23266de92..528858d7a3 100644 --- a/shared_model/validators/transactions_collection/signed_transactions_collection_validator.cpp +++ b/shared_model/validators/transactions_collection/signed_transactions_collection_validator.cpp @@ -5,14 +5,44 @@ #include "validators/transactions_collection/signed_transactions_collection_validator.hpp" +#include +#include "validators/field_validator.hpp" +#include "validators/transaction_validator.hpp" + namespace shared_model { namespace validation { - Answer SignedTransactionsCollectionValidator::validate( + template + Answer + SignedTransactionsCollectionValidator::validate( const interface::types::TransactionsForwardCollectionType &transactions) const { - return Answer(); + ReasonsGroupType reason; + reason.first = "Transaction list"; + for (const auto &tx : transactions) { + auto answer = + SignedTransactionsCollectionValidator::transaction_validator_ + .validate(tx); + if (answer.hasErrors()) { + auto message = + (boost::format("Tx %s : %s") % tx.hash().hex() % answer.reason()) + .str(); + reason.second.push_back(message); + } + } + + Answer res; + if (not reason.second.empty()) { + res.addReason(std::move(reason)); + } + return res; } + template Answer SignedTransactionsCollectionValidator< + TransactionValidator>>:: + validate(const interface::types::TransactionsForwardCollectionType + &transactions) const; + } // namespace validation } // namespace shared_model diff --git a/shared_model/validators/transactions_collection/signed_transactions_collection_validator.hpp b/shared_model/validators/transactions_collection/signed_transactions_collection_validator.hpp index 882e8b3009..d5853b3c50 100644 --- a/shared_model/validators/transactions_collection/signed_transactions_collection_validator.hpp +++ b/shared_model/validators/transactions_collection/signed_transactions_collection_validator.hpp @@ -16,9 +16,12 @@ namespace shared_model { * transaction from the collection to be unsigned. Batch logic should be * checked */ + template class SignedTransactionsCollectionValidator - : public TransactionsCollectionValidator { + : public TransactionsCollectionValidator { public: + using TransactionsCollectionValidator< + TransactionValidator>::TransactionsCollectionValidator; Answer validate(const interface::types::TransactionsForwardCollectionType &transactions) const override; }; diff --git a/shared_model/validators/transactions_collection/transactions_collection_validator.hpp b/shared_model/validators/transactions_collection/transactions_collection_validator.hpp index 3255295720..2a530d7257 100644 --- a/shared_model/validators/transactions_collection/transactions_collection_validator.hpp +++ b/shared_model/validators/transactions_collection/transactions_collection_validator.hpp @@ -16,8 +16,17 @@ namespace shared_model { * Validator of transaction's collection, this is not fair implementation * now, it always returns empty answer */ + template class TransactionsCollectionValidator { + protected: + TransactionValidator transaction_validator_; + public: + TransactionsCollectionValidator( + const TransactionValidator &transactions_validator = + TransactionValidator()) + : transaction_validator_(transactions_validator) {} + /** * Validates collection of transactions * @param transactions collection of transactions diff --git a/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.cpp b/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.cpp index af8bdf9715..c68d194e3f 100644 --- a/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.cpp +++ b/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.cpp @@ -5,14 +5,44 @@ #include "validators/transactions_collection/unsigned_transactions_collection_validator.hpp" +#include +#include "validators/field_validator.hpp" +#include "validators/transaction_validator.hpp" + namespace shared_model { namespace validation { - Answer UnsignedTransactionsCollectionValidator::validate( + template + Answer + UnsignedTransactionsCollectionValidator::validate( const interface::types::TransactionsForwardCollectionType &transactions) const { - return Answer(); + ReasonsGroupType reason; + reason.first = "Transaction list"; + for (const auto &tx : transactions) { + auto answer = + UnsignedTransactionsCollectionValidator::transaction_validator_ + .validate(tx); + if (answer.hasErrors()) { + auto message = + (boost::format("Tx %s : %s") % tx.hash().hex() % answer.reason()) + .str(); + reason.second.push_back(message); + } + } + + Answer res; + if (not reason.second.empty()) { + res.addReason(std::move(reason)); + } + return res; } + template Answer UnsignedTransactionsCollectionValidator< + TransactionValidator>>:: + validate(const interface::types::TransactionsForwardCollectionType + &transactions) const; + } // namespace validation } // namespace shared_model diff --git a/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.hpp b/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.hpp index 5afdbbcf97..6513dfd76f 100644 --- a/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.hpp +++ b/shared_model/validators/transactions_collection/unsigned_transactions_collection_validator.hpp @@ -15,9 +15,12 @@ namespace shared_model { * Unsigned transactions collection validator allows to some transaction * from the collection to be unsigned. Batch logic should be checked */ + template class UnsignedTransactionsCollectionValidator - : public TransactionsCollectionValidator { + : public TransactionsCollectionValidator { public: + using TransactionsCollectionValidator< + TransactionValidator>::TransactionsCollectionValidator; Answer validate(const interface::types::TransactionsForwardCollectionType &transactions) const override; };