mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-11 22:43:47 +00:00
fix merge conflict
This commit is contained in:
commit
0b5975fee3
19 changed files with 273 additions and 127 deletions
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
// This file contains the implementation for interacting with the Ledger hardware
|
// This file contains the implementation for interacting with the Ledger hardware
|
||||||
// wallets. The wire protocol spec can be found in the Ledger Blue GitHub repo:
|
// wallets. The wire protocol spec can be found in the Ledger Blue GitHub repo:
|
||||||
// https://raw.githubusercontent.com/LedgerHQ/blue-app-eth/master/doc/ethapp.asc
|
// https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc
|
||||||
|
|
||||||
package usbwallet
|
package usbwallet
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -754,8 +754,8 @@ func makeSidecar(data ...byte) *types.BlobTxSidecar {
|
||||||
)
|
)
|
||||||
for i := range blobs {
|
for i := range blobs {
|
||||||
blobs[i][0] = data[i]
|
blobs[i][0] = data[i]
|
||||||
c, _ := kzg4844.BlobToCommitment(blobs[i])
|
c, _ := kzg4844.BlobToCommitment(&blobs[i])
|
||||||
p, _ := kzg4844.ComputeBlobProof(blobs[i], c)
|
p, _ := kzg4844.ComputeBlobProof(&blobs[i], c)
|
||||||
commitments = append(commitments, c)
|
commitments = append(commitments, c)
|
||||||
proofs = append(proofs, p)
|
proofs = append(proofs, p)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Adapted from: https://golang.org/src/crypto/cipher/xor.go
|
// Adapted from: https://go.dev/src/crypto/subtle/xor_generic.go
|
||||||
|
|
||||||
// Package bitutil implements fast bitwise operations.
|
// Package bitutil implements fast bitwise operations.
|
||||||
package bitutil
|
package bitutil
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Adapted from: https://golang.org/src/crypto/cipher/xor_test.go
|
// Adapted from: https://go.dev/src/crypto/subtle/xor_test.go
|
||||||
|
|
||||||
package bitutil
|
package bitutil
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -637,6 +637,172 @@ func (bc *BlockChain) SetSafe(header *types.Header) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rewindPathHead implements the logic of rewindHead in the context of hash scheme.
|
||||||
|
func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash) (*types.Header, uint64) {
|
||||||
|
var (
|
||||||
|
limit uint64 // The oldest block that will be searched for this rewinding
|
||||||
|
beyondRoot = root == common.Hash{} // Flag whether we're beyond the requested root (no root, always true)
|
||||||
|
pivot = rawdb.ReadLastPivotNumber(bc.db) // Associated block number of pivot point state
|
||||||
|
rootNumber uint64 // Associated block number of requested root
|
||||||
|
|
||||||
|
start = time.Now() // Timestamp the rewinding is restarted
|
||||||
|
logged = time.Now() // Timestamp last progress log was printed
|
||||||
|
)
|
||||||
|
// The oldest block to be searched is determined by the pivot block or a constant
|
||||||
|
// searching threshold. The rationale behind this is as follows:
|
||||||
|
//
|
||||||
|
// - Snap sync is selected if the pivot block is available. The earliest available
|
||||||
|
// state is the pivot block itself, so there is no sense in going further back.
|
||||||
|
//
|
||||||
|
// - Full sync is selected if the pivot block does not exist. The hash database
|
||||||
|
// periodically flushes the state to disk, and the used searching threshold is
|
||||||
|
// considered sufficient to find a persistent state, even for the testnet. It
|
||||||
|
// might be not enough for a chain that is nearly empty. In the worst case,
|
||||||
|
// the entire chain is reset to genesis, and snap sync is re-enabled on top,
|
||||||
|
// which is still acceptable.
|
||||||
|
if pivot != nil {
|
||||||
|
limit = *pivot
|
||||||
|
} else if head.Number.Uint64() > params.FullImmutabilityThreshold {
|
||||||
|
limit = head.Number.Uint64() - params.FullImmutabilityThreshold
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
logger := log.Trace
|
||||||
|
if time.Since(logged) > time.Second*8 {
|
||||||
|
logged = time.Now()
|
||||||
|
logger = log.Info
|
||||||
|
}
|
||||||
|
logger("Block state missing, rewinding further", "number", head.Number, "hash", head.Hash(), "elapsed", common.PrettyDuration(time.Since(start)))
|
||||||
|
|
||||||
|
// If a root threshold was requested but not yet crossed, check
|
||||||
|
if !beyondRoot && head.Root == root {
|
||||||
|
beyondRoot, rootNumber = true, head.Number.Uint64()
|
||||||
|
}
|
||||||
|
// If search limit is reached, return the genesis block as the
|
||||||
|
// new chain head.
|
||||||
|
if head.Number.Uint64() < limit {
|
||||||
|
log.Info("Rewinding limit reached, resetting to genesis", "number", head.Number, "hash", head.Hash(), "limit", limit)
|
||||||
|
return bc.genesisBlock.Header(), rootNumber
|
||||||
|
}
|
||||||
|
// If the associated state is not reachable, continue searching
|
||||||
|
// backwards until an available state is found.
|
||||||
|
if !bc.HasState(head.Root) {
|
||||||
|
// If the chain is gapped in the middle, return the genesis
|
||||||
|
// block as the new chain head.
|
||||||
|
parent := bc.GetHeader(head.ParentHash, head.Number.Uint64()-1)
|
||||||
|
if parent == nil {
|
||||||
|
log.Error("Missing block in the middle, resetting to genesis", "number", head.Number.Uint64()-1, "hash", head.ParentHash)
|
||||||
|
return bc.genesisBlock.Header(), rootNumber
|
||||||
|
}
|
||||||
|
head = parent
|
||||||
|
|
||||||
|
// If the genesis block is reached, stop searching.
|
||||||
|
if head.Number.Uint64() == 0 {
|
||||||
|
log.Info("Genesis block reached", "number", head.Number, "hash", head.Hash())
|
||||||
|
return head, rootNumber
|
||||||
|
}
|
||||||
|
continue // keep rewinding
|
||||||
|
}
|
||||||
|
// Once the available state is found, ensure that the requested root
|
||||||
|
// has already been crossed. If not, continue rewinding.
|
||||||
|
if beyondRoot || head.Number.Uint64() == 0 {
|
||||||
|
log.Info("Rewound to block with state", "number", head.Number, "hash", head.Hash())
|
||||||
|
return head, rootNumber
|
||||||
|
}
|
||||||
|
log.Debug("Skipping block with threshold state", "number", head.Number, "hash", head.Hash(), "root", head.Root)
|
||||||
|
head = bc.GetHeader(head.ParentHash, head.Number.Uint64()-1) // Keep rewinding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewindPathHead implements the logic of rewindHead in the context of path scheme.
|
||||||
|
func (bc *BlockChain) rewindPathHead(head *types.Header, root common.Hash) (*types.Header, uint64) {
|
||||||
|
var (
|
||||||
|
pivot = rawdb.ReadLastPivotNumber(bc.db) // Associated block number of pivot block
|
||||||
|
rootNumber uint64 // Associated block number of requested root
|
||||||
|
|
||||||
|
// BeyondRoot represents whether the requested root is already
|
||||||
|
// crossed. The flag value is set to true if the root is empty.
|
||||||
|
beyondRoot = root == common.Hash{}
|
||||||
|
|
||||||
|
// noState represents if the target state requested for search
|
||||||
|
// is unavailable and impossible to be recovered.
|
||||||
|
noState = !bc.HasState(root) && !bc.stateRecoverable(root)
|
||||||
|
|
||||||
|
start = time.Now() // Timestamp the rewinding is restarted
|
||||||
|
logged = time.Now() // Timestamp last progress log was printed
|
||||||
|
)
|
||||||
|
// Rewind the head block tag until an available state is found.
|
||||||
|
for {
|
||||||
|
logger := log.Trace
|
||||||
|
if time.Since(logged) > time.Second*8 {
|
||||||
|
logged = time.Now()
|
||||||
|
logger = log.Info
|
||||||
|
}
|
||||||
|
logger("Block state missing, rewinding further", "number", head.Number, "hash", head.Hash(), "elapsed", common.PrettyDuration(time.Since(start)))
|
||||||
|
|
||||||
|
// If a root threshold was requested but not yet crossed, check
|
||||||
|
if !beyondRoot && head.Root == root {
|
||||||
|
beyondRoot, rootNumber = true, head.Number.Uint64()
|
||||||
|
}
|
||||||
|
// If the root threshold hasn't been crossed but the available
|
||||||
|
// state is reached, quickly determine if the target state is
|
||||||
|
// possible to be reached or not.
|
||||||
|
if !beyondRoot && noState && bc.HasState(head.Root) {
|
||||||
|
beyondRoot = true
|
||||||
|
log.Info("Disable the search for unattainable state", "root", root)
|
||||||
|
}
|
||||||
|
// Check if the associated state is available or recoverable if
|
||||||
|
// the requested root has already been crossed.
|
||||||
|
if beyondRoot && (bc.HasState(head.Root) || bc.stateRecoverable(head.Root)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// If pivot block is reached, return the genesis block as the
|
||||||
|
// new chain head. Theoretically there must be a persistent
|
||||||
|
// state before or at the pivot block, prevent endless rewinding
|
||||||
|
// towards the genesis just in case.
|
||||||
|
if pivot != nil && *pivot >= head.Number.Uint64() {
|
||||||
|
log.Info("Pivot block reached, resetting to genesis", "number", head.Number, "hash", head.Hash())
|
||||||
|
return bc.genesisBlock.Header(), rootNumber
|
||||||
|
}
|
||||||
|
// If the chain is gapped in the middle, return the genesis
|
||||||
|
// block as the new chain head
|
||||||
|
parent := bc.GetHeader(head.ParentHash, head.Number.Uint64()-1) // Keep rewinding
|
||||||
|
if parent == nil {
|
||||||
|
log.Error("Missing block in the middle, resetting to genesis", "number", head.Number.Uint64()-1, "hash", head.ParentHash)
|
||||||
|
return bc.genesisBlock.Header(), rootNumber
|
||||||
|
}
|
||||||
|
head = parent
|
||||||
|
|
||||||
|
// If the genesis block is reached, stop searching.
|
||||||
|
if head.Number.Uint64() == 0 {
|
||||||
|
log.Info("Genesis block reached", "number", head.Number, "hash", head.Hash())
|
||||||
|
return head, rootNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Recover if the target state if it's not available yet.
|
||||||
|
if !bc.HasState(head.Root) {
|
||||||
|
if err := bc.triedb.Recover(head.Root); err != nil {
|
||||||
|
log.Crit("Failed to rollback state", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Info("Rewound to block with state", "number", head.Number, "hash", head.Hash())
|
||||||
|
return head, rootNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewindHead searches the available states in the database and returns the associated
|
||||||
|
// block as the new head block.
|
||||||
|
//
|
||||||
|
// If the given root is not empty, then the rewind should attempt to pass the specified
|
||||||
|
// state root and return the associated block number as well. If the root, typically
|
||||||
|
// representing the state corresponding to snapshot disk layer, is deemed impassable,
|
||||||
|
// then block number zero is returned, indicating that snapshot recovery is disabled
|
||||||
|
// and the whole snapshot should be auto-generated in case of head mismatch.
|
||||||
|
func (bc *BlockChain) rewindHead(head *types.Header, root common.Hash) (*types.Header, uint64) {
|
||||||
|
if bc.triedb.Scheme() == rawdb.PathScheme {
|
||||||
|
return bc.rewindPathHead(head, root)
|
||||||
|
}
|
||||||
|
return bc.rewindHashHead(head, root)
|
||||||
|
}
|
||||||
|
|
||||||
// setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
|
// setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
|
||||||
// that the rewind must pass the specified state root. This method is meant to be
|
// that the rewind must pass the specified state root. This method is meant to be
|
||||||
// used when rewinding with snapshots enabled to ensure that we go back further than
|
// used when rewinding with snapshots enabled to ensure that we go back further than
|
||||||
|
|
@ -655,79 +821,40 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||||
}
|
}
|
||||||
defer bc.chainmu.Unlock()
|
defer bc.chainmu.Unlock()
|
||||||
|
|
||||||
// Track the block number of the requested root hash
|
var (
|
||||||
var rootNumber uint64 // (no root == always 0)
|
// Track the block number of the requested root hash
|
||||||
|
rootNumber uint64 // (no root == always 0)
|
||||||
// Retrieve the last pivot block to short circuit rollbacks beyond it and the
|
|
||||||
// current freezer limit to start nuking id underflown
|
|
||||||
pivot := rawdb.ReadLastPivotNumber(bc.db)
|
|
||||||
frozen, _ := bc.db.Ancients()
|
|
||||||
|
|
||||||
|
// Retrieve the last pivot block to short circuit rollbacks beyond it
|
||||||
|
// and the current freezer limit to start nuking it's underflown.
|
||||||
|
pivot = rawdb.ReadLastPivotNumber(bc.db)
|
||||||
|
)
|
||||||
updateFn := func(db ethdb.KeyValueWriter, header *types.Header) (*types.Header, bool) {
|
updateFn := func(db ethdb.KeyValueWriter, header *types.Header) (*types.Header, bool) {
|
||||||
// Rewind the blockchain, ensuring we don't end up with a stateless head
|
// Rewind the blockchain, ensuring we don't end up with a stateless head
|
||||||
// block. Note, depth equality is permitted to allow using SetHead as a
|
// block. Note, depth equality is permitted to allow using SetHead as a
|
||||||
// chain reparation mechanism without deleting any data!
|
// chain reparation mechanism without deleting any data!
|
||||||
if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.Number.Uint64() {
|
if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.Number.Uint64() {
|
||||||
newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
var newHeadBlock *types.Header
|
||||||
if newHeadBlock == nil {
|
newHeadBlock, rootNumber = bc.rewindHead(header, root)
|
||||||
log.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash())
|
|
||||||
newHeadBlock = bc.genesisBlock
|
|
||||||
} else {
|
|
||||||
// Block exists. Keep rewinding until either we find one with state
|
|
||||||
// or until we exceed the optional threshold root hash
|
|
||||||
beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true)
|
|
||||||
|
|
||||||
for {
|
|
||||||
// If a root threshold was requested but not yet crossed, check
|
|
||||||
if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root {
|
|
||||||
beyondRoot, rootNumber = true, newHeadBlock.NumberU64()
|
|
||||||
}
|
|
||||||
if !bc.HasState(newHeadBlock.Root()) && !bc.stateRecoverable(newHeadBlock.Root()) {
|
|
||||||
log.Trace("Block state missing, rewinding further", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
|
|
||||||
if pivot == nil || newHeadBlock.NumberU64() > *pivot {
|
|
||||||
parent := bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1)
|
|
||||||
if parent != nil {
|
|
||||||
newHeadBlock = parent
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Error("Missing block in the middle, aiming genesis", "number", newHeadBlock.NumberU64()-1, "hash", newHeadBlock.ParentHash())
|
|
||||||
newHeadBlock = bc.genesisBlock
|
|
||||||
} else {
|
|
||||||
log.Trace("Rewind passed pivot, aiming genesis", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "pivot", *pivot)
|
|
||||||
newHeadBlock = bc.genesisBlock
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if beyondRoot || newHeadBlock.NumberU64() == 0 {
|
|
||||||
if !bc.HasState(newHeadBlock.Root()) && bc.stateRecoverable(newHeadBlock.Root()) {
|
|
||||||
// Rewind to a block with recoverable state. If the state is
|
|
||||||
// missing, run the state recovery here.
|
|
||||||
if err := bc.triedb.Recover(newHeadBlock.Root()); err != nil {
|
|
||||||
log.Crit("Failed to rollback state", "err", err) // Shouldn't happen
|
|
||||||
}
|
|
||||||
log.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
log.Debug("Skipping block with threshold state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "root", newHeadBlock.Root())
|
|
||||||
newHeadBlock = bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) // Keep rewinding
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash())
|
rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash())
|
||||||
|
|
||||||
// Degrade the chain markers if they are explicitly reverted.
|
// Degrade the chain markers if they are explicitly reverted.
|
||||||
// In theory we should update all in-memory markers in the
|
// In theory we should update all in-memory markers in the
|
||||||
// last step, however the direction of SetHead is from high
|
// last step, however the direction of SetHead is from high
|
||||||
// to low, so it's safe to update in-memory markers directly.
|
// to low, so it's safe to update in-memory markers directly.
|
||||||
bc.currentBlock.Store(newHeadBlock.Header())
|
bc.currentBlock.Store(newHeadBlock)
|
||||||
headBlockGauge.Update(int64(newHeadBlock.NumberU64()))
|
headBlockGauge.Update(int64(newHeadBlock.Number.Uint64()))
|
||||||
|
|
||||||
// The head state is missing, which is only possible in the path-based
|
// The head state is missing, which is only possible in the path-based
|
||||||
// scheme. This situation occurs when the chain head is rewound below
|
// scheme. This situation occurs when the chain head is rewound below
|
||||||
// the pivot point. In this scenario, there is no possible recovery
|
// the pivot point. In this scenario, there is no possible recovery
|
||||||
// approach except for rerunning a snap sync. Do nothing here until the
|
// approach except for rerunning a snap sync. Do nothing here until the
|
||||||
// state syncer picks it up.
|
// state syncer picks it up.
|
||||||
if !bc.HasState(newHeadBlock.Root()) {
|
if !bc.HasState(newHeadBlock.Root) {
|
||||||
log.Info("Chain is stateless, wait state sync", "number", newHeadBlock.Number(), "hash", newHeadBlock.Hash())
|
if newHeadBlock.Number.Uint64() != 0 {
|
||||||
|
log.Crit("Chain is stateless at a non-genesis block")
|
||||||
|
}
|
||||||
|
log.Info("Chain is stateless, wait state sync", "number", newHeadBlock.Number, "hash", newHeadBlock.Hash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Rewind the snap block in a simpleton way to the target head
|
// Rewind the snap block in a simpleton way to the target head
|
||||||
|
|
@ -754,6 +881,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||||
// intent afterwards is full block importing, delete the chain segment
|
// intent afterwards is full block importing, delete the chain segment
|
||||||
// between the stateful-block and the sethead target.
|
// between the stateful-block and the sethead target.
|
||||||
var wipe bool
|
var wipe bool
|
||||||
|
frozen, _ := bc.db.Ancients()
|
||||||
if headNumber+1 < frozen {
|
if headNumber+1 < frozen {
|
||||||
wipe = pivot == nil || headNumber >= *pivot
|
wipe = pivot == nil || headNumber >= *pivot
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
emptyBlob = kzg4844.Blob{}
|
emptyBlob = new(kzg4844.Blob)
|
||||||
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
||||||
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
|
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
|
||||||
emptyBlobVHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
|
emptyBlobVHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
|
||||||
|
|
@ -199,7 +199,7 @@ func makeUnsignedTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap
|
||||||
BlobHashes: []common.Hash{emptyBlobVHash},
|
BlobHashes: []common.Hash{emptyBlobVHash},
|
||||||
Value: uint256.NewInt(100),
|
Value: uint256.NewInt(100),
|
||||||
Sidecar: &types.BlobTxSidecar{
|
Sidecar: &types.BlobTxSidecar{
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: []kzg4844.Blob{*emptyBlob},
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err
|
||||||
// Blob commitments match with the hashes in the transaction, verify the
|
// Blob commitments match with the hashes in the transaction, verify the
|
||||||
// blobs themselves via KZG
|
// blobs themselves via KZG
|
||||||
for i := range sidecar.Blobs {
|
for i := range sidecar.Blobs {
|
||||||
if err := kzg4844.VerifyBlobProof(sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil {
|
if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil {
|
||||||
return fmt.Errorf("invalid blob %d: %v", i, err)
|
return fmt.Errorf("invalid blob %d: %v", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ func TestBlobTxSize(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
emptyBlob = kzg4844.Blob{}
|
emptyBlob = new(kzg4844.Blob)
|
||||||
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
||||||
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
|
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
|
||||||
)
|
)
|
||||||
|
|
@ -72,7 +72,7 @@ func createEmptyBlobTx(key *ecdsa.PrivateKey, withSidecar bool) *Transaction {
|
||||||
|
|
||||||
func createEmptyBlobTxInner(withSidecar bool) *BlobTx {
|
func createEmptyBlobTxInner(withSidecar bool) *BlobTx {
|
||||||
sidecar := &BlobTxSidecar{
|
sidecar := &BlobTxSidecar{
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: []kzg4844.Blob{*emptyBlob},
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ func UseCKZG(use bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlobToCommitment creates a small commitment out of a data blob.
|
// BlobToCommitment creates a small commitment out of a data blob.
|
||||||
func BlobToCommitment(blob Blob) (Commitment, error) {
|
func BlobToCommitment(blob *Blob) (Commitment, error) {
|
||||||
if useCKZG.Load() {
|
if useCKZG.Load() {
|
||||||
return ckzgBlobToCommitment(blob)
|
return ckzgBlobToCommitment(blob)
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +114,7 @@ func BlobToCommitment(blob Blob) (Commitment, error) {
|
||||||
|
|
||||||
// ComputeProof computes the KZG proof at the given point for the polynomial
|
// ComputeProof computes the KZG proof at the given point for the polynomial
|
||||||
// represented by the blob.
|
// represented by the blob.
|
||||||
func ComputeProof(blob Blob, point Point) (Proof, Claim, error) {
|
func ComputeProof(blob *Blob, point Point) (Proof, Claim, error) {
|
||||||
if useCKZG.Load() {
|
if useCKZG.Load() {
|
||||||
return ckzgComputeProof(blob, point)
|
return ckzgComputeProof(blob, point)
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +134,7 @@ func VerifyProof(commitment Commitment, point Point, claim Claim, proof Proof) e
|
||||||
// the commitment.
|
// the commitment.
|
||||||
//
|
//
|
||||||
// This method does not verify that the commitment is correct with respect to blob.
|
// This method does not verify that the commitment is correct with respect to blob.
|
||||||
func ComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) {
|
func ComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) {
|
||||||
if useCKZG.Load() {
|
if useCKZG.Load() {
|
||||||
return ckzgComputeBlobProof(blob, commitment)
|
return ckzgComputeBlobProof(blob, commitment)
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +142,7 @@ func ComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
// VerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
||||||
func VerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error {
|
func VerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error {
|
||||||
if useCKZG.Load() {
|
if useCKZG.Load() {
|
||||||
return ckzgVerifyBlobProof(blob, commitment, proof)
|
return ckzgVerifyBlobProof(blob, commitment, proof)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,10 @@ func ckzgInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ckzgBlobToCommitment creates a small commitment out of a data blob.
|
// ckzgBlobToCommitment creates a small commitment out of a data blob.
|
||||||
func ckzgBlobToCommitment(blob Blob) (Commitment, error) {
|
func ckzgBlobToCommitment(blob *Blob) (Commitment, error) {
|
||||||
ckzgIniter.Do(ckzgInit)
|
ckzgIniter.Do(ckzgInit)
|
||||||
|
|
||||||
commitment, err := ckzg4844.BlobToKZGCommitment((ckzg4844.Blob)(blob))
|
commitment, err := ckzg4844.BlobToKZGCommitment((*ckzg4844.Blob)(blob))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Commitment{}, err
|
return Commitment{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -73,10 +73,10 @@ func ckzgBlobToCommitment(blob Blob) (Commitment, error) {
|
||||||
|
|
||||||
// ckzgComputeProof computes the KZG proof at the given point for the polynomial
|
// ckzgComputeProof computes the KZG proof at the given point for the polynomial
|
||||||
// represented by the blob.
|
// represented by the blob.
|
||||||
func ckzgComputeProof(blob Blob, point Point) (Proof, Claim, error) {
|
func ckzgComputeProof(blob *Blob, point Point) (Proof, Claim, error) {
|
||||||
ckzgIniter.Do(ckzgInit)
|
ckzgIniter.Do(ckzgInit)
|
||||||
|
|
||||||
proof, claim, err := ckzg4844.ComputeKZGProof((ckzg4844.Blob)(blob), (ckzg4844.Bytes32)(point))
|
proof, claim, err := ckzg4844.ComputeKZGProof((*ckzg4844.Blob)(blob), (ckzg4844.Bytes32)(point))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Proof{}, Claim{}, err
|
return Proof{}, Claim{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -102,10 +102,10 @@ func ckzgVerifyProof(commitment Commitment, point Point, claim Claim, proof Proo
|
||||||
// the commitment.
|
// the commitment.
|
||||||
//
|
//
|
||||||
// This method does not verify that the commitment is correct with respect to blob.
|
// This method does not verify that the commitment is correct with respect to blob.
|
||||||
func ckzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) {
|
func ckzgComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) {
|
||||||
ckzgIniter.Do(ckzgInit)
|
ckzgIniter.Do(ckzgInit)
|
||||||
|
|
||||||
proof, err := ckzg4844.ComputeBlobKZGProof((ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment))
|
proof, err := ckzg4844.ComputeBlobKZGProof((*ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Proof{}, err
|
return Proof{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -113,10 +113,10 @@ func ckzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ckzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
// ckzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
||||||
func ckzgVerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error {
|
func ckzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error {
|
||||||
ckzgIniter.Do(ckzgInit)
|
ckzgIniter.Do(ckzgInit)
|
||||||
|
|
||||||
valid, err := ckzg4844.VerifyBlobKZGProof((ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment), (ckzg4844.Bytes48)(proof))
|
valid, err := ckzg4844.VerifyBlobKZGProof((*ckzg4844.Blob)(blob), (ckzg4844.Bytes48)(commitment), (ckzg4844.Bytes48)(proof))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,13 @@ func ckzgInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ckzgBlobToCommitment creates a small commitment out of a data blob.
|
// ckzgBlobToCommitment creates a small commitment out of a data blob.
|
||||||
func ckzgBlobToCommitment(blob Blob) (Commitment, error) {
|
func ckzgBlobToCommitment(blob *Blob) (Commitment, error) {
|
||||||
panic("unsupported platform")
|
panic("unsupported platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ckzgComputeProof computes the KZG proof at the given point for the polynomial
|
// ckzgComputeProof computes the KZG proof at the given point for the polynomial
|
||||||
// represented by the blob.
|
// represented by the blob.
|
||||||
func ckzgComputeProof(blob Blob, point Point) (Proof, Claim, error) {
|
func ckzgComputeProof(blob *Blob, point Point) (Proof, Claim, error) {
|
||||||
panic("unsupported platform")
|
panic("unsupported platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,11 +52,11 @@ func ckzgVerifyProof(commitment Commitment, point Point, claim Claim, proof Proo
|
||||||
// the commitment.
|
// the commitment.
|
||||||
//
|
//
|
||||||
// This method does not verify that the commitment is correct with respect to blob.
|
// This method does not verify that the commitment is correct with respect to blob.
|
||||||
func ckzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) {
|
func ckzgComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) {
|
||||||
panic("unsupported platform")
|
panic("unsupported platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ckzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
// ckzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
||||||
func ckzgVerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error {
|
func ckzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error {
|
||||||
panic("unsupported platform")
|
panic("unsupported platform")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,10 @@ func gokzgInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// gokzgBlobToCommitment creates a small commitment out of a data blob.
|
// gokzgBlobToCommitment creates a small commitment out of a data blob.
|
||||||
func gokzgBlobToCommitment(blob Blob) (Commitment, error) {
|
func gokzgBlobToCommitment(blob *Blob) (Commitment, error) {
|
||||||
gokzgIniter.Do(gokzgInit)
|
gokzgIniter.Do(gokzgInit)
|
||||||
|
|
||||||
commitment, err := context.BlobToKZGCommitment((gokzg4844.Blob)(blob), 0)
|
commitment, err := context.BlobToKZGCommitment((*gokzg4844.Blob)(blob), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Commitment{}, err
|
return Commitment{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -58,10 +58,10 @@ func gokzgBlobToCommitment(blob Blob) (Commitment, error) {
|
||||||
|
|
||||||
// gokzgComputeProof computes the KZG proof at the given point for the polynomial
|
// gokzgComputeProof computes the KZG proof at the given point for the polynomial
|
||||||
// represented by the blob.
|
// represented by the blob.
|
||||||
func gokzgComputeProof(blob Blob, point Point) (Proof, Claim, error) {
|
func gokzgComputeProof(blob *Blob, point Point) (Proof, Claim, error) {
|
||||||
gokzgIniter.Do(gokzgInit)
|
gokzgIniter.Do(gokzgInit)
|
||||||
|
|
||||||
proof, claim, err := context.ComputeKZGProof((gokzg4844.Blob)(blob), (gokzg4844.Scalar)(point), 0)
|
proof, claim, err := context.ComputeKZGProof((*gokzg4844.Blob)(blob), (gokzg4844.Scalar)(point), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Proof{}, Claim{}, err
|
return Proof{}, Claim{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -80,10 +80,10 @@ func gokzgVerifyProof(commitment Commitment, point Point, claim Claim, proof Pro
|
||||||
// the commitment.
|
// the commitment.
|
||||||
//
|
//
|
||||||
// This method does not verify that the commitment is correct with respect to blob.
|
// This method does not verify that the commitment is correct with respect to blob.
|
||||||
func gokzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) {
|
func gokzgComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) {
|
||||||
gokzgIniter.Do(gokzgInit)
|
gokzgIniter.Do(gokzgInit)
|
||||||
|
|
||||||
proof, err := context.ComputeBlobKZGProof((gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), 0)
|
proof, err := context.ComputeBlobKZGProof((*gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Proof{}, err
|
return Proof{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -91,8 +91,8 @@ func gokzgComputeBlobProof(blob Blob, commitment Commitment) (Proof, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// gokzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
// gokzgVerifyBlobProof verifies that the blob data corresponds to the provided commitment.
|
||||||
func gokzgVerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error {
|
func gokzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error {
|
||||||
gokzgIniter.Do(gokzgInit)
|
gokzgIniter.Do(gokzgInit)
|
||||||
|
|
||||||
return context.VerifyBlobKZGProof((gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), (gokzg4844.KZGProof)(proof))
|
return context.VerifyBlobKZGProof((*gokzg4844.Blob)(blob), (gokzg4844.KZGCommitment)(commitment), (gokzg4844.KZGProof)(proof))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,13 @@ func randFieldElement() [32]byte {
|
||||||
return gokzg4844.SerializeScalar(r)
|
return gokzg4844.SerializeScalar(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func randBlob() Blob {
|
func randBlob() *Blob {
|
||||||
var blob Blob
|
var blob Blob
|
||||||
for i := 0; i < len(blob); i += gokzg4844.SerializedScalarSize {
|
for i := 0; i < len(blob); i += gokzg4844.SerializedScalarSize {
|
||||||
fieldElementBytes := randFieldElement()
|
fieldElementBytes := randFieldElement()
|
||||||
copy(blob[i:i+gokzg4844.SerializedScalarSize], fieldElementBytes[:])
|
copy(blob[i:i+gokzg4844.SerializedScalarSize], fieldElementBytes[:])
|
||||||
}
|
}
|
||||||
return blob
|
return &blob
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCKZGWithPoint(t *testing.T) { testKZGWithPoint(t, true) }
|
func TestCKZGWithPoint(t *testing.T) { testKZGWithPoint(t, true) }
|
||||||
|
|
|
||||||
|
|
@ -628,7 +628,6 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
var (
|
var (
|
||||||
txs = block.Transactions()
|
txs = block.Transactions()
|
||||||
blockHash = block.Hash()
|
blockHash = block.Hash()
|
||||||
blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
results = make([]*txTraceResult, len(txs))
|
results = make([]*txTraceResult, len(txs))
|
||||||
pend sync.WaitGroup
|
pend sync.WaitGroup
|
||||||
|
|
@ -651,6 +650,11 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
TxIndex: task.index,
|
TxIndex: task.index,
|
||||||
TxHash: txs[task.index].Hash(),
|
TxHash: txs[task.index].Hash(),
|
||||||
}
|
}
|
||||||
|
// Reconstruct the block context for each transaction
|
||||||
|
// as the GetHash function of BlockContext is not safe for
|
||||||
|
// concurrent use.
|
||||||
|
// See: https://github.com/ethereum/go-ethereum/issues/29114
|
||||||
|
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config)
|
res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()}
|
results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()}
|
||||||
|
|
@ -663,6 +667,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
|
|
||||||
// Feed the transactions into the tracers and return
|
// Feed the transactions into the tracers and return
|
||||||
var failed error
|
var failed error
|
||||||
|
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
txloop:
|
txloop:
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
// Send the trace task over for execution
|
// Send the trace task over for execution
|
||||||
|
|
|
||||||
4
go.mod
4
go.mod
|
|
@ -16,12 +16,12 @@ require (
|
||||||
github.com/cockroachdb/pebble v1.1.0
|
github.com/cockroachdb/pebble v1.1.0
|
||||||
github.com/consensys/gnark-crypto v0.12.1
|
github.com/consensys/gnark-crypto v0.12.1
|
||||||
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233
|
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233
|
||||||
github.com/crate-crypto/go-kzg-4844 v0.7.0
|
github.com/crate-crypto/go-kzg-4844 v1.0.0
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/deckarep/golang-set/v2 v2.1.0
|
github.com/deckarep/golang-set/v2 v2.1.0
|
||||||
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0
|
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0
|
||||||
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3
|
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3
|
||||||
github.com/ethereum/c-kzg-4844 v0.4.0
|
github.com/ethereum/c-kzg-4844 v1.0.0
|
||||||
github.com/fatih/color v1.13.0
|
github.com/fatih/color v1.13.0
|
||||||
github.com/ferranbt/fastssz v0.1.2
|
github.com/ferranbt/fastssz v0.1.2
|
||||||
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e
|
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e
|
||||||
|
|
|
||||||
8
go.sum
8
go.sum
|
|
@ -129,8 +129,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ=
|
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ=
|
||||||
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs=
|
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs=
|
||||||
github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA=
|
github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI=
|
||||||
github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc=
|
github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|
@ -160,8 +160,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY=
|
github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA=
|
||||||
github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
|
github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
|
||||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk=
|
github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk=
|
||||||
|
|
|
||||||
|
|
@ -1088,7 +1088,8 @@ func TestFillBlobTransaction(t *testing.T) {
|
||||||
Config: params.MergedTestChainConfig,
|
Config: params.MergedTestChainConfig,
|
||||||
Alloc: types.GenesisAlloc{},
|
Alloc: types.GenesisAlloc{},
|
||||||
}
|
}
|
||||||
emptyBlob = kzg4844.Blob{}
|
emptyBlob = new(kzg4844.Blob)
|
||||||
|
emptyBlobs = []kzg4844.Blob{*emptyBlob}
|
||||||
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
||||||
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
|
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
|
||||||
emptyBlobHash common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
|
emptyBlobHash common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
|
||||||
|
|
@ -1171,14 +1172,14 @@ func TestFillBlobTransaction(t *testing.T) {
|
||||||
From: &b.acc.Address,
|
From: &b.acc.Address,
|
||||||
To: &to,
|
To: &to,
|
||||||
Value: (*hexutil.Big)(big.NewInt(1)),
|
Value: (*hexutil.Big)(big.NewInt(1)),
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: emptyBlobs,
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
},
|
},
|
||||||
want: &result{
|
want: &result{
|
||||||
Hashes: []common.Hash{emptyBlobHash},
|
Hashes: []common.Hash{emptyBlobHash},
|
||||||
Sidecar: &types.BlobTxSidecar{
|
Sidecar: &types.BlobTxSidecar{
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: emptyBlobs,
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
},
|
},
|
||||||
|
|
@ -1191,14 +1192,14 @@ func TestFillBlobTransaction(t *testing.T) {
|
||||||
To: &to,
|
To: &to,
|
||||||
Value: (*hexutil.Big)(big.NewInt(1)),
|
Value: (*hexutil.Big)(big.NewInt(1)),
|
||||||
BlobHashes: []common.Hash{emptyBlobHash},
|
BlobHashes: []common.Hash{emptyBlobHash},
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: emptyBlobs,
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
},
|
},
|
||||||
want: &result{
|
want: &result{
|
||||||
Hashes: []common.Hash{emptyBlobHash},
|
Hashes: []common.Hash{emptyBlobHash},
|
||||||
Sidecar: &types.BlobTxSidecar{
|
Sidecar: &types.BlobTxSidecar{
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: emptyBlobs,
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
},
|
},
|
||||||
|
|
@ -1211,7 +1212,7 @@ func TestFillBlobTransaction(t *testing.T) {
|
||||||
To: &to,
|
To: &to,
|
||||||
Value: (*hexutil.Big)(big.NewInt(1)),
|
Value: (*hexutil.Big)(big.NewInt(1)),
|
||||||
BlobHashes: []common.Hash{{0x01, 0x22}},
|
BlobHashes: []common.Hash{{0x01, 0x22}},
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: emptyBlobs,
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
},
|
},
|
||||||
|
|
@ -1223,12 +1224,12 @@ func TestFillBlobTransaction(t *testing.T) {
|
||||||
From: &b.acc.Address,
|
From: &b.acc.Address,
|
||||||
To: &to,
|
To: &to,
|
||||||
Value: (*hexutil.Big)(big.NewInt(1)),
|
Value: (*hexutil.Big)(big.NewInt(1)),
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: emptyBlobs,
|
||||||
},
|
},
|
||||||
want: &result{
|
want: &result{
|
||||||
Hashes: []common.Hash{emptyBlobHash},
|
Hashes: []common.Hash{emptyBlobHash},
|
||||||
Sidecar: &types.BlobTxSidecar{
|
Sidecar: &types.BlobTxSidecar{
|
||||||
Blobs: []kzg4844.Blob{emptyBlob},
|
Blobs: emptyBlobs,
|
||||||
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
||||||
Proofs: []kzg4844.Proof{emptyBlobProof},
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -326,12 +326,12 @@ func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context, b Backend) er
|
||||||
commitments := make([]kzg4844.Commitment, n)
|
commitments := make([]kzg4844.Commitment, n)
|
||||||
proofs := make([]kzg4844.Proof, n)
|
proofs := make([]kzg4844.Proof, n)
|
||||||
for i, b := range args.Blobs {
|
for i, b := range args.Blobs {
|
||||||
c, err := kzg4844.BlobToCommitment(b)
|
c, err := kzg4844.BlobToCommitment(&b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("blobs[%d]: error computing commitment: %v", i, err)
|
return fmt.Errorf("blobs[%d]: error computing commitment: %v", i, err)
|
||||||
}
|
}
|
||||||
commitments[i] = c
|
commitments[i] = c
|
||||||
p, err := kzg4844.ComputeBlobProof(b, c)
|
p, err := kzg4844.ComputeBlobProof(&b, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err)
|
return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err)
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +341,7 @@ func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context, b Backend) er
|
||||||
args.Proofs = proofs
|
args.Proofs = proofs
|
||||||
} else {
|
} else {
|
||||||
for i, b := range args.Blobs {
|
for i, b := range args.Blobs {
|
||||||
if err := kzg4844.VerifyBlobProof(b, args.Commitments[i], args.Proofs[i]); err != nil {
|
if err := kzg4844.VerifyBlobProof(&b, args.Commitments[i], args.Proofs[i]); err != nil {
|
||||||
return fmt.Errorf("failed to verify blob proof: %v", err)
|
return fmt.Errorf("failed to verify blob proof: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
48
p2p/dial.go
48
p2p/dial.go
|
|
@ -25,6 +25,7 @@ import (
|
||||||
mrand "math/rand"
|
mrand "math/rand"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/mclock"
|
"github.com/ethereum/go-ethereum/common/mclock"
|
||||||
|
|
@ -248,7 +249,7 @@ loop:
|
||||||
}
|
}
|
||||||
|
|
||||||
case task := <-d.doneCh:
|
case task := <-d.doneCh:
|
||||||
id := task.dest.ID()
|
id := task.dest().ID()
|
||||||
delete(d.dialing, id)
|
delete(d.dialing, id)
|
||||||
d.updateStaticPool(id)
|
d.updateStaticPool(id)
|
||||||
d.doneSinceLastLog++
|
d.doneSinceLastLog++
|
||||||
|
|
@ -410,7 +411,7 @@ func (d *dialScheduler) startStaticDials(n int) (started int) {
|
||||||
// updateStaticPool attempts to move the given static dial back into staticPool.
|
// updateStaticPool attempts to move the given static dial back into staticPool.
|
||||||
func (d *dialScheduler) updateStaticPool(id enode.ID) {
|
func (d *dialScheduler) updateStaticPool(id enode.ID) {
|
||||||
task, ok := d.static[id]
|
task, ok := d.static[id]
|
||||||
if ok && task.staticPoolIndex < 0 && d.checkDial(task.dest) == nil {
|
if ok && task.staticPoolIndex < 0 && d.checkDial(task.dest()) == nil {
|
||||||
d.addToStaticPool(task)
|
d.addToStaticPool(task)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -437,10 +438,11 @@ func (d *dialScheduler) removeFromStaticPool(idx int) {
|
||||||
|
|
||||||
// startDial runs the given dial task in a separate goroutine.
|
// startDial runs the given dial task in a separate goroutine.
|
||||||
func (d *dialScheduler) startDial(task *dialTask) {
|
func (d *dialScheduler) startDial(task *dialTask) {
|
||||||
d.log.Trace("Starting p2p dial", "id", task.dest.ID(), "ip", task.dest.IP(), "flag", task.flags)
|
node := task.dest()
|
||||||
hkey := string(task.dest.ID().Bytes())
|
d.log.Trace("Starting p2p dial", "id", node.ID(), "ip", node.IP(), "flag", task.flags)
|
||||||
|
hkey := string(node.ID().Bytes())
|
||||||
d.history.add(hkey, d.clock.Now().Add(dialHistoryExpiration))
|
d.history.add(hkey, d.clock.Now().Add(dialHistoryExpiration))
|
||||||
d.dialing[task.dest.ID()] = task
|
d.dialing[node.ID()] = task
|
||||||
go func() {
|
go func() {
|
||||||
task.run(d)
|
task.run(d)
|
||||||
d.doneCh <- task
|
d.doneCh <- task
|
||||||
|
|
@ -451,39 +453,46 @@ func (d *dialScheduler) startDial(task *dialTask) {
|
||||||
type dialTask struct {
|
type dialTask struct {
|
||||||
staticPoolIndex int
|
staticPoolIndex int
|
||||||
flags connFlag
|
flags connFlag
|
||||||
|
|
||||||
// These fields are private to the task and should not be
|
// These fields are private to the task and should not be
|
||||||
// accessed by dialScheduler while the task is running.
|
// accessed by dialScheduler while the task is running.
|
||||||
dest *enode.Node
|
destPtr atomic.Pointer[enode.Node]
|
||||||
lastResolved mclock.AbsTime
|
lastResolved mclock.AbsTime
|
||||||
resolveDelay time.Duration
|
resolveDelay time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDialTask(dest *enode.Node, flags connFlag) *dialTask {
|
func newDialTask(dest *enode.Node, flags connFlag) *dialTask {
|
||||||
return &dialTask{dest: dest, flags: flags, staticPoolIndex: -1}
|
t := &dialTask{flags: flags, staticPoolIndex: -1}
|
||||||
|
t.destPtr.Store(dest)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
type dialError struct {
|
type dialError struct {
|
||||||
error
|
error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *dialTask) dest() *enode.Node {
|
||||||
|
return t.destPtr.Load()
|
||||||
|
}
|
||||||
|
|
||||||
func (t *dialTask) run(d *dialScheduler) {
|
func (t *dialTask) run(d *dialScheduler) {
|
||||||
if t.needResolve() && !t.resolve(d) {
|
if t.needResolve() && !t.resolve(d) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := t.dial(d, t.dest)
|
err := t.dial(d, t.dest())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// For static nodes, resolve one more time if dialing fails.
|
// For static nodes, resolve one more time if dialing fails.
|
||||||
if _, ok := err.(*dialError); ok && t.flags&staticDialedConn != 0 {
|
if _, ok := err.(*dialError); ok && t.flags&staticDialedConn != 0 {
|
||||||
if t.resolve(d) {
|
if t.resolve(d) {
|
||||||
t.dial(d, t.dest)
|
t.dial(d, t.dest())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *dialTask) needResolve() bool {
|
func (t *dialTask) needResolve() bool {
|
||||||
return t.flags&staticDialedConn != 0 && t.dest.IP() == nil
|
return t.flags&staticDialedConn != 0 && t.dest().IP() == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve attempts to find the current endpoint for the destination
|
// resolve attempts to find the current endpoint for the destination
|
||||||
|
|
@ -502,29 +511,31 @@ func (t *dialTask) resolve(d *dialScheduler) bool {
|
||||||
if t.lastResolved > 0 && time.Duration(d.clock.Now()-t.lastResolved) < t.resolveDelay {
|
if t.lastResolved > 0 && time.Duration(d.clock.Now()-t.lastResolved) < t.resolveDelay {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
resolved := d.resolver.Resolve(t.dest)
|
|
||||||
|
node := t.dest()
|
||||||
|
resolved := d.resolver.Resolve(node)
|
||||||
t.lastResolved = d.clock.Now()
|
t.lastResolved = d.clock.Now()
|
||||||
if resolved == nil {
|
if resolved == nil {
|
||||||
t.resolveDelay *= 2
|
t.resolveDelay *= 2
|
||||||
if t.resolveDelay > maxResolveDelay {
|
if t.resolveDelay > maxResolveDelay {
|
||||||
t.resolveDelay = maxResolveDelay
|
t.resolveDelay = maxResolveDelay
|
||||||
}
|
}
|
||||||
d.log.Debug("Resolving node failed", "id", t.dest.ID(), "newdelay", t.resolveDelay)
|
d.log.Debug("Resolving node failed", "id", node.ID(), "newdelay", t.resolveDelay)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// The node was found.
|
// The node was found.
|
||||||
t.resolveDelay = initialResolveDelay
|
t.resolveDelay = initialResolveDelay
|
||||||
t.dest = resolved
|
t.destPtr.Store(resolved)
|
||||||
d.log.Debug("Resolved node", "id", t.dest.ID(), "addr", &net.TCPAddr{IP: t.dest.IP(), Port: t.dest.TCP()})
|
d.log.Debug("Resolved node", "id", resolved.ID(), "addr", &net.TCPAddr{IP: resolved.IP(), Port: resolved.TCP()})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// dial performs the actual connection attempt.
|
// dial performs the actual connection attempt.
|
||||||
func (t *dialTask) dial(d *dialScheduler, dest *enode.Node) error {
|
func (t *dialTask) dial(d *dialScheduler, dest *enode.Node) error {
|
||||||
dialMeter.Mark(1)
|
dialMeter.Mark(1)
|
||||||
fd, err := d.dialer.Dial(d.ctx, t.dest)
|
fd, err := d.dialer.Dial(d.ctx, dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.log.Trace("Dial error", "id", t.dest.ID(), "addr", nodeAddr(t.dest), "conn", t.flags, "err", cleanupDialErr(err))
|
d.log.Trace("Dial error", "id", dest.ID(), "addr", nodeAddr(dest), "conn", t.flags, "err", cleanupDialErr(err))
|
||||||
dialConnectionError.Mark(1)
|
dialConnectionError.Mark(1)
|
||||||
return &dialError{err}
|
return &dialError{err}
|
||||||
}
|
}
|
||||||
|
|
@ -532,8 +543,9 @@ func (t *dialTask) dial(d *dialScheduler, dest *enode.Node) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *dialTask) String() string {
|
func (t *dialTask) String() string {
|
||||||
id := t.dest.ID()
|
node := t.dest()
|
||||||
return fmt.Sprintf("%v %x %v:%d", t.flags, id[:8], t.dest.IP(), t.dest.TCP())
|
id := node.ID()
|
||||||
|
return fmt.Sprintf("%v %x %v:%d", t.flags, id[:8], node.IP(), node.TCP())
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanupDialErr(err error) error {
|
func cleanupDialErr(err error) error {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue