From b32e1729f24b1c86b3f4be0e1c7f13dac57756c5 Mon Sep 17 00:00:00 2001 From: Niven Date: Tue, 5 Sep 2023 18:00:32 +0800 Subject: [PATCH] Fix witness v16 endianness (#2369) * Add support for unit testing * Add erc55 and wpkh key tests * Rename test py to functional tests * Add test-cpp and test-rs * Remove func test, rename to test-units * Fix test func * Fix endianness for witnessv16 to LE * Fix transferdomain rpc * Fix getaccount RPC for evm account * Add helper comments for legacy func * Revert test test_runner * Fix transferdomain test * Fix py lint * Add script to destination key tests * Encode key ID from serialised block * Apply missing changes post-merge --------- Co-authored-by: Bushstar Co-authored-by: Prasanna Loganathar --- src/hash.h | 8 +++++--- src/key_io.cpp | 3 ++- src/masternodes/consensus/xvm.cpp | 8 ++++---- src/masternodes/rpc_accounts.cpp | 4 ++-- src/masternodes/rpc_evm.cpp | 2 +- src/miner.cpp | 3 +-- src/script/standard.cpp | 5 ----- src/script/standard.h | 1 - src/test/key_tests.cpp | 1 + 9 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/hash.h b/src/hash.h index 78e1d3e807..bc6a9928f7 100644 --- a/src/hash.h +++ b/src/hash.h @@ -129,10 +129,12 @@ inline uint160 Hash160(const prevector& vch) } inline uint160 EthHash160(const std::vector& vch) { - std::vector output; - sha3_256_safe(vch, output); + std::vector result; + sha3_256_safe(vch, result); const size_t ADDRESS_OFFSET{12}; - return uint160({output.begin() + ADDRESS_OFFSET, output.end()}); + std::vector output(result.begin() + ADDRESS_OFFSET, result.end()); + std::reverse(output.begin(), output.end()); + return uint160(output); } /** A writer stream (for serialization) that computes a 256-bit hash. */ diff --git a/src/key_io.cpp b/src/key_io.cpp index 3a08819283..9d408df90b 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -63,7 +63,7 @@ class DestinationEncoder { // Raw addr = ETH_ADDR_PREFIX + HexStr(id); // Produce ERC55 checksum address: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md - const auto address = HexStr(id); + const auto address = id.GetHex(); std::vector input(address.begin(), address.end()); std::vector output; sha3_256_safe(input, output); @@ -93,6 +93,7 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par return CNoDestination(); } data = ParseHex(hex); + std::reverse(data.begin(), data.end()); return WitnessV16EthHash(uint160(data)); } if (DecodeBase58Check(str, data)) { diff --git a/src/masternodes/consensus/xvm.cpp b/src/masternodes/consensus/xvm.cpp index ef11e59162..ce827e8bca 100644 --- a/src/masternodes/consensus/xvm.cpp +++ b/src/masternodes/consensus/xvm.cpp @@ -209,14 +209,14 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { auto tokenId = dst.amount.nTokenId; CrossBoundaryResult result; if (tokenId == DCT_ID{0}) { - evm_unsafe_try_add_balance_in_q(result, evmQueueId, toAddress.ToHexString(), balanceIn, tx.GetHash().GetHex()); + evm_unsafe_try_add_balance_in_q(result, evmQueueId, toAddress.GetHex(), balanceIn, tx.GetHash().GetHex()); if (!result.ok) { return Res::Err("Error bridging DFI: %s", result.reason); } } else { CrossBoundaryResult result; - evm_try_bridge_dst20(result, evmQueueId, toAddress.ToHexString(), balanceIn, tx.GetHash().GetHex(), tokenId.v, false); + evm_try_bridge_dst20(result, evmQueueId, toAddress.GetHex(), balanceIn, tx.GetHash().GetHex(), tokenId.v, false); if (!result.ok) { return Res::Err("Error bridging DST20: %s", result.reason); } @@ -235,7 +235,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { auto tokenId = dst.amount.nTokenId; if (tokenId == DCT_ID{0}) { CrossBoundaryResult result; - if (!evm_unsafe_try_sub_balance_in_q(result, evmQueueId, fromAddress.ToHexString(), balanceIn, tx.GetHash().GetHex())) { + if (!evm_unsafe_try_sub_balance_in_q(result, evmQueueId, fromAddress.GetHex(), balanceIn, tx.GetHash().GetHex())) { return DeFiErrors::TransferDomainNotEnoughBalance(EncodeDestination(dest)); } if (!result.ok) { @@ -244,7 +244,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const { } else { CrossBoundaryResult result; - evm_try_bridge_dst20(result, evmQueueId, fromAddress.ToHexString(), balanceIn, tx.GetHash().GetHex(), tokenId.v, true); + evm_try_bridge_dst20(result, evmQueueId, fromAddress.GetHex(), balanceIn, tx.GetHash().GetHex(), tokenId.v, true); if (!result.ok) { return Res::Err("Error bridging DST20: %s", result.reason); } diff --git a/src/masternodes/rpc_accounts.cpp b/src/masternodes/rpc_accounts.cpp index 30cb9f82b8..9449e39d4b 100644 --- a/src/masternodes/rpc_accounts.cpp +++ b/src/masternodes/rpc_accounts.cpp @@ -477,7 +477,7 @@ UniValue getaccount(const JSONRPCRequest& request) { CTxDestination dest; if (ExtractDestination(reqOwner, dest) && dest.index() == WitV16KeyEthHashType) { const auto keyID = std::get(dest); - auto r = XResultValue(evm_try_get_balance(result, keyID.ToHexString())); + auto r = XResultValue(evm_try_get_balance(result, keyID.GetHex())); if (!r) throw JSONRPCError(RPC_MISC_ERROR, r.msg); if (const auto balance = *r) { balances[DCT_ID{}] = balance; @@ -605,7 +605,7 @@ UniValue gettokenbalances(const JSONRPCRequest& request) { if (evm_dfi_lookup) { for (const auto keyID : pwallet->GetKeys()) { // TODO: Use GetHex when eth key is fixed to be stored in LE - auto res = XResultValue(evm_try_get_balance(result, HexStr(keyID))); + auto res = XResultValue(evm_try_get_balance(result, keyID.GetHex())); if (res) { auto evmAmount = *res; totalBalances.Add({{}, static_cast(evmAmount)}); diff --git a/src/masternodes/rpc_evm.cpp b/src/masternodes/rpc_evm.cpp index 1c3e15a749..26b06fbd4f 100644 --- a/src/masternodes/rpc_evm.cpp +++ b/src/masternodes/rpc_evm.cpp @@ -107,7 +107,7 @@ UniValue evmtx(const JSONRPCRequest &request) { } const auto toEth = std::get(toDest); - to = toEth.ToHexString(); + to = toEth.GetHex(); } rust::Vec input{}; diff --git a/src/miner.cpp b/src/miner.cpp index 5d262574cd..4ece5ca4e1 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1154,8 +1154,7 @@ Staker::Status Staker::stake(const CChainParams& chainparams, const ThreadStaker if (pubKey.IsCompressed()) { pubKey.Decompress(); } - // TODO: Use GetHex when eth key is fixed to be stored in LE - const auto evmBeneficiary = HexStr(pubKey.GetEthID()); + const auto evmBeneficiary = pubKey.GetEthID().GetHex(); auto pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, blockTime, evmBeneficiary); if (!pblocktemplate) { LogPrintf("Error: WalletStaker: Keypool ran out, keypoolrefill and restart required\n"); diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 5b2a108f94..cb20c0b181 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -29,11 +29,6 @@ WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : uint160(pubkey.GetID WitnessV16EthHash::WitnessV16EthHash(const CPubKey& pubkey) : uint160(pubkey.GetEthID()) {} -// TO DO: Remove this temporary fix to return hex string, once EthHash is switched from big endian to little endian. -std::string WitnessV16EthHash::ToHexString() const { - return HexStr(data, data + sizeof(data)); -} - const char* GetTxnOutputType(txnouttype t) { switch (t) diff --git a/src/script/standard.h b/src/script/standard.h index 140688fe37..42442b0882 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -114,7 +114,6 @@ struct WitnessV16EthHash : public uint160 { WitnessV16EthHash() : uint160() {} explicit WitnessV16EthHash(const uint160& hash) : uint160(hash) {} explicit WitnessV16EthHash(const CPubKey& pubkey); - std::string ToHexString() const; using uint160::uint160; }; diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 742c994981..a04f1f6db6 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -16,6 +16,7 @@ #include +// private keys static const std::string strSecret1 = "5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj"; static const std::string strSecret2 = "5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3"; static const std::string strSecret1C = "Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw";