diff --git a/distributed/proto/strong-proto.proto b/distributed/proto/strong-proto.proto index 4bb417d..9f6db3a 100644 --- a/distributed/proto/strong-proto.proto +++ b/distributed/proto/strong-proto.proto @@ -108,10 +108,9 @@ message MPTProof { } message SQLLedgerProof { - optional MTProof blk_proof = 1; - optional MTProof txn_proof = 2; - repeated bytes blocks = 3; - optional bytes digest = 4; + repeated bytes blocks = 1; + repeated MTProof txn_proof = 2; + repeated MTProof data_proof = 3; } message Range { diff --git a/distributed/store/common/backend/versionstore.cc b/distributed/store/common/backend/versionstore.cc index 10649c1..5b7e88a 100644 --- a/distributed/store/common/backend/versionstore.cc +++ b/distributed/store/common/backend/versionstore.cc @@ -16,7 +16,7 @@ VersionedKVStore::VersionedKVStore(const string& db_path, int timeout) { qldb_.reset(new ledgebase::qldb::QLDB(db_path)); #endif #ifdef SQLLEDGER - ledgebase::qldb::BPlusConfig::Init(45, 25); + ledgebase::qldb::BPlusConfig::Init(45, 45); sqlledger_.reset(new ledgebase::sqlledger::SQLLedger(timeout, db_path)); #endif } @@ -271,35 +271,40 @@ bool VersionedKVStore::GetProof( #ifdef SQLLEDGER GetDigest(reply); for (auto& entry : keys) { + int level; + + auto block_proof = sqlledger_->getBlockProof(entry.first, + reply->digest().block(), &level); + //ledgebase::sqlledger::BlockProof block_proof; + auto p = reply->add_sproof(); + for (size_t i = 0; i < block_proof.blks.size(); ++i) { + p->add_blocks(block_proof.blks[i]); + } + for (auto& key : entry.second) { nkey++; - auto res = sqlledger_->getProof(key, entry.first); - auto p = reply->add_sproof(); - auto blk_proof = p->mutable_blk_proof(); - auto txn_proof = p->mutable_txn_proof(); - p->set_digest(res.digest); - for (size_t i = 0; i < res.blks.size(); ++i) { - p->add_blocks(res.blks[i]); - } - blk_proof->set_digest(res.blk_proof.digest); - blk_proof->set_value(res.blk_proof.value); - for (size_t i = 0; i < res.blk_proof.proof.size(); ++i) { - blk_proof->add_proof(res.blk_proof.proof[i]); - blk_proof->add_pos(res.blk_proof.pos[i]); - } + auto res = sqlledger_->getDetailProof(key, entry.first, level); + auto txn_proof = p->add_txn_proof(); + auto data_proof = p->add_data_proof(); txn_proof->set_digest(res.txn_proof.digest); txn_proof->set_value(res.txn_proof.value); for (size_t i = 0; i < res.txn_proof.proof.size(); ++i) { txn_proof->add_proof(res.txn_proof.proof[i]); txn_proof->add_pos(res.txn_proof.pos[i]); } + data_proof->set_digest(res.data_proof.digest); + data_proof->set_value(res.data_proof.value); + for (size_t i = 0; i < res.data_proof.proof.size(); ++i) { + data_proof->add_proof(res.data_proof.proof[i]); + data_proof->add_pos(res.data_proof.pos[i]); + } } } #endif gettimeofday(&t1, NULL); auto lat = (t1.tv_sec - t0.tv_sec)*1000000 + t1.tv_usec - t0.tv_usec; - //std::cout << "getproof " << lat << " " << nkey << std::endl; + std::cout << "getproof " << lat << " " << nkey << std::endl; return true; } diff --git a/distributed/store/strongstore/shardclient.cc b/distributed/store/strongstore/shardclient.cc index 0812e31..10a7436 100644 --- a/distributed/store/strongstore/shardclient.cc +++ b/distributed/store/strongstore/shardclient.cc @@ -388,33 +388,43 @@ ShardClient::GetProofCallback(size_t uid, #endif #ifdef SQLLEDGER res = VerifyStatus::PASS; - std::string ledger = "test"; - auto digest = ledgebase::Hash::FromBase32(reply.digest().hash()); + for (int i = 0; i < reply.sproof_size(); ++i) { - ledgebase::sqlledger::SQLLedgerProof prover; auto curr_proof = reply.sproof(i); - prover.digest = curr_proof.digest(); + + ledgebase::sqlledger::BlockProof blk_prover; for (int j = 0; j < curr_proof.blocks_size(); ++j) { - prover.blks.emplace_back(curr_proof.blocks(j)); + blk_prover.blks.emplace_back(curr_proof.blocks(j)); } - auto blk_proof = curr_proof.blk_proof(); - prover.blk_proof.digest = blk_proof.digest(); - prover.blk_proof.value = blk_proof.value(); - for (int j = 0; j < blk_proof.proof_size(); ++j) { - prover.blk_proof.proof.emplace_back(blk_proof.proof(j)); - prover.blk_proof.pos.emplace_back(blk_proof.pos(j)); + std::string txn_hash; + if (!blk_prover.Verify(reply.digest().hash(), &txn_hash)) { + res = VerifyStatus::FAILED; + break; } - auto txn_proof = curr_proof.txn_proof(); - prover.txn_proof.digest = txn_proof.digest(); - prover.txn_proof.value = txn_proof.value(); - for (int j = 0; j < txn_proof.proof_size(); ++j) { - prover.txn_proof.proof.emplace_back(txn_proof.proof(j)); - prover.txn_proof.pos.emplace_back(txn_proof.pos(j)); - } - - if (!prover.Verify()) { - res = VerifyStatus::FAILED; + for (int j = 0; j < curr_proof.txn_proof_size(); ++j) { + ledgebase::sqlledger::DetailProof dtl_prover; + + auto txn_proof = curr_proof.txn_proof(j); + dtl_prover.txn_proof.digest = txn_proof.digest(); + dtl_prover.txn_proof.value = txn_proof.value(); + for (int k = 0; k < txn_proof.proof_size(); ++k) { + dtl_prover.txn_proof.proof.emplace_back(txn_proof.proof(k)); + dtl_prover.txn_proof.pos.emplace_back(txn_proof.pos(k)); + } + + auto data_proof = curr_proof.data_proof(j); + dtl_prover.data_proof.digest = data_proof.digest(); + dtl_prover.data_proof.value = data_proof.value(); + for (int k = 0; k < data_proof.proof_size(); ++k) { + dtl_prover.data_proof.proof.emplace_back(data_proof.proof(k)); + dtl_prover.data_proof.pos.emplace_back(data_proof.pos(k)); + } + + if (!dtl_prover.Verify(txn_hash)) { + res = VerifyStatus::FAILED; + break; + } } } #endif diff --git a/ledger/sqlledger/sqlledger.cc b/ledger/sqlledger/sqlledger.cc index b07bd49..563aa14 100644 --- a/ledger/sqlledger/sqlledger.cc +++ b/ledger/sqlledger/sqlledger.cc @@ -179,31 +179,24 @@ std::vector SQLLedger::GetHistory(const std::string& key, return retval; } -SQLLedgerProof SQLLedger::getProof(const std::string& key, - const uint64_t block_addr) { - SQLLedgerProof proof; - - // get digest - std::string value; - db_.Get("digest", &value); - auto digest = Utils::splitBy(value, '|'); - proof.digest = digest[0]; - int tip = std::stoul(digest[1]); - - // get block - int level; - std::string blkroot; - //std::cout << "blocks " << (tip - block_addr) << std::endl; +BlockProof SQLLedger::getBlockProof(const uint64_t block_addr, + const uint64_t tip, int* level) { + BlockProof proof; for (size_t i = block_addr; i <= tip; ++i) { std::string block; db_.Get("blk" + std::to_string(i), &block); - proof.blks.emplace_back(block); + proof.blks.push_back(block); if (i == block_addr) { auto blockinfo = Utils::splitBy(block, '|'); - level = std::stoul(blockinfo[2]); - blkroot = blockinfo[1]; + *level = std::stoul(blockinfo[2]); } } + return proof; +} + +DetailProof SQLLedger::getDetailProof(const std::string& key, + const uint64_t block_addr, int level) { + DetailProof proof; std::string doc = GetDataAtBlock(key, block_addr); auto docitems = Utils::splitBy(doc, '|'); @@ -217,45 +210,44 @@ SQLLedgerProof SQLLedger::getProof(const std::string& key, auto txnroot = txnitems[3]; auto txnrootlevel = std::stoul(txnitems[4]); - proof.blk_proof = mt_->GetProof("blk" + std::to_string(block_addr), + proof.txn_proof = mt_->GetProof("blk" + std::to_string(block_addr), level, txnseq); - proof.blk_proof.value = txn; - proof.txn_proof = mt_->GetProof("txn" + txnid, txnrootlevel, docseq); - proof.txn_proof.value = doc; + proof.txn_proof.value = txn; + proof.data_proof = mt_->GetProof("txn" + txnid, txnrootlevel, docseq); + proof.data_proof.value = doc; //std::cout << "height " << level + txnrootlevel << std::endl; return proof; } -bool SQLLedgerProof::Verify() { - std::string target = digest; - std::string blk_mt_root; - int blocks = 0; +bool BlockProof::Verify(const std::string& hash, std::string* blk_mt_root) { + std::string target = hash; for (auto it = blks.rbegin(); it != blks.rend(); ++it) { if (Hash::ComputeFrom(*it).ToBase32().compare(target) != 0) { - //std::cout << "verification failed at block" << std::endl; + return false; } auto block_info = Utils::splitBy(*it, '|'); target = block_info[0]; - blk_mt_root = block_info[1]; - blocks++; + *blk_mt_root = block_info[1]; } - //std::cout << "block " << blks.size() << " " << blocks << std::endl; + return true; +} - if (blk_mt_root.compare(blk_proof.digest) != 0) { - //std::cout << "verification failed at txn mt root" << std::endl; +bool DetailProof::Verify(const std::string& hash) { + if (hash.compare(txn_proof.digest) != 0) { + return false; } - //std::cout << "txn "; - if (!blk_proof.Verify()) { - //std::cout << "verification failed at txn tree" << std::endl; + + if (!txn_proof.Verify()) { + return false; } - auto txn_info = Utils::splitBy(blk_proof.value, '|'); + auto txn_info = Utils::splitBy(txn_proof.value, '|'); std::string txn_mt_root = txn_info[3]; - if (txn_mt_root != txn_proof.digest) { - //std::cout << "verification failed at row mt root" << std::endl; + if (txn_mt_root.compare(txn_proof.digest) != 0) { + return false; } - //std::cout << "row "; - return txn_proof.Verify(); + + return data_proof.Verify(); } Auditor SQLLedger::getAudit(const uint64_t& seq) { diff --git a/ledger/sqlledger/sqlledger.h b/ledger/sqlledger/sqlledger.h index 01c39c9..998309c 100644 --- a/ledger/sqlledger/sqlledger.h +++ b/ledger/sqlledger/sqlledger.h @@ -12,13 +12,17 @@ namespace ledgebase { namespace sqlledger { -struct SQLLedgerProof { - Proof txn_proof; - Proof blk_proof; +struct BlockProof { std::vector blks; - std::string digest; - bool Verify(); + bool Verify(const std::string& hash, std::string* mt_blk_root); +}; + +struct DetailProof { + Proof txn_proof; + Proof data_proof; + + bool Verify(const std::string& Hash); }; struct Auditor { @@ -51,8 +55,12 @@ class SQLLedger { const std::string& to); std::vector GetHistory(const std::string& key, size_t n); - - SQLLedgerProof getProof(const std::string& key, const uint64_t block_addr); + + BlockProof getBlockProof(const uint64_t block_addr, const uint64_t tip, + int* level); + + DetailProof getDetailProof(const std::string& key, const uint64_t block_addr, + int level); Auditor getAudit(const uint64_t& seq);