mirror of
				https://git.wownero.com/wownero/wownero.git
				synced 2024-08-15 01:03:23 +00:00 
			
		
		
		
	Merge pull request #8676
29208a3 Cache successful erRctNonSemanticsSimple calls (SChernykh)
			
			
This commit is contained in:
		
						commit
						c48f572e46
					
				
					 4 changed files with 104 additions and 1 deletions
				
			
		
							
								
								
									
										65
									
								
								src/common/data_cache.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/common/data_cache.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
// Copyright (c) 2014-2022, The Monero Project
 | 
			
		||||
// 
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
// 
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without modification, are
 | 
			
		||||
// permitted provided that the following conditions are met:
 | 
			
		||||
// 
 | 
			
		||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
			
		||||
//    conditions and the following disclaimer.
 | 
			
		||||
// 
 | 
			
		||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
			
		||||
//    of conditions and the following disclaimer in the documentation and/or other
 | 
			
		||||
//    materials provided with the distribution.
 | 
			
		||||
// 
 | 
			
		||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
 | 
			
		||||
//    used to endorse or promote products derived from this software without specific
 | 
			
		||||
//    prior written permission.
 | 
			
		||||
// 
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 | 
			
		||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 | 
			
		||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 | 
			
		||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
// 
 | 
			
		||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
 | 
			
		||||
 | 
			
		||||
#pragma once 
 | 
			
		||||
 | 
			
		||||
#include <unordered_set>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
namespace tools
 | 
			
		||||
{
 | 
			
		||||
  template<typename T, size_t MAX_SIZE>
 | 
			
		||||
  class data_cache
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    void add(const T& value)
 | 
			
		||||
    {
 | 
			
		||||
      std::lock_guard<std::mutex> lock(m);
 | 
			
		||||
      if (data.insert(value).second)
 | 
			
		||||
      {
 | 
			
		||||
        T& old_value = buf[counter++ % MAX_SIZE];
 | 
			
		||||
        data.erase(old_value);
 | 
			
		||||
        old_value = value;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool has(const T& value) const
 | 
			
		||||
    {
 | 
			
		||||
      std::lock_guard<std::mutex> lock(m);
 | 
			
		||||
      return (data.find(value) != data.end());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    mutable std::mutex m;
 | 
			
		||||
    std::unordered_set<T> data;
 | 
			
		||||
    T buf[MAX_SIZE] = {};
 | 
			
		||||
    size_t counter = 0;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3632,7 +3632,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!rct::verRctNonSemanticsSimple(rv))
 | 
			
		||||
      if (!rct::verRctNonSemanticsSimpleCached(rv))
 | 
			
		||||
      {
 | 
			
		||||
        MERROR_VER("Failed to check ringct signatures!");
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@
 | 
			
		|||
 | 
			
		||||
#include "misc_log_ex.h"
 | 
			
		||||
#include "misc_language.h"
 | 
			
		||||
#include "common/data_cache.h"
 | 
			
		||||
#include "common/perf_timer.h"
 | 
			
		||||
#include "common/threadpool.h"
 | 
			
		||||
#include "common/util.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -1578,6 +1579,42 @@ namespace rct {
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool verRctNonSemanticsSimpleCached(const rctSig & rv)
 | 
			
		||||
    {
 | 
			
		||||
      // Hello future Monero dev! If you got this assert, read the following carefully:
 | 
			
		||||
      //
 | 
			
		||||
      // RCT cache assumes that this function will serialize and hash all rv's fields used for RingCT verification
 | 
			
		||||
      // If you're about to add a new RCTType here, first you must check that binary_archive serialization writes all rv's fields to the binary blob
 | 
			
		||||
      // If it's not the case, rewrite this function to serialize everything, even some "temporary" fields which are not serialized normally
 | 
			
		||||
      CHECK_AND_ASSERT_MES_L1(rv.type <= RCTTypeBulletproofPlus, false, "Unknown RCT type. Make sure RCT cache works correctly with this type and then enable it in the code here.");
 | 
			
		||||
 | 
			
		||||
      // Don't cache older (or newer) rctSig types
 | 
			
		||||
      // This cache only makes sense when it caches data from mempool first,
 | 
			
		||||
      // so only "current fork version-enabled" RCT types need to be cached
 | 
			
		||||
      if (rv.type != RCTTypeBulletproofPlus)
 | 
			
		||||
        return verRctNonSemanticsSimple(rv);
 | 
			
		||||
 | 
			
		||||
      // Get the hash of rv
 | 
			
		||||
      std::stringstream ss;
 | 
			
		||||
      binary_archive<true> ar(ss);
 | 
			
		||||
 | 
			
		||||
      ::do_serialize(ar, const_cast<rctSig&>(rv));
 | 
			
		||||
 | 
			
		||||
      crypto::hash h;
 | 
			
		||||
      cryptonote::get_blob_hash(ss.str(), h);
 | 
			
		||||
 | 
			
		||||
      static tools::data_cache<crypto::hash, 8192> cache;
 | 
			
		||||
 | 
			
		||||
      if (cache.has(h))
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
      const bool res = verRctNonSemanticsSimple(rv);
 | 
			
		||||
      if (res)
 | 
			
		||||
        cache.add(h);
 | 
			
		||||
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //RingCT protocol
 | 
			
		||||
    //genRct: 
 | 
			
		||||
    //   creates an rctSig with all data necessary to verify the rangeProofs and that the signer owns one of the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,6 +132,7 @@ namespace rct {
 | 
			
		|||
    bool verRctSemanticsSimple(const rctSig & rv);
 | 
			
		||||
    bool verRctSemanticsSimple(const std::vector<const rctSig*> & rv);
 | 
			
		||||
    bool verRctNonSemanticsSimple(const rctSig & rv);
 | 
			
		||||
    bool verRctNonSemanticsSimpleCached(const rctSig & rv);
 | 
			
		||||
    static inline bool verRctSimple(const rctSig & rv) { return verRctSemanticsSimple(rv) && verRctNonSemanticsSimple(rv); }
 | 
			
		||||
    xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask, hw::device &hwdev);
 | 
			
		||||
    xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, hw::device &hwdev);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue