-
Notifications
You must be signed in to change notification settings - Fork 14
/
abi_miner.go
130 lines (111 loc) · 3.59 KB
/
abi_miner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package abi
import (
"fmt"
"math/big"
"strings"
"github.com/qlcchain/go-qlc/common"
"github.com/qlcchain/go-qlc/common/types"
"github.com/qlcchain/go-qlc/common/vmcontract/contractaddress"
"github.com/qlcchain/go-qlc/vm/abi"
"github.com/qlcchain/go-qlc/vm/vmstore"
)
const (
JsonMiner = `
[
{"type":"function","name":"MinerReward","inputs":[
{"name":"coinbase","type":"address"},
{"name":"beneficial","type":"address"},
{"name":"startHeight","type":"uint64"},
{"name":"endHeight","type":"uint64"},
{"name":"rewardBlocks","type":"uint64"},
{"name":"rewardAmount","type":"uint256"}
]},
{"type":"variable","name":"MinerRewardInfo","inputs":[
{"name":"endHeight","type":"uint64"},
{"name":"rewardBlocks","type":"uint64"},
{"name":"timestamp","type":"int64"},
{"name":"rewardAmount","type":"uint256"}
]}
]`
MethodNameMinerReward = "MinerReward"
VariableNameMinerReward = "MinerRewardInfo"
)
var (
MinerABI, _ = abi.JSONToABIContract(strings.NewReader(JsonMiner))
)
type MinerRewardParam struct {
Coinbase types.Address `json:"coinbase"`
Beneficial types.Address `json:"beneficial"`
StartHeight uint64 `json:"startHeight"`
EndHeight uint64 `json:"endHeight"`
RewardBlocks uint64 `json:"rewardBlocks"`
RewardAmount *big.Int `json:"rewardAmount"`
}
func (p *MinerRewardParam) Verify() (bool, error) {
if p.Coinbase.IsZero() {
return false, fmt.Errorf("coinbase is zero")
}
if p.Beneficial.IsZero() {
return false, fmt.Errorf("beneficial is zero")
}
if p.StartHeight < common.PovMinerRewardHeightStart {
return false, fmt.Errorf("startHeight %d less than %d", p.StartHeight, common.PovMinerRewardHeightStart)
}
if p.StartHeight > p.EndHeight {
return false, fmt.Errorf("startHeight %d greater than endHeight %d", p.StartHeight, p.EndHeight)
}
gapCount := p.EndHeight - p.StartHeight + 1
if gapCount > common.PovMinerMaxRewardBlocksPerCall {
return false, fmt.Errorf("gap count %d exceed max blocks %d", p.StartHeight, common.PovMinerMaxRewardBlocksPerCall)
}
return true, nil
}
type MinerRewardInfo struct {
Beneficial types.Address `json:"beneficial"`
StartHeight uint64 `json:"startHeight"`
EndHeight uint64 `json:"endHeight"`
RewardBlocks uint64 `json:"rewardBlocks"`
RewardAmount *big.Int `json:"rewardAmount"`
Timestamp int64 `json:"_"`
}
func GetLastMinerRewardHeightByAccount(ctx *vmstore.VMContext, coinbase types.Address) (uint64, error) {
data, err := ctx.GetStorage(contractaddress.MinerAddress[:], coinbase[:])
if err == nil {
info := new(MinerRewardInfo)
er := MinerABI.UnpackVariable(info, VariableNameMinerReward, data)
if er != nil {
return 0, er
}
return info.EndHeight, nil
} else {
return 0, err
}
}
func MinerCalcRewardEndHeight(startHeight uint64, maxEndHeight uint64) uint64 {
if maxEndHeight < common.PovMinerRewardHeightStart {
return 0
}
if startHeight < common.PovMinerRewardHeightStart {
startHeight = common.PovMinerRewardHeightStart
}
endHeight := startHeight + common.PovMinerMaxRewardBlocksPerCall - 1
if endHeight > maxEndHeight {
endHeight = maxEndHeight
}
endHeight = MinerRoundPovHeight(endHeight, common.PovMinerRewardHeightRound)
if endHeight < common.PovMinerRewardHeightStart {
return 0
}
return endHeight
}
// height begin from 0, so height + 1 == blocks count
func MinerPovHeightToCount(height uint64) uint64 {
return height + 1
}
func MinerRoundPovHeight(height uint64, round uint64) uint64 {
roundCount := (MinerPovHeightToCount(height) / round) * round
if roundCount == 0 {
return 0
}
return roundCount - 1
}