transaction: set output position when decoding

We had a kludge for getrawtransaction to set this useless field, but
7e371588a7 broke it. Add it right into the
decoder now to fix all types of queries (getblock/getrawtransaction/gettxout).

Fixes #1392.
This commit is contained in:
Roman Khimov 2020-09-07 15:34:53 +03:00
parent 04ebef9119
commit 9aee3e5a34
3 changed files with 32 additions and 4 deletions

View file

@ -117,6 +117,7 @@ func (t *Transaction) DecodeBinary(br *io.BinReader) {
br.Err = errors.New("negative output") br.Err = errors.New("negative output")
return return
} }
t.Outputs[i].Position = i
} }
br.ReadArray(&t.Scripts) br.ReadArray(&t.Scripts)

View file

@ -30,10 +30,6 @@ type TransactionMetadata struct {
func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain core.Blockchainer) TransactionOutputRaw { func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain core.Blockchainer) TransactionOutputRaw {
// confirmations formula // confirmations formula
confirmations := int(chain.BlockHeight() - header.Base.Index + 1) confirmations := int(chain.BlockHeight() - header.Base.Index + 1)
// set index position
for i, o := range tx.Outputs {
o.Position = i
}
return TransactionOutputRaw{ return TransactionOutputRaw{
Transaction: tx, Transaction: tx,
TransactionMetadata: TransactionMetadata{ TransactionMetadata: TransactionMetadata{

View file

@ -1086,6 +1086,37 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
assert.Equal(t, TXHash, actual.Transaction.Hash()) assert.Equal(t, TXHash, actual.Transaction.Hash())
}) })
t.Run("getrawtransaction verbose, check outputs", func(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(1))
TXHash := block.Transactions[1].Hash()
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE())
body := doRPCCall(rpc, httpSrv.URL, t)
txOut := checkErrGetResult(t, body, false)
actual := result.TransactionOutputRaw{}
err := json.Unmarshal(txOut, &actual)
require.NoErrorf(t, err, "could not parse response: %s", txOut)
neoID := core.GoverningTokenID()
multiAddr, err := util.Uint160DecodeStringBE("be48d3a3f5d10013ab9ffee489706078714f1ea2")
require.NoError(t, err)
singleAddr, err := keys.NewPrivateKeyFromWIF("KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY")
require.NoError(t, err)
assert.Equal(t, transaction.ContractType, actual.Transaction.Type)
assert.Equal(t, []transaction.Output{
{
AssetID: neoID,
Amount: util.Fixed8FromInt64(99999000),
ScriptHash: singleAddr.GetScriptHash(),
Position: 0,
},
{
AssetID: neoID,
Amount: util.Fixed8FromInt64(1000),
ScriptHash: multiAddr,
Position: 1,
},
}, actual.Transaction.Outputs)
})
t.Run("gettxout", func(t *testing.T) { t.Run("gettxout", func(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
tx := block.Transactions[3] tx := block.Transactions[3]