mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
The module already called itself github.com/luxfi/node while containing no node in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and the Go column of the matrix measured a VM plugin. A repo that fetches the thing it claims to be has not replaced it, so the Go sources move in — 1515 files, the daemon and everything under it — and the build reaches outside this module for nothing. Rust and C++ sit beside it unchanged and are still measured against it by the differential. That is the point of one repo: the reference implementation and the two ports are the same checkout, so parity is a thing you can run rather than a thing you assert. Verified: builds, and the closure carries no lux-private — checked at build time rather than believed. The daemon starts twelve chains on a local network (P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
97 lines
3.0 KiB
Go
97 lines
3.0 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package predicate
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/luxfi/geth/common"
|
|
"github.com/luxfi/geth/core/types"
|
|
)
|
|
|
|
// delimiter separates the actual predicate bytes from the padded zero bytes.
|
|
//
|
|
// Predicates are encoded in the Access List of transactions by using in the
|
|
// access tuples. This means that the length must be a multiple of
|
|
// [common.HashLength].
|
|
//
|
|
// Even if the original predicate bytes is a multiple of [common.HashLength],
|
|
// the delimiter must be appended to support decoding.
|
|
const delimiter = 0xff
|
|
|
|
var (
|
|
errMissingDelimiter = errors.New("no delimiter found")
|
|
errExcessPadding = errors.New("predicate included excess padding")
|
|
errWrongDelimiter = errors.New("wrong delimiter")
|
|
)
|
|
|
|
// Predicate is a message padded with the delimiter and zeros and chunked into
|
|
// 32-byte chunks.
|
|
type Predicate []common.Hash
|
|
|
|
// New constructs a predicate from raw predicate bytes.
|
|
//
|
|
// It chunks the predicate by appending [predicate.Delimiter] and zero-padding
|
|
// to a multiple of 32 bytes.
|
|
func New(b []byte) Predicate {
|
|
numUnpaddedChunks := len(b) / common.HashLength
|
|
chunks := make([]common.Hash, numUnpaddedChunks+1)
|
|
// Copy over chunks that don't require padding.
|
|
for i := range chunks[:numUnpaddedChunks] {
|
|
chunks[i] = common.Hash(b[common.HashLength*i:])
|
|
}
|
|
|
|
// Add the delimiter and required padding to the last chunk.
|
|
copy(chunks[numUnpaddedChunks][:], b[common.HashLength*numUnpaddedChunks:])
|
|
chunks[numUnpaddedChunks][len(b)%common.HashLength] = delimiter
|
|
return chunks
|
|
}
|
|
|
|
// Bytes converts the chunked predicate into the original message.
|
|
//
|
|
// Returns an error if it finds an incorrect encoding.
|
|
func (p Predicate) Bytes() ([]byte, error) {
|
|
padded := make([]byte, common.HashLength*len(p))
|
|
for i, chunk := range p {
|
|
copy(padded[common.HashLength*i:], chunk[:])
|
|
}
|
|
trimmed := common.TrimRightZeroes(padded)
|
|
if len(trimmed) == 0 {
|
|
return nil, fmt.Errorf("%w: length (%d)", errMissingDelimiter, len(p))
|
|
}
|
|
|
|
expectedLen := (len(trimmed) + common.HashLength - 1) / common.HashLength
|
|
if expectedLen != len(p) {
|
|
return nil, fmt.Errorf("%w: got length (%d), expected length (%d)", errExcessPadding, len(p), expectedLen)
|
|
}
|
|
|
|
delimiterIndex := len(trimmed) - 1
|
|
if trimmed[delimiterIndex] != delimiter {
|
|
return nil, errWrongDelimiter
|
|
}
|
|
|
|
return trimmed[:delimiterIndex], nil
|
|
}
|
|
|
|
type Predicates interface {
|
|
HasPredicate(address common.Address) bool
|
|
}
|
|
|
|
// FromAccessList extracts predicates from a transaction's access list.
|
|
//
|
|
// If an address is specified multiple times in the access list, each set of
|
|
// storage keys for that address is considered an individual predicate.
|
|
func FromAccessList(rules Predicates, list types.AccessList) map[common.Address][]Predicate {
|
|
predicates := make(map[common.Address][]Predicate)
|
|
for _, el := range list {
|
|
if !rules.HasPredicate(el.Address) {
|
|
continue
|
|
}
|
|
predicates[el.Address] = append(predicates[el.Address], el.StorageKeys)
|
|
}
|
|
|
|
return predicates
|
|
}
|