From d5d570f79335f4ed21d1ba9867e2a32a10461507 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 22 Aug 2019 20:33:58 +0300 Subject: [PATCH] uint256: add Reverse(), change String() to be BE This one makes a little more obvious that we're operating with LE representations mostly. Refs. #307. See #314 also. --- _pkg.dev/wire/util/uint256.go | 77 ------------------------ _pkg.dev/wire/util/uint256_test.go | 50 --------------- pkg/core/block_test.go | 6 +- pkg/core/blockchain_test.go | 2 +- pkg/core/storage/helpers.go | 2 +- pkg/core/transaction/register_test.go | 2 +- pkg/core/transaction/transaction_test.go | 4 +- pkg/core/util_test.go | 6 +- pkg/crypto/merkle_tree_test.go | 4 +- pkg/rpc/neoScanBalanceGetter.go | 2 +- pkg/rpc/rpc.go | 2 +- pkg/rpc/server.go | 8 +-- pkg/rpc/stack_param.go | 2 +- pkg/rpc/stack_param_test.go | 4 +- pkg/util/uint256.go | 27 ++++++--- pkg/util/uint256_test.go | 14 ++--- 16 files changed, 48 insertions(+), 164 deletions(-) delete mode 100644 _pkg.dev/wire/util/uint256.go delete mode 100644 _pkg.dev/wire/util/uint256_test.go diff --git a/_pkg.dev/wire/util/uint256.go b/_pkg.dev/wire/util/uint256.go deleted file mode 100644 index fc3fe86ca..000000000 --- a/_pkg.dev/wire/util/uint256.go +++ /dev/null @@ -1,77 +0,0 @@ -package util - -import ( - "encoding/hex" - "encoding/json" - "fmt" - - "github.com/CityOfZion/neo-go/pkg/wire/util/slice" -) - -const uint256Size = 32 - -// Uint256 is a 32 byte long unsigned integer. -type Uint256 [uint256Size]uint8 - -// Uint256DecodeString attempts to decode the given string into an Uint256. -func Uint256DecodeString(s string) (u Uint256, err error) { - if len(s) != uint256Size*2 { - return u, fmt.Errorf("expected string size of %d got %d", uint256Size*2, len(s)) - } - b, err := hex.DecodeString(s) - if err != nil { - return u, err - } - return Uint256DecodeBytes(b) -} - -// Uint256DecodeBytes attempts to decode the given string into an Uint256. -func Uint256DecodeBytes(b []byte) (u Uint256, err error) { - if len(b) != uint256Size { - return u, fmt.Errorf("expected []byte of size %d got %d", uint256Size, len(b)) - } - for i := 0; i < uint256Size; i++ { - u[i] = b[i] - } - return u, nil -} - -// Bytes returns a byte slice representation of u. -func (u Uint256) Bytes() []byte { - b := make([]byte, uint256Size) - for i := 0; i < uint256Size; i++ { - b[i] = byte(u[i]) - } - return b -} - -// Reverse reverses the Uint256 object -func (u Uint256) Reverse() Uint256 { - res, _ := Uint256DecodeBytes(u.BytesReverse()) - return res -} - -// BytesReverse return a reversed byte representation of u. -func (u Uint256) BytesReverse() []byte { - return slice.Reverse(u.Bytes()) -} - -// Equals returns true if both Uint256 values are the same. -func (u Uint256) Equals(other Uint256) bool { - return u.String() == other.String() -} - -// String implements the stringer interface. -func (u Uint256) String() string { - return hex.EncodeToString(u.Bytes()) -} - -// ReverseString displays a reverse string representation of Uint256. -func (u Uint256) ReverseString() string { - return hex.EncodeToString(slice.Reverse(u.Bytes())) -} - -// MarshalJSON implements the json marshaller interface. -func (u Uint256) MarshalJSON() ([]byte, error) { - return json.Marshal(fmt.Sprintf("0x%s", u.String())) -} diff --git a/_pkg.dev/wire/util/uint256_test.go b/_pkg.dev/wire/util/uint256_test.go deleted file mode 100644 index ae6b8a438..000000000 --- a/_pkg.dev/wire/util/uint256_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package util - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestUint256DecodeString(t *testing.T) { - hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - val, err := Uint256DecodeString(hexStr) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, hexStr, val.String()) -} - -func TestUint256DecodeBytes(t *testing.T) { - hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - b, err := hex.DecodeString(hexStr) - if err != nil { - t.Fatal(err) - } - val, err := Uint256DecodeBytes(b) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, hexStr, val.String()) -} - -func TestUInt256Equals(t *testing.T) { - a := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - b := "e287c5b29a1b66092be6803c59c765308ac20287e1b4977fd399da5fc8f66ab5" - - ua, err := Uint256DecodeString(a) - if err != nil { - t.Fatal(err) - } - ub, err := Uint256DecodeString(b) - if err != nil { - t.Fatal(err) - } - if ua.Equals(ub) { - t.Fatalf("%s and %s cannot be equal", ua, ub) - } - if !ua.Equals(ua) { - t.Fatalf("%s and %s must be equal", ua, ua) - } -} diff --git a/pkg/core/block_test.go b/pkg/core/block_test.go index 9ae7f2a98..a3f660d97 100644 --- a/pkg/core/block_test.go +++ b/pkg/core/block_test.go @@ -30,9 +30,9 @@ func TestDecodeBlock1(t *testing.T) { assert.Equal(t, uint32(data["index"].(float64)), block.Index) assert.Equal(t, uint32(data["version"].(float64)), block.Version) - assert.Equal(t, data["hash"].(string), block.Hash().String()) - assert.Equal(t, data["previousblockhash"].(string), block.PrevHash.String()) - assert.Equal(t, data["merkleroot"].(string), block.MerkleRoot.String()) + assert.Equal(t, data["hash"].(string), block.Hash().ReverseString()) + assert.Equal(t, data["previousblockhash"].(string), block.PrevHash.ReverseString()) + assert.Equal(t, data["merkleroot"].(string), block.MerkleRoot.ReverseString()) assert.Equal(t, data["nextconsensus"].(string), crypto.AddressFromUint160(block.NextConsensus)) script := data["script"].(map[string]interface{}) diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index 7dbe23637..aec494683 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -185,7 +185,7 @@ func getTestBlockchain(t *testing.T) *Blockchain { func getTestTransaction(txID string, t *testing.T) *transaction.Transaction { chain := getTestBlockchain(t) - txHash, err := util.Uint256DecodeString(txID) + txHash, err := util.Uint256DecodeReverseString(txID) require.NoErrorf(t, err, "could not decode string %s to Uint256", txID) tx, _, err := chain.GetTransaction(txHash) diff --git a/pkg/core/storage/helpers.go b/pkg/core/storage/helpers.go index 88dde7a5a..d62f2bcfc 100644 --- a/pkg/core/storage/helpers.go +++ b/pkg/core/storage/helpers.go @@ -38,7 +38,7 @@ func CurrentHeaderHeight(s Store) (i uint32, h util.Uint256, err error) { return } i = binary.LittleEndian.Uint32(b[32:36]) - h, err = util.Uint256DecodeBytes(b[:32]) + h, err = util.Uint256DecodeReverseBytes(b[:32]) return } diff --git a/pkg/core/transaction/register_test.go b/pkg/core/transaction/register_test.go index b9d83e078..00ef0f218 100644 --- a/pkg/core/transaction/register_test.go +++ b/pkg/core/transaction/register_test.go @@ -52,7 +52,7 @@ func TestDecodeRegisterTXFromRawString(t *testing.T) { assert.Equal(t, uint8(0), txData.Precision) assert.Equal(t, &crypto.PublicKey{}, txData.Owner) assert.Equal(t, "Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt", crypto.AddressFromUint160(txData.Admin)) - assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().String()) + assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().ReverseString()) buf := new(bytes.Buffer) assert.Nil(t, tx.EncodeBinary(buf)) diff --git a/pkg/core/transaction/transaction_test.go b/pkg/core/transaction/transaction_test.go index c8761db10..6c1633cae 100644 --- a/pkg/core/transaction/transaction_test.go +++ b/pkg/core/transaction/transaction_test.go @@ -59,7 +59,7 @@ func TestDecodeEncodeClaimTX(t *testing.T) { assert.Equal(t, 1, len(tx.Outputs)) address := crypto.AddressFromUint160(tx.Outputs[0].ScriptHash) assert.Equal(t, "AQJseD8iBmCD4sgfHRhMahmoi9zvopG6yz", address) - assert.Equal(t, "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7", tx.Outputs[0].AssetID.String()) + assert.Equal(t, "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7", tx.Outputs[0].AssetID.ReverseString()) assert.Equal(t, tx.Outputs[0].Amount.String(), "0.06247739") invoc := "40456349cec43053009accdb7781b0799c6b591c812768804ab0a0b56b5eae7a97694227fcd33e70899c075848b2cee8fae733faac6865b484d3f7df8949e2aadb" verif := "2103945fae1ed3c31d778f149192b76734fcc951b400ba3598faa81ff92ebe477eacac" @@ -74,7 +74,7 @@ func TestDecodeEncodeClaimTX(t *testing.T) { assert.Equal(t, rawClaimTX, hex.EncodeToString(buf.Bytes())) hash := "2c6a45547b3898318e400e541628990a07acb00f3b9a15a8e966ae49525304da" - assert.Equal(t, hash, tx.hash.String()) + assert.Equal(t, hash, tx.hash.ReverseString()) } func TestDecodeEncodeInvocationTX(t *testing.T) { diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index 4d48bb359..ba8233756 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -20,7 +20,7 @@ func TestGenesisBlockMainNet(t *testing.T) { } expect := "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf" - assert.Equal(t, expect, block.Hash().String()) + assert.Equal(t, expect, block.Hash().ReverseString()) } func TestGetConsensusAddressMainNet(t *testing.T) { @@ -51,11 +51,11 @@ func TestGetConsensusAddressMainNet(t *testing.T) { func TestUtilityTokenTX(t *testing.T) { expect := "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7" tx := utilityTokenTX() - assert.Equal(t, expect, tx.Hash().String()) + assert.Equal(t, expect, tx.Hash().ReverseString()) } func TestGoverningTokenTX(t *testing.T) { expect := "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" tx := governingTokenTX() - assert.Equal(t, expect, tx.Hash().String()) + assert.Equal(t, expect, tx.Hash().ReverseString()) } diff --git a/pkg/crypto/merkle_tree_test.go b/pkg/crypto/merkle_tree_test.go index 4be94f786..413671c80 100644 --- a/pkg/crypto/merkle_tree_test.go +++ b/pkg/crypto/merkle_tree_test.go @@ -17,7 +17,7 @@ func TestComputeMerkleTree(t *testing.T) { hashes := make([]util.Uint256, len(rawHashes)) for i, str := range rawHashes { - hash, _ := util.Uint256DecodeString(str) + hash, _ := util.Uint256DecodeReverseString(str) hashes[i] = hash } @@ -25,5 +25,5 @@ func TestComputeMerkleTree(t *testing.T) { if err != nil { t.Fatal(err) } - assert.Equal(t, "803ff4abe3ea6533bcc0be574efa02f83ae8fdc651c879056b0d9be336c01bf4", merkle.Root().String()) + assert.Equal(t, "803ff4abe3ea6533bcc0be574efa02f83ae8fdc651c879056b0d9be336c01bf4", merkle.Root().ReverseString()) } diff --git a/pkg/rpc/neoScanBalanceGetter.go b/pkg/rpc/neoScanBalanceGetter.go index 6bd243042..d763d5f24 100644 --- a/pkg/rpc/neoScanBalanceGetter.go +++ b/pkg/rpc/neoScanBalanceGetter.go @@ -57,7 +57,7 @@ func (s NeoScanServer) CalculateInputs(address string, assetIdUint util.Uint256, selected = util.Fixed8(0) us []*Unspent assetUnspent Unspent - assetId = GlobalAssets[assetIdUint.String()] + assetId = GlobalAssets[assetIdUint.ReverseString()] ) if us, err = s.GetBalance(address); err != nil { return nil, util.Fixed8(0), errs.Wrapf(err, "Cannot get balance for address %v", address) diff --git a/pkg/rpc/rpc.go b/pkg/rpc/rpc.go index a4c09aa49..cdf60be7e 100644 --- a/pkg/rpc/rpc.go +++ b/pkg/rpc/rpc.go @@ -139,7 +139,7 @@ func (c *Client) SendToAddress(asset util.Uint256, address string, amount util.F response.ID = resp.ID response.JSONRPC = resp.JSONRPC response.Result = &TxResponse{ - TxID: rawTx.Hash().String(), + TxID: rawTx.Hash().ReverseString(), } return response, nil } diff --git a/pkg/rpc/server.go b/pkg/rpc/server.go index ce7b62fe3..c6a1a2669 100644 --- a/pkg/rpc/server.go +++ b/pkg/rpc/server.go @@ -107,7 +107,7 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *Request, reqParams Pa Methods: switch req.Method { case "getbestblockhash": - results = s.chain.CurrentBlockHash().String() + results = s.chain.CurrentBlockHash().ReverseString() case "getblock": var hash util.Uint256 @@ -120,7 +120,7 @@ Methods: switch param.Type { case "string": - hash, err = util.Uint256DecodeString(param.StringVal) + hash, err = util.Uint256DecodeReverseString(param.StringVal) if err != nil { resultsErr = errInvalidParams break Methods @@ -204,7 +204,7 @@ Methods: break Methods } - paramAssetID, err := util.Uint256DecodeString(param.StringVal) + paramAssetID, err := util.Uint256DecodeReverseString(param.StringVal) if err != nil { resultsErr = errInvalidParams break @@ -253,7 +253,7 @@ func (s *Server) getrawtransaction(reqParams Params) (interface{}, error) { param0, err := reqParams.ValueWithType(0, "string") if err != nil { resultsErr = err - } else if txHash, err := util.Uint256DecodeString(param0.StringVal); err != nil { + } else if txHash, err := util.Uint256DecodeReverseString(param0.StringVal); err != nil { resultsErr = errInvalidParams } else if tx, height, err := s.chain.GetTransaction(txHash); err != nil { err = errors.Wrapf(err, "Invalid transaction hash: %s", txHash) diff --git a/pkg/rpc/stack_param.go b/pkg/rpc/stack_param.go index bea6bf882..ff62b5424 100644 --- a/pkg/rpc/stack_param.go +++ b/pkg/rpc/stack_param.go @@ -214,7 +214,7 @@ func (p StackParam) TryParse(dest interface{}) error { *dest = data return nil case *util.Uint256: - if *dest, err = util.Uint256DecodeBytes(data); err != nil { + if *dest, err = util.Uint256DecodeReverseBytes(data); err != nil { return err } return nil diff --git a/pkg/rpc/stack_param_test.go b/pkg/rpc/stack_param_test.go index e1fd8a60d..6aa602475 100644 --- a/pkg/rpc/stack_param_test.go +++ b/pkg/rpc/stack_param_test.go @@ -90,7 +90,7 @@ func TestStackParam_UnmarshalJSON(t *testing.T) { if err != nil { t.Errorf("error while unmarhsalling: %v", err) } - h256, err := util.Uint256DecodeString("f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d") + h256, err := util.Uint256DecodeReverseString("f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d") if err != nil { t.Errorf("unmarshal error: %v", err) } @@ -149,7 +149,7 @@ func TestStackParam_TryParse(t *testing.T) { Value: data, } ) - expectedUint256, err = util.Uint256DecodeString(hash256) + expectedUint256, err = util.Uint256DecodeReverseString(hash256) if err != nil { t.Fatal(err) } diff --git a/pkg/util/uint256.go b/pkg/util/uint256.go index 9565cb956..07eb73001 100644 --- a/pkg/util/uint256.go +++ b/pkg/util/uint256.go @@ -13,8 +13,8 @@ const uint256Size = 32 // Uint256 is a 32 byte long unsigned integer. type Uint256 [uint256Size]uint8 -// Uint256DecodeString attempts to decode the given string into an Uint256. -func Uint256DecodeString(s string) (u Uint256, err error) { +// Uint256DecodeReverseString attempts to decode the given string (in LE representation) into an Uint256. +func Uint256DecodeReverseString(s string) (u Uint256, err error) { if len(s) != uint256Size*2 { return u, fmt.Errorf("expected string size of %d got %d", uint256Size*2, len(s)) } @@ -22,11 +22,11 @@ func Uint256DecodeString(s string) (u Uint256, err error) { if err != nil { return u, err } - return Uint256DecodeBytes(b) + return Uint256DecodeReverseBytes(b) } -// Uint256DecodeBytes attempts to decode the given string into an Uint256. -func Uint256DecodeBytes(b []byte) (u Uint256, err error) { +// Uint256DecodeReverseBytes attempts to decode the given string (in LE representation) into an Uint256. +func Uint256DecodeReverseBytes(b []byte) (u Uint256, err error) { b = ArrayReverse(b) if len(b) != uint256Size { return u, fmt.Errorf("expected []byte of size %d got %d", uint256Size, len(b)) @@ -40,6 +40,12 @@ func (u Uint256) Bytes() []byte { return u[:] } +// Reverse reverses the Uint256 object +func (u Uint256) Reverse() Uint256 { + res, _ := Uint256DecodeReverseBytes(u.Bytes()) + return res +} + // BytesReverse return a reversed byte representation of u. func (u Uint256) BytesReverse() []byte { return ArrayReverse(u.Bytes()) @@ -52,7 +58,12 @@ func (u Uint256) Equals(other Uint256) bool { // String implements the stringer interface. func (u Uint256) String() string { - return hex.EncodeToString(ArrayReverse(u.Bytes())) + return hex.EncodeToString(u.Bytes()) +} + +// ReverseString produces string representation of Uint256 with LE byte order. +func (u Uint256) ReverseString() string { + return hex.EncodeToString(u.BytesReverse()) } // UnmarshalJSON implements the json unmarshaller interface. @@ -62,7 +73,7 @@ func (u *Uint256) UnmarshalJSON(data []byte) (err error) { return err } js = strings.TrimPrefix(js, "0x") - *u, err = Uint256DecodeString(js) + *u, err = Uint256DecodeReverseString(js) return err } @@ -73,7 +84,7 @@ func (u Uint256) Size() int { // MarshalJSON implements the json marshaller interface. func (u Uint256) MarshalJSON() ([]byte, error) { - return []byte(`"0x` + u.String() + `"`), nil + return []byte(`"0x` + u.ReverseString() + `"`), nil } // CompareTo compares two Uint256 with each other. Possible output: 1, -1, 0 diff --git a/pkg/util/uint256_test.go b/pkg/util/uint256_test.go index 6e7371945..fcd23e479 100644 --- a/pkg/util/uint256_test.go +++ b/pkg/util/uint256_test.go @@ -9,7 +9,7 @@ import ( func TestUint256UnmarshalJSON(t *testing.T) { str := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - expected, err := Uint256DecodeString(str) + expected, err := Uint256DecodeReverseString(str) if err != nil { t.Fatal(err) } @@ -36,11 +36,11 @@ func TestUint256UnmarshalJSON(t *testing.T) { func TestUint256DecodeString(t *testing.T) { hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - val, err := Uint256DecodeString(hexStr) + val, err := Uint256DecodeReverseString(hexStr) if err != nil { t.Fatal(err) } - assert.Equal(t, hexStr, val.String()) + assert.Equal(t, hexStr, val.ReverseString()) } func TestUint256DecodeBytes(t *testing.T) { @@ -49,22 +49,22 @@ func TestUint256DecodeBytes(t *testing.T) { if err != nil { t.Fatal(err) } - val, err := Uint256DecodeBytes(b) + val, err := Uint256DecodeReverseBytes(b) if err != nil { t.Fatal(err) } - assert.Equal(t, hexStr, val.String()) + assert.Equal(t, hexStr, val.ReverseString()) } func TestUInt256Equals(t *testing.T) { a := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" b := "e287c5b29a1b66092be6803c59c765308ac20287e1b4977fd399da5fc8f66ab5" - ua, err := Uint256DecodeString(a) + ua, err := Uint256DecodeReverseString(a) if err != nil { t.Fatal(err) } - ub, err := Uint256DecodeString(b) + ub, err := Uint256DecodeReverseString(b) if err != nil { t.Fatal(err) }