Skip to content

Commit

Permalink
Added Hardfork history field to ChainInfo rpc.
Browse files Browse the repository at this point in the history
- The keys and values are the hardfork version and the block height at which the hardfork starts.
  • Loading branch information
hayarobi committed Nov 4, 2024
1 parent b3380d4 commit abbeddd
Show file tree
Hide file tree
Showing 25 changed files with 1,237 additions and 2,662 deletions.
2 changes: 1 addition & 1 deletion aergo-protobuf
35 changes: 33 additions & 2 deletions chain/chaindb.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/json"
"errors"
"fmt"
"strconv"
"sync/atomic"

"github.com/aergoio/aergo-lib/db"
Expand Down Expand Up @@ -757,12 +758,42 @@ func (cdb *ChainDB) Hardfork(hConfig config.HardforkConfig) config.HardforkDbCon
if err := json.Unmarshal(data, &c); err != nil {
return nil
}
// When a new hardkfork height is added, the hardfork config from DB (HardforkDBConfig)
// When a new hardfork height is added, the hardfork config from DB (HardforkDBConfig)
// must be modified by using the height from HardforkConfig. Without this, aergosvr fails
// to start, since a harfork heght value not stored on DB is evaluated as 0.
// to start, since a hardfork height value not stored on DB is evaluated as 0.
return c.FixDbConfig(hConfig)
}

func (cdb *ChainDB) hardforkHeights() config.HardforkDbConfig {
var c config.HardforkDbConfig
data := cdb.store.Get(dbkey.HardFork())
if len(data) == 0 {
return c
}
// TODO Hardfork status is not changed during the lifetime of server process.
// We can optimize this
if err := json.Unmarshal(data, &c); err != nil {
logger.Error().Msg("Failed to read hardfork from cdb")
return c
}
returned := make(map[string]uint64, len(c))
for key, value := range c {
newKey := key[1:]
if key[0] != 'V' || !IsInteger(newKey) {
return make(map[string]uint64, 0)
}
returned[newKey] = value
}

return returned
}

// IsInteger check the parameter is integer form or not
func IsInteger(s string) bool {
_, err := strconv.Atoi(s)
return err == nil
}

func (cdb *ChainDB) WriteHardfork(c *config.HardforkConfig) error {
data, err := json.Marshal(c)
if err != nil {
Expand Down
97 changes: 97 additions & 0 deletions chain/chaindb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package chain

import (
"github.com/aergoio/aergo-lib/db"
"github.com/aergoio/aergo/v2/consensus"
"github.com/stretchr/testify/assert"
"sync/atomic"
"testing"
)

func TestChainDB_hardforkHeights(t *testing.T) {
type fields struct {
cc consensus.ChainConsensus
latest atomic.Value
bestBlock atomic.Value
store db.DB
}
tests := []struct {
name string
hardfork string
wantSuccess bool
}{
{ "normal", `{"V2":2000,"V3":30000,"V4":400000}`, true},
{ "wrong", `{"A":2000,"B3A":30000,"V4":400000}`, false},
{ "wrong2", `{"A2":2000,"B3":30000,"V4":400000}`, false},
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cdb := &ChainDB{
store: DBStub{tt.hardfork},
}
actual := cdb.hardforkHeights()
if tt.wantSuccess {
assert.Equal(t, 3,len(actual), "hardforkHeights()")
assert.Equal(t, uint64(2000), actual["2"], "hardforkHeights() : 2")
assert.Equal(t, uint64(30000), actual["3"], "hardforkHeights() : 3")
assert.Equal(t, uint64(400000), actual["4"], "hardforkHeights() : 4")
assert.Equal(t, uint64(0), actual["5"], "hardforkHeights() : 5")
} else {
assert.Equal(t, 0, len(actual), "hardforkHeights()")
}
})
}
}

type DBStub struct {
hardfork string
}

func (m DBStub) Type() string {
//TODO implement me
panic("implement me")
}

func (m DBStub) Set(key, value []byte) {
//TODO implement me
panic("implement me")
}

func (m DBStub) Delete(key []byte) {
//TODO implement me
panic("implement me")
}

func (m DBStub) Get(key []byte) []byte {
if string(key) == "hardfork" {
return []byte(m.hardfork)
}
//TODO implement me
panic("implement me")
}

