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 net = config.ModeMainNet
} }
configPath := "./config" configPath := "../config"
if argCp := ctx.String("config-path"); argCp != "" { if argCp := ctx.String("config-path"); argCp != "" {
configPath = argCp configPath = argCp
} }

View file

@ -38,6 +38,7 @@ type AssetState struct {
Available util.Fixed8 Available util.Fixed8
Precision uint8 Precision uint8
FeeMode uint8 FeeMode uint8
FeeAddress util.Uint160
Owner *crypto.PublicKey Owner *crypto.PublicKey
Admin util.Uint160 Admin util.Uint160
Issuer 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 { if err := binary.Read(r, binary.LittleEndian, &a.FeeMode); err != nil {
return err return err
} }
if err := binary.Read(r, binary.LittleEndian, &a.FeeAddress); err != nil {
return err
}
a.Owner = &crypto.PublicKey{} a.Owner = &crypto.PublicKey{}
if err := a.Owner.DecodeBinary(r); err != nil { 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 { if err := binary.Write(w, binary.LittleEndian, a.FeeMode); err != nil {
return err return err
} }
if err := binary.Write(w, binary.LittleEndian, a.FeeAddress); err != nil {
return err
}
if err := a.Owner.EncodeBinary(w); err != nil { if err := a.Owner.EncodeBinary(w); err != nil {
return err return err
} }
@ -129,3 +138,15 @@ func (a *AssetState) EncodeBinary(w io.Writer) error {
} }
return binary.Write(w, binary.LittleEndian, a.IsFrozen) 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" "time"
"github.com/CityOfZion/neo-go/config" "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/storage"
"github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/util"
@ -527,6 +528,20 @@ func (bc *Blockchain) HeaderHeight() uint32 {
return uint32(bc.headerListLen() - 1) 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 { func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
buf := make([]byte, 4) buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, index) binary.LittleEndian.PutUint32(buf, index)

View file

@ -1,6 +1,8 @@
package core 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 // Blockchainer is an interface that abstract the implementation
// of the blockchain. // of the blockchain.
@ -15,4 +17,5 @@ type Blockchainer interface {
CurrentBlockHash() util.Uint256 CurrentBlockHash() util.Uint256
HasBlock(util.Uint256) bool HasBlock(util.Uint256) bool
HasTransaction(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. // String implements the Stringer interface.
func (p *ECPoint) String() string { func (p *ECPoint) String() string {
if p.IsInfinity() { if p.IsInfinity() {
return "(inf, inf)" return "00"
} }
bx := hex.EncodeToString(p.X.Bytes()) bx := hex.EncodeToString(p.X.Bytes())
by := hex.EncodeToString(p.Y.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. // 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 { func (chain testChain) GetHeaderHash(int) util.Uint256 {
return util.Uint256{} return util.Uint256{}
} }
func (chain testChain) GetAssetState(util.Uint256) *core.AssetState {
return nil
}
func (chain testChain) CurrentHeaderHash() util.Uint256 { func (chain testChain) CurrentHeaderHash() util.Uint256 {
return 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` | | `submitblock` | No | Needs to be implemented in `pkg/core/blockchain.go` |
| `gettxout` | No | Needs to be implemented in `pkg/core/blockchain.go` | | `gettxout` | No | Needs to be implemented in `pkg/core/blockchain.go` |
| `invoke` | No | VM | | `invoke` | No | VM |
| `getassetstate` | No | Needs to be implemented in `pkg/core/blockchain.go` | | `getassetstate` | Yes |-|
| `getpeers` | Yes | - | | `getpeers` | Yes | - |
| `getversion` | Yes | - | | `getversion` | Yes | - |
| `getconnectioncount` | Yes | - | | `getconnectioncount` | Yes | - |

View file

@ -179,9 +179,35 @@ Methods:
results = peers 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" 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: default:
resultsErr = NewMethodNotFoundError(fmt.Sprintf("Method '%s' not supported", req.Method), nil) 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,
}
}