import (
"encoding/json"
- "github.com/vapor/api"
"github.com/vapor/errors"
- "github.com/vapor/protocol/bc/types"
+ "github.com/vapor/protocol/bc"
"github.com/vapor/toolbar/common"
)
hostPort string
}
-// NewNode create a api client with target server
+// Node create a api client with target server
func NewNode(hostPort string) *Node {
return &Node{hostPort: hostPort}
}
-func (n *Node) GetBlockByHash(hash string) (*types.Block, error) {
+func (n *Node) GetBlockByHash(hash string) (string, *bc.TransactionStatus, error) {
return n.getRawBlock(&getRawBlockReq{BlockHash: hash})
}
-func (n *Node) GetBlockByHeight(height uint64) (*types.Block, error) {
+func (n *Node) GetBlockByHeight(height uint64) (string, *bc.TransactionStatus, error) {
return n.getRawBlock(&getRawBlockReq{BlockHeight: height})
}
BlockHash string `json:"block_hash"`
}
-func (n *Node) getRawBlock(req *getRawBlockReq) (*types.Block, error) {
+type getRawBlockResp struct {
+ RawBlock string `json:"raw_block"`
+ // TransactionStatus has same marshalling rule for both bytom and vapor
+ TransactionStatus *bc.TransactionStatus `json:"transaction_status"`
+}
+
+func (n *Node) getRawBlock(req *getRawBlockReq) (string, *bc.TransactionStatus, error) {
url := "/get-raw-block"
payload, err := json.Marshal(req)
if err != nil {
- return nil, errors.Wrap(err, "json marshal")
+ return "", nil, errors.Wrap(err, "json marshal")
}
- resp := &api.GetRawBlockResp{}
- return resp.RawBlock, n.request(url, payload, resp)
+ res := &getRawBlockResp{}
+ return res.RawBlock, res.TransactionStatus, n.request(url, payload, res)
}
type response struct {
"github.com/vapor/consensus"
"github.com/vapor/errors"
"github.com/vapor/protocol/bc"
- "github.com/vapor/toolbar/common/service"
"github.com/vapor/toolbar/federation/common"
"github.com/vapor/toolbar/federation/config"
"github.com/vapor/toolbar/federation/database"
"github.com/vapor/toolbar/federation/database/orm"
+ "github.com/vapor/toolbar/federation/service"
)
type mainchainKeeper struct {
"github.com/vapor/errors"
"github.com/vapor/protocol/bc"
"github.com/vapor/protocol/bc/types"
- "github.com/vapor/toolbar/common/service"
"github.com/vapor/toolbar/federation/common"
"github.com/vapor/toolbar/federation/config"
"github.com/vapor/toolbar/federation/database"
"github.com/vapor/toolbar/federation/database/orm"
+ "github.com/vapor/toolbar/federation/service"
)
type sidechainKeeper struct {
--- /dev/null
+package service
+
+import (
+ "encoding/json"
+
+ "github.com/vapor/api"
+ "github.com/vapor/errors"
+ "github.com/vapor/protocol/bc/types"
+ "github.com/vapor/toolbar/common"
+)
+
+// Node can invoke the api which provide by the full node server
+type Node struct {
+ hostPort string
+}
+
+// NewNode create a api client with target server
+func NewNode(hostPort string) *Node {
+ return &Node{hostPort: hostPort}
+}
+
+func (n *Node) GetBlockByHash(hash string) (*types.Block, error) {
+ return n.getRawBlock(&getRawBlockReq{BlockHash: hash})
+}
+
+func (n *Node) GetBlockByHeight(height uint64) (*types.Block, error) {
+ return n.getRawBlock(&getRawBlockReq{BlockHeight: height})
+}
+
+type getBlockCountResp struct {
+ BlockCount uint64 `json:"block_count"`
+}
+
+func (n *Node) GetBlockCount() (uint64, error) {
+ url := "/get-block-count"
+ res := &getBlockCountResp{}
+ return res.BlockCount, n.request(url, nil, res)
+}
+
+type getRawBlockReq struct {
+ BlockHeight uint64 `json:"block_height"`
+ BlockHash string `json:"block_hash"`
+}
+
+func (n *Node) getRawBlock(req *getRawBlockReq) (*types.Block, error) {
+ url := "/get-raw-block"
+ payload, err := json.Marshal(req)
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ resp := &api.GetRawBlockResp{}
+ return resp.RawBlock, n.request(url, payload, resp)
+}
+
+type response struct {
+ Status string `json:"status"`
+ Data json.RawMessage `json:"data"`
+ ErrDetail string `json:"error_detail"`
+}
+
+func (n *Node) request(path string, payload []byte, respData interface{}) error {
+ resp := &response{}
+ if err := common.Post(n.hostPort+path, payload, resp); err != nil {
+ return err
+ }
+
+ if resp.Status != "success" {
+ return errors.New(resp.ErrDetail)
+ }
+
+ return json.Unmarshal(resp.Data, respData)
+}
"github.com/vapor/errors"
"github.com/vapor/protocol/bc/types"
"github.com/vapor/toolbar/common"
- "github.com/vapor/toolbar/common/service"
"github.com/vapor/toolbar/reward/config"
"github.com/vapor/toolbar/reward/database/orm"
+ "github.com/vapor/toolbar/reward/service"
)
type ChainKeeper struct {
}
blockState := &orm.BlockState{}
- if err := db.First(blockState).Error; err == gorm.ErrRecordNotFound {
- block, err := keeper.node.GetBlockByHeight(0)
- if err != nil {
- return nil, errors.Wrap(err, "Failed to get genenis block")
- }
+ err := db.First(blockState).Error
+ if err == nil {
+ return keeper, nil
+ }
- if err := keeper.initBlockState(db, block); err != nil {
- return nil, errors.Wrap(err, "Failed to insert blockState")
- }
- } else if err != nil {
+ if err != gorm.ErrRecordNotFound {
return nil, errors.Wrap(err, "Failed to get blockState")
}
+ block, err := keeper.node.GetBlockByHeight(0)
+ if err != nil {
+ return nil, errors.Wrap(err, "Failed to get genenis block")
+ }
+
+ if err := keeper.initBlockState(db, block); err != nil {
+ return nil, errors.Wrap(err, "Failed to insert blockState")
+ }
+
return keeper, nil
}
-func (c *ChainKeeper) Start() error {
+func (c *ChainKeeper) SyncBlock() error {
for {
blockState := &orm.BlockState{}
- if c.db.First(blockState).RecordNotFound() {
- return errors.New("The query blockState record is empty empty on process block")
+ if err := c.db.First(blockState).Error; err != nil {
+ return errors.Wrap(err, "The query blockState record is empty empty on process block")
}
if blockState.Height >= c.syncHeight {
func (c *ChainKeeper) AttachBlock(ormDB *gorm.DB, block *types.Block) error {
for _, tx := range block.Transactions {
for _, input := range tx.Inputs {
- vetoInput, ok := input.TypedInput.(*types.VetoInput)
- if !ok {
+ if _, ok := input.TypedInput.(*types.VetoInput); !ok {
continue
}
return err
}
utxo := &orm.Utxo{
- VoterAddress: common.GetAddressFromControlProgram(vetoInput.ControlProgram),
- OutputID: outputID.String(),
+ OutputID: outputID.String(),
}
// update data
db := ormDB.Model(&orm.Utxo{}).Where(utxo).Update("veto_height", block.Height)
BlockHash: blockHash.String(),
}
- if err := c.updateBlockState(ormDB, blockState); err != nil {
- return err
- }
-
- return nil
+ return c.updateBlockState(ormDB, blockState)
}
func (c *ChainKeeper) DetachBlock(ormDB *gorm.DB, block *types.Block) error {
BlockHash: block.PreviousBlockHash.String(),
}
- if err := c.updateBlockState(ormDB, blockState); err != nil {
- return err
- }
-
- return nil
+ return c.updateBlockState(ormDB, blockState)
}
func (c *ChainKeeper) initBlockState(db *gorm.DB, block *types.Block) error {