diff --git a/src/base/crypto/Coin.cpp b/src/base/crypto/Coin.cpp index b63570e1d..2508e9cc7 100644 --- a/src/base/crypto/Coin.cpp +++ b/src/base/crypto/Coin.cpp @@ -53,6 +53,7 @@ static const CoinInfo coinInfo[] = { { Algorithm::RX_KEVA, "KVA", "Kevacoin", 0, 0, MAGENTA_BG_BOLD(WHITE_BOLD_S " keva ") }, { Algorithm::KAWPOW_RVN, "RVN", "Ravencoin", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " raven ") }, { Algorithm::RX_WOW, "WOW", "Wownero", 300, 100000000000, MAGENTA_BG_BOLD(WHITE_BOLD_S " wownero ") }, + { Algorithm::RX_0, "ZEPH", "Zephyr", 120, 1000000000000, BLUE_BG_BOLD( WHITE_BOLD_S " zephyr ") }, }; diff --git a/src/base/crypto/Coin.h b/src/base/crypto/Coin.h index fbd36371f..166618b19 100644 --- a/src/base/crypto/Coin.h +++ b/src/base/crypto/Coin.h @@ -39,6 +39,7 @@ public: KEVA, RAVEN, WOWNERO, + ZEPHYR, MAX }; diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index 6ce49679e..6f73ec700 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -197,6 +197,11 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_vote); } + if (m_coin == Coin::ZEPHYR) { + uint8_t pricing_record[24]; + ar(pricing_record); + } + // Miner transaction begin // Prefix begin setOffset(MINER_TX_PREFIX_OFFSET, ar.index()); @@ -220,8 +225,8 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_height); ar(m_numOutputs); - // must be 1 output - if (m_numOutputs != 1) { + const uint64_t expected_outputs = (m_coin == Coin::ZEPHYR) ? 2 : 1; + if (m_numOutputs != expected_outputs) { return false; } @@ -237,7 +242,35 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_ephPublicKey, kKeySize); - if (m_outputType == 3) { + if (m_coin == Coin::ZEPHYR) { + if (m_outputType != 2) { + return false; + } + + uint64_t asset_type_len; + ar(asset_type_len); + ar.skip(asset_type_len); + ar(m_viewTag); + + uint64_t amount2; + ar(amount2); + + uint8_t output_type2; + ar(output_type2); + if (output_type2 != 2) { + return false; + } + + Span key2; + ar(key2, kKeySize); + + ar(asset_type_len); + ar.skip(asset_type_len); + + uint8_t view_tag2; + ar(view_tag2); + } + else if (m_outputType == 3) { ar(m_viewTag); } @@ -248,6 +281,8 @@ bool xmrig::BlockTemplate::parse(bool hashes) BlobReader ar_extra(blob(TX_EXTRA_OFFSET), m_extraSize); ar.skip(m_extraSize); + bool pubkey_offset_first = true; + while (ar_extra.index() < m_extraSize) { uint64_t extra_tag = 0; uint64_t size = 0; @@ -256,7 +291,10 @@ bool xmrig::BlockTemplate::parse(bool hashes) switch (extra_tag) { case 0x01: // TX_EXTRA_TAG_PUBKEY - setOffset(TX_PUBKEY_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index()); + if (pubkey_offset_first) { + pubkey_offset_first = false; + setOffset(TX_PUBKEY_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index()); + } ar_extra.skip(kKeySize); break;