Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b402ceb37f | |||
| f31a2751ab | |||
| af5a7c2186 | |||
| 916e440fb6 | |||
| bd305271cd | |||
| e86f0a8afd | |||
| 80b9b2be12 | |||
| d405a871a4 | |||
| de78291246 | |||
| 04ba92e6fd | |||
| 9021066354 | |||
| 7c139874ce | |||
| 58f8aeb67b | |||
| 2c6f6e6dd2 | |||
| 8729782845 | |||
| df11d9c2bf |
@@ -5,8 +5,7 @@ const bignum = require('bignum');
|
|||||||
const bitcoin = require('bitcoinjs-lib');
|
const bitcoin = require('bitcoinjs-lib');
|
||||||
const varuint = require('varuint-bitcoin');
|
const varuint = require('varuint-bitcoin');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const promise = require('promise');
|
const fastMerkleRoot = require('merkle-lib/fastRoot');
|
||||||
const merklebitcoin = promise.denodeify(require('merkle-bitcoin'));
|
|
||||||
|
|
||||||
function scriptCompile(addrHash) {
|
function scriptCompile(addrHash) {
|
||||||
return bitcoin.script.compile([
|
return bitcoin.script.compile([
|
||||||
@@ -37,23 +36,32 @@ function txesHaveWitnessCommit(transactions) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hash256(buffer) {
|
function sha256(buffer) {
|
||||||
return crypto.createHash('sha256').update(buffer).digest();
|
return crypto.createHash('sha256').update(buffer).digest();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function hash256(buffer) {
|
||||||
|
return sha256(sha256(buffer));
|
||||||
|
};
|
||||||
|
|
||||||
function getMerkleRoot(transactions) {
|
function getMerkleRoot(transactions) {
|
||||||
if (transactions.length === 0) return null;
|
if (transactions.length === 0) return new Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
|
||||||
if (transactions.length === 1) return transactions[0].getHash();
|
const forWitness = txesHaveWitnessCommit(transactions);
|
||||||
let hashes = [ reverseBuffer(transactions[0]).toString('hex') ];
|
const hashes = transactions.map(transaction => transaction.getHash(forWitness));
|
||||||
transactions.split(1).forEach(function (value) {
|
const rootHash = fastMerkleRoot(hashes, hash256);
|
||||||
hashes.push(value.hash);
|
return forWitness ? hash256(Buffer.concat([rootHash, transactions[0].ins[0].witness[0]])) : rootHash;
|
||||||
});
|
|
||||||
return reverseBuffer(new Buffer(Object.values(merklebitcoin(hashes))[2].root, 'hex'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let last_epoch_number;
|
let last_epoch_number;
|
||||||
let last_seed_hash;
|
let last_seed_hash;
|
||||||
const diff1 = 0x00000000ff000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
module.exports.baseDiff = function() {
|
||||||
|
return bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.baseRavenDiff = function() {
|
||||||
|
return parseInt('0x00000000ff000000000000000000000000000000000000000000000000000000');
|
||||||
|
};
|
||||||
|
|
||||||
module.exports.RavenBlockTemplate = function(rpcData, poolAddress) {
|
module.exports.RavenBlockTemplate = function(rpcData, poolAddress) {
|
||||||
const poolAddrHash = bitcoin.address.fromBase58Check(poolAddress).hash;
|
const poolAddrHash = bitcoin.address.fromBase58Check(poolAddress).hash;
|
||||||
@@ -127,7 +135,7 @@ module.exports.RavenBlockTemplate = function(rpcData, poolAddress) {
|
|||||||
last_epoch_number = epoch_number;
|
last_epoch_number = epoch_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const difficulty = parseFloat((diff1 / bignum(rpcData.target, 16).toNumber()).toFixed(9));
|
const difficulty = parseFloat((module.exports.baseRavenDiff() / bignum(rpcData.target, 16).toNumber()).toFixed(9));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
blocktemplate_blob: blob.toString('hex'),
|
blocktemplate_blob: blob.toString('hex'),
|
||||||
@@ -138,6 +146,7 @@ module.exports.RavenBlockTemplate = function(rpcData, poolAddress) {
|
|||||||
difficulty: difficulty,
|
difficulty: difficulty,
|
||||||
height: rpcData.height,
|
height: rpcData.height,
|
||||||
bits: rpcData.bits,
|
bits: rpcData.bits,
|
||||||
|
prev_hash: rpcData.previousblockhash,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -157,7 +166,7 @@ function update_merkle_root_hash(blob_in, blob_out) {
|
|||||||
module.exports.convertRavenBlob = function(blobBuffer) {
|
module.exports.convertRavenBlob = function(blobBuffer) {
|
||||||
let header = blobBuffer.slice(0, 80);
|
let header = blobBuffer.slice(0, 80);
|
||||||
update_merkle_root_hash(blobBuffer, header);
|
update_merkle_root_hash(blobBuffer, header);
|
||||||
return reverseBuffer(hash256(hash256(header)));
|
return reverseBuffer(hash256(header));
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.constructNewRavenBlob = function(blockTemplate, nonceBuff, mixhashBuff) {
|
module.exports.constructNewRavenBlob = function(blockTemplate, nonceBuff, mixhashBuff) {
|
||||||
@@ -170,4 +179,24 @@ module.exports.constructNewRavenBlob = function(blockTemplate, nonceBuff, mixhas
|
|||||||
module.exports.constructNewDeroBlob = function(blockTemplate, nonceBuff) {
|
module.exports.constructNewDeroBlob = function(blockTemplate, nonceBuff) {
|
||||||
nonceBuff.copy(blockTemplate, 39, 0, 4);
|
nonceBuff.copy(blockTemplate, 39, 0, 4);
|
||||||
return blockTemplate;
|
return blockTemplate;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.EthBlockTemplate = function(rpcData) {
|
||||||
|
const difficulty = module.exports.baseDiff().div(bignum(rpcData[2].substr(2), 16)).toNumber();
|
||||||
|
return {
|
||||||
|
hash: rpcData[0].substr(2),
|
||||||
|
seed_hash: rpcData[1].substr(2),
|
||||||
|
difficulty: difficulty,
|
||||||
|
height: parseInt(rpcData[3])
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.ErgBlockTemplate = function(rpcData) {
|
||||||
|
const difficulty = module.exports.baseDiff().div(bignum(rpcData.b)).toNumber();
|
||||||
|
return {
|
||||||
|
hash: rpcData.msg,
|
||||||
|
hash2: rpcData.pk,
|
||||||
|
difficulty: difficulty,
|
||||||
|
height: parseInt(rpcData.h)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
+7
-8
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cryptoforknote-util",
|
"name": "cryptoforknote-util",
|
||||||
"version": "9.0.14",
|
"version": "10.0.0",
|
||||||
"main": "cryptoforknote-util",
|
"main": "cryptoforknote-util",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "LucasJones",
|
"name": "LucasJones",
|
||||||
@@ -8,17 +8,16 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/MoneroOcean/node-cryptoforknote-util.git"
|
"url": "https://github.com/haven-protocol-org/node-cryptoforknote-util.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"promise": "*",
|
"promise": "*",
|
||||||
"bindings": "*",
|
"bindings": "*",
|
||||||
"nan": "^2.0.0",
|
"nan": "^2.14.2",
|
||||||
"bignum": "^0.13.1",
|
"bignum": "^0.13.1",
|
||||||
"sha3": "*",
|
"sha3": "*",
|
||||||
"varuint-bitcoin": "^1.0.4",
|
"varuint-bitcoin": "^1.0.4",
|
||||||
"bitcoinjs-lib": "git+https://github.com/bitcoinjs/bitcoinjs-lib.git#533d6c2e6d0aa4111f7948b1c12003cf6ef83137",
|
"bitcoinjs-lib": "git+https://github.com/bitcoinjs/bitcoinjs-lib.git#533d6c2e6d0aa4111f7948b1c12003cf6ef83137"
|
||||||
"merkle-bitcoin": "git+https://github.com/CloudMining/merkle-bitcoin.git#ec00ae20ba60d444e150ead03c747695ddaa83a1"
|
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"cryptonight",
|
"cryptonight",
|
||||||
|
|||||||
@@ -81,6 +81,19 @@ namespace cryptonote
|
|||||||
crypto::public_key key;
|
crypto::public_key key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct txout_xasset
|
||||||
|
{
|
||||||
|
txout_xasset() { }
|
||||||
|
txout_xasset(const crypto::public_key &_key, const std::string &_asset_type) : key(_key), asset_type(_asset_type) { }
|
||||||
|
crypto::public_key key;
|
||||||
|
std::string asset_type;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
FIELD(key)
|
||||||
|
FIELD(asset_type)
|
||||||
|
END_SERIALIZE()
|
||||||
|
};
|
||||||
|
|
||||||
/* inputs */
|
/* inputs */
|
||||||
|
|
||||||
struct txin_gen
|
struct txin_gen
|
||||||
@@ -159,9 +172,24 @@ namespace cryptonote
|
|||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::variant<txin_gen, txin_to_script, txin_to_scripthash, txin_to_key, txin_offshore, txin_onshore> txin_v;
|
struct txin_xasset
|
||||||
|
{
|
||||||
|
uint64_t amount;
|
||||||
|
std::string asset_type;
|
||||||
|
std::vector<uint64_t> key_offsets;
|
||||||
|
crypto::key_image k_image; // double spending protection
|
||||||
|
|
||||||
typedef boost::variant<txout_to_script, txout_to_scripthash, txout_to_key, txout_offshore> txout_target_v;
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VARINT_FIELD(amount)
|
||||||
|
FIELD(asset_type)
|
||||||
|
FIELD(key_offsets)
|
||||||
|
FIELD(k_image)
|
||||||
|
END_SERIALIZE()
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::variant<txin_gen, txin_to_script, txin_to_scripthash, txin_to_key, txin_offshore, txin_onshore, txin_xasset> txin_v;
|
||||||
|
|
||||||
|
typedef boost::variant<txout_to_script, txout_to_scripthash, txout_to_key, txout_offshore, txout_xasset> txout_target_v;
|
||||||
|
|
||||||
//typedef std::pair<uint64_t, txout> out_t;
|
//typedef std::pair<uint64_t, txout> out_t;
|
||||||
struct tx_out
|
struct tx_out
|
||||||
@@ -321,6 +349,7 @@ namespace cryptonote
|
|||||||
vin.size() > 0 && vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(vin[0]).key_offsets.size() - 1 :
|
vin.size() > 0 && vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(vin[0]).key_offsets.size() - 1 :
|
||||||
vin.size() > 0 && vin[0].type() == typeid(txin_offshore) ? boost::get<txin_offshore>(vin[0]).key_offsets.size() - 1 :
|
vin.size() > 0 && vin[0].type() == typeid(txin_offshore) ? boost::get<txin_offshore>(vin[0]).key_offsets.size() - 1 :
|
||||||
vin.size() > 0 && vin[0].type() == typeid(txin_onshore) ? boost::get<txin_onshore>(vin[0]).key_offsets.size() - 1 :
|
vin.size() > 0 && vin[0].type() == typeid(txin_onshore) ? boost::get<txin_onshore>(vin[0]).key_offsets.size() - 1 :
|
||||||
|
vin.size() > 0 && vin[0].type() == typeid(txin_xasset) ? boost::get<txin_xasset>(vin[0]).key_offsets.size() - 1 :
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
if (!r || !ar.stream().good()) return false;
|
if (!r || !ar.stream().good()) return false;
|
||||||
@@ -372,6 +401,7 @@ namespace cryptonote
|
|||||||
size_t operator()(const txin_to_key& txin) const {return txin.key_offsets.size();}
|
size_t operator()(const txin_to_key& txin) const {return txin.key_offsets.size();}
|
||||||
size_t operator()(const txin_offshore& txin) const {return txin.key_offsets.size();}
|
size_t operator()(const txin_offshore& txin) const {return txin.key_offsets.size();}
|
||||||
size_t operator()(const txin_onshore& txin) const {return txin.key_offsets.size();}
|
size_t operator()(const txin_onshore& txin) const {return txin.key_offsets.size();}
|
||||||
|
size_t operator()(const txin_xasset& txin) const {return txin.key_offsets.size();}
|
||||||
};
|
};
|
||||||
|
|
||||||
return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
|
return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
|
||||||
@@ -612,10 +642,12 @@ VARIANT_TAG(binary_archive, cryptonote::txin_to_scripthash, 0x1);
|
|||||||
VARIANT_TAG(binary_archive, cryptonote::txin_to_key, 0x2);
|
VARIANT_TAG(binary_archive, cryptonote::txin_to_key, 0x2);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::txin_offshore, 0x3);
|
VARIANT_TAG(binary_archive, cryptonote::txin_offshore, 0x3);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::txin_onshore, 0x4);
|
VARIANT_TAG(binary_archive, cryptonote::txin_onshore, 0x4);
|
||||||
|
VARIANT_TAG(binary_archive, cryptonote::txin_xasset, 0x5);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::txout_to_script, 0x0);
|
VARIANT_TAG(binary_archive, cryptonote::txout_to_script, 0x0);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::txout_to_scripthash, 0x1);
|
VARIANT_TAG(binary_archive, cryptonote::txout_to_scripthash, 0x1);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::txout_to_key, 0x2);
|
VARIANT_TAG(binary_archive, cryptonote::txout_to_key, 0x2);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::txout_offshore, 0x3);
|
VARIANT_TAG(binary_archive, cryptonote::txout_offshore, 0x3);
|
||||||
|
VARIANT_TAG(binary_archive, cryptonote::txout_xasset, 0x5);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::transaction, 0xcc);
|
VARIANT_TAG(binary_archive, cryptonote::transaction, 0xcc);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::block, 0xbb);
|
VARIANT_TAG(binary_archive, cryptonote::block, 0xbb);
|
||||||
|
|
||||||
@@ -625,10 +657,12 @@ VARIANT_TAG(json_archive, cryptonote::txin_to_scripthash, "scripthash");
|
|||||||
VARIANT_TAG(json_archive, cryptonote::txin_to_key, "key");
|
VARIANT_TAG(json_archive, cryptonote::txin_to_key, "key");
|
||||||
VARIANT_TAG(json_archive, cryptonote::txin_offshore, "offshore");
|
VARIANT_TAG(json_archive, cryptonote::txin_offshore, "offshore");
|
||||||
VARIANT_TAG(json_archive, cryptonote::txin_onshore, "onshore");
|
VARIANT_TAG(json_archive, cryptonote::txin_onshore, "onshore");
|
||||||
|
VARIANT_TAG(json_archive, cryptonote::txin_xasset, "xasset");
|
||||||
VARIANT_TAG(json_archive, cryptonote::txout_to_script, "script");
|
VARIANT_TAG(json_archive, cryptonote::txout_to_script, "script");
|
||||||
VARIANT_TAG(json_archive, cryptonote::txout_to_scripthash, "scripthash");
|
VARIANT_TAG(json_archive, cryptonote::txout_to_scripthash, "scripthash");
|
||||||
VARIANT_TAG(json_archive, cryptonote::txout_to_key, "key");
|
VARIANT_TAG(json_archive, cryptonote::txout_to_key, "key");
|
||||||
VARIANT_TAG(json_archive, cryptonote::txout_offshore, "offshore");
|
VARIANT_TAG(json_archive, cryptonote::txout_offshore, "offshore");
|
||||||
|
VARIANT_TAG(json_archive, cryptonote::txout_xasset, "xasset");
|
||||||
VARIANT_TAG(json_archive, cryptonote::transaction, "tx");
|
VARIANT_TAG(json_archive, cryptonote::transaction, "tx");
|
||||||
VARIANT_TAG(json_archive, cryptonote::block, "block");
|
VARIANT_TAG(json_archive, cryptonote::block, "block");
|
||||||
|
|
||||||
@@ -638,9 +672,11 @@ VARIANT_TAG(debug_archive, cryptonote::txin_to_scripthash, "scripthash");
|
|||||||
VARIANT_TAG(debug_archive, cryptonote::txin_to_key, "key");
|
VARIANT_TAG(debug_archive, cryptonote::txin_to_key, "key");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::txin_offshore, "offshore");
|
VARIANT_TAG(debug_archive, cryptonote::txin_offshore, "offshore");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::txin_onshore, "onshore");
|
VARIANT_TAG(debug_archive, cryptonote::txin_onshore, "onshore");
|
||||||
|
VARIANT_TAG(debug_archive, cryptonote::txin_xasset, "xasset");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::txout_to_script, "script");
|
VARIANT_TAG(debug_archive, cryptonote::txout_to_script, "script");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::txout_to_scripthash, "scripthash");
|
VARIANT_TAG(debug_archive, cryptonote::txout_to_scripthash, "scripthash");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::txout_to_key, "key");
|
VARIANT_TAG(debug_archive, cryptonote::txout_to_key, "key");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::txout_offshore, "offshore");
|
VARIANT_TAG(debug_archive, cryptonote::txout_offshore, "offshore");
|
||||||
|
VARIANT_TAG(debug_archive, cryptonote::txout_xasset, "xasset");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::transaction, "tx");
|
VARIANT_TAG(debug_archive, cryptonote::transaction, "tx");
|
||||||
VARIANT_TAG(debug_archive, cryptonote::block, "block");
|
VARIANT_TAG(debug_archive, cryptonote::block, "block");
|
||||||
|
|||||||
@@ -85,14 +85,24 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
uint64_t amount_in = 0;
|
uint64_t amount_in = 0;
|
||||||
uint64_t amount_out = 0;
|
uint64_t amount_out = 0;
|
||||||
|
if ((tx.blob_type == BLOB_TYPE_CRYPTONOTE_XHV) && (tx.version > 1))
|
||||||
|
{
|
||||||
|
// This is the correct way to get the fee for Haven, because outs may be in different currencies to ins
|
||||||
|
fee = tx.rct_signatures.txnFee + tx.rct_signatures.txnOffshoreFee;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
BOOST_FOREACH(auto& in, tx.vin)
|
BOOST_FOREACH(auto& in, tx.vin)
|
||||||
{
|
{
|
||||||
if (tx.blob_type != BLOB_TYPE_CRYPTONOTE_XHV) {
|
if (tx.blob_type != BLOB_TYPE_CRYPTONOTE_XHV) {
|
||||||
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), 0, "unexpected type id in transaction");
|
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), 0, "unexpected type id in transaction");
|
||||||
amount_in += boost::get<txin_to_key>(in).amount;
|
amount_in += boost::get<txin_to_key>(in).amount;
|
||||||
} else {
|
} else {
|
||||||
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key) || in.type() == typeid(txin_offshore) || in.type() == typeid(txin_onshore), 0, "unexpected type id in transaction");
|
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key) || in.type() == typeid(txin_offshore) || in.type() == typeid(txin_onshore) || in.type() == typeid(txin_xasset), 0, "unexpected type id in transaction");
|
||||||
amount_in += in.type() == typeid(txin_to_key) ? boost::get<txin_to_key>(in).amount : in.type() == typeid(txin_onshore) ? boost::get<txin_onshore>(in).amount : boost::get<txin_offshore>(in).amount;
|
amount_in +=
|
||||||
|
in.type() == typeid(txin_to_key) ? boost::get<txin_to_key>(in).amount :
|
||||||
|
in.type() == typeid(txin_onshore) ? boost::get<txin_onshore>(in).amount :
|
||||||
|
in.type() == typeid(txin_offshore) ? boost::get<txin_offshore>(in).amount :
|
||||||
|
boost::get<txin_xasset>(in).amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_FOREACH(auto& o, tx.vout)
|
BOOST_FOREACH(auto& o, tx.vout)
|
||||||
@@ -245,9 +255,12 @@ namespace cryptonote
|
|||||||
<< in.type().name() << ", expected " << typeid(txin_to_key).name()
|
<< in.type().name() << ", expected " << typeid(txin_to_key).name()
|
||||||
<< ", in transaction id=" << get_transaction_hash(tx));
|
<< ", in transaction id=" << get_transaction_hash(tx));
|
||||||
} else {
|
} else {
|
||||||
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key) || in.type() == typeid(txin_offshore) || in.type() == typeid(txin_onshore), false, "wrong variant type: "
|
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key) || in.type() == typeid(txin_offshore) || in.type() == typeid(txin_onshore) || in.type() == typeid(txin_xasset), false, "wrong variant type: "
|
||||||
<< in.type().name() << ", expected " << typeid(txin_to_key).name() << "or " << typeid(txin_onshore).name()
|
<< in.type().name() << ", expected " << typeid(txin_to_key).name()
|
||||||
<< ", in transaction id=" << get_transaction_hash(tx));
|
<< "or " << typeid(txin_offshore).name()
|
||||||
|
<< "or " << typeid(txin_onshore).name()
|
||||||
|
<< "or " << typeid(txin_xasset).name()
|
||||||
|
<< ", in transaction id=" << get_transaction_hash(tx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -262,10 +275,13 @@ namespace cryptonote
|
|||||||
<< out.target.type().name() << ", expected " << typeid(txout_to_key).name()
|
<< out.target.type().name() << ", expected " << typeid(txout_to_key).name()
|
||||||
<< ", in transaction id=" << get_transaction_hash(tx));
|
<< ", in transaction id=" << get_transaction_hash(tx));
|
||||||
} else {
|
} else {
|
||||||
CHECK_AND_ASSERT_MES(out.target.type() == typeid(txout_to_key) || out.target.type() == typeid(txout_offshore), false, "wrong variant type: "
|
CHECK_AND_ASSERT_MES(out.target.type() == typeid(txout_to_key) ||
|
||||||
<< out.target.type().name() << ", expected " << typeid(txout_to_key).name()
|
out.target.type() == typeid(txout_offshore) ||
|
||||||
<< "or " << typeid(txout_offshore).name()
|
out.target.type() == typeid(txout_xasset), false, "wrong variant type: "
|
||||||
<< ", in transaction id=" << get_transaction_hash(tx));
|
<< out.target.type().name() << ", expected " << typeid(txout_to_key).name()
|
||||||
|
<< "or " << typeid(txout_offshore).name()
|
||||||
|
<< "or " << typeid(txout_xasset).name()
|
||||||
|
<< ", in transaction id=" << get_transaction_hash(tx));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.version == 1)
|
if (tx.version == 1)
|
||||||
@@ -277,7 +293,9 @@ namespace cryptonote
|
|||||||
if(!check_key(boost::get<txout_to_key>(out.target).key))
|
if(!check_key(boost::get<txout_to_key>(out.target).key))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(!check_key(out.target.type() == typeid(txout_to_key) ? boost::get<txout_to_key>(out.target).key : boost::get<txout_offshore>(out.target).key))
|
if(!check_key(out.target.type() == typeid(txout_to_key) ? boost::get<txout_to_key>(out.target).key :
|
||||||
|
out.target.type() == typeid(txout_offshore) ? boost::get<txout_offshore>(out.target).key :
|
||||||
|
boost::get<txout_xasset>(out.target).key))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,7 +312,12 @@ namespace cryptonote
|
|||||||
uint64_t money = 0;
|
uint64_t money = 0;
|
||||||
BOOST_FOREACH(const auto& in, tx.vin)
|
BOOST_FOREACH(const auto& in, tx.vin)
|
||||||
{
|
{
|
||||||
if (tx.blob_type == BLOB_TYPE_CRYPTONOTE_XHV && tx.vin[0].type() == typeid(txin_offshore)) {
|
if (tx.blob_type == BLOB_TYPE_CRYPTONOTE_XHV && tx.vin[0].type() == typeid(txin_xasset)) {
|
||||||
|
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_xasset, tokey_in, false);
|
||||||
|
if(money > tokey_in.amount + money)
|
||||||
|
return false;
|
||||||
|
money += tokey_in.amount;
|
||||||
|
} else if (tx.blob_type == BLOB_TYPE_CRYPTONOTE_XHV && tx.vin[0].type() == typeid(txin_offshore)) {
|
||||||
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_offshore, tokey_in, false);
|
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_offshore, tokey_in, false);
|
||||||
if(money > tokey_in.amount + money)
|
if(money > tokey_in.amount + money)
|
||||||
return false;
|
return false;
|
||||||
@@ -325,6 +348,7 @@ namespace cryptonote
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
uint64_t get_outs_money_amount(const transaction& tx)
|
uint64_t get_outs_money_amount(const transaction& tx)
|
||||||
{
|
{
|
||||||
@@ -333,6 +357,25 @@ namespace cryptonote
|
|||||||
outputs_amount += o.amount;
|
outputs_amount += o.amount;
|
||||||
return outputs_amount;
|
return outputs_amount;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
std::map<std::string, uint64_t> get_outs_money_amount(const transaction& tx)
|
||||||
|
{
|
||||||
|
std::map<std::string, uint64_t> outputs_amount;
|
||||||
|
for(const auto& o: tx.vout) {
|
||||||
|
std::string asset_type;
|
||||||
|
if (o.target.type() == typeid(txout_offshore)) {
|
||||||
|
asset_type = "XUSD";
|
||||||
|
} else if (o.target.type() == typeid(txout_xasset)) {;
|
||||||
|
asset_type = boost::get<txout_xasset>(o.target).asset_type;
|
||||||
|
} else {
|
||||||
|
// this close covers miner tx and normal XHV ouputs.
|
||||||
|
asset_type = "XHV";
|
||||||
|
}
|
||||||
|
outputs_amount[asset_type] += o.amount;
|
||||||
|
}
|
||||||
|
return outputs_amount;
|
||||||
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
std::string short_hash_str(const crypto::hash& h)
|
std::string short_hash_str(const crypto::hash& h)
|
||||||
{
|
{
|
||||||
@@ -451,6 +494,7 @@ namespace cryptonote
|
|||||||
t.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(t.vin[0]).key_offsets.size() - 1 :
|
t.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(t.vin[0]).key_offsets.size() - 1 :
|
||||||
t.vin[0].type() == typeid(txin_offshore) ? boost::get<txin_offshore>(t.vin[0]).key_offsets.size() - 1 :
|
t.vin[0].type() == typeid(txin_offshore) ? boost::get<txin_offshore>(t.vin[0]).key_offsets.size() - 1 :
|
||||||
t.vin[0].type() == typeid(txin_onshore) ? boost::get<txin_onshore>(t.vin[0]).key_offsets.size() - 1 :
|
t.vin[0].type() == typeid(txin_onshore) ? boost::get<txin_onshore>(t.vin[0]).key_offsets.size() - 1 :
|
||||||
|
t.vin[0].type() == typeid(txin_xasset) ? boost::get<txin_xasset>(t.vin[0]).key_offsets.size() - 1 :
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
bool r = tt.rct_signatures.p.serialize_rctsig_prunable(ba, t.rct_signatures.type, inputs, outputs, mixin);
|
bool r = tt.rct_signatures.p.serialize_rctsig_prunable(ba, t.rct_signatures.type, inputs, outputs, mixin);
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ namespace cryptonote
|
|||||||
bool get_bytecoin_block_longhash(const block& blk, crypto::hash& res);
|
bool get_bytecoin_block_longhash(const block& blk, crypto::hash& res);
|
||||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
|
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
|
||||||
bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
|
bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
|
||||||
uint64_t get_outs_money_amount(const transaction& tx);
|
//uint64_t get_outs_money_amount(const transaction& tx);
|
||||||
|
std::map<std::string, uint64_t> get_outs_money_amount(const transaction& tx);
|
||||||
bool check_inputs_types_supported(const transaction& tx);
|
bool check_inputs_types_supported(const transaction& tx);
|
||||||
bool check_outs_valid(const transaction& tx);
|
bool check_outs_valid(const transaction& tx);
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,16 @@
|
|||||||
|
|
||||||
#define TX_EXTRA_PADDING_MAX_COUNT 255
|
#define TX_EXTRA_PADDING_MAX_COUNT 255
|
||||||
#define TX_EXTRA_NONCE_MAX_COUNT 255
|
#define TX_EXTRA_NONCE_MAX_COUNT 255
|
||||||
|
#define TX_EXTRA_OFFSHORE_MAX_COUNT 255
|
||||||
|
#define TX_EXTRA_MEMO_MAX_COUNT 255
|
||||||
|
|
||||||
#define TX_EXTRA_TAG_PADDING 0x00
|
#define TX_EXTRA_TAG_PADDING 0x00
|
||||||
#define TX_EXTRA_TAG_PUBKEY 0x01
|
#define TX_EXTRA_TAG_PUBKEY 0x01
|
||||||
#define TX_EXTRA_NONCE 0x02
|
#define TX_EXTRA_NONCE 0x02
|
||||||
#define TX_EXTRA_MERGE_MINING_TAG 0x03
|
#define TX_EXTRA_MERGE_MINING_TAG 0x03
|
||||||
#define TX_EXTRA_TAG_ADDITIONAL_PUBKEYS 0x04
|
#define TX_EXTRA_TAG_ADDITIONAL_PUBKEYS 0x04
|
||||||
|
#define TX_EXTRA_TAG_OFFSHORE 0x17
|
||||||
|
#define TX_EXTRA_TAG_MEMO 0x18
|
||||||
#define TX_EXTRA_TAG_SERVICE_NODE_REGISTER 0x70
|
#define TX_EXTRA_TAG_SERVICE_NODE_REGISTER 0x70
|
||||||
#define TX_EXTRA_TAG_SERVICE_NODE_DEREGISTER 0x71
|
#define TX_EXTRA_TAG_SERVICE_NODE_DEREGISTER 0x71
|
||||||
#define TX_EXTRA_TAG_SERVICE_NODE_WINNER 0x72
|
#define TX_EXTRA_TAG_SERVICE_NODE_WINNER 0x72
|
||||||
@@ -186,6 +190,25 @@ namespace cryptonote
|
|||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tx_extra_offshore
|
||||||
|
{
|
||||||
|
std::string data;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE()
|
||||||
|
FIELD(data)
|
||||||
|
END_SERIALIZE()
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tx_extra_memo
|
||||||
|
{
|
||||||
|
// Actual memo data as string
|
||||||
|
std::string data;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE()
|
||||||
|
FIELD(data)
|
||||||
|
END_SERIALIZE()
|
||||||
|
};
|
||||||
|
|
||||||
struct tx_extra_service_node_winner
|
struct tx_extra_service_node_winner
|
||||||
{
|
{
|
||||||
crypto::public_key m_service_node_key;
|
crypto::public_key m_service_node_key;
|
||||||
@@ -301,6 +324,8 @@ namespace cryptonote
|
|||||||
tx_extra_merge_mining_tag,
|
tx_extra_merge_mining_tag,
|
||||||
tx_extra_additional_pub_keys,
|
tx_extra_additional_pub_keys,
|
||||||
tx_extra_mysterious_minergate,
|
tx_extra_mysterious_minergate,
|
||||||
|
tx_extra_offshore,
|
||||||
|
tx_extra_memo,
|
||||||
tx_extra_service_node_pubkey,
|
tx_extra_service_node_pubkey,
|
||||||
tx_extra_service_node_register,
|
tx_extra_service_node_register,
|
||||||
tx_extra_service_node_contributor,
|
tx_extra_service_node_contributor,
|
||||||
@@ -321,6 +346,8 @@ VARIANT_TAG(binary_archive, cryptonote::tx_extra_nonce, TX_EX
|
|||||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_merge_mining_tag, TX_EXTRA_MERGE_MINING_TAG);
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_merge_mining_tag, TX_EXTRA_MERGE_MINING_TAG);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_additional_pub_keys, TX_EXTRA_TAG_ADDITIONAL_PUBKEYS);
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_additional_pub_keys, TX_EXTRA_TAG_ADDITIONAL_PUBKEYS);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_mysterious_minergate, TX_EXTRA_MYSTERIOUS_MINERGATE_TAG);
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_mysterious_minergate, TX_EXTRA_MYSTERIOUS_MINERGATE_TAG);
|
||||||
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_offshore, TX_EXTRA_TAG_OFFSHORE);
|
||||||
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_memo, TX_EXTRA_TAG_MEMO);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_service_node_register, TX_EXTRA_TAG_SERVICE_NODE_REGISTER);
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_service_node_register, TX_EXTRA_TAG_SERVICE_NODE_REGISTER);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_service_node_deregister, TX_EXTRA_TAG_SERVICE_NODE_DEREGISTER);
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_service_node_deregister, TX_EXTRA_TAG_SERVICE_NODE_DEREGISTER);
|
||||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_service_node_contributor, TX_EXTRA_TAG_SERVICE_NODE_CONTRIBUTOR);
|
VARIANT_TAG(binary_archive, cryptonote::tx_extra_service_node_contributor, TX_EXTRA_TAG_SERVICE_NODE_CONTRIBUTOR);
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (c) 2021, Haven Protocol
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace offshore {
|
||||||
|
|
||||||
|
const std::vector<std::string> ASSET_TYPES = {"XHV", "XAG", "XAU", "XAUD", "XBTC", "XCAD", "XCHF", "XCNY", "XEUR", "XGBP", "XJPY", "XNOK", "XNZD", "XUSD"};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,17 +29,6 @@
|
|||||||
|
|
||||||
#include "pricing_record.h"
|
#include "pricing_record.h"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <openssl/bio.h>
|
|
||||||
#include <openssl/crypto.h>
|
|
||||||
#include <openssl/ecdsa.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/pem.h>
|
|
||||||
#include <openssl/rsa.h>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
|
|
||||||
#include "serialization/keyvalue_serialization.h"
|
#include "serialization/keyvalue_serialization.h"
|
||||||
#include "storages/portable_storage.h"
|
#include "storages/portable_storage.h"
|
||||||
|
|
||||||
@@ -199,6 +188,41 @@ namespace offshore
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t pricing_record::operator[](const std::string asset_type) const noexcept
|
||||||
|
{
|
||||||
|
if (asset_type == "XHV") {
|
||||||
|
return 1000000000000;
|
||||||
|
} else if (asset_type == "XUSD") {
|
||||||
|
return unused1;
|
||||||
|
} else if (asset_type == "XAG") {
|
||||||
|
return xAG;
|
||||||
|
} else if (asset_type == "XAU") {
|
||||||
|
return xAU;
|
||||||
|
} else if (asset_type == "XAUD") {
|
||||||
|
return xAUD;
|
||||||
|
} else if (asset_type == "XBTC") {
|
||||||
|
return xBTC;
|
||||||
|
} else if (asset_type == "XCAD") {
|
||||||
|
return xCAD;
|
||||||
|
} else if (asset_type == "XCHF") {
|
||||||
|
return xCHF;
|
||||||
|
} else if (asset_type == "XCNY") {
|
||||||
|
return xCNY;
|
||||||
|
} else if (asset_type == "XEUR") {
|
||||||
|
return xEUR;
|
||||||
|
} else if (asset_type == "XGBP") {
|
||||||
|
return xGBP;
|
||||||
|
} else if (asset_type == "XJPY") {
|
||||||
|
return xJPY;
|
||||||
|
} else if (asset_type == "XNOK") {
|
||||||
|
return xNOK;
|
||||||
|
} else if (asset_type == "XNZD") {
|
||||||
|
return xNZD;
|
||||||
|
} else {
|
||||||
|
return 1000000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool pricing_record::equal(const pricing_record& other) const noexcept
|
bool pricing_record::equal(const pricing_record& other) const noexcept
|
||||||
{
|
{
|
||||||
return ((xAG == other.xAG) &&
|
return ((xAG == other.xAG) &&
|
||||||
@@ -221,7 +245,7 @@ namespace offshore
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool pricing_record::verifySignature() const noexcept
|
bool pricing_record::verifySignature(EVP_PKEY* public_key) const noexcept
|
||||||
{
|
{
|
||||||
// Sanity check - accept empty pricing records
|
// Sanity check - accept empty pricing records
|
||||||
unsigned char test_sig[64];
|
unsigned char test_sig[64];
|
||||||
@@ -295,19 +319,28 @@ namespace offshore
|
|||||||
compact += (byte);
|
compact += (byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HERE BE DRAGONS!!!
|
// Check to see if we have been passed a public key to use
|
||||||
// NEAC: the public key should be in a file
|
EVP_PKEY* pubkey = NULL;
|
||||||
static const char public_key[] = "-----BEGIN PUBLIC KEY-----\n"
|
if (public_key) {
|
||||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5YBxWx1AZCA9jTUk8Pr2uZ9jpfRt\n"
|
|
||||||
"KWv3Vo1/Gny+1vfaxsXhBQiG1KlHkafNGarzoL0WHW4ocqaaqF5iv8i35A==\n"
|
// Take a copy for local use
|
||||||
"-----END PUBLIC KEY-----\n";
|
pubkey = public_key;
|
||||||
// LAND AHOY!!!
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// No public key provided - failover to embedded key
|
||||||
|
static const char public_key[] = "-----BEGIN PUBLIC KEY-----\n"
|
||||||
|
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5YBxWx1AZCA9jTUk8Pr2uZ9jpfRt\n"
|
||||||
|
"KWv3Vo1/Gny+1vfaxsXhBQiG1KlHkafNGarzoL0WHW4ocqaaqF5iv8i35A==\n"
|
||||||
|
"-----END PUBLIC KEY-----\n";
|
||||||
|
|
||||||
// Grab the public key and make it usable
|
BIO* bio = BIO_new_mem_buf(public_key, (int)sizeof(public_key));
|
||||||
BIO* bio = BIO_new_mem_buf(public_key, (int)sizeof(public_key));
|
if (!bio) {
|
||||||
assert(bio != NULL);
|
return false;
|
||||||
EVP_PKEY* pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
}
|
||||||
BIO_free(bio);
|
pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
||||||
|
BIO_free(bio);
|
||||||
|
}
|
||||||
assert(pubkey != NULL);
|
assert(pubkey != NULL);
|
||||||
|
|
||||||
// Create a verify digest from the message
|
// Create a verify digest from the message
|
||||||
@@ -325,9 +358,12 @@ namespace offshore
|
|||||||
// Cleanup the context we created
|
// Cleanup the context we created
|
||||||
EVP_MD_CTX_destroy(ctx);
|
EVP_MD_CTX_destroy(ctx);
|
||||||
|
|
||||||
// Cleanup the openssl stuff
|
// Was the key provided by the caller?
|
||||||
EVP_PKEY_free(pubkey);
|
if (pubkey != public_key) {
|
||||||
|
// Cleanup the openssl stuff
|
||||||
|
EVP_PKEY_free(pubkey);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -336,4 +372,4 @@ namespace offshore
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common/pod-class.h"
|
#include "common/pod-class.h"
|
||||||
|
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/ecdsa.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace epee
|
namespace epee
|
||||||
{
|
{
|
||||||
@@ -101,10 +111,12 @@ namespace offshore
|
|||||||
pricing_record(const pricing_record& orig) noexcept;
|
pricing_record(const pricing_record& orig) noexcept;
|
||||||
~pricing_record() = default;
|
~pricing_record() = default;
|
||||||
pricing_record& operator=(const pricing_record& orig) noexcept;
|
pricing_record& operator=(const pricing_record& orig) noexcept;
|
||||||
|
|
||||||
|
uint64_t operator[](const std::string asset_type) const noexcept;
|
||||||
|
|
||||||
bool equal(const pricing_record& other) const noexcept;
|
bool equal(const pricing_record& other) const noexcept;
|
||||||
|
|
||||||
bool verifySignature() const noexcept;
|
bool verifySignature(EVP_PKEY* public_key = NULL) const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const pricing_record& a, const pricing_record& b) noexcept
|
inline bool operator==(const pricing_record& a, const pricing_record& b) noexcept
|
||||||
@@ -117,4 +129,4 @@ namespace offshore
|
|||||||
return !a.equal(b);
|
return !a.equal(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // offshore
|
} // offshore
|
||||||
|
|||||||
+52
-23
@@ -254,6 +254,7 @@ namespace rct {
|
|||||||
RCTTypeBulletproof = 3,
|
RCTTypeBulletproof = 3,
|
||||||
RCTTypeBulletproof2 = 4,
|
RCTTypeBulletproof2 = 4,
|
||||||
RCTTypeCLSAG = 5,
|
RCTTypeCLSAG = 5,
|
||||||
|
RCTTypeCLSAGN = 6,
|
||||||
};
|
};
|
||||||
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
|
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
|
||||||
struct RCTConfig {
|
struct RCTConfig {
|
||||||
@@ -269,10 +270,13 @@ namespace rct {
|
|||||||
std::vector<ecdhTuple> ecdhInfo;
|
std::vector<ecdhTuple> ecdhInfo;
|
||||||
ctkeyV outPk;
|
ctkeyV outPk;
|
||||||
ctkeyV outPk_usd;
|
ctkeyV outPk_usd;
|
||||||
|
ctkeyV outPk_xasset;
|
||||||
xmr_amount txnFee; // contains b
|
xmr_amount txnFee; // contains b
|
||||||
xmr_amount txnFee_usd;
|
xmr_amount txnFee_usd;
|
||||||
|
xmr_amount txnFee_xasset;
|
||||||
xmr_amount txnOffshoreFee;
|
xmr_amount txnOffshoreFee;
|
||||||
xmr_amount txnOffshoreFee_usd;
|
xmr_amount txnOffshoreFee_usd;
|
||||||
|
xmr_amount txnOffshoreFee_xasset;
|
||||||
|
|
||||||
template<bool W, template <bool> class Archive>
|
template<bool W, template <bool> class Archive>
|
||||||
bool serialize_rctsig_base(Archive<W> &ar, size_t inputs, size_t outputs)
|
bool serialize_rctsig_base(Archive<W> &ar, size_t inputs, size_t outputs)
|
||||||
@@ -280,18 +284,28 @@ namespace rct {
|
|||||||
FIELD(type)
|
FIELD(type)
|
||||||
if (type == RCTTypeNull)
|
if (type == RCTTypeNull)
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG)
|
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN)
|
||||||
return false;
|
return false;
|
||||||
VARINT_FIELD(txnFee)
|
VARINT_FIELD(txnFee)
|
||||||
if (type == RCTTypeCLSAG)
|
if ((type == RCTTypeCLSAG) || (type == RCTTypeCLSAGN))
|
||||||
{
|
{
|
||||||
VARINT_FIELD(txnFee_usd)
|
VARINT_FIELD(txnFee_usd)
|
||||||
|
if (type == RCTTypeCLSAGN)
|
||||||
|
{
|
||||||
|
VARINT_FIELD(txnFee_xasset)
|
||||||
|
}
|
||||||
VARINT_FIELD(txnOffshoreFee)
|
VARINT_FIELD(txnOffshoreFee)
|
||||||
VARINT_FIELD(txnOffshoreFee_usd)
|
VARINT_FIELD(txnOffshoreFee_usd)
|
||||||
|
if (type == RCTTypeCLSAGN)
|
||||||
|
{
|
||||||
|
VARINT_FIELD(txnOffshoreFee_xasset)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
txnFee_usd = 0;
|
txnFee_usd = 0;
|
||||||
|
txnFee_xasset = 0;
|
||||||
txnOffshoreFee = 0;
|
txnOffshoreFee = 0;
|
||||||
txnOffshoreFee_usd = 0;
|
txnOffshoreFee_usd = 0;
|
||||||
|
txnOffshoreFee_xasset = 0;
|
||||||
}
|
}
|
||||||
// inputs/outputs not saved, only here for serialization help
|
// inputs/outputs not saved, only here for serialization help
|
||||||
// FIELD(message) - not serialized, it can be reconstructed
|
// FIELD(message) - not serialized, it can be reconstructed
|
||||||
@@ -319,7 +333,7 @@ namespace rct {
|
|||||||
return false;
|
return false;
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
for (size_t i = 0; i < outputs; ++i)
|
||||||
{
|
{
|
||||||
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG)
|
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN)
|
||||||
{
|
{
|
||||||
ar.begin_object();
|
ar.begin_object();
|
||||||
if (!typename Archive<W>::is_saving())
|
if (!typename Archive<W>::is_saving())
|
||||||
@@ -350,21 +364,36 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
|
|
||||||
if (type == RCTTypeCLSAG)
|
if ((type == RCTTypeCLSAG) || (type == RCTTypeCLSAGN))
|
||||||
{
|
{
|
||||||
ar.tag("outPk_usd");
|
ar.tag("outPk_usd");
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk_usd);
|
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk_usd);
|
||||||
if (outPk_usd.size() != outputs)
|
if (outPk_usd.size() != outputs)
|
||||||
return false;
|
return false;
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
for (size_t i = 0; i < outputs; ++i)
|
||||||
{
|
{
|
||||||
FIELDS(outPk_usd[i].mask)
|
FIELDS(outPk_usd[i].mask)
|
||||||
if (outputs - i > 1)
|
if (outputs - i > 1)
|
||||||
ar.delimit_array();
|
ar.delimit_array();
|
||||||
}
|
}
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
}
|
}
|
||||||
|
if (type == RCTTypeCLSAGN)
|
||||||
|
{
|
||||||
|
ar.tag("outPk_xasset");
|
||||||
|
ar.begin_array();
|
||||||
|
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk_xasset);
|
||||||
|
if (outPk_xasset.size() != outputs)
|
||||||
|
return false;
|
||||||
|
for (size_t i = 0; i < outputs; ++i)
|
||||||
|
{
|
||||||
|
FIELDS(outPk_xasset[i].mask)
|
||||||
|
if (outputs - i > 1)
|
||||||
|
ar.delimit_array();
|
||||||
|
}
|
||||||
|
ar.end_array();
|
||||||
|
}
|
||||||
|
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
}
|
}
|
||||||
@@ -382,12 +411,12 @@ namespace rct {
|
|||||||
{
|
{
|
||||||
if (type == RCTTypeNull)
|
if (type == RCTTypeNull)
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG)
|
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN)
|
||||||
return false;
|
return false;
|
||||||
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG)
|
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN)
|
||||||
{
|
{
|
||||||
uint32_t nbp = bulletproofs.size();
|
uint32_t nbp = bulletproofs.size();
|
||||||
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG)
|
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN)
|
||||||
VARINT_FIELD(nbp)
|
VARINT_FIELD(nbp)
|
||||||
else
|
else
|
||||||
FIELD(nbp)
|
FIELD(nbp)
|
||||||
@@ -422,7 +451,7 @@ namespace rct {
|
|||||||
ar.end_array();
|
ar.end_array();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == RCTTypeCLSAG)
|
if ((type == RCTTypeCLSAG) || (type == RCTTypeCLSAGN))
|
||||||
{
|
{
|
||||||
ar.tag("CLSAGs");
|
ar.tag("CLSAGs");
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
@@ -513,7 +542,7 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
}
|
}
|
||||||
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG)
|
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN)
|
||||||
{
|
{
|
||||||
ar.tag("pseudoOuts");
|
ar.tag("pseudoOuts");
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
@@ -537,12 +566,12 @@ namespace rct {
|
|||||||
|
|
||||||
keyV& get_pseudo_outs()
|
keyV& get_pseudo_outs()
|
||||||
{
|
{
|
||||||
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG ? p.pseudoOuts : pseudoOuts;
|
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN ? p.pseudoOuts : pseudoOuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyV const& get_pseudo_outs() const
|
keyV const& get_pseudo_outs() const
|
||||||
{
|
{
|
||||||
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG ? p.pseudoOuts : pseudoOuts;
|
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN ? p.pseudoOuts : pseudoOuts;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user