This is a greatly simplified and slightly tweaked version of
af2e3713e2
Their version will detect duplicate zkproofs across transactions while
this code will only detect duplicate zkproofs in a single ztx. If dupes
are found, the tx will be denied entry into the mempool.
This provides most of the benefit (increased CPU cost to attackers) with the
least code change and no annoyance to full node operators. Detecting
duplicate zkproofs across transactions requires a one-time reindex of
all of history, which means significant downtime for nodes.
Since Hush + HSCs have a much more strict policy on number of shielded
outputs and shielded inputs, only detecting duplicate zkproofs in
individual ztxs seems sufficient for now.
No correctly functioning node or wallet will ever create duplicate
zkproofs, so there is no worry of this accidentally affecting normal
users. Currently this is not a consensus rule but it could become one
in the future.
100 lines
4.0 KiB
C++
100 lines
4.0 KiB
C++
// Copyright (c) 2016-2023 The Hush developers
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
|
// Distributed under the GPLv3 software license, see the accompanying
|
|
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
|
|
/******************************************************************************
|
|
* Copyright © 2014-2019 The SuperNET Developers. *
|
|
* *
|
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
|
* the top-level directory of this distribution for the individual copyright *
|
|
* holder information and the developer policies on copyright and licensing. *
|
|
* *
|
|
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
|
* SuperNET software, including this file may be copied, modified, propagated *
|
|
* or distributed except according to the terms contained in the LICENSE file *
|
|
* *
|
|
* Removal or modification of this copyright notice is prohibited. *
|
|
* *
|
|
******************************************************************************/
|
|
|
|
#ifndef HUSH_CONSENSUS_VALIDATION_H
|
|
#define HUSH_CONSENSUS_VALIDATION_H
|
|
|
|
#include <string>
|
|
|
|
/** "reject" message codes */
|
|
static const unsigned char REJECT_MALFORMED = 0x01;
|
|
static const unsigned char REJECT_INVALID = 0x10;
|
|
static const unsigned char REJECT_OBSOLETE = 0x11;
|
|
static const unsigned char REJECT_DUPLICATE = 0x12;
|
|
static const unsigned char REJECT_DUPLICATE_OUTPUT_PROOF = 0x13;
|
|
static const unsigned char REJECT_DUPLICATE_SPEND_PROOF = 0x14;
|
|
static const unsigned char REJECT_NONSTANDARD = 0x40;
|
|
static const unsigned char REJECT_DUST = 0x41;
|
|
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
|
|
static const unsigned char REJECT_CHECKPOINT = 0x43;
|
|
static const unsigned char REJECT_HAVEBETTER = 0x44;
|
|
|
|
/** Capture information about block/transaction validation */
|
|
class CValidationState {
|
|
private:
|
|
enum mode_state {
|
|
MODE_VALID, //! everything ok
|
|
MODE_INVALID, //! network rule violation (DoS value may be set)
|
|
MODE_ERROR, //! run-time error
|
|
} mode;
|
|
int nDoS;
|
|
std::string strRejectReason;
|
|
unsigned char chRejectCode;
|
|
bool corruptionPossible;
|
|
public:
|
|
CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {}
|
|
virtual bool DoS(int level, bool ret = false,
|
|
unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="",
|
|
bool corruptionIn=false) {
|
|
chRejectCode = chRejectCodeIn;
|
|
strRejectReason = strRejectReasonIn;
|
|
corruptionPossible = corruptionIn;
|
|
if (mode == MODE_ERROR)
|
|
return ret;
|
|
nDoS += level;
|
|
mode = MODE_INVALID;
|
|
return ret;
|
|
}
|
|
virtual bool Invalid(bool ret = false,
|
|
unsigned char _chRejectCode=0, std::string _strRejectReason="") {
|
|
return DoS(0, ret, _chRejectCode, _strRejectReason);
|
|
}
|
|
virtual bool Error(const std::string& strRejectReasonIn) {
|
|
if (mode == MODE_VALID)
|
|
strRejectReason = strRejectReasonIn;
|
|
mode = MODE_ERROR;
|
|
return false;
|
|
}
|
|
virtual bool IsValid() const {
|
|
return mode == MODE_VALID;
|
|
}
|
|
virtual bool IsInvalid() const {
|
|
return mode == MODE_INVALID;
|
|
}
|
|
virtual bool IsError() const {
|
|
return mode == MODE_ERROR;
|
|
}
|
|
virtual bool IsInvalid(int &nDoSOut) const {
|
|
if (IsInvalid()) {
|
|
nDoSOut = nDoS;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
virtual bool CorruptionPossible() const {
|
|
return corruptionPossible;
|
|
}
|
|
virtual unsigned char GetRejectCode() const { return chRejectCode; }
|
|
virtual std::string GetRejectReason() const { return strRejectReason; }
|
|
};
|
|
|
|
#endif // HUSH_CONSENSUS_VALIDATION_H
|