Skip to content

Commit

Permalink
added reward application before layer is processed by tortoise
Browse files Browse the repository at this point in the history
  • Loading branch information
antonlerner committed Mar 5, 2019
1 parent 97ace2b commit 39d1987
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 22 deletions.
2 changes: 1 addition & 1 deletion app/main.go
Expand Up @@ -325,7 +325,7 @@ func (app *SpacemeshApp) initServices(instanceName string, swarm server.Service,
ld := time.Duration(app.Config.LayerDurationSec) * time.Second
clock := timesync.NewTicker(timesync.RealClock{}, ld, gTime)
trtl := consensus.NewAlgorithm(consensus.NewNinjaTortoise(layerSize, lg))
msh := mesh.NewMesh(db, db, db, trtl, processor, lg) //todo: what to do with the logger?
msh := mesh.NewMesh(db, db, db, app.Config.REWARD, trtl, processor, lg) //todo: what to do with the logger?

conf := sync.Configuration{SyncInterval: 1 * time.Second, Concurrency: 4, LayerSize: int(layerSize), RequestTimeout: 100 * time.Millisecond}
syncer := sync.NewSync(swarm, msh, blockOracle, conf, clock.Subscribe(), lg)
Expand Down
3 changes: 3 additions & 0 deletions config/config.go
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/spacemeshos/go-spacemesh/filesystem"
hareConfig "github.com/spacemeshos/go-spacemesh/hare/config"
"github.com/spacemeshos/go-spacemesh/log"
"github.com/spacemeshos/go-spacemesh/mesh"
p2pConfig "github.com/spacemeshos/go-spacemesh/p2p/config"
"github.com/spacemeshos/go-spacemesh/state"
timeConfig "github.com/spacemeshos/go-spacemesh/timesync/config"
Expand Down Expand Up @@ -42,6 +43,7 @@ type Config struct {
HARE hareConfig.Config `mapstructure:"hare"`
TIME timeConfig.TimeConfig `mapstructure:"time"`
GAS state.GasParams `mapstructure:"gas"`
REWARD mesh.RewardParams
}

// BaseConfig defines the default configuration options for spacemesh app
Expand Down Expand Up @@ -78,6 +80,7 @@ func DefaultConfig() Config {
HARE: hareConfig.DefaultConfig(),
TIME: timeConfig.DefaultConfig(),
GAS: state.DefaultConfig(),
REWARD: mesh.DefaultRewardParams(),
}
}

