1717package fetcher
1818
1919import (
20+ "crypto/sha256"
2021 "errors"
2122 "math/big"
2223 "math/rand"
@@ -28,7 +29,10 @@ import (
2829 "github.com/ethereum/go-ethereum/common/mclock"
2930 "github.com/ethereum/go-ethereum/core/txpool"
3031 "github.com/ethereum/go-ethereum/core/types"
32+ "github.com/ethereum/go-ethereum/crypto"
33+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
3134 "github.com/ethereum/go-ethereum/params"
35+ "github.com/holiman/uint256"
3236)
3337
3438var (
@@ -1908,6 +1912,114 @@ func TestTransactionFetcherDropAlternates(t *testing.T) {
19081912 })
19091913}
19101914
1915+ func makeInvalidBlobTx () * types.Transaction {
1916+ key , _ := crypto .GenerateKey ()
1917+ blob := & kzg4844.Blob {byte (0xa )}
1918+ commitment , _ := kzg4844 .BlobToCommitment (blob )
1919+ blobHash := kzg4844 .CalcBlobHashV1 (sha256 .New (), & commitment )
1920+ cellProof , _ := kzg4844 .ComputeCellProofs (blob )
1921+
1922+ // Mutate the cell proof
1923+ cellProof [0 ][0 ] = 0x0
1924+
1925+ blobtx := & types.BlobTx {
1926+ ChainID : uint256 .MustFromBig (params .MainnetChainConfig .ChainID ),
1927+ Nonce : 0 ,
1928+ GasTipCap : uint256 .NewInt (100 ),
1929+ GasFeeCap : uint256 .NewInt (200 ),
1930+ Gas : 21000 ,
1931+ BlobFeeCap : uint256 .NewInt (200 ),
1932+ BlobHashes : []common.Hash {blobHash },
1933+ Value : uint256 .NewInt (100 ),
1934+ Sidecar : types .NewBlobTxSidecar (types .BlobSidecarVersion1 , []kzg4844.Blob {* blob }, []kzg4844.Commitment {commitment }, cellProof ),
1935+ }
1936+ return types .MustSignNewTx (key , types .LatestSigner (params .MainnetChainConfig ), blobtx )
1937+ }
1938+
1939+ // This test ensures that the peer will be disconnected for protocol violation
1940+ // and all its internal traces should be removed properly.
1941+ func TestTransactionProtocolViolation (t * testing.T ) {
1942+ //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true)))
1943+
1944+ var (
1945+ badTx = makeInvalidBlobTx ()
1946+ drop = make (chan struct {}, 1 )
1947+ )
1948+ testTransactionFetcherParallel (t , txFetcherTest {
1949+ init : func () * TxFetcher {
1950+ return NewTxFetcher (
1951+ func (common.Hash ) bool { return false },
1952+ func (txs []* types.Transaction ) []error {
1953+ var errs []error
1954+ for range txs {
1955+ errs = append (errs , txpool .ErrKZGVerificationError )
1956+ }
1957+ return errs
1958+ },
1959+ func (a string , b []common.Hash ) error {
1960+ return nil
1961+ },
1962+ func (peer string ) { drop <- struct {}{} },
1963+ )
1964+ },
1965+ steps : []interface {}{
1966+ // Initial announcement to get something into the waitlist
1967+ doTxNotify {
1968+ peer : "A" ,
1969+ hashes : []common.Hash {testTxs [0 ].Hash (), badTx .Hash (), testTxs [1 ].Hash ()},
1970+ types : []byte {types .LegacyTxType , types .BlobTxType , types .LegacyTxType },
1971+ sizes : []uint32 {uint32 (testTxs [0 ].Size ()), uint32 (badTx .Size ()), uint32 (testTxs [1 ].Size ())},
1972+ },
1973+ isWaiting (map [string ][]announce {
1974+ "A" : {
1975+ {testTxs [0 ].Hash (), types .LegacyTxType , uint32 (testTxs [0 ].Size ())},
1976+ {badTx .Hash (), types .BlobTxType , uint32 (badTx .Size ())},
1977+ {testTxs [1 ].Hash (), types .LegacyTxType , uint32 (testTxs [1 ].Size ())},
1978+ },
1979+ }),
1980+ doWait {time : 0 , step : true }, // zero time, but the blob fetching should be scheduled
1981+
1982+ isWaiting (map [string ][]announce {
1983+ "A" : {
1984+ {testTxs [0 ].Hash (), types .LegacyTxType , uint32 (testTxs [0 ].Size ())},
1985+ {testTxs [1 ].Hash (), types .LegacyTxType , uint32 (testTxs [1 ].Size ())},
1986+ },
1987+ }),
1988+ isScheduled {
1989+ tracking : map [string ][]announce {
1990+ "A" : {
1991+ {badTx .Hash (), types .BlobTxType , uint32 (badTx .Size ())},
1992+ },
1993+ },
1994+ fetching : map [string ][]common.Hash {
1995+ "A" : {badTx .Hash ()},
1996+ },
1997+ },
1998+
1999+ doTxEnqueue {
2000+ peer : "A" ,
2001+ txs : []* types.Transaction {badTx },
2002+ direct : true ,
2003+ },
2004+ // Some internal traces are left and will be cleaned by a following drop
2005+ // operation.
2006+ isWaiting (map [string ][]announce {
2007+ "A" : {
2008+ {testTxs [0 ].Hash (), types .LegacyTxType , uint32 (testTxs [0 ].Size ())},
2009+ {testTxs [1 ].Hash (), types .LegacyTxType , uint32 (testTxs [1 ].Size ())},
2010+ },
2011+ }),
2012+ isScheduled {},
2013+ doFunc (func () { <- drop }),
2014+
2015+ // Simulate the drop operation emitted by the server
2016+ doDrop ("A" ),
2017+ isWaiting (nil ),
2018+ isScheduled {nil , nil , nil },
2019+ },
2020+ })
2021+ }
2022+
19112023func testTransactionFetcherParallel (t * testing.T , tt txFetcherTest ) {
19122024 t .Parallel ()
19132025 testTransactionFetcher (t , tt )
0 commit comments