mirror of
https://github.com/libp2p/go-libp2p-core.git
synced 2025-03-22 12:20:07 +08:00
cache unmarshalled Record payload inside Envelope
This commit is contained in:
parent
d567b24477
commit
cf0122ad8c
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
pool "github.com/libp2p/go-buffer-pool"
|
pool "github.com/libp2p/go-buffer-pool"
|
||||||
@ -36,6 +37,11 @@ type Envelope struct {
|
|||||||
|
|
||||||
// The signature of the domain string :: type hint :: payload.
|
// The signature of the domain string :: type hint :: payload.
|
||||||
signature []byte
|
signature []byte
|
||||||
|
|
||||||
|
// the unmarshalled payload as a Record, cached on first access via the Record accessor method
|
||||||
|
cached Record
|
||||||
|
unmarshalError error
|
||||||
|
unmarshalOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrEmptyDomain = errors.New("envelope domain must not be empty")
|
var ErrEmptyDomain = errors.New("envelope domain must not be empty")
|
||||||
@ -110,7 +116,7 @@ func ConsumeEnvelope(data []byte, domain string) (envelope *Envelope, rec Record
|
|||||||
return e, nil, fmt.Errorf("failed to validate envelope: %w", err)
|
return e, nil, fmt.Errorf("failed to validate envelope: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rec, err = unmarshalRecordPayload(e.PayloadType, e.RawPayload)
|
rec, err = e.Record()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return e, nil, fmt.Errorf("failed to unmarshal envelope payload: %w", err)
|
return e, nil, fmt.Errorf("failed to unmarshal envelope payload: %w", err)
|
||||||
}
|
}
|
||||||
@ -190,6 +196,32 @@ func (e *Envelope) Equal(other *Envelope) bool {
|
|||||||
bytes.Compare(e.RawPayload, other.RawPayload) == 0
|
bytes.Compare(e.RawPayload, other.RawPayload) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Record returns the Envelope's payload unmarshalled as a Record.
|
||||||
|
// The concrete type of the returned Record depends on which Record
|
||||||
|
// type was registered for the Envelope's PayloadType - see record.RegisterPayloadType.
|
||||||
|
//
|
||||||
|
// Once unmarshalled, the Record is cached for future access.
|
||||||
|
func (e *Envelope) Record() (Record, error) {
|
||||||
|
e.unmarshalOnce.Do(func() {
|
||||||
|
if e.cached != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
e.cached, e.unmarshalError = unmarshalRecordPayload(e.PayloadType, e.RawPayload)
|
||||||
|
})
|
||||||
|
return e.cached, e.unmarshalError
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypedRecord unmarshals the Envelope's payload to the given Record instance.
|
||||||
|
// It is the caller's responsibility to ensure that the Record type is capable
|
||||||
|
// of unmarshalling the Envelope payload. Callers can inspect the Envelope's
|
||||||
|
// PayloadType field to determine the correct type of Record to use.
|
||||||
|
//
|
||||||
|
// This method will always unmarshal the Envelope payload even if a cached record
|
||||||
|
// exists.
|
||||||
|
func (e *Envelope) TypedRecord(dest Record) error {
|
||||||
|
return dest.UnmarshalRecord(e.RawPayload)
|
||||||
|
}
|
||||||
|
|
||||||
// validate returns nil if the envelope signature is valid for the given 'domain',
|
// validate returns nil if the envelope signature is valid for the given 'domain',
|
||||||
// or an error if signature validation fails.
|
// or an error if signature validation fails.
|
||||||
func (e *Envelope) validate(domain string) error {
|
func (e *Envelope) validate(domain string) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user