Update blockchain height to 64-bits according to the Whitepaper 0.9.2. Close #74

This commit is contained in:
Kleissner
2021-12-11 20:43:38 +01:00
parent 5db25f2704
commit c12b68c35c
6 changed files with 42 additions and 42 deletions

View File

@@ -82,7 +82,7 @@ func (cache *BlockchainCache) SeenBlockchainVersion(peer *PeerInfo) {
}
// get the old header
header, status, err := cache.store.AssessBlockchainHeader(peer.PublicKey, peer.BlockchainVersion, uint64(peer.BlockchainHeight))
header, status, err := cache.store.AssessBlockchainHeader(peer.PublicKey, peer.BlockchainVersion, peer.BlockchainHeight)
if err != nil {
return
}
@@ -95,27 +95,27 @@ func (cache *BlockchainCache) SeenBlockchainVersion(peer *PeerInfo) {
cache.store.DeleteBlockchain(peer.PublicKey, header)
case blockchain.MultiStatusHeaderNA:
if header, err = cache.store.NewBlockchainHeader(peer.PublicKey, peer.BlockchainVersion, uint64(peer.BlockchainHeight)); err != nil {
if header, err = cache.store.NewBlockchainHeader(peer.PublicKey, peer.BlockchainVersion, peer.BlockchainHeight); err != nil {
return
}
downloadAndProcessBlocks(peer, header, 0, uint64(peer.BlockchainHeight))
downloadAndProcessBlocks(peer, header, 0, peer.BlockchainHeight)
case blockchain.MultiStatusNewVersion:
// delete existing data first, then create it new
cache.store.DeleteBlockchain(peer.PublicKey, header)
if header, err = cache.store.NewBlockchainHeader(peer.PublicKey, peer.BlockchainVersion, uint64(peer.BlockchainHeight)); err != nil {
if header, err = cache.store.NewBlockchainHeader(peer.PublicKey, peer.BlockchainVersion, peer.BlockchainHeight); err != nil {
return
}
downloadAndProcessBlocks(peer, header, 0, uint64(peer.BlockchainHeight))
downloadAndProcessBlocks(peer, header, 0, peer.BlockchainHeight)
case blockchain.MultiStatusNewBlocks:
offset := header.Height
limit := uint64(peer.BlockchainHeight) - header.Height
limit := peer.BlockchainHeight - header.Height
header.Height = uint64(peer.BlockchainHeight)
header.Height = peer.BlockchainHeight
downloadAndProcessBlocks(peer, header, offset, limit)

View File

@@ -100,7 +100,7 @@ type PeerInfo struct {
isVirtual bool // Whether it is a virtual peer for establishing a connection.
targetAddresses []*peerAddress // Virtual peer: Addresses to send any replies.
traversePeer *PeerInfo // Virtual peer: Same field as in connection.
BlockchainHeight uint32 // Blockchain height
BlockchainHeight uint64 // Blockchain height
BlockchainVersion uint64 // Blockchain version
// statistics

View File

@@ -8,9 +8,9 @@ Offset Size Info
0 65 Signature of entire block
65 32 Hash (blake3) of last block. 0 for first one.
97 8 Blockchain version number
105 4 Block number
109 4 Size of entire block including this header
113 2 Count of records that follow
105 8 Block number
113 4 Size of entire block including this header
117 2 Count of records that follow
*/
@@ -44,7 +44,7 @@ type BlockRecordRaw struct {
Data []byte // Data according to the type
}
const blockHeaderSize = 115
const blockHeaderSize = 119
const blockRecordHeaderSize = 13
// decodeBlock decodes a single block
@@ -68,16 +68,16 @@ func decodeBlock(raw []byte) (block *Block, err error) {
copy(block.LastBlockHash, raw[65:65+protocol.HashSize])
block.BlockchainVersion = binary.LittleEndian.Uint64(raw[97 : 97+8])
block.Number = uint64(binary.LittleEndian.Uint32(raw[105 : 105+4])) // for now 32-bit in protocol
block.Number = binary.LittleEndian.Uint64(raw[105 : 105+8])
blockSize := binary.LittleEndian.Uint32(raw[109 : 109+4])
blockSize := binary.LittleEndian.Uint32(raw[113 : 113+4])
if blockSize != uint32(len(raw)) {
return nil, errors.New("decodeBlock invalid block size")
}
// decode on a low-level all block records
countRecords := binary.LittleEndian.Uint16(raw[113 : 113+2])
index := 115
countRecords := binary.LittleEndian.Uint16(raw[117 : 117+2])
index := blockHeaderSize
for n := uint16(0); n < countRecords; n++ {
if index+blockRecordHeaderSize > len(raw) {
@@ -114,10 +114,10 @@ func encodeBlock(block *Block, ownerPrivateKey *btcec.PrivateKey) (raw []byte, e
var temp [8]byte
binary.LittleEndian.PutUint64(temp[0:8], block.BlockchainVersion)
buffer.Write(temp[:])
buffer.Write(temp[:8])
binary.LittleEndian.PutUint32(temp[0:4], uint32(block.Number)) // for now 32-bit in protocol
buffer.Write(temp[:4])
binary.LittleEndian.PutUint64(temp[0:8], block.Number)
buffer.Write(temp[:8])
buffer.Write(make([]byte, 4)) // Size of block, filled later
buffer.Write(make([]byte, 2)) // Count of records, filled later
@@ -148,8 +148,8 @@ func encodeBlock(block *Block, ownerPrivateKey *btcec.PrivateKey) (raw []byte, e
return nil, errors.New("encodeBlock invalid block size")
}
binary.LittleEndian.PutUint32(raw[109:109+4], uint32(len(raw))) // Size of block
binary.LittleEndian.PutUint16(raw[113:113+2], countRecords) // Count of records
binary.LittleEndian.PutUint32(raw[113:113+4], uint32(len(raw))) // Size of block
binary.LittleEndian.PutUint16(raw[117:117+2], countRecords) // Count of records
// signature is last
signature, err := btcec.SignCompact(btcec.S256(), ownerPrivateKey, protocol.HashData(raw[65:]), true)

View File

@@ -18,7 +18,7 @@ type MessageAnnouncement struct {
Protocol uint8 // Protocol version supported (low 4 bits).
Features uint8 // Feature support
Actions uint8 // Action bit array. See ActionX
BlockchainHeight uint32 // Blockchain height
BlockchainHeight uint64 // Blockchain height
BlockchainVersion uint64 // Blockchain version
PortInternal uint16 // Internal port. Can be used to detect NATs.
PortExternal uint16 // External port if known. 0 if not. Can be used for UPnP support.
@@ -56,7 +56,7 @@ const (
)
// Minimum length of Announcement payload header without User Agent
const announcementPayloadHeaderSize = 20
const announcementPayloadHeaderSize = 24
// DecodeAnnouncement decodes the incoming announcement message. Returns nil if invalid.
func DecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err error) {
@@ -71,12 +71,12 @@ func DecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err error
result.Protocol = msg.Payload[0] & 0x0F // Protocol version support is stored in the first 4 bits
result.Features = msg.Payload[1] // Feature support
result.Actions = msg.Payload[2]
result.BlockchainHeight = binary.LittleEndian.Uint32(msg.Payload[3:7])
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[7:15])
result.PortInternal = binary.LittleEndian.Uint16(msg.Payload[15:17])
result.PortExternal = binary.LittleEndian.Uint16(msg.Payload[17:19])
result.BlockchainHeight = binary.LittleEndian.Uint64(msg.Payload[3 : 3+8])
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[11 : 11+8])
result.PortInternal = binary.LittleEndian.Uint16(msg.Payload[19 : 19+2])
result.PortExternal = binary.LittleEndian.Uint16(msg.Payload[21 : 21+2])
userAgentLength := int(msg.Payload[19])
userAgentLength := int(msg.Payload[23])
if userAgentLength > 0 {
if userAgentLength > len(msg.Payload)-announcementPayloadHeaderSize {
return nil, errors.New("announcement: user agent overflow")
@@ -193,8 +193,8 @@ createPacketLoop:
raw[1] = features // Feature support
//raw[2] = Actions // Action bit array
binary.LittleEndian.PutUint32(raw[3:7], uint32(blockchainHeight))
binary.LittleEndian.PutUint64(raw[7:15], blockchainVersion)
binary.LittleEndian.PutUint64(raw[3:3+8], blockchainHeight)
binary.LittleEndian.PutUint64(raw[11:11+8], blockchainVersion)
// only on initial announcement the User Agent must be provided according to the protocol spec
if sendUA {
@@ -203,7 +203,7 @@ createPacketLoop:
userAgentB = userAgentB[:255]
}
raw[19] = byte(len(userAgentB))
raw[23] = byte(len(userAgentB))
copy(raw[announcementPayloadHeaderSize:announcementPayloadHeaderSize+len(userAgentB)], userAgentB)
packetSize += len(userAgentB)
}

View File

@@ -23,7 +23,7 @@ type MessageResponse struct {
Protocol uint8 // Protocol version supported (low 4 bits).
Features uint8 // Feature support (high 4 bits). Future use.
Actions uint8 // Action bit array. See ActionX
BlockchainHeight uint32 // Blockchain height
BlockchainHeight uint64 // Blockchain height
BlockchainVersion uint64 // Blockchain version
PortInternal uint16 // Internal port. Can be used to detect NATs.
PortExternal uint16 // External port if known. 0 if not. Can be used for UPnP support.
@@ -82,12 +82,12 @@ func DecodeResponse(msg *MessageRaw) (result *MessageResponse, err error) {
result.Protocol = msg.Payload[0] & 0x0F // Protocol version support is stored in the first 4 bits
result.Features = msg.Payload[1] // Feature support
result.Actions = msg.Payload[2]
result.BlockchainHeight = binary.LittleEndian.Uint32(msg.Payload[3:7])
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[7:15])
result.PortInternal = binary.LittleEndian.Uint16(msg.Payload[15:17])
result.PortExternal = binary.LittleEndian.Uint16(msg.Payload[17:19])
result.BlockchainHeight = binary.LittleEndian.Uint64(msg.Payload[3 : 3+8])
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[11 : 11+8])
result.PortInternal = binary.LittleEndian.Uint16(msg.Payload[19 : 19+2])
result.PortExternal = binary.LittleEndian.Uint16(msg.Payload[21 : 21+2])
userAgentLength := int(msg.Payload[19])
userAgentLength := int(msg.Payload[23])
read := announcementPayloadHeaderSize
if userAgentLength > 0 {
@@ -289,8 +289,8 @@ createPacketLoop:
raw[1] = features // Feature support
//raw[2] = Actions // Action bit array
binary.LittleEndian.PutUint32(raw[3:7], uint32(blockchainHeight))
binary.LittleEndian.PutUint64(raw[7:15], blockchainVersion)
binary.LittleEndian.PutUint64(raw[3:3+8], blockchainHeight)
binary.LittleEndian.PutUint64(raw[11:11+8], blockchainVersion)
// only on initial response the User Agent must be provided according to the protocol spec
if sendUA {
@@ -299,7 +299,7 @@ createPacketLoop:
userAgentB = userAgentB[:255]
}
raw[19] = byte(len(userAgentB))
raw[23] = byte(len(userAgentB))
copy(raw[announcementPayloadHeaderSize:announcementPayloadHeaderSize+len(userAgentB)], userAgentB)
packetSize += len(userAgentB)
}

View File

@@ -152,6 +152,6 @@ func (packet *PacketRaw) SetSelfReportedPorts(portI, portE uint16) {
return
}
binary.LittleEndian.PutUint16(packet.Payload[15:17], portI)
binary.LittleEndian.PutUint16(packet.Payload[17:19], portE)
binary.LittleEndian.PutUint16(packet.Payload[19:19+2], portI)
binary.LittleEndian.PutUint16(packet.Payload[21:21+2], portE)
}