From a9abd3d84110d09c07c3a5cd67c3dc90eff0824f Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 5 Mar 2020 19:44:09 +0300 Subject: [PATCH] core: fix wrong endian used in interop functions C# uses ToArray() or UintXXX(bytes) here which interprets hashes as they should be interpreted (BE, although they always convert to LE when converting to String just for the fun of it). It leads to state difference for us at block 2025204 where even though we have the same value for the key, the key itself differs, ours: dd2b538e2a0c1db1ae5061c15be14f916bd1e678e512ffcda6d9499d8e7fe97ee71fd6b8004583d9afe09cc4dadbd5deb63d01e061009b7cffdaa674beae0f930ebe6085af900093e5fe56b34a5c220ccdcf6efc336fc5000000000000000000000000000000000010 theirs: dd2b538e2a0c1db1ae5061c15be14f916bd1e67861e0013db6ded5dbdac49ce0afd9834500b8d61fe77ee97f8e9d49d9a6cdff12e5009b7cffdaa674beae0f930ebe6085af900093e5fe56b34a5c220ccdcf6efc336fc5000000000000000000000000000000000010 In this key there is a tx hash encoded (e512ffcda6d9499d8e7fe97ee71fd6b84583d9afe09cc4dadbd5deb63d01e061 in LE used by all the tools like neoscan). I love Neo. --- pkg/core/interop_neo.go | 4 ++-- pkg/core/interop_neo_test.go | 4 ++-- pkg/core/interop_system.go | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index a8ed517e5..7140b1fa2 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -60,7 +60,7 @@ func (ic *interopContext) headerGetMerkleRoot(v *vm.VM) error { if err != nil { return err } - v.Estack().PushVal(header.MerkleRoot.BytesLE()) + v.Estack().PushVal(header.MerkleRoot.BytesBE()) return nil } @@ -70,7 +70,7 @@ func (ic *interopContext) headerGetNextConsensus(v *vm.VM) error { if err != nil { return err } - v.Estack().PushVal(header.NextConsensus.BytesLE()) + v.Estack().PushVal(header.NextConsensus.BytesBE()) return nil } diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index e83d012b9..e701c94d2 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -147,7 +147,7 @@ func TestHeaderGetMerkleRoot(t *testing.T) { err := context.headerGetMerkleRoot(v) require.NoError(t, err) value := v.Estack().Pop().Value() - require.Equal(t, block.MerkleRoot.BytesLE(), value) + require.Equal(t, block.MerkleRoot.BytesBE(), value) } func TestHeaderGetNextConsensus(t *testing.T) { @@ -157,7 +157,7 @@ func TestHeaderGetNextConsensus(t *testing.T) { err := context.headerGetNextConsensus(v) require.NoError(t, err) value := v.Estack().Pop().Value() - require.Equal(t, block.NextConsensus.BytesLE(), value) + require.Equal(t, block.NextConsensus.BytesBE(), value) } func TestTxGetAttributes(t *testing.T) { diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index 81ea87299..59dcbc72a 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -41,7 +41,7 @@ func getBlockHashFromElement(bc Blockchainer, element *vm.Element) (util.Uint256 } hash = bc.GetHeaderHash(int(hashint)) } else { - return util.Uint256DecodeBytesLE(hashbytes) + return util.Uint256DecodeBytesBE(hashbytes) } return hash, nil } @@ -102,7 +102,7 @@ func (ic *interopContext) bcGetHeight(v *vm.VM) error { // returns transaction and its height if it's present in the blockchain. func getTransactionAndHeight(cd *cachedDao, v *vm.VM) (*transaction.Transaction, uint32, error) { hashbytes := v.Estack().Pop().Bytes() - hash, err := util.Uint256DecodeBytesLE(hashbytes) + hash, err := util.Uint256DecodeBytesBE(hashbytes) if err != nil { return nil, 0, err } @@ -161,7 +161,7 @@ func (ic *interopContext) headerGetHash(v *vm.VM) error { if err != nil { return err } - v.Estack().PushVal(header.Hash().BytesLE()) + v.Estack().PushVal(header.Hash().BytesBE()) return nil } @@ -171,7 +171,7 @@ func (ic *interopContext) headerGetPrevHash(v *vm.VM) error { if err != nil { return err } - v.Estack().PushVal(header.PrevHash.BytesLE()) + v.Estack().PushVal(header.PrevHash.BytesBE()) return nil } @@ -238,7 +238,7 @@ func (ic *interopContext) txGetHash(v *vm.VM) error { if !ok { return errors.New("value is not a transaction") } - v.Estack().PushVal(tx.Hash().BytesLE()) + v.Estack().PushVal(tx.Hash().BytesBE()) return nil }