func (m DBStub) Exist(key []byte) bool {
//TODO implement me
panic("implement me")
}

func (m DBStub) Iterator(start, end []byte) db.Iterator {
//TODO implement me
panic("implement me")
}

func (m DBStub) NewTx() db.Transaction {
//TODO implement me
panic("implement me")
}

func (m DBStub) NewBulk() db.Bulk {
//TODO implement me
panic("implement me")
}

func (m DBStub) Close() {
//TODO implement me
panic("implement me")
}
4 changes: 4 additions & 0 deletions chain/chainservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -987,3 +987,7 @@ func (cs *ChainService) ChainID(bno types.BlockNo) *types.ChainID {
cid.Version = cs.cfg.Hardfork.Version(bno)
return cid
}

func (cs *ChainService) HardforkHeights() map[string]types.BlockNo {
return cs.cdb.hardforkHeights()
}
5 changes: 5 additions & 0 deletions chain/stubchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ func (tchain *StubBlockChain) ChainID(bno types.BlockNo) *types.ChainID {
return nil
}

func (tchain *StubBlockChain) HardforkHeights() map[string]types.BlockNo {
// FIXME: maybe it should return at least latest hardfork
return nil
}

func (tchain *StubBlockChain) Rollback(ancestor *types.BlockInfo) {
prevBest := tchain.Best
tchain.Best = int(ancestor.No)
Expand Down
16 changes: 15 additions & 1 deletion p2p/p2pmock/mock_chainaccessor.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions p2p/p2pmock/readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mockgen -source=p2p/p2pcommon/pool.go -mock_names=WaitingPeerManager=MockWaiting


# Manually generated mock classes
The generate decriptions of these mock objects are in p2p/p2pcommon/temptypes.go . So you can use such like `go generate ./p2p/p2pcommon/temptypes.go` command.
The generate descriptions of these mock objects are in p2p/p2pcommon/temptypes.go . So you can use such like `go generate ./p2p/p2pcommon/temptypes.go` command.

# mock files which are not generated automatically by go generate ./p2p
mockgen github.com/aergoio/aergo/v2/consensus ConsensusAccessor,AergoRaftAccessor | gsed -e 's/^package mock_[a-zA-Z0-9_]\+/package p2pmock/g' > p2p/p2pmock/mock_consensus.go
Expand All @@ -26,4 +26,4 @@ mockgen -source=types/blockchain.go -package=p2pmock -destination=p2p/p2pmock/mo

mockgen io Reader,ReadCloser,Writer,WriteCloser,ReadWriteCloser > p2p/p2pmock/mock_io.go | gsed -e 's/^package mock_[a-zA-Z0-9_]\+/package p2pmock/g' > p2p/p2pmock/mock_io.go

mockgen github.com/aergoio/aergo/v2/types ChainAccessor | sed -e 's/^package mock_mock_[a-zA-Z0-9_]\+/package p2pmock/g' > ../p2pmock/mock_chainaccessor.go
mockgen github.com/aergoio/aergo/v2/types ChainAccessor | sed -e 's/^package mock_[a-zA-Z0-9_]\+/package p2pmock/g' > ../p2pmock/mock_chainaccessor.go
5 changes: 5 additions & 0 deletions p2p/subproto/blockhash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package subproto
import (
"bytes"
"crypto/sha256"
"fmt"
"sync"
"testing"

Expand Down Expand Up @@ -261,6 +262,10 @@ func (a *testDoubleChainAccessor) getChain() [][]byte {
}
}

func (a *testDoubleChainAccessor) GetBlockByNo(blockNo types.BlockNo) (*types.Block, error) {
return nil, fmt.Errorf("not implemented")
}

type testDoubleHashesRespFactory struct {
lastResp *types.GetHashesResponse
lastStatus types.ResultStatus
Expand Down
2 changes: 2 additions & 0 deletions rpc/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ func (rpc *AergoRPCService) getChainInfo(ctx context.Context) (*types.ChainInfo,
return nil, err
}

chainInfo.Hardfork = rpc.actorHelper.GetChainAccessor().HardforkHeights()

return chainInfo, nil
}

Expand Down
52 changes: 11 additions & 41 deletions types/account.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions types/admin.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion types/admin_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit abbeddd

Please sign in to comment.