Implemented rcp method GetAssetState (#103)

* Fix missing dot in configPath

* Add rpc GetAssetState method

* Update rpc README.md

* Update version to 0.45.10
This commit is contained in:
dauTT 2018-11-26 22:12:33 +01:00 committed by Anthony De Meulemeester
parent de45c58551
commit e2f42e92a0
10 changed files with 120 additions and 7 deletions

View file

@ -1 +1 @@
0.44.11
0.45.11

View file

@ -40,7 +40,7 @@ func startServer(ctx *cli.Context) error {
net = config.ModeMainNet
}
configPath := "./config"
configPath := "../config"
if argCp := ctx.String("config-path"); argCp != "" {
configPath = argCp
}

View file

@ -38,6 +38,7 @@ type AssetState struct {
Available util.Fixed8
Precision uint8
FeeMode uint8
FeeAddress util.Uint160
Owner *crypto.PublicKey
Admin util.Uint160
Issuer util.Uint160
@ -72,6 +73,9 @@ func (a *AssetState) DecodeBinary(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &a.FeeMode); err != nil {
return err
}
if err := binary.Read(r, binary.LittleEndian, &a.FeeAddress); err != nil {
return err
}
a.Owner = &crypto.PublicKey{}
if err := a.Owner.DecodeBinary(r); err != nil {
@ -115,6 +119,11 @@ func (a *AssetState) EncodeBinary(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, a.FeeMode); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, a.FeeAddress); err != nil {
return err
}
if err := a.Owner.EncodeBinary(w); err != nil {
return err
}
@ -129,3 +138,15 @@ func (a *AssetState) EncodeBinary(w io.Writer) error {
}
return binary.Write(w, binary.LittleEndian, a.IsFrozen)
}
// Get the asset name based on its type.
func (a *AssetState) GetName() string {
if a.AssetType == transaction.GoverningToken {
return "NEO"
} else if a.AssetType == transaction.UtilityToken {
return "NEOGas"
}
return a.Name
}

View file

@ -8,6 +8,7 @@ import (
"time"
"github.com/CityOfZion/neo-go/config"
//"github.com/CityOfZion/neo-go/pkg/core"
"github.com/CityOfZion/neo-go/pkg/core/storage"
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/util"
@ -527,6 +528,20 @@ func (bc *Blockchain) HeaderHeight() uint32 {
return uint32(bc.headerListLen() - 1)
}
func (bc *Blockchain) GetAssetState(assetID util.Uint256) *AssetState {
var as *AssetState
bc.Store.Seek(storage.STAsset.Bytes(), func(k, v []byte) {
var a AssetState
a.DecodeBinary(bytes.NewReader(v))
if a.ID == assetID {
as = &a
}
})
return as
}
func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, index)

View file

@ -1,6 +1,8 @@
package core
import "github.com/CityOfZion/neo-go/pkg/util"
import (
"github.com/CityOfZion/neo-go/pkg/util"
)
// Blockchainer is an interface that abstract the implementation
// of the blockchain.
@ -15,4 +17,5 @@ type Blockchainer interface {
CurrentBlockHash() util.Uint256
HasBlock(util.Uint256) bool
HasTransaction(util.Uint256) bool
GetAssetState(util.Uint256) *AssetState
}

View file

@ -138,11 +138,11 @@ func (p ECPoint) EncodeBinary(w io.Writer) error {
// String implements the Stringer interface.
func (p *ECPoint) String() string {
if p.IsInfinity() {
return "(inf, inf)"
return "00"
}
bx := hex.EncodeToString(p.X.Bytes())
by := hex.EncodeToString(p.Y.Bytes())
return fmt.Sprintf("(%s, %s)", bx, by)
return fmt.Sprintf("%s%s", bx, by)
}
// IsInfinity checks if point P is infinity on EllipticCurve ec.

View file

@ -29,6 +29,9 @@ func (chain testChain) GetBlock(hash util.Uint256) (*core.Block, error) {
func (chain testChain) GetHeaderHash(int) util.Uint256 {
return util.Uint256{}
}
func (chain testChain) GetAssetState(util.Uint256) *core.AssetState {
return nil
}
func (chain testChain) CurrentHeaderHash() util.Uint256 {
return util.Uint256{}
}

View file

@ -101,7 +101,7 @@ which would yield the response:
| `submitblock` | No | Needs to be implemented in `pkg/core/blockchain.go` |
| `gettxout` | No | Needs to be implemented in `pkg/core/blockchain.go` |
| `invoke` | No | VM |
| `getassetstate` | No | Needs to be implemented in `pkg/core/blockchain.go` |
| `getassetstate` | Yes |-|
| `getpeers` | Yes | - |
| `getversion` | Yes | - |
| `getconnectioncount` | Yes | - |

View file

@ -179,9 +179,35 @@ Methods:
results = peers
case "validateaddress", "getblocksysfee", "getcontractstate", "getrawmempool", "getrawtransaction", "getstorage", "submitblock", "gettxout", "invoke", "invokefunction", "invokescript", "sendrawtransaction", "getaccountstate", "getassetstate":
case "validateaddress", "getblocksysfee", "getcontractstate", "getrawmempool", "getrawtransaction", "getstorage", "submitblock", "gettxout", "invoke", "invokefunction", "invokescript", "sendrawtransaction", "getaccountstate":
results = "TODO"
case "getassetstate":
var err error
param, exists := reqParams.ValueAt(0)
if !exists {
err = errors.New("Param at index at 0 doesn't exist")
resultsErr = NewInvalidParamsError(err.Error(), err)
break
}
if param.Type != "string" {
err = errors.New("Param need to be a string")
resultsErr = NewInvalidParamsError(err.Error(), err)
break
}
paramAssetID, err := util.Uint256DecodeString(param.StringVal)
as := s.chain.GetAssetState(paramAssetID)
if as != nil {
results = wrappers.NewAssetState(as)
} else {
results = "Invalid assetid"
}
default:
resultsErr = NewMethodNotFoundError(fmt.Sprintf("Method '%s' not supported", req.Method), nil)
}

View file

@ -0,0 +1,45 @@
package wrappers
import (
"github.com/CityOfZion/neo-go/pkg/core"
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto"
"github.com/CityOfZion/neo-go/pkg/util"
)
// AssetState wrapper used for the representation of
// core.AssetState on the RPC Server.
type AssetState struct {
ID util.Uint256 `json:"assetId"`
AssetType transaction.AssetType `json:"assetType"`
Name string `json:"name"`
Amount util.Fixed8 `json:"amount"`
Available util.Fixed8 `json:"available"`
Precision uint8 `json:"precision"`
FeeMode uint8 `json:"fee"`
FeeAddress util.Uint160 `json:"address"`
Owner string `json:"owner"`
Admin string `json:"admin"`
Issuer string `json:"issuer"`
Expiration uint32 `json:"expiration"`
IsFrozen bool `json:"is_frozen"`
}
// NewAssetState creates a new AssetState wrapper.
func NewAssetState(a *core.AssetState) AssetState {
return AssetState{
ID: a.ID,
AssetType: a.AssetType,
Name: a.GetName(),
Amount: a.Amount,
Available: a.Available,
Precision: a.Precision,
FeeMode: a.FeeMode,
FeeAddress: a.FeeAddress,
Owner: a.Owner.String(),
Admin: crypto.AddressFromUint160(a.Admin),
Issuer: crypto.AddressFromUint160(a.Issuer),
Expiration: a.Expiration,
IsFrozen: a.IsFrozen,
}
}