Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved performance degradation due to change in json format of consensus snapshot #69

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions consensus/oasys/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,40 @@ type Snapshot struct {
Number uint64 `json:"number"` // Block number where the snapshot was created
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
Validators map[common.Address]*ValidatorInfo `json:"validators"` // Set of authorized validators and stakes at this moment
Attestation *types.VoteData `json:"attestation:omitempty"` // Attestation for fast finality, but `Source` used as `Finalized`
Attestation *types.VoteData `json:"attestation,omitempty"` // Attestation for fast finality, but `Source` used as `Finalized`

Environment *params.EnvironmentValue `json:"environment"`
}

type ValidatorInfo struct {
// The index is determined by the sorted order of the validator owner address
Stake *big.Int `json:"stake:omitempty"` // The stake amount
Index int `json:"index:omitempty"` // The index should offset by 1
Stake *big.Int `json:"stake,omitempty"` // The stake amount
Index int `json:"index,omitempty"` // The index should offset by 1
VoteAddress types.BLSPublicKey `json:"vote_address,omitempty"` // The vote address
}

// Note: This code can be removed after each validators has been upgraded to v1.6.0.
func (info *ValidatorInfo) UnmarshalJSON(b []byte) error {
// v1.5.0 or earlier
bigint := new(big.Int)
if err := json.Unmarshal(b, bigint); err == nil {
info.Stake = bigint
return nil
}

// v1.6.0 or later
type Alias ValidatorInfo
alias := new(Alias)
if err := json.Unmarshal(b, alias); err != nil {
return err
}

info.Stake = alias.Stake
info.Index = alias.Index
info.VoteAddress = alias.VoteAddress
return nil
}

// validatorsAscending implements the sort interface to allow sorting a list of addresses
type validatorsAscending []common.Address

Expand Down
44 changes: 44 additions & 0 deletions consensus/oasys/snapshot_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package oasys

import (
"encoding/json"
"math/big"
"testing"

"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)

func TestUnmarshalValidatorInfo(t *testing.T) {
jsonbody := []byte(`[
1,
{
"stake": 2,
"index": 3,
"vote_address": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004"
}
]`)

expects := []*ValidatorInfo{
&ValidatorInfo{
Stake: big.NewInt(1),
Index: 0,
VoteAddress: types.BLSPublicKey{},
},
&ValidatorInfo{
Stake: big.NewInt(2),
Index: 3,
VoteAddress: types.BLSPublicKey([]byte{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
}),
},
}

var actuals []*ValidatorInfo
err := json.Unmarshal(jsonbody, &actuals)
require.NoError(t, err)
require.Equal(t, expects, actuals)
}
20 changes: 19 additions & 1 deletion core/types/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package types
import (
"bytes"
"math/big"
"reflect"
"sync/atomic"

"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)

const (
Expand All @@ -18,6 +20,10 @@ const (
MaxAttestationExtraLength = 256
)

var (
blsPublicKeyT = reflect.TypeOf(BLSPublicKey{})
)

type BLSPublicKey [BLSPublicKeyLength]byte
type BLSSignature [BLSSignatureLength]byte
type ValidatorsBitSet uint64
Expand Down Expand Up @@ -71,7 +77,19 @@ func (v *VoteEnvelope) calcVoteHash() common.Hash {
return rlpHash(vote)
}

func (b BLSPublicKey) Bytes() []byte { return b[:] }
func (b BLSPublicKey) Bytes() []byte { return b[:] }
func (b BLSPublicKey) String() string { return hexutil.Encode(b[:]) }

// MarshalText gets implements encoding.TextMarshaler. Since BLSPublicKey is stored as JSON in the
// consensus engine's snapshot db, it is converted to a hex-string to improve readability and reduce size.
func (b BLSPublicKey) MarshalText() ([]byte, error) {
return hexutil.Bytes(b[:]).MarshalText()
}

// UnmarshalJSON decodes the input as a string with 0x prefix
func (b *BLSPublicKey) UnmarshalJSON(input []byte) error {
return hexutil.UnmarshalFixedJSON(blsPublicKeyT, input, b[:])
}

// Verify vote using BLS.
func (vote *VoteEnvelope) Verify() error {
Expand Down