Expand Down
10 changes: 9 additions & 1 deletion mesh/mesh.go
Expand Up @@ -31,6 +31,7 @@ type StateUpdater interface {
type Mesh struct {
log.Log
*meshDB
rewardConfig RewardParams
verifiedLayer uint32
latestLayer uint32
lastSeenLayer uint32
Expand All @@ -43,14 +44,15 @@ type Mesh struct {
done chan struct{}
}

func NewMesh(layers, blocks, validity database.DB, mesh MeshValidator, state StateUpdater, logger log.Log) *Mesh {
func NewMesh(layers, blocks, validity database.DB, rewardConfig RewardParams, mesh MeshValidator, state StateUpdater, logger log.Log) *Mesh {
//todo add boot from disk
ll := &Mesh{
Log: logger,
tortoise: mesh,
state: state,
done: make(chan struct{}),
meshDB: NewMeshDB(layers, blocks, validity, logger),
rewardConfig: rewardConfig,
}

return ll
Expand Down Expand Up @@ -92,6 +94,12 @@ func (m *Mesh) SetLatestLayer(idx uint32) {

func (m *Mesh) ValidateLayer(layer *Layer) {
m.Info("Validate layer %d", layer.Index())

//todo: with the introduction of rewards we need to refactor this loop out of since it now serves multiple purposes
if layer.index >= m.rewardConfig.RewardMaturity {
m.AccumulateRewards(layer.index - m.rewardConfig.RewardMaturity, m.rewardConfig)
}

oldPbase, newPbase := m.tortoise.HandleIncomingLayer(layer)
atomic.StoreUint32(&m.verifiedLayer, uint32(layer.Index()))
if newPbase > oldPbase {
Expand Down
2 changes: 1 addition & 1 deletion mesh/mesh_test.go
Expand Up @@ -35,7 +35,7 @@ func getMesh(id string) *Mesh {
bdb := database.NewMemDatabase()
ldb := database.NewMemDatabase()
cdb := database.NewMemDatabase()
layers := NewMesh(ldb, bdb, cdb, &MeshValidatorMock{}, &MockState{}, log.New(id, "", ""))
layers := NewMesh(ldb, bdb, cdb, ConfigTst(), &MeshValidatorMock{}, &MockState{}, log.New(id, "", ""))
return layers
}

Expand Down
12 changes: 11 additions & 1 deletion mesh/reward.go
Expand Up @@ -12,9 +12,19 @@ type RewardParams struct {
BaseReward *big.Int
PenaltyPercent *big.Int
TxQuota uint32
RewardMaturity LayerID
}

func DefaultRewardParams() RewardParams{
return RewardParams{
big.NewInt(10),
big.NewInt(5000),
big.NewInt(15),
15,
5,
}
}

//type Transactions []*state.Transaction

func CalculateLayerReward(id LayerID, params RewardParams) *big.Int {
//todo: add inflation rules here
Expand Down
76 changes: 63 additions & 13 deletions mesh/reward_test.go
Expand Up @@ -34,13 +34,23 @@ func (s *MockMapState) ApplyRewards(layer state.LayerID, miners map[string]struc

}

func ConfigTst() RewardParams{
return RewardParams{
big.NewInt(10),
big.NewInt(5000),
big.NewInt(15),
15,
5,
}
}

func getMeshWithMapState(id string, s StateUpdater) *Mesh {

//time := time.Now()
bdb := database.NewMemDatabase()
ldb := database.NewMemDatabase()
cdb := database.NewMemDatabase()
layers := NewMesh(ldb, bdb, cdb, &MeshValidatorMock{}, s, log.New(id, "", ""))
layers := NewMesh(ldb, bdb, cdb, ConfigTst(), &MeshValidatorMock{}, s,log.New(id, "", ""))
return layers
}

Expand Down Expand Up @@ -105,12 +115,7 @@ func TestMesh_AccumulateRewards_happyFlow(t *testing.T) {
layers.AddBlock(block3)
layers.AddBlock(block4)

params := RewardParams{
big.NewInt(10),
big.NewInt(5000),
big.NewInt(20),
5,
}
params := NewTestRewardParams()

layers.AccumulateRewards(1, params)
remainder := (totalRewards * params.SimpleTxCost.Int64()) % 4
Expand All @@ -119,6 +124,16 @@ func TestMesh_AccumulateRewards_happyFlow(t *testing.T) {

}

func NewTestRewardParams() RewardParams {
return RewardParams{
big.NewInt(10),
big.NewInt(5000),
big.NewInt(20),
15,
10,
}
}

func TestMesh_AccumulateRewards_underQuota(t *testing.T) {
s := &MockMapState{Rewards: make(map[string]*big.Int)}
layers := getMeshWithMapState("t1", s)
Expand Down Expand Up @@ -148,12 +163,7 @@ func TestMesh_AccumulateRewards_underQuota(t *testing.T) {
layers.AddBlock(block3)
layers.AddBlock(block4)

params := RewardParams{
big.NewInt(10),
big.NewInt(5000),
big.NewInt(20),
15,
}
params := NewTestRewardParams()

layers.AccumulateRewards(1, params)
remainder := (totalRewards * params.SimpleTxCost.Int64()) % 4
Expand All @@ -165,6 +175,46 @@ func TestMesh_AccumulateRewards_underQuota(t *testing.T) {

}

func createLayer(mesh *Mesh,id LayerID, numOfBlocks, maxTransactions int) (totalRewards int64){
for i := 0; i< numOfBlocks; i++ {
block1 := NewBlock(true, []byte("data1"), time.Now(), id)
block1.MinerID = strconv.Itoa(i)
totalRewards += addTransactions(block1, rand.Intn(maxTransactions))
mesh.addBlock(block1)
}
return totalRewards
}

func TestMesh_integration(t *testing.T){
numofLayers := 10
numofBlocks := 10
maxTxs := 20

s := &MockMapState{Rewards: make(map[string]*big.Int)}
layers := getMeshWithMapState("t1", s)
defer layers.Close()

var rewards int64
for i := 0; i < numofLayers; i++{
reward := createLayer(layers, LayerID(i), numofBlocks, maxTxs)
if rewards == 0 {
rewards += reward
}
}

oldTotal := s.Total
l4, err := layers.getLayer(4)
assert.NoError(t,err)
l5, err := layers.getLayer(5)
assert.NoError(t, err)
//test negative case
layers.ValidateLayer(l4)
assert.Equal(t,oldTotal,s.Total)

layers.ValidateLayer(l5)
assert.Equal(t, rewards * ConfigTst().SimpleTxCost.Int64() + ConfigTst().BaseReward.Int64(), s.Total)
}

func TestMesh_MergeDoubles(t *testing.T) {
s := &MockMapState{Rewards: make(map[string]*big.Int)}
layers := getMeshWithMapState("t1", s)
Expand Down
6 changes: 3 additions & 3 deletions sync/syncer.go
Expand Up @@ -78,7 +78,7 @@ func (s *Syncer) Start() {

//fires a sync every sm.syncInterval or on force space from outside
func (s *Syncer) run() {
foo := func() {
syncRoutine := func() {
if atomic.CompareAndSwapUint32(&s.SyncLock, IDLE, RUNNING) {
s.Synchronise()
atomic.StoreUint32(&s.SyncLock, IDLE)
Expand All @@ -90,11 +90,11 @@ func (s *Syncer) run() {
s.Debug("run stoped")
return
case <-s.forceSync:
go foo()
go syncRoutine()
case layer := <-s.clock:
atomic.StoreUint32(&s.currentLayer, uint32(layer))
s.Info("sync got tick for layer %v", layer)
go foo()
go syncRoutine()
}
}
}
Expand Down
14 changes: 12 additions & 2 deletions sync/syncer_test.go
Expand Up @@ -81,13 +81,23 @@ func (s *stateMock) ApplyTransactions(id state.LayerID, tx state.Transactions) (
return 0, nil
}

func ConfigTst() mesh.RewardParams{
return mesh.RewardParams{
big.NewInt(10),
big.NewInt(5000),
big.NewInt(15),
15,
5,
}
}

func getMeshWithLevelDB(id string) *mesh.Mesh {
//time := time.Now()
bdb := database.NewLevelDbStore("blocks_test_"+id, nil, nil)
ldb := database.NewLevelDbStore("layers_test_"+id, nil, nil)
cv := database.NewLevelDbStore("contextually_valid_test_"+id, nil, nil)
//odb := database.NewLevelDbStore("orphans_test_"+id+"_"+time.String(), nil, nil)
layers := mesh.NewMesh(ldb, bdb, cv, &MeshValidatorMock{}, &stateMock{}, log.New(id, "", ""))
layers := mesh.NewMesh(ldb, bdb, cv,ConfigTst(), &MeshValidatorMock{}, &stateMock{}, log.New(id, "", ""))
return layers
}

Expand All @@ -106,7 +116,7 @@ func getMeshWithMemoryDB(id string) *mesh.Mesh {
ldb := database.NewMemDatabase()
cv := database.NewMemDatabase()
//odb := database.NewMemDatabase()
layers := mesh.NewMesh(ldb, bdb, cv, &MeshValidatorMock{}, &stateMock{}, log.New(id, "", ""))
layers := mesh.NewMesh(ldb, bdb, cv, ConfigTst(), &MeshValidatorMock{}, &stateMock{}, log.New(id, "", ""))
return layers
}

Expand Down

0 comments on commit 39d1987

Please sign in to comment.