Skip to content

Commit

Permalink
Merge pull request #101 from MinterTeam/dev
Browse files Browse the repository at this point in the history
v0.3.3
  • Loading branch information
danil-lashin authored Sep 11, 2018
2 parents 4e7639a + 2af06e8 commit d14f751
Show file tree
Hide file tree
Showing 13 changed files with 292 additions and 14 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Changelog

## TBD
## 0.3.3
*Sept 8th, 2018*

IMPROVEMENT

- [api] Add validators rewards to block api
- [api] Add block size in bytes
- [api] #100 Add "events" to block response. To get events add ?withEvents=true to request URL.
WARNING! You should sync blockchain from scratch to get this feature working

## 0.3.2
*Sept 8th, 2018*
Expand Down
2 changes: 2 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"github.com/MinterTeam/minter-go-node/config"
"github.com/MinterTeam/minter-go-node/eventsdb"
"log"
"net/http"

Expand All @@ -26,6 +27,7 @@ var (

func init() {
cryptoAmino.RegisterAmino(cdc)
eventsdb.RegisterAminoEvents(cdc)
}

func RunApi(b *minter.Blockchain, node *node.Node) {
Expand Down
34 changes: 31 additions & 3 deletions api/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/MinterTeam/minter-go-node/core/rewards"
"github.com/MinterTeam/minter-go-node/core/transaction"
"github.com/MinterTeam/minter-go-node/core/types"
"github.com/MinterTeam/minter-go-node/eventsdb"
"github.com/gorilla/mux"
"github.com/tendermint/tendermint/libs/common"
"math/big"
Expand All @@ -21,8 +22,10 @@ type BlockResponse struct {
NumTxs int64 `json:"num_txs"`
TotalTxs int64 `json:"total_txs"`
Transactions []BlockTransactionResponse `json:"transactions"`
Events json.RawMessage `json:"events,omitempty"`
Precommits json.RawMessage `json:"precommits"`
BlockReward string `json:"block_reward"`
Size int `json:"size"`
}

type BlockTransactionResponse struct {
Expand All @@ -44,6 +47,7 @@ func Block(w http.ResponseWriter, r *http.Request) {

vars := mux.Vars(r)
height, _ := strconv.ParseInt(vars["height"], 10, 64)
includeEvents, _ := strconv.ParseBool(r.URL.Query().Get("withEvents"))

block, err := client.Block(&height)
blockResults, err := client.BlockResults(&height)
Expand All @@ -59,8 +63,6 @@ func Block(w http.ResponseWriter, r *http.Request) {
return
}

w.WriteHeader(http.StatusOK)

txs := make([]BlockTransactionResponse, len(block.Block.Data.Txs))

for i, rawTx := range block.Block.Data.Txs {
Expand Down Expand Up @@ -93,17 +95,43 @@ func Block(w http.ResponseWriter, r *http.Request) {

precommits, _ := cdc.MarshalJSON(block.Block.LastCommit.Precommits)

encodedBlock, _ := cdc.MarshalBinary(block)

size := len(encodedBlock)

var eventsRaw []byte

if includeEvents {
events := eventsdb.GetCurrent().GetEvents(height)

if len(events) > 0 {
eventsRaw, err = cdc.MarshalJSON(events)

if err != nil {
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(Response{
Code: 0,
Log: err.Error(),
})
return
}
}
}

response := BlockResponse{
Hash: block.Block.Hash(),
Height: block.Block.Height,
Time: block.Block.Time,
NumTxs: block.Block.NumTxs,
TotalTxs: block.Block.TotalTxs,
Transactions: txs,
Precommits: json.RawMessage(precommits),
Precommits: precommits,
BlockReward: rewards.GetRewardForBlock(uint64(height)).String(),
Size: size,
Events: eventsRaw,
}

w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(Response{
Code: 0,
Result: response,
Expand Down
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ type BaseConfig struct {

// Address to listen for API connections
APIListenAddress string `mapstructure:"api_listen_addr"`

EnableEvents bool `mapstructure:"enable_events"`
}

// DefaultBaseConfig returns a default base configuration for a Tendermint node
Expand All @@ -241,6 +243,7 @@ func DefaultBaseConfig() BaseConfig {
DBPath: "data",
GUIListenAddress: ":3000",
APIListenAddress: ":8841",
EnableEvents: false,
}
}

Expand Down
3 changes: 3 additions & 0 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ gui_listen_addr = "{{ .BaseConfig.GUIListenAddress }}"
# Address to listen for API connections
api_listen_addr = "{{ .BaseConfig.APIListenAddress }}"
# Enable events for API. Slows down node.
enable_events = {{ .BaseConfig.EnableEvents }}
# If this node is many blocks behind the tip of the chain, FastSync
# allows them to catchup quickly by downloading blocks in parallel
# and verifying their commits
Expand Down
4 changes: 2 additions & 2 deletions core/minter/minter.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (app *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTypes.Res
app.stateDeliver.SetValidatorPresent(address)
app.validatorsStatuses[address] = ValidatorPresent
} else {
app.stateDeliver.SetValidatorAbsent(address)
app.stateDeliver.SetValidatorAbsent(req.Header.Height, address)
app.validatorsStatuses[address] = ValidatorAbsent
}
}
Expand Down Expand Up @@ -193,7 +193,7 @@ func (app *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes.Respons

// pay rewards
if app.height%12 == 0 {
app.stateDeliver.PayRewards()
app.stateDeliver.PayRewards(req.Height)
}

hasDroppedValidators := false
Expand Down
14 changes: 14 additions & 0 deletions core/state/state_frozen_fund.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package state

import (
"github.com/MinterTeam/minter-go-node/eventsdb"
"io"

"fmt"
Expand Down Expand Up @@ -119,6 +120,9 @@ func (c *stateFrozenFund) PunishFund(candidateAddress [20]byte) {
}

func (c *stateFrozenFund) punishFund(candidateAddress [20]byte) {

edb := eventsdb.GetCurrent()

var NewList []FrozenFund

for _, item := range c.data.List {
Expand All @@ -134,6 +138,16 @@ func (c *stateFrozenFund) punishFund(candidateAddress [20]byte) {
newValue.Mul(newValue, big.NewInt(95))
newValue.Div(newValue, big.NewInt(100))

slashed := big.NewInt(0).Set(item.Value)
slashed.Sub(slashed, newValue)

edb.SaveEvent(int64(c.blockHeight), eventsdb.SlashEvent{
Address: item.Address,
Amount: slashed.String(),
Coin: item.Coin,
ValidatorPubKey: item.CandidateKey,
})

item.Value = newValue
}

Expand Down
60 changes: 58 additions & 2 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package state

import (
"fmt"
"github.com/MinterTeam/minter-go-node/eventsdb"
"math/big"
"sync"

Expand Down Expand Up @@ -812,7 +813,9 @@ func (s *StateDB) AddAccumReward(pubkey types.Pubkey, reward *big.Int) {
}
}

func (s *StateDB) PayRewards() {
func (s *StateDB) PayRewards(height int64) {
edb := eventsdb.GetCurrent()

validators := s.getStateValidators()

for i := range validators.data {
Expand All @@ -827,12 +830,24 @@ func (s *StateDB) PayRewards() {
DAOReward.Mul(DAOReward, big.NewInt(int64(dao.Commission)))
DAOReward.Div(DAOReward, big.NewInt(100))
s.AddBalance(dao.Address, types.GetBaseCoin(), DAOReward)
edb.SaveEvent(height, eventsdb.RewardEvent{
Role: eventsdb.RoleDAO,
Address: dao.Address,
Amount: DAOReward.String(),
ValidatorPubKey: validator.PubKey,
})

// pay commission to Developers
DevelopersReward := big.NewInt(0).Set(totalReward)
DevelopersReward.Mul(DevelopersReward, big.NewInt(int64(developers.Commission)))
DevelopersReward.Div(DevelopersReward, big.NewInt(100))
s.AddBalance(developers.Address, types.GetBaseCoin(), DevelopersReward)
edb.SaveEvent(height, eventsdb.RewardEvent{
Role: eventsdb.RoleDevelopers,
Address: developers.Address,
Amount: DevelopersReward.String(),
ValidatorPubKey: validator.PubKey,
})

totalReward.Sub(totalReward, DevelopersReward)
totalReward.Sub(totalReward, DAOReward)
Expand All @@ -843,6 +858,12 @@ func (s *StateDB) PayRewards() {
validatorReward.Div(validatorReward, big.NewInt(100))
totalReward.Sub(totalReward, validatorReward)
s.AddBalance(validator.CandidateAddress, types.GetBaseCoin(), validatorReward)
edb.SaveEvent(height, eventsdb.RewardEvent{
Role: eventsdb.RoleValidator,
Address: validator.CandidateAddress,
Amount: validatorReward.String(),
ValidatorPubKey: validator.PubKey,
})

candidate := s.GetStateCandidate(validator.PubKey)

Expand All @@ -858,7 +879,18 @@ func (s *StateDB) PayRewards() {
reward.Mul(reward, stake.BipValue)
reward.Div(reward, validator.TotalBipStake)

if reward.Cmp(types.Big0) < 1 {
continue
}

s.AddBalance(stake.Owner, types.GetBaseCoin(), reward)

edb.SaveEvent(height, eventsdb.RewardEvent{
Role: eventsdb.RoleDelegator,
Address: stake.Owner,
Amount: reward.String(),
ValidatorPubKey: candidate.PubKey,
})
}

validator.AccumReward.SetInt64(0)
Expand Down Expand Up @@ -990,7 +1022,9 @@ func (s *StateDB) SetCandidateOffline(pubkey []byte) {
s.MarkStateCandidateDirty()
}

func (s *StateDB) SetValidatorAbsent(address [20]byte) {
func (s *StateDB) SetValidatorAbsent(height int64, address [20]byte) {
edb := eventsdb.GetCurrent()

validators := s.getStateValidators()

for i := range validators.data {
Expand Down Expand Up @@ -1026,6 +1060,16 @@ func (s *StateDB) SetValidatorAbsent(address [20]byte) {
newValue.Mul(newValue, big.NewInt(99))
newValue.Div(newValue, big.NewInt(100))

slashed := big.NewInt(0).Set(stake.Value)
slashed.Sub(slashed, newValue)

edb.SaveEvent(height, eventsdb.SlashEvent{
Address: stake.Owner,
Amount: slashed.String(),
Coin: stake.Coin,
ValidatorPubKey: candidate.PubKey,
})

candidate.Stakes[j] = Stake{
Owner: stake.Owner,
Coin: stake.Coin,
Expand All @@ -1049,6 +1093,8 @@ func (s *StateDB) SetValidatorAbsent(address [20]byte) {

func (s *StateDB) PunishByzantineValidator(currentBlock uint64, address [20]byte) {

edb := eventsdb.GetCurrent()

validators := s.getStateValidators()

for i := range validators.data {
Expand All @@ -1072,6 +1118,16 @@ func (s *StateDB) PunishByzantineValidator(currentBlock uint64, address [20]byte
newValue.Mul(newValue, big.NewInt(95))
newValue.Div(newValue, big.NewInt(100))

slashed := big.NewInt(0).Set(stake.Value)
slashed.Sub(slashed, newValue)

edb.SaveEvent(int64(currentBlock), eventsdb.SlashEvent{
Address: stake.Owner,
Amount: slashed.String(),
Coin: stake.Coin,
ValidatorPubKey: candidate.PubKey,
})

s.GetOrNewStateFrozenFunds(currentBlock+UnbondPeriod).AddFund(stake.Owner, candidate.PubKey, stake.Coin, newValue)
}

Expand Down
5 changes: 2 additions & 3 deletions core/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@
package types

import (
"bytes"
"encoding/hex"
"fmt"
"github.com/MinterTeam/minter-go-node/hexutil"
"math/big"
"math/rand"
"reflect"

"bytes"
"github.com/MinterTeam/minter-go-node/hexutil"
)

const (
Expand Down
11 changes: 11 additions & 0 deletions eventsdb/amino.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package eventsdb

import "github.com/tendermint/go-amino"

func RegisterAminoEvents(codec *amino.Codec) {
codec.RegisterInterface((*Event)(nil), nil)
codec.RegisterConcrete(RewardEvent{},
"minter/RewardEvent", nil)
codec.RegisterConcrete(SlashEvent{},
"minter/SlashEvent", nil)
}
Loading

0 comments on commit d14f751

Please sign in to comment.