rpc: change getunclaimed to getunclaimedgas

getunclaimed doesn't exist on Neo 3 and getunclaimedgas works for NEP5 GAS.
This commit is contained in:
Roman Khimov 2020-06-01 23:27:03 +03:00
parent d856df36a7
commit 657bb7575e
10 changed files with 58 additions and 93 deletions

View file

@ -51,7 +51,7 @@ which would yield the response:
| `getrawtransaction` | | `getrawtransaction` |
| `getstorage` | | `getstorage` |
| `gettransactionheight` | | `gettransactionheight` |
| `getunclaimed` | | `getunclaimedgas` |
| `getvalidators` | | `getvalidators` |
| `getversion` | | `getversion` |
| `invoke` | | `invoke` |
@ -73,6 +73,11 @@ in returning it.
Both methods also don't currently support arrays in function parameters. Both methods also don't currently support arrays in function parameters.
##### `getunclaimedgas`
It's possible to call this method for any address with neo-go, unlike with C#
node where it only works for addresses from opened wallet.
### Unsupported methods ### Unsupported methods
Methods listed down below are not going to be supported for various reasons Methods listed down below are not going to be supported for various reasons
@ -85,7 +90,6 @@ and we're not accepting issues related to them.
| `getbalance` | Use `getaccountstate` instead, see `claimgas` comment also | | `getbalance` | Use `getaccountstate` instead, see `claimgas` comment also |
| `getmetricblocktimestamp` | Not really useful, use other means for node monitoring | | `getmetricblocktimestamp` | Not really useful, use other means for node monitoring |
| `getnewaddress` | See `claimgas` comment | | `getnewaddress` | See `claimgas` comment |
| `getunclaimedgas` | Use `getunclaimed` instead, see `claimgas` comment also |
| `getwalletheight` | Not applicable to neo-go, see `claimgas` comment | | `getwalletheight` | Not applicable to neo-go, see `claimgas` comment |
| `importprivkey` | Not applicable to neo-go, see `claimgas` comment | | `importprivkey` | Not applicable to neo-go, see `claimgas` comment |
| `listaddress` | Not applicable to neo-go, see `claimgas` comment | | `listaddress` | Not applicable to neo-go, see `claimgas` comment |

View file

