Added pool block metadata field, register precise ingress time and peer information

This commit is contained in:
DataHoarder 2024-04-13 04:45:47 +02:00
parent b3b0690f6f
commit 82d2a2a2bd
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
5 changed files with 55 additions and 10 deletions

View file

@ -89,7 +89,9 @@ func (c *Cache) LoadAll(l cache.Loadee) {
}
block := &sidechain.PoolBlock{
LocalTimestamp: uint64(time.Now().Unix()),
Metadata: sidechain.PoolBlockReceptionMetadata{
LocalTime: time.Now().UTC(),
},
}
if err := block.UnmarshalBinary(c.consensus, &sidechain.NilDerivationCache{}, buf[:blobLength]); err != nil {

View file

@ -150,6 +150,16 @@ func (c *Client) getNextBlockRequest() (id types.Hash, ok bool) {
}
}
// PreferredAddressPort Return the address and port to which the peer is most probably reachable
func (c *Client) PreferredAddressPort() netip.AddrPort {
if listenPort := c.ListenPort.Load(); listenPort != 0 {
return netip.AddrPortFrom(c.AddressPort.Addr(), uint16(listenPort))
}
//take default from consensus
return netip.AddrPortFrom(c.AddressPort.Addr(), c.Owner.Consensus().DefaultPort())
}
func (c *Client) SendListenPort() {
c.SendMessage(&ClientMessage{
MessageId: MessageListenPort,
@ -486,7 +496,13 @@ func (c *Client) OnConnection() {
c.SendBlockResponse(block)
case MessageBlockResponse:
block := &sidechain.PoolBlock{
LocalTimestamp: uint64(time.Now().Unix()),
Metadata: sidechain.PoolBlockReceptionMetadata{
LocalTime: time.Now().UTC(),
AddressPort: c.PreferredAddressPort(),
PeerId: c.PeerId.Load(),
SoftwareId: uint32(c.VersionInformation.SoftwareId),
SoftwareVersion: uint32(c.VersionInformation.SoftwareVersion),
},
}
expectedBlockId, ok := c.getNextBlockRequest()
@ -573,7 +589,13 @@ func (c *Client) OnConnection() {
case MessageBlockBroadcast, MessageBlockBroadcastCompact:
block := &sidechain.PoolBlock{
LocalTimestamp: uint64(time.Now().Unix()),
Metadata: sidechain.PoolBlockReceptionMetadata{
LocalTime: time.Now().UTC(),
AddressPort: c.PreferredAddressPort(),
PeerId: c.PeerId.Load(),
SoftwareId: uint32(c.VersionInformation.SoftwareId),
SoftwareVersion: uint32(c.VersionInformation.SoftwareVersion),
},
}
var blockSize uint32
if err := binary.Read(c, binary.LittleEndian, &blockSize); err != nil {

View file

@ -16,8 +16,10 @@ import (
"git.gammaspectra.live/P2Pool/consensus/v3/types"
"git.gammaspectra.live/P2Pool/consensus/v3/utils"
fasthex "github.com/tmthrgd/go-hex"
"net/netip"
"slices"
"sync/atomic"
"time"
"unsafe"
)
@ -80,12 +82,26 @@ type PoolBlock struct {
WantBroadcast atomic.Bool `json:"-"`
Broadcasted atomic.Bool `json:"-"`
LocalTimestamp uint64 `json:"-"`
Metadata PoolBlockReceptionMetadata `json:"-"`
CachedShareVersion ShareVersion `json:"share_version"`
iterationCache *IterationCache
}
type PoolBlockReceptionMetadata struct {
// LocalTime Moment the block was received from a source
LocalTime time.Time `json:"local_time,omitempty"`
// AddressPort The address and port of the peer who broadcasted or sent us this block
// If the peer specified a listen port, the port will be that instead of current connection one
AddressPort netip.AddrPort `json:"address_port,omitempty"`
// PeerId The peer id of the peer who broadcasted or sent us this block
PeerId uint64 `json:"peer_id,omitempty"`
SoftwareId uint32 `json:"software_id"`
SoftwareVersion uint32 `json:"software_version"`
}
func (b *PoolBlock) iteratorGetParent(getByTemplateId GetByTemplateIdFunc) *PoolBlock {
if b.iterationCache == nil {
return getByTemplateId(b.Side.Parent)

View file

@ -995,10 +995,12 @@ func (c *SideChain) pruneOldBlocks() {
// Leave 2 minutes worth of spare blocks in addition to 2xPPLNS window for lagging nodes which need to sync
pruneDistance := c.Consensus().ChainWindowSize*2 + monero.BlockTime/c.Consensus().TargetBlockTime
curTime := uint64(time.Now().Unix())
curTime := time.Now().UTC()
// Remove old blocks from alternative unconnected chains after long enough time
pruneDelay := c.Consensus().ChainWindowSize * 4 * c.Consensus().TargetBlockTime
pruneDelay := time.Duration(c.Consensus().ChainWindowSize*4*c.Consensus().TargetBlockTime) * time.Second
curTime.Add(-pruneDelay)
tip := c.GetChainTip()
if tip == nil || tip.Side.Height < pruneDistance {
@ -1025,7 +1027,7 @@ func (c *SideChain) pruneOldBlocks() {
// loop backwards for proper deletions
for i := len(v) - 1; i >= 0; i-- {
block := v[i]
if block.Depth.Load() >= pruneDistance || (curTime >= (block.LocalTimestamp + pruneDelay)) {
if block.Depth.Load() >= pruneDistance || curTime.Compare(block.Metadata.LocalTime) >= 0 {
templateId := block.SideTemplateId(c.Consensus())
if c.blocksByTemplateId.Has(templateId) {
c.blocksByTemplateId.Delete(templateId)
@ -1256,11 +1258,11 @@ func (c *SideChain) GetChainTip() *PoolBlock {
return c.chainTip.Load()
}
func (c *SideChain) LastUpdated() uint64 {
func (c *SideChain) LastUpdated() time.Time {
if tip := c.chainTip.Load(); tip != nil {
return tip.LocalTimestamp
return tip.Metadata.LocalTime
}
return 0
return time.Time{}
}
func (c *SideChain) IsLongerChain(block, candidate *PoolBlock) (isLonger, isAlternative bool) {

View file

@ -255,6 +255,9 @@ func (s *Server) fillNewTemplateData(currentDifficulty types.Difficulty) error {
Difficulty: s.newTemplateData.Difficulty,
CumulativeDifficulty: s.newTemplateData.CumulativeDifficulty,
},
Metadata: sidechain.PoolBlockReceptionMetadata{
LocalTime: time.Now().UTC(),
},
CachedShareVersion: s.newTemplateData.ShareVersion,
}