+++ /dev/null
-package reward
-
-import (
- "encoding/json"
- "fmt"
-
- "github.com/vapor/blockchain/txbuilder"
- "github.com/vapor/errors"
- "github.com/vapor/protocol/bc"
- "github.com/vapor/protocol/bc/types"
- "github.com/vapor/toolbar/common"
-)
-
-var buildSpendReqFmt = `
- {"actions": [
- %s,
- %s
- ]}`
-
-var inputActionFmt = `
-{"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","amount": %d,"account_id": "%s"}
-`
-var outputActionFmt = `
-{"type": "control_address", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": %d, "address": "%s"}
-`
-
-type Transaction struct {
- ip string
-}
-
-func (t *Transaction) buildTx(inputAction, outputAction string) (*txbuilder.Template, error) {
- url := "/build-transaction"
- buildReqStr := fmt.Sprintf(buildSpendReqFmt, inputAction, outputAction)
-
- tmpl := &txbuilder.Template{}
- return tmpl, t.request(url, []byte(buildReqStr), tmpl)
-}
-
-type signTxReq struct {
- Password string `json:"password"`
- Txs txbuilder.Template `json:"transaction"`
-}
-
-type signTemplateResp struct {
- Tx *txbuilder.Template `json:"transaction"`
- SignComplete bool `json:"sign_complete"`
-}
-
-func (t *Transaction) signTx(passwd string, tmpl txbuilder.Template) (*txbuilder.Template, error) {
- url := "/sign-transaction"
- req := &signTxReq{
- Password: passwd,
- Txs: tmpl,
- }
-
- payload, err := json.Marshal(req)
- if err != nil {
- return nil, errors.Wrap(err, "json marshal")
- }
-
- resp := &signTemplateResp{}
-
- if err := t.request(url, payload, resp); err != nil {
- return nil, err
- }
-
- if !resp.SignComplete {
- return nil, errors.Wrap(err, "sign fail")
- }
-
- return resp.Tx, nil
-}
-
-type submitTxReq struct {
- Tx interface{} `json:"raw_transaction"`
-}
-
-type submitTxResp struct {
- TxID string `json:"tx_id"`
-}
-
-func (t *Transaction) SubmitTx(tx interface{}) (string, error) {
- url := "/submit-transaction"
- payload, err := json.Marshal(submitTxReq{Tx: tx})
- if err != nil {
- return "", errors.Wrap(err, "json marshal")
- }
-
- res := &submitTxResp{}
- return res.TxID, t.request(url, payload, res)
-}
-
-type response struct {
- Status string `json:"status"`
- Data json.RawMessage `json:"data"`
- ErrDetail string `json:"error_detail"`
-}
-
-func (t *Transaction) request(url string, payload []byte, respData interface{}) error {
- resp := &response{}
- if err := common.Post(t.ip+url, payload, resp); err != nil {
- return err
- }
-
- if resp.Status != "success" {
- return errors.New(resp.ErrDetail)
- }
-
- return json.Unmarshal(resp.Data, respData)
-}
-
-type getRawBlockReq struct {
- BlockHeight uint64 `json:"block_height"`
- BlockHash string `json:"block_hash"`
-}
-
-type getRawBlockResp struct {
- RawBlock *types.Block `json:"raw_block"`
- TransactionStatus *bc.TransactionStatus `json:"transaction_status"`
-}
-
-// GetCoinbaseTx return coinbase tx
-func (t *Transaction) GetCoinbaseTx(blockHeight uint64) (*types.Tx, error) {
- url := "/get-raw-block"
- req := getRawBlockReq{
- BlockHeight: blockHeight,
- }
- payload, err := json.Marshal(req)
- if err != nil {
- return nil, errors.Wrap(err, "json marshal")
- }
-
- res := &getRawBlockResp{}
- if err := t.request(url, payload, res); err != nil {
- return nil, err
- }
- if len(res.RawBlock.Transactions) > 0 {
- return res.RawBlock.Transactions[0], nil
- }
-
- return nil, errors.New("no coinbase")
-}
-
-type getBlockCountResp struct {
- BlockCount uint64 `json:"block_count"`
-}
-
-func (t *Transaction) GetCurrentHeight() (uint64, error) {
- url := "/get-block-count"
- res := &getBlockCountResp{}
- return res.BlockCount, t.request(url, nil, res)
-}
"fmt"
"math/big"
+ "github.com/vapor/toolbar/common/service"
+
"github.com/jinzhu/gorm"
log "github.com/sirupsen/logrus"
}
type Vote struct {
- node *config.VoteRewardConfig
+ nodeConfig *config.VoteRewardConfig
+ node *service.Node
db *gorm.DB
reward *voterReward
coinBaseRewards map[uint64]*coinBaseReward
rewardEndHeight uint64
}
-func NewVote(db *gorm.DB, node *config.VoteRewardConfig, rewardStartHeight, rewardEndHeight uint64) *Vote {
+func NewVote(db *gorm.DB, nodeConfig *config.VoteRewardConfig, rewardStartHeight, rewardEndHeight uint64) *Vote {
return &Vote{
db: db,
- node: node,
+ nodeConfig: nodeConfig,
+ node: service.NewNode(nodeConfig.Upstream),
reward: &voterReward{rewards: make(map[string]*big.Int)},
coinBaseRewards: make(map[uint64]*coinBaseReward),
roundVoteBlockNums: consensus.ActiveNetParams.DPOSConfig.RoundVoteBlockNums,
func (v *Vote) getVoteByXpub(height uint64) ([]*orm.Utxo, error) {
utxos := []*orm.Utxo{}
- if err := v.db.Where("(veto_height >= ? or veto_height = 0) and vote_height <= ? and xpub = ?", height-v.roundVoteBlockNums+1, height-v.roundVoteBlockNums, v.node.XPub).Find(&utxos).Error; err != nil {
+ if err := v.db.Where("(veto_height >= ? or veto_height = 0) and vote_height <= ? and xpub = ?", height-v.roundVoteBlockNums+1, height-v.roundVoteBlockNums, v.nodeConfig.XPub).Find(&utxos).Error; err != nil {
return nil, err
}
return utxos, nil
}
func (v *Vote) getCoinbaseReward() error {
-
- tx := Transaction{
- ip: fmt.Sprintf("http://%s:%d", v.node.Host, v.node.Port),
- }
for height := v.rewardStartHeight + v.roundVoteBlockNums; height <= v.rewardEndHeight; height += v.roundVoteBlockNums {
- coinbaseTx, err := tx.GetCoinbaseTx(height)
+ coinbaseTx, err := v.node.GetCoinbaseTx(height)
if err != nil {
log.WithFields(log.Fields{"error": err, "coinbase_height": height}).Error("get coinbase reward")
return err
continue
}
- if address == v.node.MiningAddress {
+ if address == v.nodeConfig.MiningAddress {
reward := &coinBaseReward{
totalReward: output.Amount,
}
- ratioNumerator := big.NewInt(int64(v.node.RewardRatio))
+ ratioNumerator := big.NewInt(int64(v.nodeConfig.RewardRatio))
ratioDenominator := big.NewInt(100)
coinBaseReward := big.NewInt(0).SetUint64(output.Amount)
reward.voteTotalReward = coinBaseReward.Mul(coinBaseReward, ratioNumerator).Div(coinBaseReward, ratioDenominator)
func (v *Vote) sendRewardTransaction() {
txID, err := v.sendReward()
if err != nil {
- log.WithFields(log.Fields{"error": err, "node": v.node}).Error("send reward transaction")
+ log.WithFields(log.Fields{"error": err, "node": v.nodeConfig}).Error("send reward transaction")
return
}
log.Info("tx_id: ", txID)
func (v *Vote) sendReward() (string, error) {
var outputAction string
- inputAction := fmt.Sprintf(inputActionFmt, v.reward.totalCoinbaseReward, v.node.AccountID)
+ inputAction := fmt.Sprintf(service.InputActionFmt, v.reward.totalCoinbaseReward, v.nodeConfig.AccountID)
index := 0
for address, amount := range v.reward.rewards {
index++
- outputAction += fmt.Sprintf(outputActionFmt, amount.Uint64(), address)
+ outputAction += fmt.Sprintf(service.OutputActionFmt, amount.Uint64(), address)
if index != len(v.reward.rewards) {
outputAction += ","
}
}
- tx := Transaction{
- ip: fmt.Sprintf("http://%s:%d", v.node.Host, v.node.Port),
- }
-
- tmpl, err := tx.buildTx(inputAction, outputAction)
- if err != nil {
- return "", err
- }
-
- tmpl, err = tx.signTx(v.node.Passwd, *tmpl)
- if err != nil {
- return "", err
- }
-
- return tx.SubmitTx(tmpl.Transaction)
+ return v.node.SendTransaction(inputAction, outputAction, v.nodeConfig.Passwd)
}