@ -930,6 +930,17 @@ func (bc *Blockchain) GetUtilityTokenBalance(acc util.Uint160) util.Fixed8 {
return util.Fixed8(bc.GetNEP5Balances(acc).Trackers[bc.contracts.GAS.Hash].Balance) return util.Fixed8(bc.GetNEP5Balances(acc).Trackers[bc.contracts.GAS.Hash].Balance)
} }
// GetGoverningTokenBalance returns governing token (NEO) balance and the height
// of the last balance change for the account.
func (bc *Blockchain) GetGoverningTokenBalance(acc util.Uint160) (util.Fixed8, uint32) {
bs, err := bc.dao.GetNEP5Balances(acc)
if err != nil {
return 0, 0
}
neo := bs.Trackers[bc.contracts.NEO.Hash]
return util.Fixed8(neo.Balance), neo.LastUpdatedBlock
}
// LastBatch returns last persisted storage batch. // LastBatch returns last persisted storage batch.
func (bc *Blockchain) LastBatch() *storage.MemBatch { func (bc *Blockchain) LastBatch() *storage.MemBatch {
return bc.lastBatch return bc.lastBatch

View file

@ -25,6 +25,7 @@ type Blockchainer interface {
GetBlock(hash util.Uint256) (*block.Block, error) GetBlock(hash util.Uint256) (*block.Block, error)
GetContractState(hash util.Uint160) *state.Contract GetContractState(hash util.Uint160) *state.Contract
GetEnrollments() ([]state.Validator, error) GetEnrollments() ([]state.Validator, error)
GetGoverningTokenBalance(acc util.Uint160) (util.Fixed8, uint32)
GetHeaderHash(int) util.Uint256 GetHeaderHash(int) util.Uint256
GetHeader(hash util.Uint256) (*block.Header, error) GetHeader(hash util.Uint256) (*block.Header, error)
CurrentHeaderHash() util.Uint256 CurrentHeaderHash() util.Uint256

View file

@ -138,6 +138,10 @@ func (chain testChain) IsLowPriority(util.Fixed8) bool {
panic("TODO") panic("TODO")
} }
func (chain testChain) GetGoverningTokenBalance(acc util.Uint160) (util.Fixed8, uint32) {
panic("TODO")
}
func (chain testChain) GetUtilityTokenBalance(uint160 util.Uint160) util.Fixed8 { func (chain testChain) GetUtilityTokenBalance(uint160 util.Uint160) util.Fixed8 {
panic("TODO") panic("TODO")
} }

View file

@ -35,7 +35,7 @@ Supported methods
getrawtransaction getrawtransaction
getstorage getstorage
gettransactionheight gettransactionheight
getunclaimed getunclaimedgas
getvalidators getvalidators
getversion getversion
invoke invoke
@ -52,7 +52,6 @@ Unsupported methods
getbalance getbalance
getmetricblocktimestamp getmetricblocktimestamp
getnewaddress getnewaddress
getunclaimedgas
getwalletheight getwalletheight
importprivkey importprivkey
listaddress listaddress

View file

@ -2,6 +2,7 @@ package client
import ( import (
"encoding/hex" "encoding/hex"
"strconv"
"github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
@ -307,16 +308,20 @@ func (c *Client) GetTransactionHeight(hash util.Uint256) (uint32, error) {
return resp, nil return resp, nil
} }
// GetUnclaimed returns unclaimed GAS amount of the specified address. // GetUnclaimedGas returns unclaimed GAS amount for the specified address.
func (c *Client) GetUnclaimed(address string) (*result.Unclaimed, error) { func (c *Client) GetUnclaimedGas(address string) (util.Fixed8, error) {
var ( var (
params = request.NewRawParams(address) params = request.NewRawParams(address)
resp = &result.Unclaimed{} resp string
) )
if err := c.performRequest("getunclaimed", params, resp); err != nil { if err := c.performRequest("getunclaimedgas", params, &resp); err != nil {
return nil, err return 0, err
} }
return resp, nil i, err := strconv.ParseInt(resp, 10, 64)
if err != nil {
return 0, err
}
return util.Fixed8(i), nil
} }
// GetValidators returns the current NEO consensus nodes information and voting status. // GetValidators returns the current NEO consensus nodes information and voting status.

View file

@ -670,19 +670,15 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
}, },
}, },
}, },
"getunclaimed": { "getunclaimedgas": {
{ {
name: "positive", name: "positive",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.GetUnclaimed("AGofsxAUDwt52KjaB664GYsqVAkULYvKNt") return c.GetUnclaimedGas("AGofsxAUDwt52KjaB664GYsqVAkULYvKNt")
}, },
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"available":750.032,"unavailable":2815.408,"unclaimed":3565.44}}`, serverResponse: `{"jsonrpc":"2.0","id":1,"result":"897299680935"}`,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {
return &result.Unclaimed{ return util.Fixed8(897299680935)
Available: util.Fixed8FromFloat(750.032),
Unavailable: util.Fixed8FromFloat(2815.408),
Unclaimed: util.Fixed8FromFloat(3565.44),
}
}, },
}, },
}, },
@ -1039,9 +1035,9 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
}, },
}, },
{ {
name: "getunclaimed_invalid_params_error", name: "getunclaimedgas_invalid_params_error",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.GetUnclaimed("") return c.GetUnclaimedGas("")
}, },
}, },
{ {
@ -1209,9 +1205,9 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
}, },
}, },
{ {
name: "getunclaimed_unmarshalling_error", name: "getunclaimedgas_unmarshalling_error",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.GetUnclaimed("") return c.GetUnclaimedGas("")
}, },
}, },
{ {

View file

@ -1,54 +0,0 @@
package result
import (
"github.com/nspcc-dev/neo-go/pkg/core"
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/util"
)
// Unclaimed wrapper is used to represent getunclaimed return result.
type Unclaimed struct {
Available util.Fixed8 `json:"available"`
Unavailable util.Fixed8 `json:"unavailable"`
Unclaimed util.Fixed8 `json:"unclaimed"`
}
// NewUnclaimed creates a new Unclaimed wrapper using given Blockchainer.
func NewUnclaimed(a *state.Account, chain blockchainer.Blockchainer) (*Unclaimed, error) {
var (
available util.Fixed8
unavailable util.Fixed8
)
err := a.Unclaimed.ForEach(func(ucb *state.UnclaimedBalance) error {
gen, sys, err := chain.CalculateClaimable(ucb.Value, ucb.Start, ucb.End)
if err != nil {
return err
}
available += gen + sys
return nil
})
if err != nil {
return nil, err
}
blockHeight := chain.BlockHeight()
for _, usb := range a.Balances[core.GoverningTokenID()] {
_, txHeight, err := chain.GetTransaction(usb.Tx)
if err != nil {
return nil, err
}
gen, sys, err := chain.CalculateClaimable(usb.Value, txHeight, blockHeight)
if err != nil {
return nil, err
}
unavailable += gen + sys
}
return &Unclaimed{
Available: available,
Unavailable: unavailable,
Unclaimed: available + unavailable,
}, nil
}

View file

@ -96,7 +96,7 @@ var rpcHandlers = map[string]func(*Server, request.Params) (interface{}, *respon
"getrawtransaction": (*Server).getrawtransaction, "getrawtransaction": (*Server).getrawtransaction,
"getstorage": (*Server).getStorage, "getstorage": (*Server).getStorage,
"gettransactionheight": (*Server).getTransactionHeight, "gettransactionheight": (*Server).getTransactionHeight,
"getunclaimed": (*Server).getUnclaimed, "getunclaimedgas": (*Server).getUnclaimedGas,
"getvalidators": (*Server).getValidators, "getvalidators": (*Server).getValidators,
"getversion": (*Server).getVersion, "getversion": (*Server).getVersion,
"invoke": (*Server).invoke, "invoke": (*Server).invoke,
@ -827,8 +827,8 @@ func (s *Server) getBlockHeader(reqParams request.Params) (interface{}, *respons
return hex.EncodeToString(buf.Bytes()), nil return hex.EncodeToString(buf.Bytes()), nil
} }
// getUnclaimed returns unclaimed GAS amount of the specified address. // getUnclaimedGas returns unclaimed GAS amount of the specified address.
func (s *Server) getUnclaimed(ps request.Params) (interface{}, *response.Error) { func (s *Server) getUnclaimedGas(ps request.Params) (interface{}, *response.Error) {
p, ok := ps.ValueWithType(0, request.StringT) p, ok := ps.ValueWithType(0, request.StringT)
if !ok { if !ok {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -838,15 +838,15 @@ func (s *Server) getUnclaimed(ps request.Params) (interface{}, *response.Error)
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
} }
acc := s.chain.GetAccountState(u) neo, neoHeight := s.chain.GetGoverningTokenBalance(u)
if acc == nil { if neo == 0 {
return nil, response.NewInternalServerError("unknown account", nil) return "0", nil
} }
res, errRes := result.NewUnclaimed(acc, s.chain) gasG, gasF, err := s.chain.CalculateClaimable(neo, neoHeight, s.chain.BlockHeight()+1) // +1 as in C#, for the next block.
if errRes != nil { if err != nil {
return nil, response.NewInternalServerError("can't create unclaimed response", errRes) return nil, response.NewInternalServerError("calculation error", err)
} }
return res, nil return strconv.FormatInt(int64(gasG+gasF), 10), nil // It's not represented as Fixed8 in C#.
} }
// getValidators returns the current NEO consensus nodes information and voting status. // getValidators returns the current NEO consensus nodes information and voting status.

View file

@ -507,7 +507,7 @@ var rpcTestCases = map[string][]rpcTestCase{
fail: true, fail: true,
}, },
}, },
"getunclaimed": { "getunclaimedgas": {
{ {
name: "no params", name: "no params",
params: "[]", params: "[]",
@ -522,14 +522,13 @@ var rpcTestCases = map[string][]rpcTestCase{
name: "positive", name: "positive",
params: `["` + testchain.MultisigAddress() + `"]`, params: `["` + testchain.MultisigAddress() + `"]`,
result: func(*executor) interface{} { result: func(*executor) interface{} {
return &result.Unclaimed{} var s string
return &s
}, },
check: func(t *testing.T, e *executor, uncl interface{}) { check: func(t *testing.T, e *executor, resp interface{}) {
res, ok := uncl.(*result.Unclaimed) s, ok := resp.(*string)
require.True(t, ok) require.True(t, ok)
assert.Equal(t, res.Available, util.Fixed8FromInt64(8)) assert.Equal(t, "1772", *s)
assert.True(t, res.Unavailable > 0)
assert.Equal(t, res.Available+res.Unavailable, res.Unclaimed)
}, },
}, },
}, },