Merge pull request #3819 from nspcc-dev/genesis-header-size

*: fix GetExpectedHeaderSize for genesis block case
This commit is contained in:
Anna Shaleva 2025-02-26 20:49:34 +08:00 committed by GitHub
commit 64e3b6aa48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 12 deletions

View file

@ -238,18 +238,26 @@ func (b *Header) UnmarshalJSON(data []byte) error {
} }
// GetExpectedHeaderSize returns the expected Header size with the given number of validators. // GetExpectedHeaderSize returns the expected Header size with the given number of validators.
// To calculate genesis block Header size numOfValidators should be 0.
func GetExpectedHeaderSize(stateRootInHeader bool, numOfValidators int) int { func GetExpectedHeaderSize(stateRootInHeader bool, numOfValidators int) int {
m := smartcontract.GetDefaultHonestNodeCount(numOfValidators) var size int
// expectedHeaderSizeWithEmptyWitness contains 2 bytes for zero-length (new(Header)).Script.Invocation/Verification // Genesis block case.
// InvocationScript: if numOfValidators == 0 {
// 64 is the size of the default signature length + 2 bytes length and opcode // 1 byte for the PUSH1 opcode.
// 2 = 1 push opcode + 1 length size = expectedHeaderSizeWithEmptyWitness + 1
// VerifcationScript: } else {
// m = 1 bytes m := smartcontract.GetDefaultHonestNodeCount(numOfValidators)
// 33 = 1 push opcode + 1 length + 33 bytes for public key // expectedHeaderSizeWithEmptyWitness contains 2 bytes for zero-length (new(Header)).Script.Invocation/Verification
// n = 1 bytes // InvocationScript:
// 5 for SYSCALL // 64 is the size of the default signature length + 2 bytes length and opcode
size := expectedHeaderSizeWithEmptyWitness + (1+1+64)*m + 2 + numOfValidators*(1+1+33) + 2 + 5 // 2 = 1 push opcode + 1 length
// VerifcationScript:
// m = 1 bytes
// 33 = 1 push opcode + 1 length + 33 bytes for public key
// n = 1 bytes
// 5 for SYSCALL
size = expectedHeaderSizeWithEmptyWitness + (1+1+64)*m + 2 + numOfValidators*(1+1+33) + 2 + 5
}
if stateRootInHeader { if stateRootInHeader {
size += util.Uint256Size size += util.Uint256Size

View file

@ -5,7 +5,9 @@ import (
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -39,3 +41,14 @@ func TestGetConsensusAddressMainNet(t *testing.T) {
assert.Equal(t, consensusScript, script.String()) assert.Equal(t, consensusScript, script.String())
assert.Equal(t, consensusAddr, address.Uint160ToString(script)) assert.Equal(t, consensusAddr, address.Uint160ToString(script))
} }
func TestGetExpectedHeaderSize(t *testing.T) {
cfg, err := config.Load("../../config", netmode.MainNet)
require.NoError(t, err)
blk, err := CreateGenesisBlock(cfg.ProtocolConfiguration)
require.NoError(t, err)
w := io.NewBufBinWriter()
blk.Header.EncodeBinary(w.BinWriter)
require.NoError(t, w.Err)
require.Equal(t, block.GetExpectedHeaderSize(false, 0), w.Len())
}

View file

@ -192,7 +192,8 @@ func New(chain Ledger, cfg config.NeoFSBlockFetcher, logger *zap.Logger, put fun
func getHeaderSizeMap(chain config.Blockchain) map[int]int { func getHeaderSizeMap(chain config.Blockchain) map[int]int {
headerSizeMap := make(map[int]int) headerSizeMap := make(map[int]int)
headerSizeMap[0] = block.GetExpectedHeaderSize(chain.StateRootInHeader, chain.GetNumOfCNs(0)) headerSizeMap[0] = block.GetExpectedHeaderSize(chain.StateRootInHeader, 0) // genesis header size.
headerSizeMap[1] = block.GetExpectedHeaderSize(chain.StateRootInHeader, chain.GetNumOfCNs(0))
for height := range chain.CommitteeHistory { for height := range chain.CommitteeHistory {
headerSizeMap[int(height)] = block.GetExpectedHeaderSize(chain.StateRootInHeader, chain.GetNumOfCNs(height)) headerSizeMap[int(height)] = block.GetExpectedHeaderSize(chain.StateRootInHeader, chain.GetNumOfCNs(height))
} }