Skip to content

Commit e87ab41

Browse files
committed
xhash: add getCirculatingSupply API
1 parent 4c14546 commit e87ab41

File tree

4 files changed

+48
-14
lines changed

4 files changed

+48
-14
lines changed

consensus/xhash/api.go

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
"github.com/microstack-tech/parallax/common"
2424
"github.com/microstack-tech/parallax/common/hexutil"
25+
"github.com/microstack-tech/parallax/consensus"
2526
"github.com/microstack-tech/parallax/core/types"
2627
)
2728

@@ -30,6 +31,7 @@ var errXHashStopped = errors.New("xhash stopped")
3031
// API exposes xhash related methods for the RPC interface.
3132
type API struct {
3233
xhash *XHash
34+
chain consensus.ChainHeaderReader
3335
}
3436

3537
// GetWork returns a work package for external miner.
@@ -113,13 +115,45 @@ func (api *API) GetHashrate() uint64 {
113115
return uint64(api.xhash.Hashrate())
114116
}
115117

116-
func (api *API) GetCumulativeEmissions(blockNumber hexutil.Uint64) *big.Int {
117-
emissions := big.NewInt(0)
118-
number := uint64(blockNumber)
118+
func (api *API) GetCirculatingSupply() *big.Int {
119+
header := api.chain.CurrentHeader()
120+
if header == nil {
121+
return big.NewInt(0)
122+
}
123+
124+
// Number of blocks including genesis
125+
n := header.Number.Uint64()
126+
127+
const halvingInterval uint64 = 210_000
128+
emissions := new(big.Int)
129+
tmp := new(big.Int)
130+
131+
fullEras := n / halvingInterval
132+
remainder := n % halvingInterval
133+
134+
// Full eras
135+
for era := range fullEras {
136+
// pick a representative block *in* this era
137+
sampleBlock := era * halvingInterval
138+
reward := calcBlockReward(sampleBlock)
119139

120-
for i := uint64(0); i < number; i++ {
121-
reward := calcBlockReward(number)
122-
emissions = emissions.Add(emissions, reward)
140+
tmp.SetUint64(halvingInterval)
141+
tmp.Mul(tmp, reward)
142+
emissions.Add(emissions, tmp)
123143
}
144+
145+
// Partial current era
146+
if remainder > 0 {
147+
sampleBlock := fullEras * halvingInterval
148+
if sampleBlock == 0 {
149+
sampleBlock = 1
150+
}
151+
reward := calcBlockReward(sampleBlock)
152+
153+
tmp.SetUint64(remainder)
154+
tmp.Mul(tmp, reward)
155+
emissions.Add(emissions, tmp)
156+
}
157+
124158
return emissions
125159
}

consensus/xhash/sealer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ func TestRemoteMultiNotifyFull(t *testing.T) {
217217
func TestStaleSubmission(t *testing.T) {
218218
xhash := NewTester(nil, true)
219219
defer xhash.Close()
220-
api := &API{xhash}
220+
api := &API{xhash, nil}
221221

222222
fakeNonce, fakeDigest := types.BlockNonce{0x01, 0x02, 0x03}, common.HexToHash("deadbeef")
223223

consensus/xhash/xhash.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func isLittleEndian() bool {
7575

7676
// memoryMap tries to memory map a file of uint32s for read only access.
7777
func memoryMap(path string, lock bool) (*os.File, mmap.MMap, []uint32, error) {
78-
file, err := os.OpenFile(path, os.O_RDONLY, 0644)
78+
file, err := os.OpenFile(path, os.O_RDONLY, 0o644)
7979
if err != nil {
8080
return nil, nil, nil, err
8181
}
@@ -126,7 +126,7 @@ func memoryMapFile(file *os.File, write bool) (mmap.MMap, []uint32, error) {
126126
// path requested.
127127
func memoryMapAndGenerate(path string, size uint64, lock bool, generator func(buffer []uint32)) (*os.File, mmap.MMap, []uint32, error) {
128128
// Ensure the data folder exists
129-
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
129+
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
130130
return nil, nil, nil, err
131131
}
132132
// Create a huge temporary empty file to fill with data
@@ -679,13 +679,13 @@ func (xhash *XHash) APIs(chain consensus.ChainHeaderReader) []rpc.API {
679679
{
680680
Namespace: "eth",
681681
Version: "1.0",
682-
Service: &API{xhash},
682+
Service: &API{chain: chain, xhash: xhash},
683683
Public: true,
684684
},
685685
{
686686
Namespace: "xhash",
687687
Version: "1.0",
688-
Service: &API{xhash},
688+
Service: &API{chain: chain, xhash: xhash},
689689
Public: true,
690690
},
691691
}

consensus/xhash/xhash_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func TestRemoteSealer(t *testing.T) {
9999
xhash := NewTester(nil, false)
100100
defer xhash.Close()
101101

102-
api := &API{xhash}
102+
api := &API{xhash, nil}
103103
if _, err := api.GetWork(); err != errNoMiningWork {
104104
t.Error("expect to return an error indicate there is no mining work")
105105
}
@@ -146,7 +146,7 @@ func TestHashrate(t *testing.T) {
146146
t.Error("expect the result should be zero")
147147
}
148148

149-
api := &API{xhash}
149+
api := &API{xhash, nil}
150150
for i := 0; i < len(hashrate); i += 1 {
151151
if res := api.SubmitHashrate(hashrate[i], ids[i]); !res {
152152
t.Error("remote miner submit hashrate failed")
@@ -163,7 +163,7 @@ func TestClosedRemoteSealer(t *testing.T) {
163163
time.Sleep(1 * time.Second) // ensure exit channel is listening
164164
xhash.Close()
165165

166-
api := &API{xhash}
166+
api := &API{xhash, nil}
167167
if _, err := api.GetWork(); err != errXHashStopped {
168168
t.Error("expect to return an error to indicate XHash is stopped")
169169
}

0 commit comments

Comments
 (0)