Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ __pycache__
libmdbx/build/*
tests/testdata/*

go.work*

docker-compose.*.yml
.env
coverage-test.out
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "eest-fixtures"]
path = execution/tests/execution-spec-tests
url = https://github.com/erigontech/eest-fixtures
[submodule "execution/tests/arb-execution-spec-tests"]
path = execution/tests/arb-execution-spec-tests
url = https://github.com/erigontech/arbitrum-eest-fixtures
68 changes: 68 additions & 0 deletions Dockerfile.rpc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
FROM docker.io/library/golang:1.24.3-alpine3.22 AS builder

RUN apk --no-cache add build-base linux-headers git bash ca-certificates libstdc++

WORKDIR /app
ADD go.mod go.mod
ADD go.sum go.sum
ADD erigon-lib/go.mod erigon-lib/go.mod
ADD erigon-lib/go.sum erigon-lib/go.sum
ADD p2p/go.mod p2p/go.mod
ADD p2p/go.sum p2p/go.sum

RUN go mod download
ADD . .

RUN --mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/tmp/go-build \
--mount=type=cache,target=/go/pkg/mod \
make BUILD_TAGS=nosqlite,noboltdb,nosilkworm rpcdaemon


FROM docker.io/library/alpine:3.22

# install required runtime libs, along with some helpers for debugging
RUN apk add --no-cache ca-certificates libstdc++ tzdata
RUN apk add --no-cache curl jq bind-tools

# Setup user and group
#
# from the perspective of the container, uid=1000, gid=1000 is a sensible choice
# (mimicking Ubuntu Server), but if caller creates a .env (example in repo root),
# these defaults will get overridden when make calls docker-compose
ARG UID=1000
ARG GID=1000
RUN adduser -D -u $UID -g $GID erigon
USER erigon
RUN mkdir -p ~/.local/share/erigon

RUN mkdir /erigon-data/
ADD /erigon-data/arb-sep/ /erigon-data/

## then give each binary its own layer
COPY --from=builder /app/build/bin/rpcdaemon /usr/local/bin/rpcdaemon

EXPOSE 8545 \
8551 \
8546 \
42069 \
42069/udp \
8080 \
9090 \
6060

# https://github.com/opencontainers/image-spec/blob/main/annotations.md
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION
LABEL org.label-schema.build-date=$BUILD_DATE \
org.label-schema.description="Erigon Ethereum RPC Client" \
org.label-schema.name="Erigon-RPC" \
org.label-schema.schema-version="1.0" \
org.label-schema.url="https://erigon.tech" \
org.label-schema.vcs-ref=$VCS_REF \
org.label-schema.vcs-url="https://github.com/erigontech/erigon.git" \
org.label-schema.vendor="Erigon" \
org.label-schema.version=$VERSION

ENTRYPOINT ["erigon"]
55 changes: 55 additions & 0 deletions arb/blocks/header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package arbBlocks

import (
"encoding/binary"

"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon/execution/chain"
"github.com/erigontech/erigon/execution/types"
)

type HeaderInfo struct {
SendRoot common.Hash
SendCount uint64
L1BlockNumber uint64
ArbOSFormatVersion uint64
}

func (info HeaderInfo) extra() []byte {
return info.SendRoot[:]
}

func (info HeaderInfo) mixDigest() [32]byte {
mixDigest := common.Hash{}
binary.BigEndian.PutUint64(mixDigest[:8], info.SendCount)
binary.BigEndian.PutUint64(mixDigest[8:16], info.L1BlockNumber)
binary.BigEndian.PutUint64(mixDigest[16:24], info.ArbOSFormatVersion)
return mixDigest
}

func (info HeaderInfo) UpdateHeaderWithInfo(header *types.Header) {
header.MixDigest = info.mixDigest()
header.Extra = info.extra()
}

func DeserializeHeaderExtraInformation(header *types.Header) HeaderInfo {
if header == nil || header.BaseFee == nil || header.BaseFee.Sign() == 0 || len(header.Extra) != 32 || header.Difficulty.Cmp(common.Big1) != 0 {
// imported blocks have no base fee
// The genesis block doesn't have an ArbOS encoded extra field
return HeaderInfo{}
}
extra := HeaderInfo{}
copy(extra.SendRoot[:], header.Extra)
extra.SendCount = binary.BigEndian.Uint64(header.MixDigest[:8])
extra.L1BlockNumber = binary.BigEndian.Uint64(header.MixDigest[8:16])
extra.ArbOSFormatVersion = binary.BigEndian.Uint64(header.MixDigest[16:24])
return extra
}

func GetArbOSVersion(header *types.Header, chain *chain.Config) uint64 {
if !chain.IsArbitrum() {
return 0
}
extraInfo := DeserializeHeaderExtraInformation(header)
return extraInfo.ArbOSFormatVersion
}
181 changes: 181 additions & 0 deletions arb/bloombits/bitutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package bloombits

import (
"runtime"
"unsafe"
)

const wordSize = int(unsafe.Sizeof(uintptr(0)))
const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x"

// XORBytes xors the bytes in a and b. The destination is assumed to have enough
// space. Returns the number of bytes xor'd.
func XORBytes(dst, a, b []byte) int {
if supportsUnaligned {
return fastXORBytes(dst, a, b)
}
return safeXORBytes(dst, a, b)
}

// fastXORBytes xors in bulk. It only works on architectures that support
// unaligned read/writes.
func fastXORBytes(dst, a, b []byte) int {
n := len(a)
if len(b) < n {
n = len(b)
}
w := n / wordSize
if w > 0 {
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
aw := *(*[]uintptr)(unsafe.Pointer(&a))
bw := *(*[]uintptr)(unsafe.Pointer(&b))
for i := 0; i < w; i++ {
dw[i] = aw[i] ^ bw[i]
}
}
for i := n - n%wordSize; i < n; i++ {
dst[i] = a[i] ^ b[i]
}
return n
}

// safeXORBytes xors one by one. It works on all architectures, independent if
// it supports unaligned read/writes or not.
func safeXORBytes(dst, a, b []byte) int {
n := len(a)
if len(b) < n {
n = len(b)
}
for i := 0; i < n; i++ {
dst[i] = a[i] ^ b[i]
}
return n
}

// ANDBytes ands the bytes in a and b. The destination is assumed to have enough
// space. Returns the number of bytes and'd.
func ANDBytes(dst, a, b []byte) int {
if supportsUnaligned {
return fastANDBytes(dst, a, b)
}
return safeANDBytes(dst, a, b)
}

// fastANDBytes ands in bulk. It only works on architectures that support
// unaligned read/writes.
func fastANDBytes(dst, a, b []byte) int {
n := len(a)
if len(b) < n {
n = len(b)
}
w := n / wordSize
if w > 0 {
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
aw := *(*[]uintptr)(unsafe.Pointer(&a))
bw := *(*[]uintptr)(unsafe.Pointer(&b))
for i := 0; i < w; i++ {
dw[i] = aw[i] & bw[i]
}
}
for i := n - n%wordSize; i < n; i++ {
dst[i] = a[i] & b[i]
}
return n
}

// safeANDBytes ands one by one. It works on all architectures, independent if
// it supports unaligned read/writes or not.
func safeANDBytes(dst, a, b []byte) int {
n := len(a)
if len(b) < n {
n = len(b)
}
for i := 0; i < n; i++ {
dst[i] = a[i] & b[i]
}
return n
}

// ORBytes ors the bytes in a and b. The destination is assumed to have enough
// space. Returns the number of bytes or'd.
func ORBytes(dst, a, b []byte) int {
if supportsUnaligned {
return fastORBytes(dst, a, b)
}
return safeORBytes(dst, a, b)
}

// fastORBytes ors in bulk. It only works on architectures that support
// unaligned read/writes.
func fastORBytes(dst, a, b []byte) int {
n := len(a)
if len(b) < n {
n = len(b)
}
w := n / wordSize
if w > 0 {
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
aw := *(*[]uintptr)(unsafe.Pointer(&a))
bw := *(*[]uintptr)(unsafe.Pointer(&b))
for i := 0; i < w; i++ {
dw[i] = aw[i] | bw[i]
}
}
for i := n - n%wordSize; i < n; i++ {
dst[i] = a[i] | b[i]
}
return n
}

// safeORBytes ors one by one. It works on all architectures, independent if
// it supports unaligned read/writes or not.
func safeORBytes(dst, a, b []byte) int {
n := len(a)
if len(b) < n {
n = len(b)
}
for i := 0; i < n; i++ {
dst[i] = a[i] | b[i]
}
return n
}

// TestBytes tests whether any bit is set in the input byte slice.
func TestBytes(p []byte) bool {
if supportsUnaligned {
return fastTestBytes(p)
}
return safeTestBytes(p)
}

// fastTestBytes tests for set bits in bulk. It only works on architectures that
// support unaligned read/writes.
func fastTestBytes(p []byte) bool {
n := len(p)
w := n / wordSize
if w > 0 {
pw := *(*[]uintptr)(unsafe.Pointer(&p))
for i := 0; i < w; i++ {
if pw[i] != 0 {
return true
}
}
}
for i := n - n%wordSize; i < n; i++ {
if p[i] != 0 {
return true
}
}
return false
}

// safeTestBytes tests for set bits one byte at a time. It works on all
// architectures, independent if it supports unaligned read/writes or not.
func safeTestBytes(p []byte) bool {
for i := 0; i < len(p); i++ {
if p[i] != 0 {
return true
}
}
return false
}
18 changes: 18 additions & 0 deletions arb/bloombits/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

// Package bloombits implements bloom filtering on batches of data.
package bloombits
Loading