diff --git a/core/genesis.go b/core/genesis.go index dbcacb9e7c..4c197abc52 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -432,7 +432,7 @@ func DefaultLocalGenesisBlock(consensusEngine string) *Genesis { Nonce: 66, ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"), GasLimit: 5000000, - Difficulty: big.NewInt(100000), + Difficulty: big.NewInt(10000), } } return &Genesis{ diff --git a/core/headerchain.go b/core/headerchain.go index 4d3143d435..b0a416f6fb 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -473,10 +473,10 @@ func (hc *HeaderChain) SetCurrentState(head *types.WorkObject) error { if hc.IsGenesisHash(header.Hash()) { break } - // This is not perfect because it's possible some blocks have the same root hash (no uniqueness guarantee) - // We probably need a better way to determine if we have processed the state and ETXs for a given block - _, err := hc.bc.processor.StateAt(header.EVMRoot(), header.UTXORoot(), header.EtxSetRoot()) - if err == nil { + + // Check if the state has been processed for this block + processedState := rawdb.ReadProcessedState(hc.headerDb, header.Hash()) + if processedState { break } current = types.CopyWorkObject(header) diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 4aaa3dd8cd..d70d2d7f2c 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -132,6 +132,20 @@ func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) { } } +func ReadProcessedState(db ethdb.KeyValueReader, hash common.Hash) bool { + data, _ := db.Get(processedStateKey(hash)) + if len(data) == 0 { + return false + } + return data[0] == 1 +} + +func WriteProcessedState(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Put(processedStateKey(hash), []byte{1}); err != nil { + db.Logger().WithField("err", err).Fatal("Failed to store processed state for block " + hash.String()) + } +} + // ReadHeadHeaderHash retrieves the hash of the current canonical head header. func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash { data, _ := db.Get(headHeaderKey) diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index a040d22028..fa1dd034a3 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -108,6 +108,7 @@ var ( UtxoPrefix = []byte("ut") // outpointPrefix + hash -> types.Outpoint spentUTXOsPrefix = []byte("sutxo") // spentUTXOsPrefix + hash -> []types.SpentTxOut AddressUtxosPrefix = []byte("au") // addressUtxosPrefix + hash -> []types.UtxoEntry + processedStatePrefix = []byte("ps") // processedStatePrefix + hash -> boolean blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts @@ -268,6 +269,10 @@ func headerNumberKey(hash common.Hash) []byte { return append(headerNumberPrefix, hash.Bytes()...) } +func processedStateKey(hash common.Hash) []byte { + return append(processedStatePrefix, hash.Bytes()...) +} + // blockBodyKey = blockBodyPrefix + num (uint64 big endian) + hash func blockBodyKey(number uint64, hash common.Hash) []byte { return append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...) diff --git a/core/state/statedb.go b/core/state/statedb.go index 619b13860e..4902817ae3 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -26,6 +26,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "google.golang.org/protobuf/proto" "github.com/dominant-strategies/go-quai/common" "github.com/dominant-strategies/go-quai/core/rawdb" @@ -646,7 +647,11 @@ func (s *StateDB) PushETX(etx *types.Transaction) error { if metrics_config.MetricsEnabled() { defer func(start time.Time) { stateMetrics.WithLabelValues("AddETX").Add(float64(time.Since(start))) }(time.Now()) } - data, err := rlp.EncodeToBytes(etx) + protoTx, err := etx.ProtoEncode() + if err != nil { + return err + } + protoTxBytes, err := proto.Marshal(protoTx) if err != nil { return err } @@ -654,7 +659,7 @@ func (s *StateDB) PushETX(etx *types.Transaction) error { if err != nil { return err } - if err := s.etxTrie.TryUpdate(newestIndex.Bytes(), data); err != nil { + if err := s.etxTrie.TryUpdate(newestIndex.Bytes(), protoTxBytes); err != nil { return err } newestIndex.Add(newestIndex, big.NewInt(1)) @@ -673,11 +678,15 @@ func (s *StateDB) PushETXs(etxs []*types.Transaction) error { return err } for _, etx := range etxs { - data, err := rlp.EncodeToBytes(etx) + protoTx, err := etx.ProtoEncode() + if err != nil { + return err + } + protoTxBytes, err := proto.Marshal(protoTx) if err != nil { return err } - if err := s.etxTrie.TryUpdate(newestIndex.Bytes(), data); err != nil { + if err := s.etxTrie.TryUpdate(newestIndex.Bytes(), protoTxBytes); err != nil { return err } newestIndex.Add(newestIndex, big.NewInt(1)) @@ -703,8 +712,12 @@ func (s *StateDB) PopETX() (*types.Transaction, error) { if len(enc) == 0 { return nil, nil } + protoEtx := new(types.ProtoTransaction) + if err := proto.Unmarshal(enc, protoEtx); err != nil { + return nil, err + } etx := new(types.Transaction) - if err := rlp.DecodeBytes(enc, etx); err != nil { + if err := etx.ProtoDecode(protoEtx, s.nodeLocation); err != nil { return nil, err } if err := s.etxTrie.TryDelete(oldestIndex.Bytes()); err != nil { @@ -725,8 +738,12 @@ func (s *StateDB) ReadETX(index *big.Int) (*types.Transaction, error) { if len(enc) == 0 { return nil, nil } + protoEtx := new(types.ProtoTransaction) + if err := proto.Unmarshal(enc, protoEtx); err != nil { + return nil, err + } etx := new(types.Transaction) - if err := rlp.DecodeBytes(enc, etx); err != nil { + if err := etx.ProtoDecode(protoEtx, s.nodeLocation); err != nil { return nil, err } return etx, nil diff --git a/core/state_processor.go b/core/state_processor.go index 639d5a720d..ff263a61bc 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -931,6 +931,8 @@ func (p *StateProcessor) Apply(batch ethdb.Batch, block *types.WorkObject) ([]*t "t7": time7, "t8": time8, }).Debug("times during state processor apply") + // Indicate that we have processed the state of the block + rawdb.WriteProcessedState(batch, block.Hash()) return logs, nil } diff --git a/core/types/external_tx.go b/core/types/external_tx.go index 0a121b0bfb..8b0203aa77 100644 --- a/core/types/external_tx.go +++ b/core/types/external_tx.go @@ -189,5 +189,5 @@ func (tx *ExternalTx) setEcdsaSignatureValues(chainID, v, r, s *big.Int) { } func (tx *ExternalTx) setTo(to common.Address) { - panic("You should not set To on an external transaction") + tx.To = &to } diff --git a/core/types/transaction.go b/core/types/transaction.go index 642fea8e72..dc13171a92 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -106,7 +106,6 @@ type TxData interface { parentHash() *common.Hash mixHash() *common.Hash workNonce() *BlockNonce - // Schnorr segregated sigs getSchnorrSignature() *schnorr.Signature } @@ -605,7 +604,7 @@ func (tx *Transaction) To() *common.Address { return &cpy } -func (tx *Transaction) SetGas(addr common.Address) { +func (tx *Transaction) SetTo(addr common.Address) { tx.inner.setTo(addr) } diff --git a/internal/quaiapi/quai_api.go b/internal/quaiapi/quai_api.go index bbee7ae0e1..643cfc0c1d 100644 --- a/internal/quaiapi/quai_api.go +++ b/internal/quaiapi/quai_api.go @@ -768,6 +768,9 @@ func (s *PublicBlockChainQuaiAPI) Append(ctx context.Context, raw json.RawMessag } body.Header.Header().SetCoinbase(common.BytesToAddress(body.Header.Coinbase().Bytes(), s.b.NodeLocation())) + for _, tx := range body.NewInboundEtxs { + tx.SetTo(common.BytesToAddress(tx.To().Bytes(), s.b.NodeLocation())) + } pendingEtxs, subReorg, setHead, err := s.b.Append(body.Header, body.Manifest, body.DomPendingHeader, body.DomTerminus, body.DomOrigin, body.NewInboundEtxs) if err != nil { return nil, err diff --git a/params/config.go b/params/config.go index bcccb96373..ac09690064 100644 --- a/params/config.go +++ b/params/config.go @@ -36,7 +36,7 @@ var ( Blake3PowColosseumGenesisHash = common.HexToHash("0x0ca6ff4426eab568de6773fb21d623d3fe6f2f0d2572c0b0b978384373e0895d") Blake3PowGardenGenesisHash = common.HexToHash("0x43af9e6e91fbf408b9c6fd423ed34e5ad0bd2154737cefc204d145ffc660fc9c") Blake3PowOrchardGenesisHash = common.HexToHash("0x43af9e6e91fbf408b9c6fd423ed34e5ad0bd2154737cefc204d145ffc660fc9c") - Blake3PowLocalGenesisHash = common.HexToHash("0xe145f05594415f1e7b7fdf261d41be71f9a9e53b9d07e4ec9d2658cefc4916ab") + Blake3PowLocalGenesisHash = common.HexToHash("0x3946bd52e33904f841d259cace4a22cce9a34f748f025bf8b1040a3f9300d201") Blake3PowLighthouseGenesisHash = common.HexToHash("0x43af9e6e91fbf408b9c6fd423ed34e5ad0bd2154737cefc204d145ffc660fc9c") )