mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-12 11:10:35 +00:00
rpc: fix gettxout result for already spent outputs
As per C# documentation [1]: If the transaction output is already spent, the result value will be null . [1]: https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/gettxout.html
This commit is contained in:
parent
124c674b17
commit
9e35758653
4 changed files with 25 additions and 8 deletions
|
@ -43,6 +43,11 @@ func (s *UnspentCoin) EncodeBinary(bw *io.BinWriter) {
|
|||
func (s *UnspentCoin) DecodeBinary(br *io.BinReader) {
|
||||
s.Height = br.ReadU32LE()
|
||||
br.ReadArray(&s.States)
|
||||
if br.Err == nil {
|
||||
for i := range s.States {
|
||||
s.States[i].Output.Position = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeBinary implements Serializable interface.
|
||||
|
|
|
@ -27,6 +27,7 @@ func TestDecodeEncodeUnspentCoin(t *testing.T) {
|
|||
AssetID: random.Uint256(),
|
||||
Amount: util.Fixed8(420),
|
||||
ScriptHash: random.Uint160(),
|
||||
Position: 1,
|
||||
},
|
||||
SpendHeight: 0,
|
||||
State: CoinConfirmed,
|
||||
|
@ -36,6 +37,7 @@ func TestDecodeEncodeUnspentCoin(t *testing.T) {
|
|||
AssetID: random.Uint256(),
|
||||
Amount: util.Fixed8(4200),
|
||||
ScriptHash: random.Uint160(),
|
||||
Position: 2,
|
||||
},
|
||||
SpendHeight: 111000,
|
||||
State: CoinSpent & CoinClaimed,
|
||||
|
|
|
@ -1207,17 +1207,19 @@ func (s *Server) getTxOut(ps request.Params) (interface{}, *response.Error) {
|
|||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
|
||||
tx, _, err := s.chain.GetTransaction(h)
|
||||
if err != nil {
|
||||
return nil, response.NewInvalidParamsError(err.Error(), err)
|
||||
ucs := s.chain.GetUnspentCoinState(h)
|
||||
if ucs == nil {
|
||||
return nil, response.NewInvalidParamsError("invalid tx hash", errors.New("unknown"))
|
||||
}
|
||||
|
||||
if num >= len(tx.Outputs) {
|
||||
if num >= len(ucs.States) {
|
||||
return nil, response.NewInvalidParamsError("invalid index", errors.New("too big index"))
|
||||
}
|
||||
|
||||
out := tx.Outputs[num]
|
||||
return result.NewTxOutput(&out), nil
|
||||
if ucs.States[num].State&state.CoinSpent != 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return result.NewTxOutput(&ucs.States[num].Output), nil
|
||||
}
|
||||
|
||||
// getContractState returns contract state (contract information, according to the contract script hash).
|
||||
|
|
|
@ -1204,13 +1204,21 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
|||
`"`+tx.Hash().StringLE()+`"`, 0)
|
||||
body := doRPCCall(rpc, httpSrv.URL, t)
|
||||
res := checkErrGetResult(t, body, false)
|
||||
assert.Equal(t, "null", string(res)) // already spent
|
||||
|
||||
block, _ = chain.GetBlock(e.chain.GetHeaderHash(1))
|
||||
tx = block.Transactions[1]
|
||||
rpc = fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "gettxout", "params": [%s, %d]}"`,
|
||||
`"`+tx.Hash().StringLE()+`"`, 1) // Neo remainder in txMoveNeo
|
||||
body = doRPCCall(rpc, httpSrv.URL, t)
|
||||
res = checkErrGetResult(t, body, false)
|
||||
|
||||
var txOut result.TransactionOutput
|
||||
err := json.Unmarshal(res, &txOut)
|
||||
require.NoErrorf(t, err, "could not parse response: %s", res)
|
||||
assert.Equal(t, 0, txOut.N)
|
||||
assert.Equal(t, 1, txOut.N)
|
||||
assert.Equal(t, "0x9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5", txOut.Asset)
|
||||
assert.Equal(t, util.Fixed8FromInt64(100000000), txOut.Value)
|
||||
assert.Equal(t, util.Fixed8FromInt64(1000), txOut.Value)
|
||||
assert.Equal(t, "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU", txOut.Address)
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue