From e5cb86a53f2c6e4ccc070cf5b05fd10c532dca2a Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 19 Feb 2024 15:17:39 +0100 Subject: [PATCH 01/48] Storage V2 implementation. LevelDB with 2 databases. --- blockchain/storageV2/leveldb/batch.go | 25 + blockchain/storageV2/leveldb/leveldb.go | 74 +++ .../storageV2/leveldb/leveldb_perf_test.go | 239 +++++++ blockchain/storageV2/leveldb/leveldb_test.go | 256 ++++++++ blockchain/storageV2/storage.go | 102 +++ blockchain/storageV2/storage_read.go | 182 ++++++ blockchain/storageV2/storage_write.go | 100 +++ blockchain/storageV2/testing.go | 590 ++++++++++++++++++ blockchain/storageV2/utils.go | 54 ++ go.mod | 1 + go.sum | 2 + 11 files changed, 1625 insertions(+) create mode 100644 blockchain/storageV2/leveldb/batch.go create mode 100644 blockchain/storageV2/leveldb/leveldb.go create mode 100644 blockchain/storageV2/leveldb/leveldb_perf_test.go create mode 100644 blockchain/storageV2/leveldb/leveldb_test.go create mode 100644 blockchain/storageV2/storage.go create mode 100644 blockchain/storageV2/storage_read.go create mode 100644 blockchain/storageV2/storage_write.go create mode 100644 blockchain/storageV2/testing.go create mode 100644 blockchain/storageV2/utils.go diff --git a/blockchain/storageV2/leveldb/batch.go b/blockchain/storageV2/leveldb/batch.go new file mode 100644 index 0000000000..0d694e30b0 --- /dev/null +++ b/blockchain/storageV2/leveldb/batch.go @@ -0,0 +1,25 @@ +package leveldb + +import ( + "github.com/syndtr/goleveldb/leveldb" +) + +type batchLevelDB struct { + db *leveldb.DB + b *leveldb.Batch +} + +func newBatchLevelDB(db *leveldb.DB) *batchLevelDB { + return &batchLevelDB{ + db: db, + b: new(leveldb.Batch), + } +} + +func (b *batchLevelDB) Put(k []byte, v []byte) { + b.b.Put(k, v) +} + +func (b *batchLevelDB) Write() error { + return b.db.Write(b.b, nil) +} diff --git a/blockchain/storageV2/leveldb/leveldb.go b/blockchain/storageV2/leveldb/leveldb.go new file mode 100644 index 0000000000..882aa2f123 --- /dev/null +++ b/blockchain/storageV2/leveldb/leveldb.go @@ -0,0 +1,74 @@ +package leveldb + +import ( + "github.com/0xPolygon/polygon-edge/blockchain/storageV2" + "github.com/hashicorp/go-hclog" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/opt" +) + +// levelDB is the leveldb implementation of the kv storage +type levelDB struct { + db *leveldb.DB +} + +// NewLevelDBStorage creates the new storage reference with leveldb default options +func NewLevelDBStorage(path string, logger hclog.Logger) (*storageV2.Storage, error) { + var ldbs [2]storageV2.Database + + // Open LevelDB storage + // Set default options + options := &opt.Options{ + BlockCacheCapacity: 64 * opt.MiB, + WriteBuffer: 128 * opt.MiB, // Two of these are used internally + } + db, err := openLevelDBStorage(path, options) + if err != nil { + return nil, err + } + + // Open GidLid + // Set default options + options = &opt.Options{ + BlockCacheCapacity: 64 * opt.MiB, + WriteBuffer: opt.DefaultWriteBuffer, + } + path = path + "/gidlid" + gidlid, err := openLevelDBStorage(path, options) + if err != nil { + return nil, err + } + + ldbs[0] = &levelDB{db} + ldbs[1] = &levelDB{gidlid} + return storageV2.Open(logger.Named("leveldb"), ldbs) +} + +func openLevelDBStorage(path string, options *opt.Options) (*leveldb.DB, error) { + db, err := leveldb.OpenFile(path, options) + if err != nil { + return nil, err + } + + return db, nil +} + +// Get retrieves the key-value pair in leveldb storage +func (l *levelDB) Get(k []byte) ([]byte, error) { + data, err := l.db.Get(k, nil) + if err != nil { + return nil, err + } + + return data, nil +} + +// Close closes the leveldb storage instance +func (l *levelDB) Close() error { + return l.db.Close() +} + +// NewBatch creates batch for database write operations +func (l *levelDB) NewBatch() storageV2.Batch { + return newBatchLevelDB(l.db) +} diff --git a/blockchain/storageV2/leveldb/leveldb_perf_test.go b/blockchain/storageV2/leveldb/leveldb_perf_test.go new file mode 100644 index 0000000000..de1c3b61ed --- /dev/null +++ b/blockchain/storageV2/leveldb/leveldb_perf_test.go @@ -0,0 +1,239 @@ +package leveldb + +import ( + "math/big" + "math/rand" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/0xPolygon/polygon-edge/blockchain" + "github.com/0xPolygon/polygon-edge/blockchain/storageV2" + "github.com/0xPolygon/polygon-edge/types" + "github.com/bradhe/stopwatch" + "github.com/hashicorp/go-hclog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func createTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { + t.Helper() + + txs := make([]*types.Transaction, count) + + for i := range txs { + tx := &types.Transaction{ + Gas: types.StateTransactionGasLimit, + Nonce: uint64(startNonce + i), + From: from, + To: to, + Value: big.NewInt(2000), + Type: types.DynamicFeeTx, + GasFeeCap: big.NewInt(100), + GasTipCap: big.NewInt(10), + } + + txs[i] = tx + } + + return txs +} + +const letterBytes = "abcdef0123456789" + +func randStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) +} + +func createBlock(t *testing.T) *types.FullBlock { + t.Helper() + + transactionsCount := 2500 + status := types.ReceiptSuccess + addr1 := types.StringToAddress("17878aa") + addr2 := types.StringToAddress("2bf5653") + b := &types.FullBlock{ + Block: &types.Block{ + Header: &types.Header{ + Number: 0, + ExtraData: make([]byte, 32), + Hash: types.ZeroHash, + }, + Transactions: createTxs(t, 0, transactionsCount, addr1, &addr2), + Uncles: blockchain.NewTestHeaders(10), + }, + Receipts: make([]*types.Receipt, transactionsCount), + } + + logs := make([]*types.Log, 10) + + for i := 0; i < 10; i++ { + logs[i] = &types.Log{ + Address: addr1, + Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, + Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, + } + } + + for i := 0; i < len(b.Block.Transactions); i++ { + b.Receipts[i] = &types.Receipt{ + TxHash: b.Block.Transactions[i].Hash, + Root: types.StringToHash("mockhashstring"), + TransactionType: types.LegacyTx, + GasUsed: uint64(100000), + Status: &status, + Logs: logs, + CumulativeGasUsed: uint64(100000), + ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, + } + } + + for i := 0; i < 5; i++ { + b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) + } + + return b +} + +func openStorage(t *testing.T, p string) (*storageV2.Storage, func(), string) { + t.Helper() + + s, err := NewLevelDBStorage(p, hclog.NewNullLogger()) + require.NoError(t, err) + + closeFn := func() { + require.NoError(t, s.Close()) + + if err := s.Close(); err != nil { + t.Fatal(err) + } + + require.NoError(t, os.RemoveAll(p)) + } + + return s, closeFn, p +} + +func dbSize(t *testing.T, path string) int64 { + t.Helper() + + var size int64 + + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + t.Fail() + } + if info != nil && !info.IsDir() && strings.Contains(info.Name(), ".ldb") { + size += info.Size() + } + + return err + }) + if err != nil { + t.Log(err) + } + + return size +} + +func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock { + t.Helper() + + var addr types.Address + b.Block.Header.Number = num + b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) + for i := range b.Block.Transactions { + addr = types.StringToAddress(randStringBytes(8)) + b.Block.Transactions[i].To = &addr + b.Block.Transactions[i].ComputeHash() + b.Receipts[i].TxHash = b.Block.Transactions[i].Hash + } + // big := new(big.Int) + // big.SetInt64(int64(num)) + // b.Block.Header.Hash = types.BytesToHash(big.Bytes()) + + b.Block.Header.ComputeHash() + + return b +} + +func prepareBatch(t *testing.T, s *storageV2.Storage, b *types.FullBlock) *storageV2.Writer { + t.Helper() + + batchWriter := s.NewWriter() + + // GidLid 'sorted' + batchWriter.PutHeadHash(b.Block.Header.Hash) + batchWriter.PutHeadNumber(b.Block.Number()) + batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) + for _, tx := range b.Block.Transactions { + batchWriter.PutTxLookup(tx.Hash, b.Block.Number()) + } + + // Main DB sorted + batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) + batchWriter.PutHeader(b.Block.Header) + batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + + return batchWriter +} + +func TestWriteBlockPerf(t *testing.T) { + s, _, path := openStorage(t, "/tmp/leveldbV2-test") + defer s.Close() + + count := 10000 + + b := createBlock(t) + var watchTime int + + for i := 1; i <= count; i++ { + updateBlock(t, uint64(i), b) + batchWriter := prepareBatch(t, s, b) + + watch := stopwatch.Start() + if err := batchWriter.WriteBatch(); err != nil { + require.NoError(t, err) + } + watch.Stop() + watchTime = watchTime + int(watch.Milliseconds()) + } + + time.Sleep(time.Second) + size := dbSize(t, path) + t.Logf("\tdb size %d MB", size/(1024*1024)) + t.Logf("\ttotal WriteBatch %d ms", watchTime) +} + +func TestReadBlockPerf(t *testing.T) { + s, _, _ := openStorage(t, "/tmp/leveldbV2-test") + defer s.Close() + + count := 1000 + var watchTime int + for i := 1; i <= count; i++ { + n := uint64(1 + rand.Intn(10000)) + + watch := stopwatch.Start() + _, err1 := s.ReadBody(n) + h, err2 := s.ReadCanonicalHash(n) + _, err3 := s.ReadHeader(n) + _, err4 := s.ReadReceipts(n) + b, err5 := s.ReadBlockLookup(h) + watch.Stop() + watchTime = watchTime + int(watch.Milliseconds()) + + if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil { + t.Logf("\terror") + } + assert.Equal(t, n, b) + } + t.Logf("\ttotal read %d ms", watchTime) +} diff --git a/blockchain/storageV2/leveldb/leveldb_test.go b/blockchain/storageV2/leveldb/leveldb_test.go new file mode 100644 index 0000000000..bb20dc95a2 --- /dev/null +++ b/blockchain/storageV2/leveldb/leveldb_test.go @@ -0,0 +1,256 @@ +package leveldb + +import ( + "context" + "crypto/rand" + "math/big" + "os" + "os/signal" + "path/filepath" + "syscall" + "testing" + "time" + + "github.com/0xPolygon/polygon-edge/blockchain" + "github.com/0xPolygon/polygon-edge/blockchain/storageV2" + "github.com/0xPolygon/polygon-edge/types" + "github.com/hashicorp/go-hclog" + "github.com/stretchr/testify/require" +) + +func newStorage(t *testing.T) (*storageV2.Storage, func()) { + t.Helper() + + path, err := os.MkdirTemp("/tmp", "minimal_storage") + if err != nil { + t.Fatal(err) + } + + s, err := NewLevelDBStorage(path, hclog.NewNullLogger()) + if err != nil { + t.Fatal(err) + } + + closeFn := func() { + if err := s.Close(); err != nil { + t.Fatal(err) + } + + if err := os.RemoveAll(path); err != nil { + t.Fatal(err) + } + } + + return s, closeFn +} + +func TestStorage(t *testing.T) { + storageV2.TestStorage(t, newStorage) +} + +func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { + t.Helper() + + txs := make([]*types.Transaction, count) + + for i := range txs { + tx := &types.Transaction{ + Gas: types.StateTransactionGasLimit, + Nonce: uint64(startNonce + i), + From: from, + To: to, + Value: big.NewInt(2000), + Type: types.DynamicFeeTx, + GasFeeCap: big.NewInt(100), + GasTipCap: big.NewInt(10), + } + + input := make([]byte, 1000) + _, err := rand.Read(input) + + require.NoError(t, err) + + tx.ComputeHash() + + txs[i] = tx + } + + return txs +} + +func generateBlock(t *testing.T, num uint64) *types.FullBlock { + t.Helper() + + transactionsCount := 2500 + status := types.ReceiptSuccess + addr1 := types.StringToAddress("17878aa") + addr2 := types.StringToAddress("2bf5653") + b := &types.FullBlock{ + Block: &types.Block{ + Header: &types.Header{ + Number: num, + ExtraData: make([]byte, 32), + Hash: types.ZeroHash, + }, + Transactions: generateTxs(t, 0, transactionsCount, addr1, &addr2), + Uncles: blockchain.NewTestHeaders(10), + }, + Receipts: make([]*types.Receipt, transactionsCount), + } + + logs := make([]*types.Log, 10) + + for i := 0; i < 10; i++ { + logs[i] = &types.Log{ + Address: addr1, + Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, + Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, + } + } + + for i := 0; i < len(b.Block.Transactions); i++ { + b.Receipts[i] = &types.Receipt{ + TxHash: b.Block.Transactions[i].Hash, + Root: types.StringToHash("mockhashstring"), + TransactionType: types.LegacyTx, + GasUsed: uint64(100000), + Status: &status, + Logs: logs, + CumulativeGasUsed: uint64(100000), + ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, + } + } + + for i := 0; i < 5; i++ { + b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) + } + + return b +} + +func newStorageP(t *testing.T) (*storageV2.Storage, func(), string) { + t.Helper() + + p, err := os.MkdirTemp("", "leveldbV2-test") + require.NoError(t, err) + + require.NoError(t, os.MkdirAll(p, 0755)) + + s, err := NewLevelDBStorage(p, hclog.NewNullLogger()) + require.NoError(t, err) + + closeFn := func() { + require.NoError(t, s.Close()) + + if err := s.Close(); err != nil { + t.Fatal(err) + } + + require.NoError(t, os.RemoveAll(p)) + } + + return s, closeFn, p +} + +func countLdbFilesInPath(path string) int { + pattern := filepath.Join(path, "*.ldb") + + files, err := filepath.Glob(pattern) + if err != nil { + return -1 + } + + return len(files) +} + +func generateBlocks(t *testing.T, count int, ch chan *types.FullBlock, ctx context.Context) { + t.Helper() + + ticker := time.NewTicker(time.Second) + + for i := 1; i <= count; i++ { + b := generateBlock(t, uint64(i)) + select { + case <-ctx.Done(): + close(ch) + ticker.Stop() + + return + case <-ticker.C: + ch <- b + } + } +} + +func dirSize(t *testing.T, path string) int64 { + t.Helper() + + var size int64 + + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + t.Fail() + } + if !info.IsDir() { + size += info.Size() + } + + return err + }) + if err != nil { + t.Log(err) + } + + return size +} + +func TestWriteFullBlock(t *testing.T) { + s, _, path := newStorageP(t) + defer s.Close() + + count := 100 + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*45) + + signchan := make(chan os.Signal, 1) + signal.Notify(signchan, syscall.SIGINT) + + go func() { + <-signchan + cancel() + }() + + blockchain := make(chan *types.FullBlock, 1) + go generateBlocks(t, count, blockchain, ctx) + +insertloop: + for i := 1; i <= count; i++ { + select { + case <-ctx.Done(): + break insertloop + case b := <-blockchain: + batchWriter := s.NewWriter() + + batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + + for _, tx := range b.Block.Transactions { + batchWriter.PutTxLookup(tx.Hash, b.Block.Number()) + } + + batchWriter.PutHeader(b.Block.Header) + batchWriter.PutHeadNumber(uint64(i)) + batchWriter.PutHeadHash(b.Block.Header.Hash) + batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash()) + + if err := batchWriter.WriteBatch(); err != nil { + require.NoError(t, err) + } + + t.Logf("writing block %d", i) + + size := dirSize(t, path) + t.Logf("\tldb file count: %d", countLdbFilesInPath(path)) + t.Logf("\tdir size %d MBs", size/1_000_000) + } + } +} diff --git a/blockchain/storageV2/storage.go b/blockchain/storageV2/storage.go new file mode 100644 index 0000000000..0e36c2870a --- /dev/null +++ b/blockchain/storageV2/storage.go @@ -0,0 +1,102 @@ +package storageV2 + +import ( + "bytes" + + "github.com/hashicorp/go-hclog" +) + +// Database interface. +type Database interface { + Close() error + Get(p []byte) ([]byte, error) + NewBatch() Batch +} + +// Database transaction/batch interface +type Batch interface { + Write() error + Put(k []byte, v []byte) +} + +type Storage struct { + logger hclog.Logger + db [2]Database +} + +type Writer struct { + batch [2]Batch +} + +// MCs for the key-value store +var ( + // DIFFICULTY is the difficulty prefix + DIFFICULTY = []byte("d") + + // HEADER is the header prefix + HEADER = []byte("h") + + // CANONICAL is the prefix for the canonical chain numbers + CANONICAL = []byte("c") + + // BODY is the prefix for bodies + BODY = []byte("b") + + // RECEIPTS is the prefix for receipts + RECEIPTS = []byte("r") +) + +// GidLid database MCs +var ( + // FORK is the entry to store forks + FORK = []byte("0000000f") + + // HASH is the entry for head hash + HASH = []byte("0000000h") + + // NUMBER is the entry for head number + NUMBER = []byte("0000000n") + + // GIDLID is added to the model code as sufix + GIDLID = []byte{} +) + +const ( + MAINDB_INDEX = uint8(0) + GIDLID_INDEX = uint8(1) +) + +func Open(logger hclog.Logger, db [2]Database) (*Storage, error) { + return &Storage{logger: logger, db: db}, nil +} + +func (s *Storage) Close() error { + for i, db := range s.db { + if db != nil { + err := db.Close() + if err != nil { + return err + } + + s.db[i] = nil + } + } + return nil +} + +func (s *Storage) NewWriter() *Writer { + var batch [2]Batch + batch[0] = s.db[0].NewBatch() + if s.db[1] != nil { + batch[1] = s.db[1].NewBatch() + } + return &Writer{batch: batch} +} + +func getIndex(mc []byte) uint8 { + if bytes.Equal(mc, GIDLID) { + return GIDLID_INDEX + } + + return MAINDB_INDEX +} diff --git a/blockchain/storageV2/storage_read.go b/blockchain/storageV2/storage_read.go new file mode 100644 index 0000000000..530c9966b5 --- /dev/null +++ b/blockchain/storageV2/storage_read.go @@ -0,0 +1,182 @@ +//nolint:stylecheck +package storageV2 + +import ( + "errors" + "math/big" + + "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/types" +) + +// -- canonical hash -- + +// ReadCanonicalHash gets the hash from the number of the canonical chain +func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, error) { + data, err := s.get(common.EncodeUint64ToBytes(n), CANONICAL) + if err != nil { + return types.Hash{}, err + } + + return types.BytesToHash(data), nil +} + +// HEAD // + +// ReadHeadHash returns the hash of the head +func (s *Storage) ReadHeadHash() (types.Hash, error) { + data, err := s.get(HASH, GIDLID) + if err != nil { + return types.Hash{}, err + } + + return types.BytesToHash(data), nil +} + +// ReadHeadNumber returns the number of the head +func (s *Storage) ReadHeadNumber() (uint64, error) { + data, err := s.get(NUMBER, GIDLID) + if err != nil { + return 0, err + } + + if len(data) != 8 { + return 0, errors.New("Invalid data") + } + + return common.EncodeBytesToUint64(data), nil +} + +// FORK // + +// ReadForks read the current forks +func (s *Storage) ReadForks() ([]types.Hash, error) { + forks := &Forks{} + err := s.readRLP(FORK, GIDLID, forks) + + return *forks, err +} + +// DIFFICULTY // + +// ReadTotalDifficulty reads the difficulty +func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, error) { + v, err := s.get(common.EncodeUint64ToBytes(bn), DIFFICULTY) + if err != nil { + return nil, err + } + + return big.NewInt(0).SetBytes(v), nil +} + +// HEADER // + +// ReadHeader reads the header +func (s *Storage) ReadHeader(bn uint64) (*types.Header, error) { + header := &types.Header{} + err := s.readRLP(common.EncodeUint64ToBytes(bn), HEADER, header) + + return header, err +} + +// BODY // + +// ReadBody reads the body +func (s *Storage) ReadBody(bn uint64) (*types.Body, error) { + body := &types.Body{} + if err := s.readRLP(common.EncodeUint64ToBytes(bn), BODY, body); err != nil { + return nil, err + } + + // must read header because block number is needed in order to calculate each tx hash + header := &types.Header{} + if err := s.readRLP(common.EncodeUint64ToBytes(bn), HEADER, header); err != nil { + return nil, err + } + + for _, tx := range body.Transactions { + tx.ComputeHash() + } + + return body, nil +} + +// RECEIPTS // + +// ReadReceipts reads the receipts +func (s *Storage) ReadReceipts(bn uint64) ([]*types.Receipt, error) { + receipts := &types.Receipts{} + err := s.readRLP(common.EncodeUint64ToBytes(bn), RECEIPTS, receipts) + + return *receipts, err +} + +// TX LOOKUP // + +// ReadTxLookup reads the block number using the transaction hash +func (s *Storage) ReadTxLookup(hash types.Hash) (uint64, error) { + return s.readLookup(hash) +} + +// BLOCK LOOKUP // + +// ReadBlockLookup reads the block number using the block hash +func (s *Storage) ReadBlockLookup(hash types.Hash) (uint64, error) { + return s.readLookup(hash) +} + +func (s *Storage) readLookup(hash types.Hash) (uint64, error) { + data, err := s.get(hash.Bytes(), GIDLID) + if err != nil { + return 0, err + } + + if len(data) != 8 { + return 0, errors.New("Invalid data") + } + + return common.EncodeBytesToUint64(data), nil +} + +func (s *Storage) readRLP(k, mc []byte, raw types.RLPUnmarshaler) error { + k = append(k, mc...) + data, err := s.getDB(mc).Get(k) + + if err != nil { + return err + } + + if obj, ok := raw.(types.RLPStoreUnmarshaler); ok { + // decode in the store format + if err := obj.UnmarshalStoreRLP(data); err != nil { + return err + } + } else { + // normal rlp decoding + if err := raw.UnmarshalRLP(data); err != nil { + return err + } + } + + return nil +} + +func (s *Storage) get(k, mc []byte) ([]byte, error) { + k = append(k, mc...) + data, err := s.getDB(mc).Get(k) + + if err != nil { + return nil, err + } + + return data, nil +} + +func (s *Storage) getDB(mc []byte) Database { + i := getIndex(mc) + if s.db[i] != nil { + return s.db[i] + } + + return s.db[MAINDB_INDEX] +} diff --git a/blockchain/storageV2/storage_write.go b/blockchain/storageV2/storage_write.go new file mode 100644 index 0000000000..99d68a170a --- /dev/null +++ b/blockchain/storageV2/storage_write.go @@ -0,0 +1,100 @@ +package storageV2 + +import ( + "math/big" + + "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/types" +) + +func (w *Writer) PutHeader(h *types.Header) { + w.putRlp(common.EncodeUint64ToBytes(h.Number), HEADER, h) +} + +func (w *Writer) PutBody(bn uint64, body *types.Body) { + w.putRlp(common.EncodeUint64ToBytes(bn), BODY, body) +} + +func (w *Writer) PutHeadHash(h types.Hash) { + w.putWithSuffix(HASH, GIDLID, h.Bytes()) +} + +func (w *Writer) PutHeadNumber(bn uint64) { + w.putWithSuffix(NUMBER, GIDLID, common.EncodeUint64ToBytes(bn)) +} + +func (w *Writer) PutTxLookup(hash types.Hash, bn uint64) { + w.putWithSuffix(hash.Bytes(), GIDLID, common.EncodeUint64ToBytes(bn)) +} + +func (w *Writer) PutBlockLookup(hash types.Hash, bn uint64) { + w.putWithSuffix(hash.Bytes(), GIDLID, common.EncodeUint64ToBytes(bn)) +} + +func (w *Writer) PutReceipts(bn uint64, receipts []*types.Receipt) { + rs := types.Receipts(receipts) + w.putRlp(common.EncodeUint64ToBytes(bn), RECEIPTS, &rs) +} + +func (w *Writer) PutCanonicalHeader(h *types.Header, diff *big.Int) { + w.PutHeader(h) + w.PutHeadHash(h.Hash) + w.PutHeadNumber(h.Number) + w.PutCanonicalHash(h.Number, h.Hash) + w.PutTotalDifficulty(h.Number, diff) +} + +func (w *Writer) PutCanonicalHash(bn uint64, hash types.Hash) { + w.putWithSuffix(common.EncodeUint64ToBytes(bn), CANONICAL, hash.Bytes()) +} + +func (w *Writer) PutTotalDifficulty(bn uint64, diff *big.Int) { + w.putWithSuffix(common.EncodeUint64ToBytes(bn), DIFFICULTY, diff.Bytes()) +} + +func (w *Writer) PutForks(forks []types.Hash) { + fs := Forks(forks) + w.putRlp(FORK, GIDLID, &fs) +} + +func (w *Writer) putRlp(k, mc []byte, raw types.RLPMarshaler) { + var data []byte + + if obj, ok := raw.(types.RLPStoreMarshaler); ok { + data = obj.MarshalStoreRLPTo(nil) + } else { + data = raw.MarshalRLPTo(nil) + } + + w.putWithSuffix(k, mc, data) +} + +func (w *Writer) putWithSuffix(k, mc, data []byte) { + fullKey := append(append(make([]byte, 0, len(k)+len(mc)), k...), mc...) + + w.getBatch(mc).Put(fullKey, data) +} + +func (w *Writer) WriteBatch() error { + for i, b := range w.batch { + if b != nil { + err := b.Write() + if err != nil { + return err + } + + w.batch[i] = nil + } + } + + return nil +} + +func (w *Writer) getBatch(mc []byte) Batch { + i := getIndex(mc) + if w.batch[i] != nil { + return w.batch[i] + } + + return w.batch[MAINDB_INDEX] +} diff --git a/blockchain/storageV2/testing.go b/blockchain/storageV2/testing.go new file mode 100644 index 0000000000..bfc52c2915 --- /dev/null +++ b/blockchain/storageV2/testing.go @@ -0,0 +1,590 @@ +package storageV2 + +import ( + "math/big" + "reflect" + "testing" + + "github.com/0xPolygon/polygon-edge/helper/hex" + "github.com/0xPolygon/polygon-edge/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type PlaceholderStorage func(t *testing.T) (*Storage, func()) + +var ( + addr1 = types.StringToAddress("1") + addr2 = types.StringToAddress("2") + + hash1 = types.StringToHash("1") + hash2 = types.StringToHash("2") +) + +// TestStorage tests a set of tests on a storage +func TestStorage(t *testing.T, m PlaceholderStorage) { + t.Helper() + + t.Run("testCanonicalChain", func(t *testing.T) { + testCanonicalChain(t, m) + }) + t.Run("testDifficulty", func(t *testing.T) { + testDifficulty(t, m) + }) + t.Run("testHead", func(t *testing.T) { + testHead(t, m) + }) + t.Run("testForks", func(t *testing.T) { + testForks(t, m) + }) + t.Run("testHeader", func(t *testing.T) { + testHeader(t, m) + }) + t.Run("testBody", func(t *testing.T) { + testBody(t, m) + }) + t.Run("testWriteCanonicalHeader", func(t *testing.T) { + testWriteCanonicalHeader(t, m) + }) + t.Run("testReceipts", func(t *testing.T) { + testReceipts(t, m) + }) +} + +func testCanonicalChain(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + var cases = []struct { + Number uint64 + ParentHash types.Hash + Hash types.Hash + }{ + { + Number: 1, + ParentHash: types.StringToHash("111"), + }, + { + Number: 1, + ParentHash: types.StringToHash("222"), + }, + { + Number: 2, + ParentHash: types.StringToHash("111"), + }, + } + + for _, cc := range cases { + batch := s.NewWriter() + + h := &types.Header{ + Number: cc.Number, + ParentHash: cc.ParentHash, + ExtraData: []byte{0x1}, + } + + hash := h.Hash + + batch.PutHeader(h) + batch.PutCanonicalHash(cc.Number, hash) + + require.NoError(t, batch.WriteBatch()) + + data, err := s.ReadCanonicalHash(cc.Number) + assert.NoError(t, err) + + if !reflect.DeepEqual(data, hash) { + t.Fatal("not match") + } + } +} + +func testDifficulty(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + var cases = []struct { + Diff *big.Int + }{ + { + Diff: big.NewInt(10), + }, + { + Diff: big.NewInt(11), + }, + { + Diff: big.NewInt(12), + }, + } + + for indx, cc := range cases { + batch := s.NewWriter() + + h := &types.Header{ + Number: uint64(indx), + ExtraData: []byte{}, + } + + batch.PutHeader(h) + batch.PutTotalDifficulty(h.Number, cc.Diff) + + require.NoError(t, batch.WriteBatch()) + + diff, err := s.ReadTotalDifficulty(h.Number) + assert.NoError(t, err) + + if !reflect.DeepEqual(cc.Diff, diff) { + t.Fatal("bad") + } + } +} + +func testHead(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + for i := uint64(0); i < 5; i++ { + batch := s.NewWriter() + + h := &types.Header{ + Number: i, + ExtraData: []byte{}, + } + hash := h.Hash + + batch.PutHeader(h) + batch.PutHeadNumber(i) + batch.PutHeadHash(hash) + + require.NoError(t, batch.WriteBatch()) + + n2, err := s.ReadHeadNumber() + assert.NoError(t, err) + + if n2 != i { + t.Fatal("bad") + } + + hash1, err := s.ReadHeadHash() + assert.NoError(t, err) + + if !reflect.DeepEqual(hash1, hash) { + t.Fatal("bad") + } + } +} + +func testForks(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + var cases = []struct { + Forks []types.Hash + }{ + {[]types.Hash{types.StringToHash("111"), types.StringToHash("222")}}, + {[]types.Hash{types.StringToHash("111")}}, + } + + for _, cc := range cases { + batch := s.NewWriter() + + batch.PutForks(cc.Forks) + + require.NoError(t, batch.WriteBatch()) + + forks, err := s.ReadForks() + assert.NoError(t, err) + + if !reflect.DeepEqual(cc.Forks, forks) { + t.Fatal("bad") + } + } +} + +func testHeader(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + header := &types.Header{ + Number: 5, + Difficulty: 17179869184, + ParentHash: types.StringToHash("11"), + Timestamp: 10, + // if not set it will fail + ExtraData: hex.MustDecodeHex("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), + } + header.ComputeHash() + + batch := s.NewWriter() + + batch.PutHeader(header) + + require.NoError(t, batch.WriteBatch()) + + header1, err := s.ReadHeader(header.Number) + assert.NoError(t, err) + + if !reflect.DeepEqual(header, header1) { + t.Fatal("bad") + } +} + +func testBody(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + header := &types.Header{ + Number: 5, + Difficulty: 10, + ParentHash: types.StringToHash("11"), + Timestamp: 10, + ExtraData: []byte{}, // if not set it will fail + } + + batch := s.NewWriter() + + batch.PutHeader(header) + + require.NoError(t, batch.WriteBatch()) + + addr1 := types.StringToAddress("11") + t0 := &types.Transaction{ + Nonce: 0, + To: &addr1, + Value: big.NewInt(1), + Gas: 11, + GasPrice: big.NewInt(11), + Input: []byte{1, 2}, + V: big.NewInt(1), + } + t0.ComputeHash() + + addr2 := types.StringToAddress("22") + t1 := &types.Transaction{ + Nonce: 0, + To: &addr2, + Value: big.NewInt(1), + Gas: 22, + GasPrice: big.NewInt(11), + Input: []byte{4, 5}, + V: big.NewInt(2), + } + t1.ComputeHash() + + block := types.Block{ + Header: header, + Transactions: []*types.Transaction{t0, t1}, + } + + batch2 := s.NewWriter() + body0 := block.Body() + + batch2.PutBody(header.Number, body0) + + require.NoError(t, batch2.WriteBatch()) + + body1, err := s.ReadBody(header.Number) + assert.NoError(t, err) + + // NOTE: reflect.DeepEqual does not seem to work, check the hash of the transactions + tx0, tx1 := body0.Transactions, body1.Transactions + if len(tx0) != len(tx1) { + t.Fatal("lengths are different") + } + + for indx, i := range tx0 { + if i.Hash != tx1[indx].Hash { + t.Fatal("tx not correct") + } + } +} + +func testReceipts(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + batch := s.NewWriter() + + h := &types.Header{ + Difficulty: 133, + Number: 11, + ExtraData: []byte{}, + } + h.ComputeHash() + + body := &types.Body{ + Transactions: []*types.Transaction{ + { + Nonce: 1000, + Gas: 50, + GasPrice: new(big.Int).SetUint64(100), + V: big.NewInt(11), + }, + }, + } + receipts := []*types.Receipt{ + { + Root: types.StringToHash("1"), + CumulativeGasUsed: 10, + TxHash: body.Transactions[0].Hash, + LogsBloom: types.Bloom{0x1}, + Logs: []*types.Log{ + { + Address: addr1, + Topics: []types.Hash{hash1, hash2}, + Data: []byte{0x1, 0x2}, + }, + { + Address: addr2, + Topics: []types.Hash{hash1}, + }, + }, + }, + { + Root: types.StringToHash("1"), + CumulativeGasUsed: 10, + TxHash: body.Transactions[0].Hash, + LogsBloom: types.Bloom{0x1}, + GasUsed: 10, + ContractAddress: &types.Address{0x1}, + Logs: []*types.Log{ + { + Address: addr2, + Topics: []types.Hash{hash1}, + }, + }, + }, + } + + batch.PutHeader(h) + batch.PutBody(h.Number, body) + batch.PutReceipts(h.Number, receipts) + + require.NoError(t, batch.WriteBatch()) + + found, err := s.ReadReceipts(h.Number) + assert.NoError(t, err) + assert.True(t, reflect.DeepEqual(receipts, found)) +} + +func testWriteCanonicalHeader(t *testing.T, m PlaceholderStorage) { + t.Helper() + + s, closeFn := m(t) + defer closeFn() + + h := &types.Header{ + Number: 100, + ExtraData: []byte{0x1}, + } + h.ComputeHash() + + diff := new(big.Int).SetUint64(100) + batch := s.NewWriter() + + batch.PutCanonicalHeader(h, diff) + + require.NoError(t, batch.WriteBatch()) + + hh, err := s.ReadHeader(h.Number) + assert.NoError(t, err) + if !reflect.DeepEqual(h, hh) { + t.Fatal("bad header") + } + + headHash, err := s.ReadHeadHash() + assert.NoError(t, err) + if headHash != h.Hash { + t.Fatal("head hash not correct") + } + + headNum, err := s.ReadHeadNumber() + assert.NoError(t, err) + if headNum != h.Number { + t.Fatal("head num not correct") + } + + canHash, err := s.ReadCanonicalHash(h.Number) + assert.NoError(t, err) + if canHash != h.Hash { + t.Fatal("canonical hash not correct") + } +} + +// Storage delegators + +type readCanonicalHashDelegate func(uint64) (types.Hash, error) +type readHeadHashDelegate func() (types.Hash, error) +type readHeadNumberDelegate func() (uint64, error) +type readForksDelegate func() ([]types.Hash, error) +type readTotalDifficultyDelegate func(uint64) (*big.Int, error) +type readHeaderDelegate func(uint64) (*types.Header, error) +type readBodyDelegate func(uint64) (*types.Body, error) +type readReceiptsDelegate func(uint64) ([]*types.Receipt, error) +type readTxLookupDelegate func(types.Hash) (uint64, error) +type closeDelegate func() error +type newBatchDelegate func() Batch + +type MockStorage struct { + readCanonicalHashFn readCanonicalHashDelegate + readHeadHashFn readHeadHashDelegate + readHeadNumberFn readHeadNumberDelegate + readForksFn readForksDelegate + readTotalDifficultyFn readTotalDifficultyDelegate + readHeaderFn readHeaderDelegate + readBodyFn readBodyDelegate + readReceiptsFn readReceiptsDelegate + readTxLookupFn readTxLookupDelegate + closeFn closeDelegate + newBatchFn newBatchDelegate +} + +func NewMockStorage() *MockStorage { + return &MockStorage{} +} + +func (m *MockStorage) ReadCanonicalHash(n uint64) (types.Hash, error) { + if m.readCanonicalHashFn != nil { + return m.readCanonicalHashFn(n) + } + + return types.Hash{}, nil +} + +func (m *MockStorage) HookReadCanonicalHash(fn readCanonicalHashDelegate) { + m.readCanonicalHashFn = fn +} + +func (m *MockStorage) ReadHeadHash() (types.Hash, error) { + if m.readHeadHashFn != nil { + return m.readHeadHashFn() + } + + return types.Hash{}, nil +} + +func (m *MockStorage) HookReadHeadHash(fn readHeadHashDelegate) { + m.readHeadHashFn = fn +} + +func (m *MockStorage) ReadHeadNumber() (uint64, error) { + if m.readHeadNumberFn != nil { + return m.readHeadNumberFn() + } + + return 0, nil +} + +func (m *MockStorage) HookReadHeadNumber(fn readHeadNumberDelegate) { + m.readHeadNumberFn = fn +} + +func (m *MockStorage) ReadForks() ([]types.Hash, error) { + if m.readForksFn != nil { + return m.readForksFn() + } + + return []types.Hash{}, nil +} + +func (m *MockStorage) HookReadForks(fn readForksDelegate) { + m.readForksFn = fn +} + +func (m *MockStorage) ReadTotalDifficulty(bn uint64) (*big.Int, error) { + if m.readTotalDifficultyFn != nil { + return m.readTotalDifficultyFn(bn) + } + + return big.NewInt(0), nil +} + +func (m *MockStorage) HookReadTotalDifficulty(fn readTotalDifficultyDelegate) { + m.readTotalDifficultyFn = fn +} + +func (m *MockStorage) ReadHeader(bn uint64) (*types.Header, error) { + if m.readHeaderFn != nil { + return m.readHeaderFn(bn) + } + + return &types.Header{}, nil +} + +func (m *MockStorage) HookReadHeader(fn readHeaderDelegate) { + m.readHeaderFn = fn +} + +func (m *MockStorage) ReadBody(bn uint64) (*types.Body, error) { + if m.readBodyFn != nil { + return m.readBodyFn(bn) + } + + return &types.Body{}, nil +} + +func (m *MockStorage) HookReadBody(fn readBodyDelegate) { + m.readBodyFn = fn +} + +func (m *MockStorage) ReadReceipts(bn uint64) ([]*types.Receipt, error) { + if m.readReceiptsFn != nil { + return m.readReceiptsFn(bn) + } + + return []*types.Receipt{}, nil +} + +func (m *MockStorage) HookReadReceipts(fn readReceiptsDelegate) { + m.readReceiptsFn = fn +} + +func (m *MockStorage) ReadTxLookup(hash types.Hash) (uint64, error) { + if m.readTxLookupFn != nil { + return m.readTxLookupFn(hash) + } + + return 0, nil +} + +func (m *MockStorage) HookReadTxLookup(fn readTxLookupDelegate) { + m.readTxLookupFn = fn +} + +func (m *MockStorage) Close() error { + if m.closeFn != nil { + return m.closeFn() + } + + return nil +} + +func (m *MockStorage) HookClose(fn closeDelegate) { + m.closeFn = fn +} + +func (m *MockStorage) HookNewBatch(fn newBatchDelegate) { + m.newBatchFn = fn +} + +func (m *MockStorage) NewBatch() Batch { + if m.newBatchFn != nil { + return m.newBatchFn() + } + + return nil +} diff --git a/blockchain/storageV2/utils.go b/blockchain/storageV2/utils.go new file mode 100644 index 0000000000..25963fd8fa --- /dev/null +++ b/blockchain/storageV2/utils.go @@ -0,0 +1,54 @@ +package storageV2 + +import ( + "github.com/0xPolygon/polygon-edge/types" + "github.com/umbracle/fastrlp" +) + +type Forks []types.Hash + +// MarshalRLPTo is a wrapper function for calling the type marshal implementation +func (f *Forks) MarshalRLPTo(dst []byte) []byte { + return types.MarshalRLPTo(f.MarshalRLPWith, dst) +} + +// MarshalRLPWith is the actual RLP marshal implementation for the type +func (f *Forks) MarshalRLPWith(ar *fastrlp.Arena) *fastrlp.Value { + var vr *fastrlp.Value + + if len(*f) == 0 { + vr = ar.NewNullArray() + } else { + vr = ar.NewArray() + + for _, fork := range *f { + vr.Set(ar.NewCopyBytes(fork[:])) + } + } + + return vr +} + +// UnmarshalRLP is a wrapper function for calling the type unmarshal implementation +func (f *Forks) UnmarshalRLP(input []byte) error { + return types.UnmarshalRlp(f.UnmarshalRLPFrom, input) +} + +// UnmarshalRLPFrom is the actual RLP unmarshal implementation for the type +func (f *Forks) UnmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { + elems, err := v.GetElems() + if err != nil { + return err + } + + forks := make([]types.Hash, len(elems)) + for indx, elem := range elems { + if err := elem.GetHash(forks[indx][:]); err != nil { + return err + } + } + + *f = forks + + return nil +} diff --git a/go.mod b/go.mod index 76c04f9224..13146b9e51 100644 --- a/go.mod +++ b/go.mod @@ -82,6 +82,7 @@ require ( github.com/andybalholm/brotli v1.0.6 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect diff --git a/go.sum b/go.sum index cb7a1e2447..dba8b6ff58 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea h1:+GIgqdjrcKMHK1JqC1Bb9arFtNOGX/SWCkueobreyQU= +github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea/go.mod h1:P/j2DSP/kCOakHBACzMqmOdrTEieqdSiB3U9fqk7qgc= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= From 16c782b937b27892569b3cb91a655fe51e89d4f0 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Tue, 20 Feb 2024 10:03:07 +0100 Subject: [PATCH 02/48] Refactoring before Mdbx database import --- blockchain/storageV2/leveldb/batch.go | 4 +- blockchain/storageV2/leveldb/leveldb.go | 18 +++++++- blockchain/storageV2/storage.go | 57 ++++++++++--------------- blockchain/storageV2/storage_read.go | 40 +++++++++-------- blockchain/storageV2/storage_write.go | 34 +++++++-------- 5 files changed, 77 insertions(+), 76 deletions(-) diff --git a/blockchain/storageV2/leveldb/batch.go b/blockchain/storageV2/leveldb/batch.go index 0d694e30b0..89cd121c46 100644 --- a/blockchain/storageV2/leveldb/batch.go +++ b/blockchain/storageV2/leveldb/batch.go @@ -16,7 +16,9 @@ func newBatchLevelDB(db *leveldb.DB) *batchLevelDB { } } -func (b *batchLevelDB) Put(k []byte, v []byte) { +func (b *batchLevelDB) Put(t uint8, k []byte, v []byte) { + mc := tableMapper[t] + k = append(append(make([]byte, 0, len(k)+len(mc)), k...), mc...) b.b.Put(k, v) } diff --git a/blockchain/storageV2/leveldb/leveldb.go b/blockchain/storageV2/leveldb/leveldb.go index 882aa2f123..fa4eafd4d8 100644 --- a/blockchain/storageV2/leveldb/leveldb.go +++ b/blockchain/storageV2/leveldb/leveldb.go @@ -12,6 +12,20 @@ type levelDB struct { db *leveldb.DB } +// DB key = k + mapper +var tableMapper = map[uint8][]byte{ + storageV2.BODY: []byte("b"), // DB key = block number + mapper + storageV2.CANONICAL: []byte("c"), // DB key = block number + mapper + storageV2.DIFFICULTY: []byte("d"), // DB key = block number + mapper + storageV2.HEADER: []byte("h"), // DB key = block number + mapper + storageV2.RECEIPTS: []byte("r"), // DB key = block number + mapper + storageV2.FORK: []byte("0000000f"), // DB key = empty + mapper + storageV2.HEAD_HASH: []byte("0000000h"), // DB key = empty + mapper + storageV2.HEAD_NUMBER: []byte("0000000n"), // DB key = empty + mapper + storageV2.BLOCK_LOOKUP: []byte{}, // DB key = block hash + mapper, value = block number + storageV2.TX_LOOKUP: []byte{}, // DB key = tx hash + mapper, value = block number +} + // NewLevelDBStorage creates the new storage reference with leveldb default options func NewLevelDBStorage(path string, logger hclog.Logger) (*storageV2.Storage, error) { var ldbs [2]storageV2.Database @@ -54,7 +68,9 @@ func openLevelDBStorage(path string, options *opt.Options) (*leveldb.DB, error) } // Get retrieves the key-value pair in leveldb storage -func (l *levelDB) Get(k []byte) ([]byte, error) { +func (l *levelDB) Get(t uint8, k []byte) ([]byte, error) { + mc := tableMapper[t] + k = append(k, mc...) data, err := l.db.Get(k, nil) if err != nil { return nil, err diff --git a/blockchain/storageV2/storage.go b/blockchain/storageV2/storage.go index 0e36c2870a..00fa108670 100644 --- a/blockchain/storageV2/storage.go +++ b/blockchain/storageV2/storage.go @@ -1,22 +1,20 @@ package storageV2 import ( - "bytes" - "github.com/hashicorp/go-hclog" ) // Database interface. type Database interface { Close() error - Get(p []byte) ([]byte, error) + Get(t uint8, k []byte) ([]byte, error) NewBatch() Batch } // Database transaction/batch interface type Batch interface { Write() error - Put(k []byte, v []byte) + Put(t uint8, k []byte, v []byte) } type Storage struct { @@ -28,44 +26,33 @@ type Writer struct { batch [2]Batch } -// MCs for the key-value store -var ( - // DIFFICULTY is the difficulty prefix - DIFFICULTY = []byte("d") - - // HEADER is the header prefix - HEADER = []byte("h") - - // CANONICAL is the prefix for the canonical chain numbers - CANONICAL = []byte("c") - - // BODY is the prefix for bodies - BODY = []byte("b") - - // RECEIPTS is the prefix for receipts - RECEIPTS = []byte("r") +// Tables +const ( + BODY = uint8(0) + CANONICAL = uint8(2) + DIFFICULTY = uint8(4) + HEADER = uint8(6) + RECEIPTS = uint8(8) ) -// GidLid database MCs -var ( - // FORK is the entry to store forks - FORK = []byte("0000000f") - - // HASH is the entry for head hash - HASH = []byte("0000000h") - - // NUMBER is the entry for head number - NUMBER = []byte("0000000n") - - // GIDLID is added to the model code as sufix - GIDLID = []byte{} +// GidLid tables +const ( + FORK = uint8(0) | GIDLID_INDEX + HEAD_HASH = uint8(2) | GIDLID_INDEX + HEAD_NUMBER = uint8(4) | GIDLID_INDEX + BLOCK_LOOKUP = uint8(6) | GIDLID_INDEX + TX_LOOKUP = uint8(8) | GIDLID_INDEX ) +// Database indexes const ( MAINDB_INDEX = uint8(0) GIDLID_INDEX = uint8(1) ) +// Empty key +var EMPTY = []byte{} + func Open(logger hclog.Logger, db [2]Database) (*Storage, error) { return &Storage{logger: logger, db: db}, nil } @@ -93,8 +80,8 @@ func (s *Storage) NewWriter() *Writer { return &Writer{batch: batch} } -func getIndex(mc []byte) uint8 { - if bytes.Equal(mc, GIDLID) { +func getIndex(t uint8) uint8 { + if t&GIDLID_INDEX != 0 { return GIDLID_INDEX } diff --git a/blockchain/storageV2/storage_read.go b/blockchain/storageV2/storage_read.go index 530c9966b5..941e95a15a 100644 --- a/blockchain/storageV2/storage_read.go +++ b/blockchain/storageV2/storage_read.go @@ -13,7 +13,7 @@ import ( // ReadCanonicalHash gets the hash from the number of the canonical chain func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, error) { - data, err := s.get(common.EncodeUint64ToBytes(n), CANONICAL) + data, err := s.get(CANONICAL, common.EncodeUint64ToBytes(n)) if err != nil { return types.Hash{}, err } @@ -25,7 +25,7 @@ func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, error) { // ReadHeadHash returns the hash of the head func (s *Storage) ReadHeadHash() (types.Hash, error) { - data, err := s.get(HASH, GIDLID) + data, err := s.get(HEAD_HASH, EMPTY) if err != nil { return types.Hash{}, err } @@ -35,7 +35,7 @@ func (s *Storage) ReadHeadHash() (types.Hash, error) { // ReadHeadNumber returns the number of the head func (s *Storage) ReadHeadNumber() (uint64, error) { - data, err := s.get(NUMBER, GIDLID) + data, err := s.get(HEAD_NUMBER, EMPTY) if err != nil { return 0, err } @@ -52,7 +52,7 @@ func (s *Storage) ReadHeadNumber() (uint64, error) { // ReadForks read the current forks func (s *Storage) ReadForks() ([]types.Hash, error) { forks := &Forks{} - err := s.readRLP(FORK, GIDLID, forks) + err := s.readRLP(FORK, EMPTY, forks) return *forks, err } @@ -61,7 +61,7 @@ func (s *Storage) ReadForks() ([]types.Hash, error) { // ReadTotalDifficulty reads the difficulty func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, error) { - v, err := s.get(common.EncodeUint64ToBytes(bn), DIFFICULTY) + v, err := s.get(DIFFICULTY, common.EncodeUint64ToBytes(bn)) if err != nil { return nil, err } @@ -74,7 +74,7 @@ func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, error) { // ReadHeader reads the header func (s *Storage) ReadHeader(bn uint64) (*types.Header, error) { header := &types.Header{} - err := s.readRLP(common.EncodeUint64ToBytes(bn), HEADER, header) + err := s.readRLP(HEADER, common.EncodeUint64ToBytes(bn), header) return header, err } @@ -84,13 +84,13 @@ func (s *Storage) ReadHeader(bn uint64) (*types.Header, error) { // ReadBody reads the body func (s *Storage) ReadBody(bn uint64) (*types.Body, error) { body := &types.Body{} - if err := s.readRLP(common.EncodeUint64ToBytes(bn), BODY, body); err != nil { + if err := s.readRLP(BODY, common.EncodeUint64ToBytes(bn), body); err != nil { return nil, err } // must read header because block number is needed in order to calculate each tx hash header := &types.Header{} - if err := s.readRLP(common.EncodeUint64ToBytes(bn), HEADER, header); err != nil { + if err := s.readRLP(HEADER, common.EncodeUint64ToBytes(bn), header); err != nil { return nil, err } @@ -106,7 +106,7 @@ func (s *Storage) ReadBody(bn uint64) (*types.Body, error) { // ReadReceipts reads the receipts func (s *Storage) ReadReceipts(bn uint64) ([]*types.Receipt, error) { receipts := &types.Receipts{} - err := s.readRLP(common.EncodeUint64ToBytes(bn), RECEIPTS, receipts) + err := s.readRLP(RECEIPTS, common.EncodeUint64ToBytes(bn), receipts) return *receipts, err } @@ -115,18 +115,18 @@ func (s *Storage) ReadReceipts(bn uint64) ([]*types.Receipt, error) { // ReadTxLookup reads the block number using the transaction hash func (s *Storage) ReadTxLookup(hash types.Hash) (uint64, error) { - return s.readLookup(hash) + return s.readLookup(TX_LOOKUP, hash) } // BLOCK LOOKUP // // ReadBlockLookup reads the block number using the block hash func (s *Storage) ReadBlockLookup(hash types.Hash) (uint64, error) { - return s.readLookup(hash) + return s.readLookup(BLOCK_LOOKUP, hash) } -func (s *Storage) readLookup(hash types.Hash) (uint64, error) { - data, err := s.get(hash.Bytes(), GIDLID) +func (s *Storage) readLookup(t uint8, hash types.Hash) (uint64, error) { + data, err := s.get(t, hash.Bytes()) if err != nil { return 0, err } @@ -138,9 +138,8 @@ func (s *Storage) readLookup(hash types.Hash) (uint64, error) { return common.EncodeBytesToUint64(data), nil } -func (s *Storage) readRLP(k, mc []byte, raw types.RLPUnmarshaler) error { - k = append(k, mc...) - data, err := s.getDB(mc).Get(k) +func (s *Storage) readRLP(t uint8, k []byte, raw types.RLPUnmarshaler) error { + data, err := s.getDB(t).Get(t, k) if err != nil { return err @@ -161,9 +160,8 @@ func (s *Storage) readRLP(k, mc []byte, raw types.RLPUnmarshaler) error { return nil } -func (s *Storage) get(k, mc []byte) ([]byte, error) { - k = append(k, mc...) - data, err := s.getDB(mc).Get(k) +func (s *Storage) get(t uint8, k []byte) ([]byte, error) { + data, err := s.getDB(t).Get(t, k) if err != nil { return nil, err @@ -172,8 +170,8 @@ func (s *Storage) get(k, mc []byte) ([]byte, error) { return data, nil } -func (s *Storage) getDB(mc []byte) Database { - i := getIndex(mc) +func (s *Storage) getDB(t uint8) Database { + i := getIndex(t) if s.db[i] != nil { return s.db[i] } diff --git a/blockchain/storageV2/storage_write.go b/blockchain/storageV2/storage_write.go index 99d68a170a..edded835c1 100644 --- a/blockchain/storageV2/storage_write.go +++ b/blockchain/storageV2/storage_write.go @@ -8,32 +8,32 @@ import ( ) func (w *Writer) PutHeader(h *types.Header) { - w.putRlp(common.EncodeUint64ToBytes(h.Number), HEADER, h) + w.putRlp(HEADER, common.EncodeUint64ToBytes(h.Number), h) } func (w *Writer) PutBody(bn uint64, body *types.Body) { - w.putRlp(common.EncodeUint64ToBytes(bn), BODY, body) + w.putRlp(BODY, common.EncodeUint64ToBytes(bn), body) } func (w *Writer) PutHeadHash(h types.Hash) { - w.putWithSuffix(HASH, GIDLID, h.Bytes()) + w.putIntoTable(HEAD_HASH, EMPTY, h.Bytes()) } func (w *Writer) PutHeadNumber(bn uint64) { - w.putWithSuffix(NUMBER, GIDLID, common.EncodeUint64ToBytes(bn)) + w.putIntoTable(HEAD_NUMBER, EMPTY, common.EncodeUint64ToBytes(bn)) } func (w *Writer) PutTxLookup(hash types.Hash, bn uint64) { - w.putWithSuffix(hash.Bytes(), GIDLID, common.EncodeUint64ToBytes(bn)) + w.putIntoTable(TX_LOOKUP, hash.Bytes(), common.EncodeUint64ToBytes(bn)) } func (w *Writer) PutBlockLookup(hash types.Hash, bn uint64) { - w.putWithSuffix(hash.Bytes(), GIDLID, common.EncodeUint64ToBytes(bn)) + w.putIntoTable(BLOCK_LOOKUP, hash.Bytes(), common.EncodeUint64ToBytes(bn)) } func (w *Writer) PutReceipts(bn uint64, receipts []*types.Receipt) { rs := types.Receipts(receipts) - w.putRlp(common.EncodeUint64ToBytes(bn), RECEIPTS, &rs) + w.putRlp(RECEIPTS, common.EncodeUint64ToBytes(bn), &rs) } func (w *Writer) PutCanonicalHeader(h *types.Header, diff *big.Int) { @@ -45,19 +45,19 @@ func (w *Writer) PutCanonicalHeader(h *types.Header, diff *big.Int) { } func (w *Writer) PutCanonicalHash(bn uint64, hash types.Hash) { - w.putWithSuffix(common.EncodeUint64ToBytes(bn), CANONICAL, hash.Bytes()) + w.putIntoTable(CANONICAL, common.EncodeUint64ToBytes(bn), hash.Bytes()) } func (w *Writer) PutTotalDifficulty(bn uint64, diff *big.Int) { - w.putWithSuffix(common.EncodeUint64ToBytes(bn), DIFFICULTY, diff.Bytes()) + w.putIntoTable(DIFFICULTY, common.EncodeUint64ToBytes(bn), diff.Bytes()) } func (w *Writer) PutForks(forks []types.Hash) { fs := Forks(forks) - w.putRlp(FORK, GIDLID, &fs) + w.putRlp(FORK, EMPTY, &fs) } -func (w *Writer) putRlp(k, mc []byte, raw types.RLPMarshaler) { +func (w *Writer) putRlp(t uint8, k []byte, raw types.RLPMarshaler) { var data []byte if obj, ok := raw.(types.RLPStoreMarshaler); ok { @@ -66,13 +66,11 @@ func (w *Writer) putRlp(k, mc []byte, raw types.RLPMarshaler) { data = raw.MarshalRLPTo(nil) } - w.putWithSuffix(k, mc, data) + w.putIntoTable(t, k, data) } -func (w *Writer) putWithSuffix(k, mc, data []byte) { - fullKey := append(append(make([]byte, 0, len(k)+len(mc)), k...), mc...) - - w.getBatch(mc).Put(fullKey, data) +func (w *Writer) putIntoTable(t uint8, k []byte, data []byte) { + w.getBatch(t).Put(t, k, data) } func (w *Writer) WriteBatch() error { @@ -90,8 +88,8 @@ func (w *Writer) WriteBatch() error { return nil } -func (w *Writer) getBatch(mc []byte) Batch { - i := getIndex(mc) +func (w *Writer) getBatch(t uint8) Batch { + i := getIndex(t) if w.batch[i] != nil { return w.batch[i] } From 6e792e1b3dfae854b3bde1a81c82404c3ee3d270 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Tue, 20 Feb 2024 10:31:59 +0100 Subject: [PATCH 03/48] LevelDB 2 databases final --- .../storage/leveldb/leveldb_perf_test.go | 235 ++++++++++++++++++ blockchain/storageV2/leveldb/leveldb.go | 4 +- 2 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 blockchain/storage/leveldb/leveldb_perf_test.go diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go new file mode 100644 index 0000000000..3a5d5f7db5 --- /dev/null +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -0,0 +1,235 @@ +package leveldb + +import ( + "math/big" + "math/rand" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/0xPolygon/polygon-edge/blockchain" + "github.com/0xPolygon/polygon-edge/blockchain/storage" + "github.com/0xPolygon/polygon-edge/types" + "github.com/bradhe/stopwatch" + "github.com/hashicorp/go-hclog" + "github.com/stretchr/testify/require" +) + +func createTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { + t.Helper() + + txs := make([]*types.Transaction, count) + + for i := range txs { + tx := &types.Transaction{ + Gas: types.StateTransactionGasLimit, + Nonce: uint64(startNonce + i), + From: from, + To: to, + Value: big.NewInt(2000), + Type: types.DynamicFeeTx, + GasFeeCap: big.NewInt(100), + GasTipCap: big.NewInt(10), + } + + txs[i] = tx + } + + return txs +} + +const letterBytes = "abcdef0123456789" + +func randStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) +} + +func createBlock(t *testing.T) *types.FullBlock { + t.Helper() + + transactionsCount := 2500 + status := types.ReceiptSuccess + addr1 := types.StringToAddress("17878aa") + addr2 := types.StringToAddress("2bf5653") + b := &types.FullBlock{ + Block: &types.Block{ + Header: &types.Header{ + Number: 0, + ExtraData: make([]byte, 32), + Hash: types.ZeroHash, + }, + Transactions: createTxs(t, 0, transactionsCount, addr1, &addr2), + Uncles: blockchain.NewTestHeaders(10), + }, + Receipts: make([]*types.Receipt, transactionsCount), + } + + logs := make([]*types.Log, 10) + + for i := 0; i < 10; i++ { + logs[i] = &types.Log{ + Address: addr1, + Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, + Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, + } + } + + for i := 0; i < len(b.Block.Transactions); i++ { + b.Receipts[i] = &types.Receipt{ + TxHash: b.Block.Transactions[i].Hash, + Root: types.StringToHash("mockhashstring"), + TransactionType: types.LegacyTx, + GasUsed: uint64(100000), + Status: &status, + Logs: logs, + CumulativeGasUsed: uint64(100000), + ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, + } + } + + for i := 0; i < 5; i++ { + b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) + } + + return b +} + +func openStorage(t *testing.T, p string) (storage.Storage, func(), string) { + t.Helper() + + s, err := NewLevelDBStorage(p, hclog.NewNullLogger()) + require.NoError(t, err) + + closeFn := func() { + require.NoError(t, s.Close()) + + if err := s.Close(); err != nil { + t.Fatal(err) + } + + require.NoError(t, os.RemoveAll(p)) + } + + return s, closeFn, p +} + +func dbSize(t *testing.T, path string) int64 { + t.Helper() + + var size int64 + + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + t.Fail() + } + if info != nil && !info.IsDir() && strings.Contains(info.Name(), ".ldb") { + size += info.Size() + } + + return err + }) + if err != nil { + t.Log(err) + } + + return size +} + +func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock { + t.Helper() + + var addr types.Address + b.Block.Header.Number = num + b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) + for i := range b.Block.Transactions { + addr = types.StringToAddress(randStringBytes(8)) + b.Block.Transactions[i].To = &addr + b.Block.Transactions[i].ComputeHash() + b.Receipts[i].TxHash = b.Block.Transactions[i].Hash + } + // big := new(big.Int) + // big.SetInt64(int64(num)) + // b.Block.Header.Hash = types.BytesToHash(big.Bytes()) + + b.Block.Header.ComputeHash() + + return b +} + +func prepareBatch(t *testing.T, s storage.Storage, b *types.FullBlock) *storage.BatchWriter { + t.Helper() + + batchWriter := storage.NewBatchWriter(s) + + // GidLid 'sorted' + batchWriter.PutHeadHash(b.Block.Header.Hash) + batchWriter.PutHeadNumber(b.Block.Number()) + for _, tx := range b.Block.Transactions { + batchWriter.PutTxLookup(tx.Hash, b.Block.Hash()) + } + + // Main DB sorted + batchWriter.PutBody(b.Block.Hash(), b.Block.Body()) + batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) + batchWriter.PutHeader(b.Block.Header) + batchWriter.PutReceipts(b.Block.Hash(), b.Receipts) + + return batchWriter +} + +func TestWriteBlockPerf(t *testing.T) { + s, _, path := openStorage(t, "/tmp/leveldbV1-test") + defer s.Close() + + count := 10000 + + b := createBlock(t) + var watchTime int + + for i := 1; i <= count; i++ { + updateBlock(t, uint64(i), b) + batchWriter := prepareBatch(t, s, b) + + watch := stopwatch.Start() + if err := batchWriter.WriteBatch(); err != nil { + require.NoError(t, err) + } + watch.Stop() + watchTime = watchTime + int(watch.Milliseconds()) + } + + time.Sleep(time.Second) + size := dbSize(t, path) + t.Logf("\tdb size %d MB", size/(1024*1024)) + t.Logf("\ttotal WriteBatch %d ms", watchTime) +} + +func TestReadBlockPerf(t *testing.T) { + s, _, _ := openStorage(t, "/tmp/leveldbV1-test") + defer s.Close() + + count := 1000 + var watchTime int + for i := 1; i <= count; i++ { + n := uint64(1 + rand.Intn(10000)) + + watch := stopwatch.Start() + h, ok := s.ReadCanonicalHash(n) + _, err2 := s.ReadBody(h) + _, err3 := s.ReadHeader(h) + _, err4 := s.ReadReceipts(h) + watch.Stop() + watchTime = watchTime + int(watch.Milliseconds()) + + if !ok || err2 != nil || err3 != nil || err4 != nil { + t.Logf("\terror") + } + } + t.Logf("\ttotal read %d ms", watchTime) +} diff --git a/blockchain/storageV2/leveldb/leveldb.go b/blockchain/storageV2/leveldb/leveldb.go index fa4eafd4d8..88d3790251 100644 --- a/blockchain/storageV2/leveldb/leveldb.go +++ b/blockchain/storageV2/leveldb/leveldb.go @@ -22,8 +22,8 @@ var tableMapper = map[uint8][]byte{ storageV2.FORK: []byte("0000000f"), // DB key = empty + mapper storageV2.HEAD_HASH: []byte("0000000h"), // DB key = empty + mapper storageV2.HEAD_NUMBER: []byte("0000000n"), // DB key = empty + mapper - storageV2.BLOCK_LOOKUP: []byte{}, // DB key = block hash + mapper, value = block number - storageV2.TX_LOOKUP: []byte{}, // DB key = tx hash + mapper, value = block number + storageV2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number + storageV2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number } // NewLevelDBStorage creates the new storage reference with leveldb default options From 3f5b5463bc0fb647f0450fe49ac062d172898bc4 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Tue, 20 Feb 2024 13:04:24 +0100 Subject: [PATCH 04/48] go.mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 14b726caca..03c14f5d81 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,9 @@ require ( github.com/Ethernal-Tech/merkle-tree v0.0.0-20231213143318-4db9da419e04 github.com/armon/go-metrics v0.4.1 github.com/aws/aws-sdk-go v1.50.8 + github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/docker/docker v24.0.9+incompatible - github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea github.com/docker/go-connections v0.5.0 github.com/envoyproxy/protoc-gen-validate v1.0.4 github.com/golang/protobuf v1.5.3 From 45320fb99546978827288eb3a13b9832b8e40b45 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Tue, 20 Feb 2024 13:13:32 +0100 Subject: [PATCH 05/48] Build fix after merge --- .../storage/leveldb/leveldb_perf_test.go | 12 ++++++------ .../storageV2/leveldb/leveldb_perf_test.go | 12 ++++++------ blockchain/storageV2/leveldb/leveldb_test.go | 8 ++++---- blockchain/storageV2/testing.go | 18 +++++++++--------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go index 3a5d5f7db5..de460b0249 100644 --- a/blockchain/storage/leveldb/leveldb_perf_test.go +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -23,7 +23,7 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type txs := make([]*types.Transaction, count) for i := range txs { - tx := &types.Transaction{ + tx := types.NewTx(&types.MixedTxn{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, @@ -32,7 +32,7 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), - } + }) txs[i] = tx } @@ -82,7 +82,7 @@ func createBlock(t *testing.T) *types.FullBlock { for i := 0; i < len(b.Block.Transactions); i++ { b.Receipts[i] = &types.Receipt{ - TxHash: b.Block.Transactions[i].Hash, + TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), TransactionType: types.LegacyTx, GasUsed: uint64(100000), @@ -149,9 +149,9 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) for i := range b.Block.Transactions { addr = types.StringToAddress(randStringBytes(8)) - b.Block.Transactions[i].To = &addr + b.Block.Transactions[i].SetTo(&addr) b.Block.Transactions[i].ComputeHash() - b.Receipts[i].TxHash = b.Block.Transactions[i].Hash + b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() } // big := new(big.Int) // big.SetInt64(int64(num)) @@ -171,7 +171,7 @@ func prepareBatch(t *testing.T, s storage.Storage, b *types.FullBlock) *storage. batchWriter.PutHeadHash(b.Block.Header.Hash) batchWriter.PutHeadNumber(b.Block.Number()) for _, tx := range b.Block.Transactions { - batchWriter.PutTxLookup(tx.Hash, b.Block.Hash()) + batchWriter.PutTxLookup(tx.Hash(), b.Block.Hash()) } // Main DB sorted diff --git a/blockchain/storageV2/leveldb/leveldb_perf_test.go b/blockchain/storageV2/leveldb/leveldb_perf_test.go index de1c3b61ed..88134627a5 100644 --- a/blockchain/storageV2/leveldb/leveldb_perf_test.go +++ b/blockchain/storageV2/leveldb/leveldb_perf_test.go @@ -24,7 +24,7 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type txs := make([]*types.Transaction, count) for i := range txs { - tx := &types.Transaction{ + tx := types.NewTx(&types.MixedTxn{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, @@ -33,7 +33,7 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), - } + }) txs[i] = tx } @@ -83,7 +83,7 @@ func createBlock(t *testing.T) *types.FullBlock { for i := 0; i < len(b.Block.Transactions); i++ { b.Receipts[i] = &types.Receipt{ - TxHash: b.Block.Transactions[i].Hash, + TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), TransactionType: types.LegacyTx, GasUsed: uint64(100000), @@ -150,9 +150,9 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) for i := range b.Block.Transactions { addr = types.StringToAddress(randStringBytes(8)) - b.Block.Transactions[i].To = &addr + b.Block.Transactions[i].SetTo(&addr) b.Block.Transactions[i].ComputeHash() - b.Receipts[i].TxHash = b.Block.Transactions[i].Hash + b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() } // big := new(big.Int) // big.SetInt64(int64(num)) @@ -173,7 +173,7 @@ func prepareBatch(t *testing.T, s *storageV2.Storage, b *types.FullBlock) *stora batchWriter.PutHeadNumber(b.Block.Number()) batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) for _, tx := range b.Block.Transactions { - batchWriter.PutTxLookup(tx.Hash, b.Block.Number()) + batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) } // Main DB sorted diff --git a/blockchain/storageV2/leveldb/leveldb_test.go b/blockchain/storageV2/leveldb/leveldb_test.go index bb20dc95a2..d14e34951a 100644 --- a/blockchain/storageV2/leveldb/leveldb_test.go +++ b/blockchain/storageV2/leveldb/leveldb_test.go @@ -54,7 +54,7 @@ func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *ty txs := make([]*types.Transaction, count) for i := range txs { - tx := &types.Transaction{ + tx := types.NewTx(&types.MixedTxn{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, @@ -63,7 +63,7 @@ func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *ty Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), - } + }) input := make([]byte, 1000) _, err := rand.Read(input) @@ -110,7 +110,7 @@ func generateBlock(t *testing.T, num uint64) *types.FullBlock { for i := 0; i < len(b.Block.Transactions); i++ { b.Receipts[i] = &types.Receipt{ - TxHash: b.Block.Transactions[i].Hash, + TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), TransactionType: types.LegacyTx, GasUsed: uint64(100000), @@ -233,7 +233,7 @@ insertloop: batchWriter.PutBody(b.Block.Number(), b.Block.Body()) for _, tx := range b.Block.Transactions { - batchWriter.PutTxLookup(tx.Hash, b.Block.Number()) + batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) } batchWriter.PutHeader(b.Block.Header) diff --git a/blockchain/storageV2/testing.go b/blockchain/storageV2/testing.go index bfc52c2915..3605989784 100644 --- a/blockchain/storageV2/testing.go +++ b/blockchain/storageV2/testing.go @@ -260,7 +260,7 @@ func testBody(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) addr1 := types.StringToAddress("11") - t0 := &types.Transaction{ + t0 := types.NewTx(&types.MixedTxn{ Nonce: 0, To: &addr1, Value: big.NewInt(1), @@ -268,11 +268,11 @@ func testBody(t *testing.T, m PlaceholderStorage) { GasPrice: big.NewInt(11), Input: []byte{1, 2}, V: big.NewInt(1), - } + }) t0.ComputeHash() addr2 := types.StringToAddress("22") - t1 := &types.Transaction{ + t1 := types.NewTx(&types.MixedTxn{ Nonce: 0, To: &addr2, Value: big.NewInt(1), @@ -280,7 +280,7 @@ func testBody(t *testing.T, m PlaceholderStorage) { GasPrice: big.NewInt(11), Input: []byte{4, 5}, V: big.NewInt(2), - } + }) t1.ComputeHash() block := types.Block{ @@ -305,7 +305,7 @@ func testBody(t *testing.T, m PlaceholderStorage) { } for indx, i := range tx0 { - if i.Hash != tx1[indx].Hash { + if i.Hash() != tx1[indx].Hash() { t.Fatal("tx not correct") } } @@ -328,19 +328,19 @@ func testReceipts(t *testing.T, m PlaceholderStorage) { body := &types.Body{ Transactions: []*types.Transaction{ - { + types.NewTx(&types.MixedTxn{ Nonce: 1000, Gas: 50, GasPrice: new(big.Int).SetUint64(100), V: big.NewInt(11), - }, + }), }, } receipts := []*types.Receipt{ { Root: types.StringToHash("1"), CumulativeGasUsed: 10, - TxHash: body.Transactions[0].Hash, + TxHash: body.Transactions[0].Hash(), LogsBloom: types.Bloom{0x1}, Logs: []*types.Log{ { @@ -357,7 +357,7 @@ func testReceipts(t *testing.T, m PlaceholderStorage) { { Root: types.StringToHash("1"), CumulativeGasUsed: 10, - TxHash: body.Transactions[0].Hash, + TxHash: body.Transactions[0].Hash(), LogsBloom: types.Bloom{0x1}, GasUsed: 10, ContractAddress: &types.Address{0x1}, From 9db3b89cd09a748b7f59eedadd1dd31c6008bcae Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Tue, 20 Feb 2024 20:43:02 +0100 Subject: [PATCH 06/48] lint fixes --- .../storage/leveldb/leveldb_perf_test.go | 16 +++++++-- .../{storageV2 => storagev2}/leveldb/batch.go | 0 .../leveldb/leveldb.go | 34 +++++++++++-------- .../leveldb/leveldb_perf_test.go | 23 +++++++++---- .../leveldb/leveldb_test.go | 9 ++--- .../{storageV2 => storagev2}/storage.go | 9 +++-- .../{storageV2 => storagev2}/storage_read.go | 2 +- .../{storageV2 => storagev2}/storage_write.go | 2 +- .../{storageV2 => storagev2}/testing.go | 6 +++- blockchain/{storageV2 => storagev2}/utils.go | 2 +- 10 files changed, 68 insertions(+), 35 deletions(-) rename blockchain/{storageV2 => storagev2}/leveldb/batch.go (100%) rename blockchain/{storageV2 => storagev2}/leveldb/leveldb.go (68%) rename blockchain/{storageV2 => storagev2}/leveldb/leveldb_perf_test.go (96%) rename blockchain/{storageV2 => storagev2}/leveldb/leveldb_test.go (95%) rename blockchain/{storageV2 => storagev2}/storage.go (94%) rename blockchain/{storageV2 => storagev2}/storage_read.go (99%) rename blockchain/{storageV2 => storagev2}/storage_write.go (99%) rename blockchain/{storageV2 => storagev2}/testing.go (99%) rename blockchain/{storageV2 => storagev2}/utils.go (98%) diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go index de460b0249..ef744c8bf9 100644 --- a/blockchain/storage/leveldb/leveldb_perf_test.go +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -47,6 +47,7 @@ func randStringBytes(n int) string { for i := range b { b[i] = letterBytes[rand.Intn(len(letterBytes))] } + return string(b) } @@ -128,6 +129,7 @@ func dbSize(t *testing.T, path string) int64 { if err != nil { t.Fail() } + if info != nil && !info.IsDir() && strings.Contains(info.Name(), ".ldb") { size += info.Size() } @@ -145,8 +147,10 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock t.Helper() var addr types.Address + b.Block.Header.Number = num b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) + for i := range b.Block.Transactions { addr = types.StringToAddress(randStringBytes(8)) b.Block.Transactions[i].SetTo(&addr) @@ -170,6 +174,7 @@ func prepareBatch(t *testing.T, s storage.Storage, b *types.FullBlock) *storage. // GidLid 'sorted' batchWriter.PutHeadHash(b.Block.Header.Hash) batchWriter.PutHeadNumber(b.Block.Number()) + for _, tx := range b.Block.Transactions { batchWriter.PutTxLookup(tx.Hash(), b.Block.Hash()) } @@ -187,24 +192,27 @@ func TestWriteBlockPerf(t *testing.T) { s, _, path := openStorage(t, "/tmp/leveldbV1-test") defer s.Close() - count := 10000 + var watchTime int + count := 10000 b := createBlock(t) - var watchTime int for i := 1; i <= count; i++ { updateBlock(t, uint64(i), b) batchWriter := prepareBatch(t, s, b) watch := stopwatch.Start() + if err := batchWriter.WriteBatch(); err != nil { require.NoError(t, err) } + watch.Stop() watchTime = watchTime + int(watch.Milliseconds()) } time.Sleep(time.Second) + size := dbSize(t, path) t.Logf("\tdb size %d MB", size/(1024*1024)) t.Logf("\ttotal WriteBatch %d ms", watchTime) @@ -214,8 +222,9 @@ func TestReadBlockPerf(t *testing.T) { s, _, _ := openStorage(t, "/tmp/leveldbV1-test") defer s.Close() - count := 1000 var watchTime int + + count := 1000 for i := 1; i <= count; i++ { n := uint64(1 + rand.Intn(10000)) @@ -224,6 +233,7 @@ func TestReadBlockPerf(t *testing.T) { _, err2 := s.ReadBody(h) _, err3 := s.ReadHeader(h) _, err4 := s.ReadReceipts(h) + watch.Stop() watchTime = watchTime + int(watch.Milliseconds()) diff --git a/blockchain/storageV2/leveldb/batch.go b/blockchain/storagev2/leveldb/batch.go similarity index 100% rename from blockchain/storageV2/leveldb/batch.go rename to blockchain/storagev2/leveldb/batch.go diff --git a/blockchain/storageV2/leveldb/leveldb.go b/blockchain/storagev2/leveldb/leveldb.go similarity index 68% rename from blockchain/storageV2/leveldb/leveldb.go rename to blockchain/storagev2/leveldb/leveldb.go index 88d3790251..b60e0370a6 100644 --- a/blockchain/storageV2/leveldb/leveldb.go +++ b/blockchain/storagev2/leveldb/leveldb.go @@ -1,7 +1,7 @@ package leveldb import ( - "github.com/0xPolygon/polygon-edge/blockchain/storageV2" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/hashicorp/go-hclog" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/opt" @@ -14,21 +14,21 @@ type levelDB struct { // DB key = k + mapper var tableMapper = map[uint8][]byte{ - storageV2.BODY: []byte("b"), // DB key = block number + mapper - storageV2.CANONICAL: []byte("c"), // DB key = block number + mapper - storageV2.DIFFICULTY: []byte("d"), // DB key = block number + mapper - storageV2.HEADER: []byte("h"), // DB key = block number + mapper - storageV2.RECEIPTS: []byte("r"), // DB key = block number + mapper - storageV2.FORK: []byte("0000000f"), // DB key = empty + mapper - storageV2.HEAD_HASH: []byte("0000000h"), // DB key = empty + mapper - storageV2.HEAD_NUMBER: []byte("0000000n"), // DB key = empty + mapper - storageV2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number - storageV2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number + storagev2.BODY: []byte("b"), // DB key = block number + mapper + storagev2.CANONICAL: []byte("c"), // DB key = block number + mapper + storagev2.DIFFICULTY: []byte("d"), // DB key = block number + mapper + storagev2.HEADER: []byte("h"), // DB key = block number + mapper + storagev2.RECEIPTS: []byte("r"), // DB key = block number + mapper + storagev2.FORK: []byte("0000000f"), // DB key = empty + mapper + storagev2.HEAD_HASH: []byte("0000000h"), // DB key = empty + mapper + storagev2.HEAD_NUMBER: []byte("0000000n"), // DB key = empty + mapper + storagev2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number + storagev2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number } // NewLevelDBStorage creates the new storage reference with leveldb default options -func NewLevelDBStorage(path string, logger hclog.Logger) (*storageV2.Storage, error) { - var ldbs [2]storageV2.Database +func NewLevelDBStorage(path string, logger hclog.Logger) (*storagev2.Storage, error) { + var ldbs [2]storagev2.Database // Open LevelDB storage // Set default options @@ -36,6 +36,7 @@ func NewLevelDBStorage(path string, logger hclog.Logger) (*storageV2.Storage, er BlockCacheCapacity: 64 * opt.MiB, WriteBuffer: 128 * opt.MiB, // Two of these are used internally } + db, err := openLevelDBStorage(path, options) if err != nil { return nil, err @@ -48,6 +49,7 @@ func NewLevelDBStorage(path string, logger hclog.Logger) (*storageV2.Storage, er WriteBuffer: opt.DefaultWriteBuffer, } path = path + "/gidlid" + gidlid, err := openLevelDBStorage(path, options) if err != nil { return nil, err @@ -55,7 +57,8 @@ func NewLevelDBStorage(path string, logger hclog.Logger) (*storageV2.Storage, er ldbs[0] = &levelDB{db} ldbs[1] = &levelDB{gidlid} - return storageV2.Open(logger.Named("leveldb"), ldbs) + + return storagev2.Open(logger.Named("leveldb"), ldbs) } func openLevelDBStorage(path string, options *opt.Options) (*leveldb.DB, error) { @@ -71,6 +74,7 @@ func openLevelDBStorage(path string, options *opt.Options) (*leveldb.DB, error) func (l *levelDB) Get(t uint8, k []byte) ([]byte, error) { mc := tableMapper[t] k = append(k, mc...) + data, err := l.db.Get(k, nil) if err != nil { return nil, err @@ -85,6 +89,6 @@ func (l *levelDB) Close() error { } // NewBatch creates batch for database write operations -func (l *levelDB) NewBatch() storageV2.Batch { +func (l *levelDB) NewBatch() storagev2.Batch { return newBatchLevelDB(l.db) } diff --git a/blockchain/storageV2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go similarity index 96% rename from blockchain/storageV2/leveldb/leveldb_perf_test.go rename to blockchain/storagev2/leveldb/leveldb_perf_test.go index 88134627a5..16f6a2acf8 100644 --- a/blockchain/storageV2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -10,7 +10,7 @@ import ( "time" "github.com/0xPolygon/polygon-edge/blockchain" - "github.com/0xPolygon/polygon-edge/blockchain/storageV2" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/0xPolygon/polygon-edge/types" "github.com/bradhe/stopwatch" "github.com/hashicorp/go-hclog" @@ -48,6 +48,7 @@ func randStringBytes(n int) string { for i := range b { b[i] = letterBytes[rand.Intn(len(letterBytes))] } + return string(b) } @@ -101,7 +102,7 @@ func createBlock(t *testing.T) *types.FullBlock { return b } -func openStorage(t *testing.T, p string) (*storageV2.Storage, func(), string) { +func openStorage(t *testing.T, p string) (*storagev2.Storage, func(), string) { t.Helper() s, err := NewLevelDBStorage(p, hclog.NewNullLogger()) @@ -129,6 +130,7 @@ func dbSize(t *testing.T, path string) int64 { if err != nil { t.Fail() } + if info != nil && !info.IsDir() && strings.Contains(info.Name(), ".ldb") { size += info.Size() } @@ -146,8 +148,10 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock t.Helper() var addr types.Address + b.Block.Header.Number = num b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) + for i := range b.Block.Transactions { addr = types.StringToAddress(randStringBytes(8)) b.Block.Transactions[i].SetTo(&addr) @@ -163,7 +167,7 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock return b } -func prepareBatch(t *testing.T, s *storageV2.Storage, b *types.FullBlock) *storageV2.Writer { +func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *storagev2.Writer { t.Helper() batchWriter := s.NewWriter() @@ -172,6 +176,7 @@ func prepareBatch(t *testing.T, s *storageV2.Storage, b *types.FullBlock) *stora batchWriter.PutHeadHash(b.Block.Header.Hash) batchWriter.PutHeadNumber(b.Block.Number()) batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) + for _, tx := range b.Block.Transactions { batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) } @@ -189,24 +194,27 @@ func TestWriteBlockPerf(t *testing.T) { s, _, path := openStorage(t, "/tmp/leveldbV2-test") defer s.Close() - count := 10000 + var watchTime int + count := 10000 b := createBlock(t) - var watchTime int for i := 1; i <= count; i++ { updateBlock(t, uint64(i), b) batchWriter := prepareBatch(t, s, b) watch := stopwatch.Start() + if err := batchWriter.WriteBatch(); err != nil { require.NoError(t, err) } + watch.Stop() watchTime = watchTime + int(watch.Milliseconds()) } time.Sleep(time.Second) + size := dbSize(t, path) t.Logf("\tdb size %d MB", size/(1024*1024)) t.Logf("\ttotal WriteBatch %d ms", watchTime) @@ -216,8 +224,9 @@ func TestReadBlockPerf(t *testing.T) { s, _, _ := openStorage(t, "/tmp/leveldbV2-test") defer s.Close() - count := 1000 var watchTime int + + count := 1000 for i := 1; i <= count; i++ { n := uint64(1 + rand.Intn(10000)) @@ -227,12 +236,14 @@ func TestReadBlockPerf(t *testing.T) { _, err3 := s.ReadHeader(n) _, err4 := s.ReadReceipts(n) b, err5 := s.ReadBlockLookup(h) + watch.Stop() watchTime = watchTime + int(watch.Milliseconds()) if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") } + assert.Equal(t, n, b) } t.Logf("\ttotal read %d ms", watchTime) diff --git a/blockchain/storageV2/leveldb/leveldb_test.go b/blockchain/storagev2/leveldb/leveldb_test.go similarity index 95% rename from blockchain/storageV2/leveldb/leveldb_test.go rename to blockchain/storagev2/leveldb/leveldb_test.go index d14e34951a..afb76183fa 100644 --- a/blockchain/storageV2/leveldb/leveldb_test.go +++ b/blockchain/storagev2/leveldb/leveldb_test.go @@ -12,13 +12,13 @@ import ( "time" "github.com/0xPolygon/polygon-edge/blockchain" - "github.com/0xPolygon/polygon-edge/blockchain/storageV2" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/require" ) -func newStorage(t *testing.T) (*storageV2.Storage, func()) { +func newStorage(t *testing.T) (*storagev2.Storage, func()) { t.Helper() path, err := os.MkdirTemp("/tmp", "minimal_storage") @@ -45,7 +45,7 @@ func newStorage(t *testing.T) (*storageV2.Storage, func()) { } func TestStorage(t *testing.T) { - storageV2.TestStorage(t, newStorage) + storagev2.TestStorage(t, newStorage) } func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { @@ -128,7 +128,7 @@ func generateBlock(t *testing.T, num uint64) *types.FullBlock { return b } -func newStorageP(t *testing.T) (*storageV2.Storage, func(), string) { +func newStorageP(t *testing.T) (*storagev2.Storage, func(), string) { t.Helper() p, err := os.MkdirTemp("", "leveldbV2-test") @@ -191,6 +191,7 @@ func dirSize(t *testing.T, path string) int64 { if err != nil { t.Fail() } + if !info.IsDir() { size += info.Size() } diff --git a/blockchain/storageV2/storage.go b/blockchain/storagev2/storage.go similarity index 94% rename from blockchain/storageV2/storage.go rename to blockchain/storagev2/storage.go index 00fa108670..64dc284534 100644 --- a/blockchain/storageV2/storage.go +++ b/blockchain/storagev2/storage.go @@ -1,4 +1,5 @@ -package storageV2 +//nolint:stylecheck +package storagev2 import ( "github.com/hashicorp/go-hclog" @@ -50,8 +51,7 @@ const ( GIDLID_INDEX = uint8(1) ) -// Empty key -var EMPTY = []byte{} +var EMPTY = []byte{} // Empty key func Open(logger hclog.Logger, db [2]Database) (*Storage, error) { return &Storage{logger: logger, db: db}, nil @@ -68,15 +68,18 @@ func (s *Storage) Close() error { s.db[i] = nil } } + return nil } func (s *Storage) NewWriter() *Writer { var batch [2]Batch batch[0] = s.db[0].NewBatch() + if s.db[1] != nil { batch[1] = s.db[1].NewBatch() } + return &Writer{batch: batch} } diff --git a/blockchain/storageV2/storage_read.go b/blockchain/storagev2/storage_read.go similarity index 99% rename from blockchain/storageV2/storage_read.go rename to blockchain/storagev2/storage_read.go index 941e95a15a..94dab9ecbd 100644 --- a/blockchain/storageV2/storage_read.go +++ b/blockchain/storagev2/storage_read.go @@ -1,5 +1,5 @@ //nolint:stylecheck -package storageV2 +package storagev2 import ( "errors" diff --git a/blockchain/storageV2/storage_write.go b/blockchain/storagev2/storage_write.go similarity index 99% rename from blockchain/storageV2/storage_write.go rename to blockchain/storagev2/storage_write.go index edded835c1..a8ee422b74 100644 --- a/blockchain/storageV2/storage_write.go +++ b/blockchain/storagev2/storage_write.go @@ -1,4 +1,4 @@ -package storageV2 +package storagev2 import ( "math/big" diff --git a/blockchain/storageV2/testing.go b/blockchain/storagev2/testing.go similarity index 99% rename from blockchain/storageV2/testing.go rename to blockchain/storagev2/testing.go index 3605989784..3bf1acd65a 100644 --- a/blockchain/storageV2/testing.go +++ b/blockchain/storagev2/testing.go @@ -1,4 +1,4 @@ -package storageV2 +package storagev2 import ( "math/big" @@ -402,24 +402,28 @@ func testWriteCanonicalHeader(t *testing.T, m PlaceholderStorage) { hh, err := s.ReadHeader(h.Number) assert.NoError(t, err) + if !reflect.DeepEqual(h, hh) { t.Fatal("bad header") } headHash, err := s.ReadHeadHash() assert.NoError(t, err) + if headHash != h.Hash { t.Fatal("head hash not correct") } headNum, err := s.ReadHeadNumber() assert.NoError(t, err) + if headNum != h.Number { t.Fatal("head num not correct") } canHash, err := s.ReadCanonicalHash(h.Number) assert.NoError(t, err) + if canHash != h.Hash { t.Fatal("canonical hash not correct") } diff --git a/blockchain/storageV2/utils.go b/blockchain/storagev2/utils.go similarity index 98% rename from blockchain/storageV2/utils.go rename to blockchain/storagev2/utils.go index 25963fd8fa..a51d48affb 100644 --- a/blockchain/storageV2/utils.go +++ b/blockchain/storagev2/utils.go @@ -1,4 +1,4 @@ -package storageV2 +package storagev2 import ( "github.com/0xPolygon/polygon-edge/types" From 053076968f56064a4188cddf9f42777d3dd6efe3 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Wed, 21 Feb 2024 09:17:21 +0100 Subject: [PATCH 07/48] SkipNow for storage perf tests --- blockchain/storage/leveldb/leveldb_perf_test.go | 4 ++++ blockchain/storagev2/leveldb/leveldb_perf_test.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go index ef744c8bf9..e0631181bf 100644 --- a/blockchain/storage/leveldb/leveldb_perf_test.go +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -189,6 +189,8 @@ func prepareBatch(t *testing.T, s storage.Storage, b *types.FullBlock) *storage. } func TestWriteBlockPerf(t *testing.T) { + t.SkipNow() + s, _, path := openStorage(t, "/tmp/leveldbV1-test") defer s.Close() @@ -219,6 +221,8 @@ func TestWriteBlockPerf(t *testing.T) { } func TestReadBlockPerf(t *testing.T) { + t.SkipNow() + s, _, _ := openStorage(t, "/tmp/leveldbV1-test") defer s.Close() diff --git a/blockchain/storagev2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go index 16f6a2acf8..0b73bd20ba 100644 --- a/blockchain/storagev2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -191,6 +191,8 @@ func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *stora } func TestWriteBlockPerf(t *testing.T) { + t.SkipNow() + s, _, path := openStorage(t, "/tmp/leveldbV2-test") defer s.Close() @@ -221,6 +223,8 @@ func TestWriteBlockPerf(t *testing.T) { } func TestReadBlockPerf(t *testing.T) { + t.SkipNow() + s, _, _ := openStorage(t, "/tmp/leveldbV2-test") defer s.Close() From 7ba346766c7a64c718ce40727d47435e1df81f24 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Thu, 22 Feb 2024 08:28:09 +0100 Subject: [PATCH 08/48] mdbx added into storage V2 --- blockchain/storagev2/leveldb/leveldb.go | 20 +- blockchain/storagev2/leveldb/leveldb_test.go | 2 +- blockchain/storagev2/mdbx/batch.go | 46 ++++ blockchain/storagev2/mdbx/mdbx.go | 190 ++++++++++++++ blockchain/storagev2/mdbx/mdbx_perf_test.go | 229 +++++++++++++++++ blockchain/storagev2/mdbx/mdbx_test.go | 246 +++++++++++++++++++ blockchain/storagev2/storage.go | 6 +- blockchain/storagev2/storage_read.go | 6 +- blockchain/storagev2/storage_write.go | 6 +- go.mod | 1 + go.sum | 2 + 11 files changed, 736 insertions(+), 18 deletions(-) create mode 100644 blockchain/storagev2/mdbx/batch.go create mode 100644 blockchain/storagev2/mdbx/mdbx.go create mode 100644 blockchain/storagev2/mdbx/mdbx_perf_test.go create mode 100644 blockchain/storagev2/mdbx/mdbx_test.go diff --git a/blockchain/storagev2/leveldb/leveldb.go b/blockchain/storagev2/leveldb/leveldb.go index b60e0370a6..bb852c6be0 100644 --- a/blockchain/storagev2/leveldb/leveldb.go +++ b/blockchain/storagev2/leveldb/leveldb.go @@ -14,16 +14,16 @@ type levelDB struct { // DB key = k + mapper var tableMapper = map[uint8][]byte{ - storagev2.BODY: []byte("b"), // DB key = block number + mapper - storagev2.CANONICAL: []byte("c"), // DB key = block number + mapper - storagev2.DIFFICULTY: []byte("d"), // DB key = block number + mapper - storagev2.HEADER: []byte("h"), // DB key = block number + mapper - storagev2.RECEIPTS: []byte("r"), // DB key = block number + mapper - storagev2.FORK: []byte("0000000f"), // DB key = empty + mapper - storagev2.HEAD_HASH: []byte("0000000h"), // DB key = empty + mapper - storagev2.HEAD_NUMBER: []byte("0000000n"), // DB key = empty + mapper - storagev2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number - storagev2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number + storagev2.BODY: []byte("b"), // DB key = block number + mapper + storagev2.CANONICAL: []byte("c"), // DB key = block number + mapper + storagev2.DIFFICULTY: []byte("d"), // DB key = block number + mapper + storagev2.HEADER: []byte("h"), // DB key = block number + mapper + storagev2.RECEIPTS: []byte("r"), // DB key = block number + mapper + storagev2.FORK: {}, // DB key = FORK_KEY + mapper + storagev2.HEAD_HASH: {}, // DB key = HEAD_HASH_KEY + mapper + storagev2.HEAD_NUMBER: {}, // DB key = HEAD_NUMBER_KEY + mapper + storagev2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number + storagev2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number } // NewLevelDBStorage creates the new storage reference with leveldb default options diff --git a/blockchain/storagev2/leveldb/leveldb_test.go b/blockchain/storagev2/leveldb/leveldb_test.go index afb76183fa..db7abe6ca4 100644 --- a/blockchain/storagev2/leveldb/leveldb_test.go +++ b/blockchain/storagev2/leveldb/leveldb_test.go @@ -166,7 +166,7 @@ func countLdbFilesInPath(path string) int { func generateBlocks(t *testing.T, count int, ch chan *types.FullBlock, ctx context.Context) { t.Helper() - ticker := time.NewTicker(time.Second) + ticker := time.NewTicker(100 * time.Millisecond) for i := 1; i <= count; i++ { b := generateBlock(t, uint64(i)) diff --git a/blockchain/storagev2/mdbx/batch.go b/blockchain/storagev2/mdbx/batch.go new file mode 100644 index 0000000000..553276e16c --- /dev/null +++ b/blockchain/storagev2/mdbx/batch.go @@ -0,0 +1,46 @@ +//nolint:errcheck +package mdbx + +import ( + "runtime" + + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/erigontech/mdbx-go/mdbx" +) + +type batchMdbx struct { + tx *mdbx.Txn + dbi [storagev2.MAX_TABLES]mdbx.DBI +} + +func newBatchMdbx(db *MdbxDB) *batchMdbx { + runtime.LockOSThread() + + tx, err := db.env.BeginTxn(nil, 0) + if err != nil { + return nil + } + + return &batchMdbx{ + tx: tx, + dbi: db.dbi, + } +} + +func (b *batchMdbx) Put(t uint8, k []byte, v []byte) { + if t&storagev2.GIDLID_INDEX != 0 { + // Random write + b.tx.Put(b.dbi[t], k, v, mdbx.NoDupData) + } else { + // Sequential write + b.tx.Put(b.dbi[t], k, v, mdbx.Append) // Append at the end + } +} + +func (b *batchMdbx) Write() error { + defer runtime.UnlockOSThread() + + _, err := b.tx.Commit() + + return err +} diff --git a/blockchain/storagev2/mdbx/mdbx.go b/blockchain/storagev2/mdbx/mdbx.go new file mode 100644 index 0000000000..180e5f8ef7 --- /dev/null +++ b/blockchain/storagev2/mdbx/mdbx.go @@ -0,0 +1,190 @@ +package mdbx + +import ( + "os" + + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/erigontech/mdbx-go/mdbx" + "github.com/hashicorp/go-hclog" +) + +type MdbxOpts struct { + // must be in the range from 12.5% (almost empty) to 50% (half empty) + // which corresponds to the range from 8192 and to 32768 in units respectively + + // log log.Logger + // roTxsLimiter *semaphore.Weighted + // bucketsCfg TableCfgFunc + path string + // syncPeriod time.Duration + // mapSize datasize.ByteSize + // growthStep datasize.ByteSize + // shrinkThreshold int + flags uint + // pageSize uint64 + // dirtySpace uint64 // if exeed this space, modified pages will `spill` to disk + // mergeThreshold uint64 + // verbosity kv.DBVerbosityLvl +} + +// MdbxDB is the mdbx implementation of the kv storage +type MdbxDB struct { + env *mdbx.Env + dbi [storagev2.MAX_TABLES]mdbx.DBI +} + +var tableMapper = map[uint8]string{ + storagev2.BODY: "Body", + storagev2.CANONICAL: "Canonical", + storagev2.DIFFICULTY: "Difficulty", + storagev2.HEADER: "Header", + storagev2.RECEIPTS: "Receipts", + storagev2.FORK: "Fork", + storagev2.HEAD_HASH: "HeadHash", + storagev2.HEAD_NUMBER: "HeadNumber", + storagev2.BLOCK_LOOKUP: "BlockLookup", + storagev2.TX_LOOKUP: "TxLookup", +} + +// NewMdbxStorage creates the new storage reference for mdbx database +func NewMdbxStorage(path string, logger hclog.Logger) (*storagev2.Storage, error) { + var dbs [2]storagev2.Database + + // Set default options + opts := &MdbxOpts{ + path: path, + } + + env, err := mdbx.NewEnv() + if err != nil { + return nil, err + } + + if err = env.SetOption(mdbx.OptMaxDB, uint64(storagev2.MAX_TABLES)); err != nil { + return nil, err + } + + if err = env.SetGeometry(-1, -1, 2*1024*1024*1024*1024, 2*1024*1024*1024, -1, int(defaultPageSize())); err != nil { + return nil, err + } + + err = env.Open(opts.path, opts.flags, 0664) + if err != nil { + return nil, err + } + + db := &MdbxDB{ + env: env, + } + + if err := db.openDBI(0); err != nil { + return nil, err + } + + dbs[0] = db + dbs[1] = nil + + return storagev2.Open(logger.Named("mdbx"), dbs) +} + +func defaultPageSize() uint64 { + osPageSize := os.Getpagesize() + if osPageSize < 4096 { // reduce further may lead to errors (because some data is just big) + osPageSize = 4096 + } else if osPageSize > mdbx.MaxPageSize { + osPageSize = mdbx.MaxPageSize + } + + osPageSize = osPageSize / 4096 * 4096 // ensure it's rounded + + return uint64(osPageSize) +} + +func (db *MdbxDB) view(f func(tx *mdbx.Txn) error) (err error) { + // can't use db.env.View method - because it calls commit for read transactions - it conflicts with write transactions. + tx, err := db.env.BeginTxn(nil, mdbx.Readonly) + if err != nil { + return err + } + + return f(tx) +} + +func (db *MdbxDB) update(f func(tx *mdbx.Txn) error) (err error) { + tx, err := db.env.BeginTxn(nil, 0) + if err != nil { + return err + } + + err = f(tx) + if err != nil { + return err + } + + _, err = tx.Commit() + if err != nil { + return err + } + + return nil +} + +func (db *MdbxDB) openDBI(flags uint) error { + if flags&mdbx.Accede != 0 { + return db.view(func(tx *mdbx.Txn) error { + for i, name := range tableMapper { + dbi, err := tx.OpenDBISimple(name, mdbx.Accede) + if err == nil { + db.dbi[i] = dbi + } else { + return err + } + } + + return nil + }) + } + + err := db.update(func(tx *mdbx.Txn) error { + for i, name := range tableMapper { + dbi, err := tx.OpenDBISimple(name, mdbx.Create) + if err == nil { + db.dbi[i] = dbi + } else { + return err + } + } + + return nil + }) + + return err +} + +// Get retrieves the key-value pair in mdbx storage +func (db *MdbxDB) Get(t uint8, k []byte) ([]byte, error) { + tx, err := db.env.BeginTxn(nil, mdbx.Readonly) + defer tx.Abort() + + if err != nil { + return nil, err + } + + v, err := tx.Get(db.dbi[t], k) + if err != nil { + return nil, err + } + + return v, nil +} + +// Close closes the mdbx storage instance +func (db *MdbxDB) Close() error { + db.env.Close() + + return nil +} + +func (db *MdbxDB) NewBatch() storagev2.Batch { + return newBatchMdbx(db) +} diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go new file mode 100644 index 0000000000..5142d5a060 --- /dev/null +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -0,0 +1,229 @@ +package mdbx + +import ( + "math/big" + "math/rand" + "os" + "testing" + "time" + + "github.com/0xPolygon/polygon-edge/blockchain" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/0xPolygon/polygon-edge/types" + "github.com/bradhe/stopwatch" + "github.com/hashicorp/go-hclog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func createTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { + t.Helper() + + txs := make([]*types.Transaction, count) + + for i := range txs { + tx := types.NewTx(&types.MixedTxn{ + Gas: types.StateTransactionGasLimit, + Nonce: uint64(startNonce + i), + From: from, + To: to, + Value: big.NewInt(2000), + Type: types.DynamicFeeTx, + GasFeeCap: big.NewInt(100), + GasTipCap: big.NewInt(10), + }) + + txs[i] = tx + } + + return txs +} + +const letterBytes = "abcdef0123456789" + +func randStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + + return string(b) +} + +func createBlock(t *testing.T) *types.FullBlock { + t.Helper() + + transactionsCount := 2500 + status := types.ReceiptSuccess + addr1 := types.StringToAddress("17878aa") + addr2 := types.StringToAddress("2bf5653") + b := &types.FullBlock{ + Block: &types.Block{ + Header: &types.Header{ + Number: 0, + ExtraData: make([]byte, 32), + Hash: types.ZeroHash, + }, + Transactions: createTxs(t, 0, transactionsCount, addr1, &addr2), + Uncles: blockchain.NewTestHeaders(10), + }, + Receipts: make([]*types.Receipt, transactionsCount), + } + + logs := make([]*types.Log, 10) + + for i := 0; i < 10; i++ { + logs[i] = &types.Log{ + Address: addr1, + Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, + Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, + } + } + + for i := 0; i < len(b.Block.Transactions); i++ { + b.Receipts[i] = &types.Receipt{ + TxHash: b.Block.Transactions[i].Hash(), + Root: types.StringToHash("mockhashstring"), + TransactionType: types.LegacyTx, + GasUsed: uint64(100000), + Status: &status, + Logs: logs, + CumulativeGasUsed: uint64(100000), + ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, + } + } + + for i := 0; i < 5; i++ { + b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) + } + + return b +} + +func openStorage(t *testing.T, p string) (*storagev2.Storage, func(), string) { + t.Helper() + + s, err := NewMdbxStorage(p, hclog.NewNullLogger()) + require.NoError(t, err) + + closeFn := func() { + require.NoError(t, s.Close()) + + if err := s.Close(); err != nil { + t.Fatal(err) + } + + require.NoError(t, os.RemoveAll(p)) + } + + return s, closeFn, p +} + +func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock { + t.Helper() + + var addr types.Address + + b.Block.Header.Number = num + b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) + + for i := range b.Block.Transactions { + addr = types.StringToAddress(randStringBytes(8)) + b.Block.Transactions[i].SetTo(&addr) + b.Block.Transactions[i].ComputeHash() + b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() + } + // big := new(big.Int) + // big.SetInt64(int64(num)) + // b.Block.Header.Hash = types.BytesToHash(big.Bytes()) + + b.Block.Header.ComputeHash() + + return b +} + +func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *storagev2.Writer { + t.Helper() + + batchWriter := s.NewWriter() + + // GidLid 'sorted' + batchWriter.PutHeadHash(b.Block.Header.Hash) + batchWriter.PutHeadNumber(b.Block.Number()) + batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) + + for _, tx := range b.Block.Transactions { + batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) + } + + // Main DB sorted + batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) + batchWriter.PutHeader(b.Block.Header) + batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + + return batchWriter +} + +func TestWriteBlockPerf(t *testing.T) { + t.SkipNow() + + s, _, path := openStorage(t, "/tmp/mdbx-test") + defer s.Close() + + var watchTime int + + count := 10000 + b := createBlock(t) + + for i := 1; i <= count; i++ { + updateBlock(t, uint64(i), b) + batchWriter := prepareBatch(t, s, b) + + watch := stopwatch.Start() + + if err := batchWriter.WriteBatch(); err != nil { + require.NoError(t, err) + } + + watch.Stop() + watchTime = watchTime + int(watch.Milliseconds()) + } + + time.Sleep(time.Second) + + size := dbSize(t, path) + t.Logf("\tdb size %d MB", size/(1024*1024)) + t.Logf("\ttotal WriteBatch %d ms", watchTime) +} + +func TestReadBlockPerf(t *testing.T) { + t.SkipNow() + + s, _, _ := openStorage(t, "/tmp/mdbx-test") + defer s.Close() + + var watchTime int + + count := 1000 + for i := 1; i <= count; i++ { + n := uint64(1 + rand.Intn(10000)) + + watch := stopwatch.Start() + _, err1 := s.ReadBody(n) + h, err2 := s.ReadCanonicalHash(n) + _, err3 := s.ReadHeader(n) + _, err4 := s.ReadReceipts(n) + b, err5 := s.ReadBlockLookup(h) + + watch.Stop() + watchTime = watchTime + int(watch.Milliseconds()) + + if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil { + t.Logf("\terror") + } + + assert.Equal(t, n, b) + } + t.Logf("\ttotal read %d ms", watchTime) +} diff --git a/blockchain/storagev2/mdbx/mdbx_test.go b/blockchain/storagev2/mdbx/mdbx_test.go new file mode 100644 index 0000000000..c874e2df57 --- /dev/null +++ b/blockchain/storagev2/mdbx/mdbx_test.go @@ -0,0 +1,246 @@ +package mdbx + +import ( + "context" + "crypto/rand" + "math/big" + "os" + "os/signal" + "path/filepath" + "strings" + "syscall" + "testing" + "time" + + "github.com/0xPolygon/polygon-edge/blockchain" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/0xPolygon/polygon-edge/types" + "github.com/hashicorp/go-hclog" + "github.com/stretchr/testify/require" +) + +func newStorage(t *testing.T) (*storagev2.Storage, func()) { + t.Helper() + + path, err := os.MkdirTemp("/tmp", "minimal_storage") + if err != nil { + t.Fatal(err) + } + + s, err := NewMdbxStorage(path, hclog.NewNullLogger()) + if err != nil { + t.Fatal(err) + } + + closeFn := func() { + if err := s.Close(); err != nil { + t.Fatal(err) + } + + if err := os.RemoveAll(path); err != nil { + t.Fatal(err) + } + } + + return s, closeFn +} + +func TestStorage(t *testing.T) { + storagev2.TestStorage(t, newStorage) +} + +func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { + t.Helper() + + txs := make([]*types.Transaction, count) + + for i := range txs { + tx := types.NewTx(&types.MixedTxn{ + Gas: types.StateTransactionGasLimit, + Nonce: uint64(startNonce + i), + From: from, + To: to, + Value: big.NewInt(2000), + Type: types.DynamicFeeTx, + GasFeeCap: big.NewInt(100), + GasTipCap: big.NewInt(10), + }) + + input := make([]byte, 1000) + _, err := rand.Read(input) + + require.NoError(t, err) + + tx.ComputeHash() + + txs[i] = tx + } + + return txs +} + +func generateBlock(t *testing.T, num uint64) *types.FullBlock { + t.Helper() + + transactionsCount := 2500 + status := types.ReceiptSuccess + addr1 := types.StringToAddress("17878aa") + addr2 := types.StringToAddress("2bf5653") + b := &types.FullBlock{ + Block: &types.Block{ + Header: &types.Header{ + Number: num, + ExtraData: make([]byte, 32), + Hash: types.ZeroHash, + }, + Transactions: generateTxs(t, 0, transactionsCount, addr1, &addr2), + Uncles: blockchain.NewTestHeaders(10), + }, + Receipts: make([]*types.Receipt, transactionsCount), + } + + logs := make([]*types.Log, 10) + + for i := 0; i < 10; i++ { + logs[i] = &types.Log{ + Address: addr1, + Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, + Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, + } + } + + for i := 0; i < len(b.Block.Transactions); i++ { + b.Receipts[i] = &types.Receipt{ + TxHash: b.Block.Transactions[i].Hash(), + Root: types.StringToHash("mockhashstring"), + TransactionType: types.LegacyTx, + GasUsed: uint64(100000), + Status: &status, + Logs: logs, + CumulativeGasUsed: uint64(100000), + ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, + } + } + + for i := 0; i < 5; i++ { + b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) + } + + return b +} + +func newStorageP(t *testing.T) (*storagev2.Storage, func(), string) { + t.Helper() + + p, err := os.MkdirTemp("", "mdbx-test") + require.NoError(t, err) + + require.NoError(t, os.MkdirAll(p, 0755)) + + s, err := NewMdbxStorage(p, hclog.NewNullLogger()) + require.NoError(t, err) + + closeFn := func() { + require.NoError(t, s.Close()) + + if err := s.Close(); err != nil { + t.Fatal(err) + } + + require.NoError(t, os.RemoveAll(p)) + } + + return s, closeFn, p +} + +func generateBlocks(t *testing.T, count int, ch chan *types.FullBlock, ctx context.Context) { + t.Helper() + + ticker := time.NewTicker(100 * time.Millisecond) + + for i := 1; i <= count; i++ { + b := generateBlock(t, uint64(i)) + select { + case <-ctx.Done(): + close(ch) + ticker.Stop() + + return + case <-ticker.C: + ch <- b + } + } +} + +func dbSize(t *testing.T, path string) int64 { + t.Helper() + + var size int64 + + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + t.Fail() + } + + if info != nil && !info.IsDir() && strings.Contains(info.Name(), ".dat") { + size += info.Size() + } + + return err + }) + if err != nil { + t.Log(err) + } + + return size +} + +func TestWriteFullBlock(t *testing.T) { + s, _, path := newStorageP(t) + defer s.Close() + + count := 100 + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*45) + + signchan := make(chan os.Signal, 1) + signal.Notify(signchan, syscall.SIGINT) + + go func() { + <-signchan + cancel() + }() + + blockchain := make(chan *types.FullBlock, 1) + go generateBlocks(t, count, blockchain, ctx) + +insertloop: + for i := 1; i <= count; i++ { + select { + case <-ctx.Done(): + break insertloop + case b := <-blockchain: + batchWriter := s.NewWriter() + + batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + + for _, tx := range b.Block.Transactions { + batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) + } + + batchWriter.PutHeader(b.Block.Header) + batchWriter.PutHeadNumber(uint64(i)) + batchWriter.PutHeadHash(b.Block.Header.Hash) + batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash()) + + if err := batchWriter.WriteBatch(); err != nil { + require.NoError(t, err) + } + + t.Logf("writing block %d", i) + + size := dbSize(t, path) + t.Logf("\tdir size %d MBs", size/1_000_000) + } + } +} diff --git a/blockchain/storagev2/storage.go b/blockchain/storagev2/storage.go index 64dc284534..38a62a659f 100644 --- a/blockchain/storagev2/storage.go +++ b/blockchain/storagev2/storage.go @@ -45,13 +45,17 @@ const ( TX_LOOKUP = uint8(8) | GIDLID_INDEX ) +const MAX_TABLES = uint8(20) + // Database indexes const ( MAINDB_INDEX = uint8(0) GIDLID_INDEX = uint8(1) ) -var EMPTY = []byte{} // Empty key +var FORK_KEY = []byte("0000000f") +var HEAD_HASH_KEY = []byte("0000000h") +var HEAD_NUMBER_KEY = []byte("0000000n") func Open(logger hclog.Logger, db [2]Database) (*Storage, error) { return &Storage{logger: logger, db: db}, nil diff --git a/blockchain/storagev2/storage_read.go b/blockchain/storagev2/storage_read.go index 94dab9ecbd..35a10e0442 100644 --- a/blockchain/storagev2/storage_read.go +++ b/blockchain/storagev2/storage_read.go @@ -25,7 +25,7 @@ func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, error) { // ReadHeadHash returns the hash of the head func (s *Storage) ReadHeadHash() (types.Hash, error) { - data, err := s.get(HEAD_HASH, EMPTY) + data, err := s.get(HEAD_HASH, HEAD_HASH_KEY) if err != nil { return types.Hash{}, err } @@ -35,7 +35,7 @@ func (s *Storage) ReadHeadHash() (types.Hash, error) { // ReadHeadNumber returns the number of the head func (s *Storage) ReadHeadNumber() (uint64, error) { - data, err := s.get(HEAD_NUMBER, EMPTY) + data, err := s.get(HEAD_NUMBER, HEAD_NUMBER_KEY) if err != nil { return 0, err } @@ -52,7 +52,7 @@ func (s *Storage) ReadHeadNumber() (uint64, error) { // ReadForks read the current forks func (s *Storage) ReadForks() ([]types.Hash, error) { forks := &Forks{} - err := s.readRLP(FORK, EMPTY, forks) + err := s.readRLP(FORK, FORK_KEY, forks) return *forks, err } diff --git a/blockchain/storagev2/storage_write.go b/blockchain/storagev2/storage_write.go index a8ee422b74..fcdcd355d5 100644 --- a/blockchain/storagev2/storage_write.go +++ b/blockchain/storagev2/storage_write.go @@ -16,11 +16,11 @@ func (w *Writer) PutBody(bn uint64, body *types.Body) { } func (w *Writer) PutHeadHash(h types.Hash) { - w.putIntoTable(HEAD_HASH, EMPTY, h.Bytes()) + w.putIntoTable(HEAD_HASH, HEAD_HASH_KEY, h.Bytes()) } func (w *Writer) PutHeadNumber(bn uint64) { - w.putIntoTable(HEAD_NUMBER, EMPTY, common.EncodeUint64ToBytes(bn)) + w.putIntoTable(HEAD_NUMBER, HEAD_NUMBER_KEY, common.EncodeUint64ToBytes(bn)) } func (w *Writer) PutTxLookup(hash types.Hash, bn uint64) { @@ -54,7 +54,7 @@ func (w *Writer) PutTotalDifficulty(bn uint64, diff *big.Int) { func (w *Writer) PutForks(forks []types.Hash) { fs := Forks(forks) - w.putRlp(FORK, EMPTY, &fs) + w.putRlp(FORK, FORK_KEY, &fs) } func (w *Writer) putRlp(t uint8, k []byte, raw types.RLPMarshaler) { diff --git a/go.mod b/go.mod index 03c14f5d81..ecedcc0779 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/docker/docker v24.0.9+incompatible github.com/docker/go-connections v0.5.0 github.com/envoyproxy/protoc-gen-validate v1.0.4 + github.com/erigontech/mdbx-go v0.37.1 github.com/golang/protobuf v1.5.3 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.1 diff --git a/go.sum b/go.sum index 3c5709d667..b247f6da72 100644 --- a/go.sum +++ b/go.sum @@ -157,6 +157,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +github.com/erigontech/mdbx-go v0.37.1 h1:Z4gxQrsHds+TcyQYvuEeu4Tia90I9xrrO6iduSfzRXg= +github.com/erigontech/mdbx-go v0.37.1/go.mod h1:FAMxbOgqOnRDx51j8HjuJZIgznbDwjX7LItd+/UWyA4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= From a81b56e8486039b458cf67837326a0992518d5ff Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Thu, 22 Feb 2024 20:48:16 +0100 Subject: [PATCH 09/48] Return bool for some storage Read methods --- blockchain/storagev2/leveldb/leveldb.go | 10 ++- .../storagev2/leveldb/leveldb_perf_test.go | 4 +- blockchain/storagev2/mdbx/mdbx.go | 14 ++-- blockchain/storagev2/mdbx/mdbx_perf_test.go | 4 +- blockchain/storagev2/storage.go | 7 +- blockchain/storagev2/storage_read.go | 66 ++++++++++--------- blockchain/storagev2/testing.go | 28 ++++---- 7 files changed, 74 insertions(+), 59 deletions(-) diff --git a/blockchain/storagev2/leveldb/leveldb.go b/blockchain/storagev2/leveldb/leveldb.go index bb852c6be0..3140079b43 100644 --- a/blockchain/storagev2/leveldb/leveldb.go +++ b/blockchain/storagev2/leveldb/leveldb.go @@ -71,16 +71,20 @@ func openLevelDBStorage(path string, options *opt.Options) (*leveldb.DB, error) } // Get retrieves the key-value pair in leveldb storage -func (l *levelDB) Get(t uint8, k []byte) ([]byte, error) { +func (l *levelDB) Get(t uint8, k []byte) ([]byte, bool, error) { mc := tableMapper[t] k = append(k, mc...) data, err := l.db.Get(k, nil) if err != nil { - return nil, err + if err.Error() == "leveldb: not found" { + return nil, false, nil + } + + return nil, false, err } - return data, nil + return data, true, nil } // Close closes the leveldb storage instance diff --git a/blockchain/storagev2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go index 0b73bd20ba..6a558e0851 100644 --- a/blockchain/storagev2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -236,7 +236,7 @@ func TestReadBlockPerf(t *testing.T) { watch := stopwatch.Start() _, err1 := s.ReadBody(n) - h, err2 := s.ReadCanonicalHash(n) + h, ok := s.ReadCanonicalHash(n) _, err3 := s.ReadHeader(n) _, err4 := s.ReadReceipts(n) b, err5 := s.ReadBlockLookup(h) @@ -244,7 +244,7 @@ func TestReadBlockPerf(t *testing.T) { watch.Stop() watchTime = watchTime + int(watch.Milliseconds()) - if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil { + if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") } diff --git a/blockchain/storagev2/mdbx/mdbx.go b/blockchain/storagev2/mdbx/mdbx.go index 180e5f8ef7..eb00551384 100644 --- a/blockchain/storagev2/mdbx/mdbx.go +++ b/blockchain/storagev2/mdbx/mdbx.go @@ -162,20 +162,24 @@ func (db *MdbxDB) openDBI(flags uint) error { } // Get retrieves the key-value pair in mdbx storage -func (db *MdbxDB) Get(t uint8, k []byte) ([]byte, error) { +func (db *MdbxDB) Get(t uint8, k []byte) ([]byte, bool, error) { tx, err := db.env.BeginTxn(nil, mdbx.Readonly) defer tx.Abort() if err != nil { - return nil, err + return nil, false, err } - v, err := tx.Get(db.dbi[t], k) + data, err := tx.Get(db.dbi[t], k) if err != nil { - return nil, err + if err.Error() == "key not found" { + return nil, false, nil + } + + return nil, false, err } - return v, nil + return data, true, nil } // Close closes the mdbx storage instance diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go index 5142d5a060..ca5b313647 100644 --- a/blockchain/storagev2/mdbx/mdbx_perf_test.go +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -211,7 +211,7 @@ func TestReadBlockPerf(t *testing.T) { watch := stopwatch.Start() _, err1 := s.ReadBody(n) - h, err2 := s.ReadCanonicalHash(n) + h, ok := s.ReadCanonicalHash(n) _, err3 := s.ReadHeader(n) _, err4 := s.ReadReceipts(n) b, err5 := s.ReadBlockLookup(h) @@ -219,7 +219,7 @@ func TestReadBlockPerf(t *testing.T) { watch.Stop() watchTime = watchTime + int(watch.Milliseconds()) - if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil { + if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") } diff --git a/blockchain/storagev2/storage.go b/blockchain/storagev2/storage.go index 38a62a659f..b480bc04b2 100644 --- a/blockchain/storagev2/storage.go +++ b/blockchain/storagev2/storage.go @@ -2,13 +2,15 @@ package storagev2 import ( + "fmt" + "github.com/hashicorp/go-hclog" ) // Database interface. type Database interface { Close() error - Get(t uint8, k []byte) ([]byte, error) + Get(t uint8, k []byte) ([]byte, bool, error) NewBatch() Batch } @@ -57,6 +59,9 @@ var FORK_KEY = []byte("0000000f") var HEAD_HASH_KEY = []byte("0000000h") var HEAD_NUMBER_KEY = []byte("0000000n") +var ErrNotFound = fmt.Errorf("not found") +var ErrInvalidData = fmt.Errorf("invalid data") + func Open(logger hclog.Logger, db [2]Database) (*Storage, error) { return &Storage{logger: logger, db: db}, nil } diff --git a/blockchain/storagev2/storage_read.go b/blockchain/storagev2/storage_read.go index 35a10e0442..1ff2b01740 100644 --- a/blockchain/storagev2/storage_read.go +++ b/blockchain/storagev2/storage_read.go @@ -1,8 +1,6 @@ -//nolint:stylecheck package storagev2 import ( - "errors" "math/big" "github.com/0xPolygon/polygon-edge/helper/common" @@ -12,39 +10,39 @@ import ( // -- canonical hash -- // ReadCanonicalHash gets the hash from the number of the canonical chain -func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, error) { - data, err := s.get(CANONICAL, common.EncodeUint64ToBytes(n)) - if err != nil { - return types.Hash{}, err +func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, bool) { + data, ok := s.get(CANONICAL, common.EncodeUint64ToBytes(n)) + if !ok { + return types.Hash{}, false } - return types.BytesToHash(data), nil + return types.BytesToHash(data), true } // HEAD // // ReadHeadHash returns the hash of the head -func (s *Storage) ReadHeadHash() (types.Hash, error) { - data, err := s.get(HEAD_HASH, HEAD_HASH_KEY) - if err != nil { - return types.Hash{}, err +func (s *Storage) ReadHeadHash() (types.Hash, bool) { + data, ok := s.get(HEAD_HASH, HEAD_HASH_KEY) + if !ok { + return types.Hash{}, false } - return types.BytesToHash(data), nil + return types.BytesToHash(data), true } // ReadHeadNumber returns the number of the head -func (s *Storage) ReadHeadNumber() (uint64, error) { - data, err := s.get(HEAD_NUMBER, HEAD_NUMBER_KEY) - if err != nil { - return 0, err +func (s *Storage) ReadHeadNumber() (uint64, bool) { + data, ok := s.get(HEAD_NUMBER, HEAD_NUMBER_KEY) + if !ok { + return 0, false } if len(data) != 8 { - return 0, errors.New("Invalid data") + return 0, false } - return common.EncodeBytesToUint64(data), nil + return common.EncodeBytesToUint64(data), true } // FORK // @@ -60,13 +58,13 @@ func (s *Storage) ReadForks() ([]types.Hash, error) { // DIFFICULTY // // ReadTotalDifficulty reads the difficulty -func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, error) { - v, err := s.get(DIFFICULTY, common.EncodeUint64ToBytes(bn)) - if err != nil { - return nil, err +func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, bool) { + v, ok := s.get(DIFFICULTY, common.EncodeUint64ToBytes(bn)) + if !ok { + return nil, false } - return big.NewInt(0).SetBytes(v), nil + return big.NewInt(0).SetBytes(v), true } // HEADER // @@ -126,25 +124,29 @@ func (s *Storage) ReadBlockLookup(hash types.Hash) (uint64, error) { } func (s *Storage) readLookup(t uint8, hash types.Hash) (uint64, error) { - data, err := s.get(t, hash.Bytes()) - if err != nil { - return 0, err + data, ok := s.get(t, hash.Bytes()) + if !ok { + return 0, ErrNotFound } if len(data) != 8 { - return 0, errors.New("Invalid data") + return 0, ErrInvalidData } return common.EncodeBytesToUint64(data), nil } func (s *Storage) readRLP(t uint8, k []byte, raw types.RLPUnmarshaler) error { - data, err := s.getDB(t).Get(t, k) + data, ok, err := s.getDB(t).Get(t, k) if err != nil { return err } + if !ok { + return ErrNotFound + } + if obj, ok := raw.(types.RLPStoreUnmarshaler); ok { // decode in the store format if err := obj.UnmarshalStoreRLP(data); err != nil { @@ -160,14 +162,14 @@ func (s *Storage) readRLP(t uint8, k []byte, raw types.RLPUnmarshaler) error { return nil } -func (s *Storage) get(t uint8, k []byte) ([]byte, error) { - data, err := s.getDB(t).Get(t, k) +func (s *Storage) get(t uint8, k []byte) ([]byte, bool) { + data, ok, err := s.getDB(t).Get(t, k) if err != nil { - return nil, err + return nil, false } - return data, nil + return data, ok } func (s *Storage) getDB(t uint8) Database { diff --git a/blockchain/storagev2/testing.go b/blockchain/storagev2/testing.go index 3bf1acd65a..c64c47886c 100644 --- a/blockchain/storagev2/testing.go +++ b/blockchain/storagev2/testing.go @@ -92,8 +92,8 @@ func testCanonicalChain(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) - data, err := s.ReadCanonicalHash(cc.Number) - assert.NoError(t, err) + data, ok := s.ReadCanonicalHash(cc.Number) + assert.True(t, ok) if !reflect.DeepEqual(data, hash) { t.Fatal("not match") @@ -134,8 +134,8 @@ func testDifficulty(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) - diff, err := s.ReadTotalDifficulty(h.Number) - assert.NoError(t, err) + diff, ok := s.ReadTotalDifficulty(h.Number) + assert.True(t, ok) if !reflect.DeepEqual(cc.Diff, diff) { t.Fatal("bad") @@ -164,15 +164,15 @@ func testHead(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) - n2, err := s.ReadHeadNumber() - assert.NoError(t, err) + n2, ok := s.ReadHeadNumber() + assert.True(t, ok) if n2 != i { t.Fatal("bad") } - hash1, err := s.ReadHeadHash() - assert.NoError(t, err) + hash1, ok := s.ReadHeadHash() + assert.True(t, ok) if !reflect.DeepEqual(hash1, hash) { t.Fatal("bad") @@ -407,22 +407,22 @@ func testWriteCanonicalHeader(t *testing.T, m PlaceholderStorage) { t.Fatal("bad header") } - headHash, err := s.ReadHeadHash() - assert.NoError(t, err) + headHash, ok := s.ReadHeadHash() + assert.True(t, ok) if headHash != h.Hash { t.Fatal("head hash not correct") } - headNum, err := s.ReadHeadNumber() - assert.NoError(t, err) + headNum, ok := s.ReadHeadNumber() + assert.True(t, ok) if headNum != h.Number { t.Fatal("head num not correct") } - canHash, err := s.ReadCanonicalHash(h.Number) - assert.NoError(t, err) + canHash, ok := s.ReadCanonicalHash(h.Number) + assert.True(t, ok) if canHash != h.Hash { t.Fatal("canonical hash not correct") From 215b0896b3d57849b0af79f1edaa30a5c026e9ed Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Fri, 23 Feb 2024 09:35:26 +0100 Subject: [PATCH 10/48] e2e storage test --- e2e-polybft/e2e/storage_test.go | 189 ++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 e2e-polybft/e2e/storage_test.go diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go new file mode 100644 index 0000000000..b4bde540a6 --- /dev/null +++ b/e2e-polybft/e2e/storage_test.go @@ -0,0 +1,189 @@ +package e2e + +import ( + "math/big" + "reflect" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/jsonrpc" + "github.com/umbracle/ethgo/wallet" + + "github.com/0xPolygon/polygon-edge/consensus/polybft" + "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" + "github.com/0xPolygon/polygon-edge/types" +) + +type txObject struct { + bNumber uint64 + txHash ethgo.Hash + to ethgo.Address +} + +func TestE2E_Storage(t *testing.T) { + // premine an account in the genesis file + sender, err := wallet.GenerateKey() + require.NoError(t, err) + + cluster := framework.NewTestCluster(t, 5, + framework.WithPremine(types.Address(sender.Address())), + framework.WithBurnContract(&polybft.BurnContractInfo{BlockNumber: 0, Address: types.ZeroAddress}), + ) + defer cluster.Stop() + + cluster.WaitForReady(t) + + client := cluster.Servers[0].JSONRPC().Eth() + + num := 20 + + receivers := []ethgo.Address{} + + for i := 0; i < num; i++ { + key, err := wallet.GenerateKey() + require.NoError(t, err) + + receivers = append(receivers, key.Address()) + } + + var wg sync.WaitGroup + + txs := []txObject{} + + for i := 0; i < num; i++ { + wg.Add(1) + + func(i int, to ethgo.Address) { + defer wg.Done() + + txn := ðgo.Transaction{ + From: sender.Address(), + To: &to, + Gas: 30000, // enough to send a transfer + Value: big.NewInt(int64(i)), + Nonce: uint64(i), + } + + // Send every second transaction as a dynamic fees one + if i%2 == 0 { + txn.Type = ethgo.TransactionDynamicFee + txn.MaxFeePerGas = big.NewInt(1000000000) + txn.MaxPriorityFeePerGas = big.NewInt(100000000) + } else { + txn.Type = ethgo.TransactionLegacy + txn.GasPrice = ethgo.Gwei(2).Uint64() + } + + bn, th := sendTx(t, client, sender, txn) + txs = append(txs, txObject{bNumber: bn, txHash: th, to: to}) + }(i, receivers[i]) + } + + wg.Wait() + + err = cluster.WaitUntil(2*time.Minute, 2*time.Second, func() bool { + for i, receiver := range receivers { + balance, err := client.GetBalance(receiver, ethgo.Latest) + if err != nil { + return true + } + + t.Logf("Balance %s %s", receiver, balance) + + if balance.Uint64() != uint64(i) { + return false + } + } + + return true + }) + require.NoError(t, err) + + checkStorage(t, txs, client) +} + +// sendTx is a helper function which signs transaction with provided private key and sends it +func sendTx(t *testing.T, client *jsonrpc.Eth, sender *wallet.Key, txn *ethgo.Transaction) (uint64, ethgo.Hash) { + t.Helper() + + chainID, err := client.ChainID() + require.NoError(t, err) + + if txn.Type == ethgo.TransactionDynamicFee { + txn.ChainID = chainID + } + + signer := wallet.NewEIP155Signer(chainID.Uint64()) + signedTxn, err := signer.SignTx(txn, sender) + require.NoError(t, err) + + txnRaw, err := signedTxn.MarshalRLPTo(nil) + require.NoError(t, err) + + h, err := client.SendRawTransaction(txnRaw) + require.NoError(t, err) + + bn, err := client.BlockNumber() + require.NoError(t, err) + + return bn, h +} + +func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { + t.Helper() + + for i, tx := range txs { + bn, err := client.GetBlockByNumber(ethgo.BlockNumber(tx.bNumber), true) + require.NoError(t, err) + assert.NotNil(t, bn) + + bh, err := client.GetBlockByHash(bn.Hash, true) + require.NoError(t, err) + assert.NotNil(t, bh) + + if !reflect.DeepEqual(bn, bh) { + t.Fatal("blocks dont match") + } + + bt, err := client.GetTransactionByHash(tx.txHash) + require.NoError(t, err) + assert.NotNil(t, bt) + assert.Equal(t, uint64(i), bt.Value.Uint64()) + assert.Equal(t, uint64(30000), bt.Gas) + assert.Equal(t, uint64(i), bt.Nonce) + assert.Equal(t, uint64(i), bt.TxnIndex) + assert.NotEmpty(t, bt.V) + assert.NotEmpty(t, bt.R) + assert.NotEmpty(t, bt.S) + + if !reflect.DeepEqual(tx.to, *bt.To) { + t.Fatal("tx to dont match") + } + + if i%2 == 0 { + assert.Equal(t, ethgo.TransactionDynamicFee, bt.Type) + assert.Equal(t, uint64(0), bt.GasPrice) + assert.NotNil(t, bt.ChainID) + } else { + assert.Equal(t, ethgo.TransactionLegacy, bt.Type) + assert.Equal(t, ethgo.Gwei(2).Uint64(), bt.GasPrice) + } + + r, err := client.GetTransactionReceipt(tx.txHash) + require.NoError(t, err) + assert.NotNil(t, r) + assert.Equal(t, bt.TxnIndex, r.TransactionIndex) + assert.Equal(t, bt.Hash, r.TransactionHash) + assert.Equal(t, bt.BlockHash, r.BlockHash) + assert.Equal(t, bt.BlockNumber, r.BlockNumber) + assert.NotEmpty(t, r.LogsBloom) + + if !reflect.DeepEqual(*bt.To, *r.To) { + t.Fatal("receipt to dont match") + } + } +} From febecbb95a76b17e05ace6911df1ebcd2d6c7a5c Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Fri, 23 Feb 2024 19:12:46 +0100 Subject: [PATCH 11/48] storage replaced with storagev2 --- blockchain/blockchain.go | 80 +++++--- blockchain/blockchain_test.go | 217 ++++++++++++--------- blockchain/storagev2/memory/batch.go | 29 +++ blockchain/storagev2/memory/memory.go | 48 +++++ blockchain/storagev2/memory/memory_test.go | 26 +++ blockchain/storagev2/storage_write.go | 1 + blockchain/storagev2/testing.go | 1 + blockchain/testing.go | 12 +- command/regenesis/test_on_history.go | 11 +- jsonrpc/debug_endpoint.go | 2 +- jsonrpc/debug_endpoint_test.go | 40 ++-- jsonrpc/eth_blockchain_test.go | 6 +- jsonrpc/eth_endpoint.go | 18 +- jsonrpc/helper.go | 8 +- jsonrpc/helper_test.go | 30 +-- server/server.go | 10 +- 16 files changed, 357 insertions(+), 182 deletions(-) create mode 100644 blockchain/storagev2/memory/batch.go create mode 100644 blockchain/storagev2/memory/memory.go create mode 100644 blockchain/storagev2/memory/memory_test.go diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index e9749db955..3c1fa856f9 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -7,7 +7,7 @@ import ( "sync" "sync/atomic" - "github.com/0xPolygon/polygon-edge/blockchain/storage" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/state" @@ -44,7 +44,7 @@ var ( type Blockchain struct { logger hclog.Logger // The logger object - db storage.Storage // The Storage object (database) + db *storagev2.Storage // The Storage object (database) consensus Verifier executor Executor txSigner TxSigner @@ -188,7 +188,7 @@ func (b *Blockchain) GetAvgGasPrice() *big.Int { // NewBlockchain creates a new blockchain object func NewBlockchain( logger hclog.Logger, - db storage.Storage, + db *storagev2.Storage, genesisConfig *chain.Chain, consensus Verifier, executor Executor, @@ -398,7 +398,7 @@ func (b *Blockchain) writeGenesis(genesis *chain.Genesis) error { // writeGenesisImpl writes the genesis file to the DB + blockchain reference func (b *Blockchain) writeGenesisImpl(header *types.Header) error { - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() newTD := new(big.Int).SetUint64(header.Difficulty) @@ -438,9 +438,14 @@ func (b *Blockchain) GetTD(hash types.Hash) (*big.Int, bool) { return b.readTotalDifficulty(hash) } -// GetReceiptsByHash returns the receipts by their hash +// GetReceiptsByHash returns the receipts by block hash func (b *Blockchain) GetReceiptsByHash(hash types.Hash) ([]*types.Receipt, error) { - return b.db.ReadReceipts(hash) + n, err := b.db.ReadBlockLookup(hash) + if err != nil { + return nil, err + } + + return b.db.ReadReceipts(n) } // GetBodyByHash returns the body by their hash @@ -468,7 +473,12 @@ func (b *Blockchain) readHeader(hash types.Hash) (*types.Header, bool) { } // Cache miss, load it from the DB - hh, err := b.db.ReadHeader(hash) + n, err := b.db.ReadBlockLookup(hash) + if err != nil { + return nil, false + } + + hh, err := b.db.ReadHeader(n) if err != nil { return nil, false } @@ -482,7 +492,12 @@ func (b *Blockchain) readHeader(hash types.Hash) (*types.Header, bool) { // readBody reads the block's body, using the block hash func (b *Blockchain) readBody(hash types.Hash) (*types.Body, bool) { - bb, err := b.db.ReadBody(hash) + n, err := b.db.ReadBlockLookup(hash) + if err != nil { + return nil, false + } + + bb, err := b.db.ReadBody(n) if err != nil { b.logger.Error("failed to read body", "err", err) @@ -491,9 +506,9 @@ func (b *Blockchain) readBody(hash types.Hash) (*types.Body, bool) { // To return from field in the transactions of the past blocks if updated := b.recoverFromFieldsInTransactions(bb.Transactions); updated { - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() - batchWriter.PutBody(hash, bb) + batchWriter.PutBody(n, bb) if err := batchWriter.WriteBatch(); err != nil { b.logger.Warn("failed to write body into storage", "hash", hash, "err", err) @@ -518,7 +533,12 @@ func (b *Blockchain) readTotalDifficulty(headerHash types.Hash) (*big.Int, bool) } // Miss, read the difficulty from the DB - dbDifficulty, ok := b.db.ReadTotalDifficulty(headerHash) + n, err := b.db.ReadBlockLookup(headerHash) + if err != nil { + return nil, false + } + + dbDifficulty, ok := b.db.ReadTotalDifficulty(n) if !ok { return nil, false } @@ -573,7 +593,7 @@ func (b *Blockchain) WriteHeadersWithBodies(headers []*types.Header) error { for _, header := range headers { event := &Event{} - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() isCanonical, newTD, err := b.writeHeaderImpl(batchWriter, event, header) if err != nil { @@ -811,7 +831,7 @@ func (b *Blockchain) WriteFullBlock(fblock *types.FullBlock, source string) erro header := block.Header - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() if err := b.writeBody(batchWriter, block); err != nil { return err @@ -828,7 +848,7 @@ func (b *Blockchain) WriteFullBlock(fblock *types.FullBlock, source string) erro // write the receipts, do it only after the header has been written. // Otherwise, a client might ask for a header once the receipt is valid, // but before it is written into the storage - batchWriter.PutReceipts(block.Hash(), fblock.Receipts) + batchWriter.PutReceipts(block.Number(), fblock.Receipts) // update snapshot if err := b.consensus.ProcessHeaders([]*types.Header{header}); err != nil { @@ -876,7 +896,7 @@ func (b *Blockchain) WriteBlock(block *types.Block, source string) error { header := block.Header - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() if err := b.writeBody(batchWriter, block); err != nil { return err @@ -899,7 +919,7 @@ func (b *Blockchain) WriteBlock(block *types.Block, source string) error { // write the receipts, do it only after the header has been written. // Otherwise, a client might ask for a header once the receipt is valid, // but before it is written into the storage - batchWriter.PutReceipts(block.Hash(), blockReceipts) + batchWriter.PutReceipts(block.Number(), blockReceipts) // update snapshot if err := b.consensus.ProcessHeaders([]*types.Header{header}); err != nil { @@ -990,7 +1010,7 @@ func (b *Blockchain) updateGasPriceAvgWithBlock(block *types.Block) { // writeBody writes the block body to the DB. // Additionally, it also updates the txn lookup, for txnHash -> block lookups -func (b *Blockchain) writeBody(batchWriter *storage.BatchWriter, block *types.Block) error { +func (b *Blockchain) writeBody(batchWriter *storagev2.Writer, block *types.Block) error { // Recover 'from' field in tx before saving // Because the block passed from the consensus layer doesn't have from field in tx, // due to missing encoding in RLP @@ -999,21 +1019,24 @@ func (b *Blockchain) writeBody(batchWriter *storage.BatchWriter, block *types.Bl } // Write the full body (txns + receipts) - batchWriter.PutBody(block.Header.Hash, block.Body()) + batchWriter.PutBody(block.Number(), block.Body()) - // Write txn lookups (txHash -> block) + // Write txn lookups (txHash -> block number) for _, txn := range block.Transactions { - batchWriter.PutTxLookup(txn.Hash(), block.Hash()) + batchWriter.PutTxLookup(txn.Hash(), block.Number()) } return nil } // ReadTxLookup returns the block hash using the transaction hash -func (b *Blockchain) ReadTxLookup(hash types.Hash) (types.Hash, bool) { - v, ok := b.db.ReadTxLookup(hash) +func (b *Blockchain) ReadTxLookup(hash types.Hash) (uint64, bool) { + v, err := b.db.ReadTxLookup(hash) + if err != nil { + return 0, false + } - return v, ok + return v, true } // recoverFromFieldsInBlock recovers 'from' fields in the transactions of the given block @@ -1140,7 +1163,7 @@ func (b *Blockchain) dispatchEvent(evnt *Event) { // writeHeaderImpl writes a block and the data, assumes the genesis is already set // Returning parameters (is canonical header, new total difficulty, error) func (b *Blockchain) writeHeaderImpl( - batchWriter *storage.BatchWriter, evnt *Event, header *types.Header) (bool, *big.Int, error) { + batchWriter *storagev2.Writer, evnt *Event, header *types.Header) (bool, *big.Int, error) { // parent total difficulty of incoming header parentTD, ok := b.readTotalDifficulty(header.ParentHash) if !ok { @@ -1188,8 +1211,9 @@ func (b *Blockchain) writeHeaderImpl( } batchWriter.PutHeader(header) - batchWriter.PutTotalDifficulty(header.Hash, incomingTD) + batchWriter.PutTotalDifficulty(header.Number, incomingTD) batchWriter.PutForks(forks) + batchWriter.PutBlockLookup(header.Hash, header.Number) // new block has lower difficulty, create a new fork evnt.AddOldHeader(header) @@ -1202,7 +1226,7 @@ func (b *Blockchain) writeHeaderImpl( func (b *Blockchain) getForksToWrite(header *types.Header) ([]types.Hash, error) { forks, err := b.db.ReadForks() if err != nil { - if errors.Is(err, storage.ErrNotFound) { + if errors.Is(err, storagev2.ErrNotFound) { forks = []types.Hash{} } else { return nil, err @@ -1222,7 +1246,7 @@ func (b *Blockchain) getForksToWrite(header *types.Header) ([]types.Hash, error) // handleReorg handles a reorganization event func (b *Blockchain) handleReorg( - batchWriter *storage.BatchWriter, + batchWriter *storagev2.Writer, evnt *Event, oldHeader *types.Header, newHeader *types.Header, @@ -1414,7 +1438,7 @@ func (b *Blockchain) calcBaseFeeDelta(gasUsedDelta, parentGasTarget, baseFee uin } func (b *Blockchain) writeBatchAndUpdate( - batchWriter *storage.BatchWriter, + batchWriter *storagev2.Writer, header *types.Header, newTD *big.Int, isCanonnical bool) error { diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 567e605944..b2bb0e116d 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -14,7 +14,6 @@ import ( "time" "github.com/0xPolygon/polygon-edge/helper/common" - "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/state" "github.com/hashicorp/go-hclog" lru "github.com/hashicorp/golang-lru" @@ -23,9 +22,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/0xPolygon/polygon-edge/blockchain/storage" - "github.com/0xPolygon/polygon-edge/blockchain/storage/leveldb" - "github.com/0xPolygon/polygon-edge/blockchain/storage/memory" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2/leveldb" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2/memory" "github.com/0xPolygon/polygon-edge/types" ) @@ -502,7 +501,7 @@ func TestInsertHeaders(t *testing.T) { assert.Equal(t, head.Hash, expected.Hash) forks, err := b.GetForks() - if err != nil && !errors.Is(err, storage.ErrNotFound) { + if err != nil && !errors.Is(err, storagev2.ErrNotFound) { t.Fatal(err) } @@ -546,7 +545,7 @@ func TestForkUnknownParents(t *testing.T) { h1 := AppendNewTestHeaders(h0[:5], 10) // Write genesis - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() td := new(big.Int).SetUint64(h0[0].Difficulty) batchWriter.PutCanonicalHeader(h0[0], td) @@ -574,7 +573,7 @@ func TestBlockchainWriteBody(t *testing.T) { ) *Blockchain { t.Helper() - dbStorage, err := memory.NewMemoryStorage(nil) + dbStorage, err := memory.NewMemoryStorage() assert.NoError(t, err) chain := &Blockchain{ @@ -610,7 +609,7 @@ func TestBlockchainWriteBody(t *testing.T) { chain := newChain(t, txFromByTxHash, "t1") defer chain.db.Close() - batchWriter := storage.NewBatchWriter(chain.db) + batchWriter := chain.db.NewWriter() assert.NoError( t, @@ -641,7 +640,7 @@ func TestBlockchainWriteBody(t *testing.T) { chain := newChain(t, txFromByTxHash, "t2") defer chain.db.Close() - batchWriter := storage.NewBatchWriter(chain.db) + batchWriter := chain.db.NewWriter() assert.ErrorIs( t, @@ -675,8 +674,9 @@ func TestBlockchainWriteBody(t *testing.T) { chain := newChain(t, txFromByTxHash, "t3") defer chain.db.Close() - batchWriter := storage.NewBatchWriter(chain.db) + batchWriter := chain.db.NewWriter() + batchWriter.PutBlockLookup(block.Hash(), block.Number()) batchWriter.PutHeader(block.Header) assert.NoError(t, chain.writeBody(batchWriter, block)) @@ -884,7 +884,7 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) { } func TestBlockchainReadBody(t *testing.T) { - dbStorage, err := memory.NewMemoryStorage(nil) + dbStorage, err := memory.NewMemoryStorage() assert.NoError(t, err) txFromByTxHash := make(map[types.Hash]types.Address) @@ -898,7 +898,7 @@ func TestBlockchainReadBody(t *testing.T) { }, } - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() tx := types.NewTx(&types.MixedTxn{ Value: big.NewInt(10), @@ -973,13 +973,20 @@ func TestCalculateGasLimit(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - storageCallback := func(storage *storage.MockStorage) { - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return &types.Header{ - // This is going to be the parent block header - GasLimit: tt.parentGasLimit, - }, nil - }) + storageCallback := func(storage *storagev2.Storage) { + h := &types.Header{ + // This is going to be the parent block header + GasLimit: tt.parentGasLimit, + } + h.ComputeHash() + + w := storage.NewWriter() + + w.PutBlockLookup(h.Hash, h.Number) + w.PutHeader(h) + w.PutCanonicalHash(h.Number, h.Hash) + err := w.WriteBatch() + require.NoError(t, err) } b, blockchainErr := NewMockBlockchain(map[TestCallbackType]interface{}{ @@ -1075,16 +1082,7 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { t.Run("Missing parent block", func(t *testing.T) { t.Parallel() - // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return nil, errors.New("not found") - }) - } - - blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{ - StorageCallback: storageCallback, - }) + blockchain, err := NewMockBlockchain(nil) if err != nil { t.Fatalf("unable to instantiate new blockchain, %v", err) } @@ -1103,10 +1101,15 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { t.Parallel() // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return emptyHeader.Copy(), nil - }) + storageCallback := func(storage *storagev2.Storage) { + h := emptyHeader + + w := storage.NewWriter() + + w.PutBlockLookup(types.ZeroHash, h.Number) + w.PutHeader(h) + err := w.WriteBatch() + require.NoError(t, err) } blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{ @@ -1129,10 +1132,15 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { t.Parallel() // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return emptyHeader.Copy(), nil - }) + storageCallback := func(storage *storagev2.Storage) { + h := emptyHeader + + w := storage.NewWriter() + + w.PutBlockLookup(types.ZeroHash, h.Number) + w.PutHeader(h) + err := w.WriteBatch() + require.NoError(t, err) } blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{ @@ -1156,10 +1164,15 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { t.Parallel() // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return emptyHeader.Copy(), nil - }) + storageCallback := func(storage *storagev2.Storage) { + h := emptyHeader + + w := storage.NewWriter() + + w.PutBlockLookup(h.Hash, h.Number) + w.PutHeader(h) + err := w.WriteBatch() + require.NoError(t, err) } blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{ @@ -1187,10 +1200,15 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { parentHeader.GasLimit = 5000 // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return emptyHeader.Copy(), nil - }) + storageCallback := func(storage *storagev2.Storage) { + h := emptyHeader + + w := storage.NewWriter() + + w.PutBlockLookup(types.ZeroHash, h.Number) + w.PutHeader(h) + err := w.WriteBatch() + require.NoError(t, err) } blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{ @@ -1261,16 +1279,7 @@ func TestBlockchain_VerifyBlockBody(t *testing.T) { t.Run("Invalid execution result - missing parent", func(t *testing.T) { t.Parallel() - // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return nil, errors.New("not found") - }) - } - - blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{ - StorageCallback: storageCallback, - }) + blockchain, err := NewMockBlockchain(nil) if err != nil { t.Fatalf("unable to instantiate new blockchain, %v", err) } @@ -1292,11 +1301,15 @@ func TestBlockchain_VerifyBlockBody(t *testing.T) { errBlockCreatorNotFound := errors.New("not found") // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - // This is used for parent fetching - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return emptyHeader.Copy(), nil - }) + storageCallback := func(storage *storagev2.Storage) { + h := emptyHeader + + w := storage.NewWriter() + + w.PutBlockLookup(types.ZeroHash, h.Number) + w.PutHeader(h) + err := w.WriteBatch() + require.NoError(t, err) } // Set up the verifier callback @@ -1332,11 +1345,15 @@ func TestBlockchain_VerifyBlockBody(t *testing.T) { errUnableToExecute := errors.New("unable to execute transactions") // Set up the storage callback - storageCallback := func(storage *storage.MockStorage) { - // This is used for parent fetching - storage.HookReadHeader(func(hash types.Hash) (*types.Header, error) { - return emptyHeader.Copy(), nil - }) + storageCallback := func(storage *storagev2.Storage) { + h := emptyHeader + + w := storage.NewWriter() + + w.PutBlockLookup(types.ZeroHash, h.Number) + w.PutHeader(h) + err := w.WriteBatch() + require.NoError(t, err) } executorCallback := func(executor *mockExecutor) { @@ -1554,10 +1571,6 @@ func TestBlockchain_CalculateBaseFee(t *testing.T) { func TestBlockchain_WriteFullBlock(t *testing.T) { t.Parallel() - getKey := func(p []byte, k []byte) []byte { - return append(append(make([]byte, 0, len(p)+len(k)), p...), k...) - } - db := map[string][]byte{} consensusMock := &MockVerifier{ processHeadersFn: func(hs []*types.Header) error { assert.Len(t, hs, 1) @@ -1566,10 +1579,7 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { }, } - storageMock := storage.NewMockStorage() - storageMock.HookNewBatch(func() storage.Batch { - return memory.NewBatchMemory(db) - }) + storageMock, _ := memory.NewMemoryStorage() bc := &Blockchain{ gpAverage: &gasPriceAverage{ @@ -1611,6 +1621,7 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { existingHeader.ComputeHash() bc.currentHeader.Store(existingHeader) bc.currentDifficulty.Store(existingTD) + bc.difficultyCache.Add(existingHeader.Hash, existingTD) header.ParentHash = existingHeader.Hash bc.txSigner = &mockSigner{ @@ -1629,10 +1640,15 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { }, "polybft") require.NoError(t, err) - require.Equal(t, 0, len(db)) - require.Equal(t, uint64(1), bc.currentHeader.Load().Number) + require.Equal(t, existingHeader.Number, bc.currentHeader.Load().Number) + require.Equal(t, existingTD, bc.currentDifficulty.Load()) + require.True(t, bc.difficultyCache.Contains(existingHeader.Hash)) - // already existing block write + _, err = bc.db.ReadBlockLookup(existingHeader.Hash) + require.Error(t, err) + assert.ErrorIs(t, err, storagev2.ErrNotFound) + + // new block write err = bc.WriteFullBlock(&types.FullBlock{ Block: &types.Block{ Header: header, @@ -1642,16 +1658,39 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { }, "polybft") require.NoError(t, err) - require.Equal(t, 8, len(db)) - require.Equal(t, uint64(2), bc.currentHeader.Load().Number) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.BODY, header.Hash.Bytes()))]) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.TX_LOOKUP_PREFIX, tx.Hash().Bytes()))]) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.HEADER, header.Hash.Bytes()))]) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.HEAD, storage.HASH))]) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.CANONICAL, common.EncodeUint64ToBytes(header.Number)))]) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.DIFFICULTY, header.Hash.Bytes()))]) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.CANONICAL, common.EncodeUint64ToBytes(header.Number)))]) - require.NotNil(t, db[hex.EncodeToHex(getKey(storage.RECEIPTS, header.Hash.Bytes()))]) + require.Equal(t, header.Number, bc.currentHeader.Load().Number) + + n, err := bc.db.ReadBlockLookup(header.Hash) + require.NoError(t, err) + require.Equal(t, header.Number, n) + + b, err := bc.db.ReadBody(header.Number) + require.NoError(t, err) + require.NotNil(t, b) + + l, err := bc.db.ReadTxLookup(tx.Hash()) + require.NoError(t, err) + require.Equal(t, header.Number, l) + + h, err := bc.db.ReadHeader(header.Number) + require.NoError(t, err) + require.NotNil(t, h) + + hh, ok := bc.db.ReadHeadHash() + require.True(t, ok) + require.Equal(t, header.Hash, hh) + + ch, ok := bc.db.ReadCanonicalHash(header.Number) + require.True(t, ok) + require.Equal(t, header.Hash, ch) + + td, ok := bc.db.ReadTotalDifficulty(header.Number) + require.True(t, ok) + require.NotNil(t, td) + + r, err := bc.db.ReadReceipts(header.Number) + require.NoError(t, err) + require.NotNil(t, r) } func TestDiskUsageWriteBatchAndUpdate(t *testing.T) { @@ -1759,7 +1798,7 @@ func blockWriter(tb testing.TB, numberOfBlocks uint64, blockTime, checkInterval for { <-blockTicker.C - batchWriter := storage.NewBatchWriter(db) + batchWriter := db.NewWriter() block.Block.Header.Number = counter.GetValue() block.Block.Header.Hash = types.StringToHash(fmt.Sprintf("%d", counter.GetValue())) @@ -1771,9 +1810,9 @@ func blockWriter(tb testing.TB, numberOfBlocks uint64, blockTime, checkInterval } batchWriter.PutHeader(block.Block.Header) - batchWriter.PutBody(block.Block.Hash(), block.Block.Body()) + batchWriter.PutBody(block.Block.Number(), block.Block.Body()) - batchWriter.PutReceipts(block.Block.Hash(), receipts) + batchWriter.PutReceipts(block.Block.Number(), receipts) require.NoError(tb, blockchain.writeBatchAndUpdate(batchWriter, block.Block.Header, big.NewInt(0), false)) diff --git a/blockchain/storagev2/memory/batch.go b/blockchain/storagev2/memory/batch.go new file mode 100644 index 0000000000..dd60cc668e --- /dev/null +++ b/blockchain/storagev2/memory/batch.go @@ -0,0 +1,29 @@ +package memory + +import ( + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/0xPolygon/polygon-edge/helper/hex" +) + +type batchMemory struct { + db []memoryKV + valuesToPut [storagev2.MAX_TABLES][][2][]byte +} + +func newBatchMemory(db []memoryKV) *batchMemory { + return &batchMemory{db: db} +} + +func (b *batchMemory) Put(t uint8, k []byte, v []byte) { + b.valuesToPut[t] = append(b.valuesToPut[t], [2][]byte{k, v}) +} + +func (b *batchMemory) Write() error { + for i, j := range b.valuesToPut { + for _, x := range j { + b.db[i].kv[hex.EncodeToHex(x[0])] = x[1] + } + } + + return nil +} diff --git a/blockchain/storagev2/memory/memory.go b/blockchain/storagev2/memory/memory.go new file mode 100644 index 0000000000..8e719d4a51 --- /dev/null +++ b/blockchain/storagev2/memory/memory.go @@ -0,0 +1,48 @@ +package memory + +import ( + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/0xPolygon/polygon-edge/helper/hex" +) + +type memoryKV struct { + kv map[string][]byte +} +type memoryDB struct { + db []memoryKV +} + +// NewMemoryStorage creates the new storage reference with inmemory +func NewMemoryStorage() (*storagev2.Storage, error) { + var ldbs [2]storagev2.Database + + kvs := []memoryKV{} + + for i := 0; uint8(i) < storagev2.MAX_TABLES; i++ { + kvs = append(kvs, memoryKV{kv: map[string][]byte{}}) + } + + db := &memoryDB{db: kvs} + + ldbs[0] = db + ldbs[1] = nil + + return storagev2.Open(nil, ldbs) +} + +func (m *memoryDB) Get(t uint8, k []byte) ([]byte, bool, error) { + v, ok := m.db[t].kv[hex.EncodeToHex(k)] + if !ok { + return nil, false, nil + } + + return v, true, nil +} + +func (m *memoryDB) Close() error { + return nil +} + +func (m *memoryDB) NewBatch() storagev2.Batch { + return newBatchMemory(m.db) +} diff --git a/blockchain/storagev2/memory/memory_test.go b/blockchain/storagev2/memory/memory_test.go new file mode 100644 index 0000000000..f3ef02d618 --- /dev/null +++ b/blockchain/storagev2/memory/memory_test.go @@ -0,0 +1,26 @@ +package memory + +import ( + "testing" + + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" +) + +func TestStorage(t *testing.T) { + t.Helper() + + f := func(t *testing.T) (*storagev2.Storage, func()) { + t.Helper() + + s, err := NewMemoryStorage() + + if err != nil { + t.Logf("\t Error opening MemoryDB -> %s", err.Error()) + + return nil, func() {} + } + + return s, func() {} + } + storagev2.TestStorage(t, f) +} diff --git a/blockchain/storagev2/storage_write.go b/blockchain/storagev2/storage_write.go index fcdcd355d5..36834abcab 100644 --- a/blockchain/storagev2/storage_write.go +++ b/blockchain/storagev2/storage_write.go @@ -40,6 +40,7 @@ func (w *Writer) PutCanonicalHeader(h *types.Header, diff *big.Int) { w.PutHeader(h) w.PutHeadHash(h.Hash) w.PutHeadNumber(h.Number) + w.PutBlockLookup(h.Hash, h.Number) w.PutCanonicalHash(h.Number, h.Hash) w.PutTotalDifficulty(h.Number, diff) } diff --git a/blockchain/storagev2/testing.go b/blockchain/storagev2/testing.go index c64c47886c..bac7ab30c7 100644 --- a/blockchain/storagev2/testing.go +++ b/blockchain/storagev2/testing.go @@ -130,6 +130,7 @@ func testDifficulty(t *testing.T, m PlaceholderStorage) { } batch.PutHeader(h) + batch.PutBlockLookup(h.Hash, h.Number) batch.PutTotalDifficulty(h.Number, cc.Diff) require.NoError(t, batch.WriteBatch()) diff --git a/blockchain/testing.go b/blockchain/testing.go index 94b5f4eb43..761577ed83 100644 --- a/blockchain/testing.go +++ b/blockchain/testing.go @@ -6,8 +6,8 @@ import ( "math/big" "testing" - "github.com/0xPolygon/polygon-edge/blockchain/storage" - "github.com/0xPolygon/polygon-edge/blockchain/storage/memory" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2/memory" "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/state" @@ -117,7 +117,7 @@ func NewTestBlockchain(t *testing.T, headers []*types.Header) *Blockchain { } if len(headers) > 0 { - batchWriter := storage.NewBatchWriter(b.db) + batchWriter := b.db.NewWriter() td := new(big.Int).SetUint64(headers[0].Difficulty) batchWriter.PutCanonicalHeader(headers[0], td) @@ -159,7 +159,7 @@ func NewMockBlockchain( Forks: chain.AllForksEnabled, }, } - mockStorage = storage.NewMockStorage() + mockStorage, _ = memory.NewMemoryStorage() ) // Set up the mocks and callbacks @@ -196,7 +196,7 @@ func NewMockBlockchain( // Execute the storage callback if storageCallback, ok := callbackMap[StorageCallback]; ok { - callback, ok := storageCallback.(func(storage *storage.MockStorage)) + callback, ok := storageCallback.(func(storage *storagev2.Storage)) if !ok { return nil, errInvalidTypeAssertion } @@ -358,7 +358,7 @@ func newBlockChain(config *chain.Chain, executor Executor) (*Blockchain, error) executor = &mockExecutor{} } - db, err := memory.NewMemoryStorage(nil) + db, err := memory.NewMemoryStorage() if err != nil { return nil, err } diff --git a/command/regenesis/test_on_history.go b/command/regenesis/test_on_history.go index 1572116c58..9fef4311eb 100644 --- a/command/regenesis/test_on_history.go +++ b/command/regenesis/test_on_history.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - leveldb2 "github.com/0xPolygon/polygon-edge/blockchain/storage/leveldb" + leveldb2 "github.com/0xPolygon/polygon-edge/blockchain/storagev2/leveldb" "github.com/0xPolygon/polygon-edge/command" itrie "github.com/0xPolygon/polygon-edge/state/immutable-trie" "github.com/0xPolygon/polygon-edge/types" @@ -83,7 +83,14 @@ func HistoryTestCmd() *cobra.Command { return } - header, err := st.ReadHeader(canonicalHash) + bn, err := st.ReadBlockLookup(canonicalHash) + if err != nil { + outputter.SetError(fmt.Errorf("can't read block lookup %w", err)) + + return + } + + header, err := st.ReadHeader(bn) if !ok { outputter.SetError(fmt.Errorf("can't read header %w", err)) diff --git a/jsonrpc/debug_endpoint.go b/jsonrpc/debug_endpoint.go index 1c853b7c1f..d36038e623 100644 --- a/jsonrpc/debug_endpoint.go +++ b/jsonrpc/debug_endpoint.go @@ -34,7 +34,7 @@ type debugBlockchainStore interface { GetHeaderByNumber(uint64) (*types.Header, bool) // ReadTxLookup returns a block hash in which a given txn was mined - ReadTxLookup(txnHash types.Hash) (types.Hash, bool) + ReadTxLookup(txnHash types.Hash) (uint64, bool) // GetBlockByHash gets a block using the provided hash GetBlockByHash(hash types.Hash, full bool) (*types.Block, bool) diff --git a/jsonrpc/debug_endpoint_test.go b/jsonrpc/debug_endpoint_test.go index f6e9d1603d..25880e0006 100644 --- a/jsonrpc/debug_endpoint_test.go +++ b/jsonrpc/debug_endpoint_test.go @@ -18,7 +18,7 @@ import ( type debugEndpointMockStore struct { headerFn func() *types.Header getHeaderByNumberFn func(uint64) (*types.Header, bool) - readTxLookupFn func(types.Hash) (types.Hash, bool) + readTxLookupFn func(types.Hash) (uint64, bool) getBlockByHashFn func(types.Hash, bool) (*types.Block, bool) getBlockByNumberFn func(uint64, bool) (*types.Block, bool) traceBlockFn func(*types.Block, tracer.Tracer) ([]interface{}, error) @@ -36,7 +36,7 @@ func (s *debugEndpointMockStore) GetHeaderByNumber(num uint64) (*types.Header, b return s.getHeaderByNumberFn(num) } -func (s *debugEndpointMockStore) ReadTxLookup(txnHash types.Hash) (types.Hash, bool) { +func (s *debugEndpointMockStore) ReadTxLookup(txnHash types.Hash) (uint64, bool) { return s.readTxLookupFn(txnHash) } @@ -452,13 +452,13 @@ func TestTraceTransaction(t *testing.T) { txHash: testTxHash1, config: &TraceConfig{}, store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTxHash1, hash) - return testBlock10.Hash(), true + return testBlock10.Number(), true }, - getBlockByHashFn: func(hash types.Hash, full bool) (*types.Block, bool) { - assert.Equal(t, testBlock10.Hash(), hash) + getBlockByNumberFn: func(number uint64, full bool) (*types.Block, bool) { + assert.Equal(t, testBlock10.Number(), number) assert.True(t, full) return blockWithTx, true @@ -478,10 +478,10 @@ func TestTraceTransaction(t *testing.T) { txHash: testTxHash1, config: &TraceConfig{}, store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTxHash1, hash) - return types.ZeroHash, false + return 0, false }, }, result: nil, @@ -492,13 +492,13 @@ func TestTraceTransaction(t *testing.T) { txHash: testTxHash1, config: &TraceConfig{}, store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTxHash1, hash) - return testBlock10.Hash(), true + return testBlock10.Number(), true }, - getBlockByHashFn: func(hash types.Hash, full bool) (*types.Block, bool) { - assert.Equal(t, testBlock10.Hash(), hash) + getBlockByNumberFn: func(number uint64, full bool) (*types.Block, bool) { + assert.Equal(t, testBlock10.Number(), number) assert.True(t, full) return nil, false @@ -512,13 +512,13 @@ func TestTraceTransaction(t *testing.T) { txHash: testTxHash1, config: &TraceConfig{}, store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTxHash1, hash) - return testBlock10.Hash(), true + return testBlock10.Number(), true }, - getBlockByHashFn: func(hash types.Hash, full bool) (*types.Block, bool) { - assert.Equal(t, testBlock10.Hash(), hash) + getBlockByNumberFn: func(number uint64, full bool) (*types.Block, bool) { + assert.Equal(t, testBlock10.Number(), number) assert.True(t, full) return testBlock10, true @@ -532,13 +532,13 @@ func TestTraceTransaction(t *testing.T) { txHash: testTxHash1, config: &TraceConfig{}, store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTxHash1, hash) - return testBlock10.Hash(), true + return testBlock10.Number(), true }, - getBlockByHashFn: func(hash types.Hash, full bool) (*types.Block, bool) { - assert.Equal(t, testBlock10.Hash(), hash) + getBlockByNumberFn: func(number uint64, full bool) (*types.Block, bool) { + assert.Equal(t, testBlock10.Number(), number) assert.True(t, full) return &types.Block{ diff --git a/jsonrpc/eth_blockchain_test.go b/jsonrpc/eth_blockchain_test.go index 807a0eaf6b..061072a824 100644 --- a/jsonrpc/eth_blockchain_test.go +++ b/jsonrpc/eth_blockchain_test.go @@ -586,16 +586,16 @@ func (m *mockBlockStore) Header() *types.Header { return m.blocks[len(m.blocks)-1].Header } -func (m *mockBlockStore) ReadTxLookup(txnHash types.Hash) (types.Hash, bool) { +func (m *mockBlockStore) ReadTxLookup(txnHash types.Hash) (uint64, bool) { for _, block := range m.blocks { for _, txn := range block.Transactions { if txn.Hash() == txnHash { - return block.Hash(), true + return block.Number(), true } } } - return types.ZeroHash, false + return 0, false } func (m *mockBlockStore) GetPendingTx(txHash types.Hash) (*types.Transaction, bool) { diff --git a/jsonrpc/eth_endpoint.go b/jsonrpc/eth_endpoint.go index 5ca84c79d2..0871e5a487 100644 --- a/jsonrpc/eth_endpoint.go +++ b/jsonrpc/eth_endpoint.go @@ -57,7 +57,7 @@ type ethBlockchainStore interface { GetBlockByNumber(num uint64, full bool) (*types.Block, bool) // ReadTxLookup returns a block hash in which a given txn was mined - ReadTxLookup(txnHash types.Hash) (types.Hash, bool) + ReadTxLookup(txnHash types.Hash) (uint64, bool) // GetReceiptsByHash returns the receipts for a block hash GetReceiptsByHash(hash types.Hash) ([]*types.Receipt, error) @@ -230,13 +230,13 @@ func (e *Eth) GetTransactionByHash(hash types.Hash) (interface{}, error) { // for the transaction with the provided hash findSealedTx := func() *transaction { // Check the chain state for the transaction - blockHash, ok := e.store.ReadTxLookup(hash) + blockNum, ok := e.store.ReadTxLookup(hash) if !ok { // Block not found in storage return nil } - block, ok := e.store.GetBlockByHash(blockHash, true) + block, ok := e.store.GetBlockByNumber(blockNum, true) if !ok { // Block receipts not found in storage return nil @@ -289,27 +289,27 @@ func (e *Eth) GetTransactionByHash(hash types.Hash) (interface{}, error) { // GetTransactionReceipt returns a transaction receipt by his hash func (e *Eth) GetTransactionReceipt(hash types.Hash) (interface{}, error) { - blockHash, ok := e.store.ReadTxLookup(hash) + blockNum, ok := e.store.ReadTxLookup(hash) if !ok { // txn not found return nil, nil } - block, ok := e.store.GetBlockByHash(blockHash, true) + block, ok := e.store.GetBlockByNumber(blockNum, true) if !ok { // block not found e.logger.Warn( - fmt.Sprintf("Block with hash [%s] not found", blockHash.String()), + fmt.Sprintf("Block with number [%d] not found", blockNum), ) return nil, nil } - receipts, err := e.store.GetReceiptsByHash(blockHash) + receipts, err := e.store.GetReceiptsByHash(block.Hash()) if err != nil { // block receipts not found e.logger.Warn( - fmt.Sprintf("Receipts for block with hash [%s] not found", blockHash.String()), + fmt.Sprintf("Receipts for block with hash [%s] not found", block.Hash().String()), ) return nil, nil @@ -318,7 +318,7 @@ func (e *Eth) GetTransactionReceipt(hash types.Hash) (interface{}, error) { if len(receipts) == 0 { // Receipts not written yet on the db e.logger.Warn( - fmt.Sprintf("No receipts found for block with hash [%s]", blockHash.String()), + fmt.Sprintf("No receipts found for block with hash [%s]", block.Hash().String()), ) return nil, nil diff --git a/jsonrpc/helper.go b/jsonrpc/helper.go index 5c220d1b58..2ae7138c35 100644 --- a/jsonrpc/helper.go +++ b/jsonrpc/helper.go @@ -74,18 +74,18 @@ func GetBlockHeader(number BlockNumber, store headerGetter) (*types.Header, erro } type txLookupAndBlockGetter interface { - ReadTxLookup(types.Hash) (types.Hash, bool) - GetBlockByHash(types.Hash, bool) (*types.Block, bool) + ReadTxLookup(types.Hash) (uint64, bool) + GetBlockByNumber(uint64, bool) (*types.Block, bool) } // GetTxAndBlockByTxHash returns the tx and the block including the tx by given tx hash func GetTxAndBlockByTxHash(txHash types.Hash, store txLookupAndBlockGetter) (*types.Transaction, *types.Block) { - blockHash, ok := store.ReadTxLookup(txHash) + blockNum, ok := store.ReadTxLookup(txHash) if !ok { return nil, nil } - block, ok := store.GetBlockByHash(blockHash, true) + block, ok := store.GetBlockByNumber(blockNum, true) if !ok { return nil, nil } diff --git a/jsonrpc/helper_test.go b/jsonrpc/helper_test.go index c63af1a47a..f55f50a34d 100644 --- a/jsonrpc/helper_test.go +++ b/jsonrpc/helper_test.go @@ -335,13 +335,13 @@ func TestGetTxAndBlockByTxHash(t *testing.T) { name: "should return tx and block", txHash: testTx1.Hash(), store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTx1.Hash(), hash) - return blockWithTx.Hash(), true + return blockWithTx.Number(), true }, - getBlockByHashFn: func(hash types.Hash, full bool) (*types.Block, bool) { - assert.Equal(t, blockWithTx.Hash(), hash) + getBlockByNumberFn: func(number uint64, full bool) (*types.Block, bool) { + assert.Equal(t, blockWithTx.Number(), number) assert.True(t, full) return blockWithTx, true @@ -354,26 +354,26 @@ func TestGetTxAndBlockByTxHash(t *testing.T) { name: "should return nil if ReadTxLookup returns nothing", txHash: testTx1.Hash(), store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTx1.Hash(), hash) - return types.ZeroHash, false + return 0, false }, }, tx: nil, block: nil, }, { - name: "should return nil if GetBlockByHash returns nothing", + name: "should return nil if GetBlockByNumber returns nothing", txHash: testTx1.Hash(), store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTx1.Hash(), hash) - return blockWithTx.Hash(), true + return blockWithTx.Number(), true }, - getBlockByHashFn: func(hash types.Hash, full bool) (*types.Block, bool) { - assert.Equal(t, blockWithTx.Hash(), hash) + getBlockByNumberFn: func(number uint64, full bool) (*types.Block, bool) { + assert.Equal(t, blockWithTx.Number(), number) assert.True(t, full) return nil, false @@ -386,13 +386,13 @@ func TestGetTxAndBlockByTxHash(t *testing.T) { name: "should return nil if the block doesn't include the tx", txHash: testTx1.Hash(), store: &debugEndpointMockStore{ - readTxLookupFn: func(hash types.Hash) (types.Hash, bool) { + readTxLookupFn: func(hash types.Hash) (uint64, bool) { assert.Equal(t, testTx1.Hash(), hash) - return blockWithTx.Hash(), true + return blockWithTx.Number(), true }, - getBlockByHashFn: func(hash types.Hash, full bool) (*types.Block, bool) { - assert.Equal(t, blockWithTx.Hash(), hash) + getBlockByNumberFn: func(number uint64, full bool) (*types.Block, bool) { + assert.Equal(t, blockWithTx.Number(), number) assert.True(t, full) return testBlock10, true diff --git a/server/server.go b/server/server.go index b4495f4181..c975809aff 100644 --- a/server/server.go +++ b/server/server.go @@ -12,9 +12,9 @@ import ( "path/filepath" "time" - "github.com/0xPolygon/polygon-edge/blockchain/storage" - "github.com/0xPolygon/polygon-edge/blockchain/storage/leveldb" - "github.com/0xPolygon/polygon-edge/blockchain/storage/memory" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2/leveldb" + "github.com/0xPolygon/polygon-edge/blockchain/storagev2/memory" consensusPolyBFT "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/forkmanager" "github.com/0xPolygon/polygon-edge/gasprice" @@ -294,10 +294,10 @@ func NewServer(config *Config) (*Server, error) { ) // create storage instance for blockchain - var db storage.Storage + var db *storagev2.Storage { if m.config.DataDir == "" { - db, err = memory.NewMemoryStorage(nil) + db, err = memory.NewMemoryStorage() if err != nil { return nil, err } From f2668fd1fa0db4b1ff47b9a5efc56f43059d8f95 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 26 Feb 2024 10:17:55 +0100 Subject: [PATCH 12/48] Merge fix --- blockchain/storage/leveldb/leveldb_perf_test.go | 5 ++--- blockchain/storagev2/leveldb/leveldb_perf_test.go | 5 ++--- blockchain/storagev2/leveldb/leveldb_test.go | 5 ++--- blockchain/storagev2/mdbx/mdbx_perf_test.go | 5 ++--- blockchain/storagev2/mdbx/mdbx_test.go | 5 ++--- blockchain/storagev2/testing.go | 6 +++--- 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go index e0631181bf..c8ab0e3924 100644 --- a/blockchain/storage/leveldb/leveldb_perf_test.go +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -23,13 +23,12 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, To: to, Value: big.NewInt(2000), - Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), }) @@ -85,7 +84,7 @@ func createBlock(t *testing.T) *types.FullBlock { b.Receipts[i] = &types.Receipt{ TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTx, + TransactionType: types.LegacyTxType, GasUsed: uint64(100000), Status: &status, Logs: logs, diff --git a/blockchain/storagev2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go index 6a558e0851..1bb75365f7 100644 --- a/blockchain/storagev2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -24,13 +24,12 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, To: to, Value: big.NewInt(2000), - Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), }) @@ -86,7 +85,7 @@ func createBlock(t *testing.T) *types.FullBlock { b.Receipts[i] = &types.Receipt{ TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTx, + TransactionType: types.LegacyTxType, GasUsed: uint64(100000), Status: &status, Logs: logs, diff --git a/blockchain/storagev2/leveldb/leveldb_test.go b/blockchain/storagev2/leveldb/leveldb_test.go index db7abe6ca4..14d2ce1911 100644 --- a/blockchain/storagev2/leveldb/leveldb_test.go +++ b/blockchain/storagev2/leveldb/leveldb_test.go @@ -54,13 +54,12 @@ func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *ty txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, To: to, Value: big.NewInt(2000), - Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), }) @@ -112,7 +111,7 @@ func generateBlock(t *testing.T, num uint64) *types.FullBlock { b.Receipts[i] = &types.Receipt{ TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTx, + TransactionType: types.LegacyTxType, GasUsed: uint64(100000), Status: &status, Logs: logs, diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go index ca5b313647..29074a6f60 100644 --- a/blockchain/storagev2/mdbx/mdbx_perf_test.go +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -22,13 +22,12 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, To: to, Value: big.NewInt(2000), - Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), }) @@ -84,7 +83,7 @@ func createBlock(t *testing.T) *types.FullBlock { b.Receipts[i] = &types.Receipt{ TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTx, + TransactionType: types.LegacyTxType, GasUsed: uint64(100000), Status: &status, Logs: logs, diff --git a/blockchain/storagev2/mdbx/mdbx_test.go b/blockchain/storagev2/mdbx/mdbx_test.go index c874e2df57..4c481e3cb5 100644 --- a/blockchain/storagev2/mdbx/mdbx_test.go +++ b/blockchain/storagev2/mdbx/mdbx_test.go @@ -55,13 +55,12 @@ func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *ty txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), From: from, To: to, Value: big.NewInt(2000), - Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), }) @@ -113,7 +112,7 @@ func generateBlock(t *testing.T, num uint64) *types.FullBlock { b.Receipts[i] = &types.Receipt{ TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTx, + TransactionType: types.LegacyTxType, GasUsed: uint64(100000), Status: &status, Logs: logs, diff --git a/blockchain/storagev2/testing.go b/blockchain/storagev2/testing.go index bac7ab30c7..d0acdbc216 100644 --- a/blockchain/storagev2/testing.go +++ b/blockchain/storagev2/testing.go @@ -261,7 +261,7 @@ func testBody(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) addr1 := types.StringToAddress("11") - t0 := types.NewTx(&types.MixedTxn{ + t0 := types.NewTx(&types.LegacyTx{ Nonce: 0, To: &addr1, Value: big.NewInt(1), @@ -273,7 +273,7 @@ func testBody(t *testing.T, m PlaceholderStorage) { t0.ComputeHash() addr2 := types.StringToAddress("22") - t1 := types.NewTx(&types.MixedTxn{ + t1 := types.NewTx(&types.LegacyTx{ Nonce: 0, To: &addr2, Value: big.NewInt(1), @@ -329,7 +329,7 @@ func testReceipts(t *testing.T, m PlaceholderStorage) { body := &types.Body{ Transactions: []*types.Transaction{ - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.StateTx{ Nonce: 1000, Gas: 50, GasPrice: new(big.Int).SetUint64(100), From fff2ad6a7036ab863a75bbd7d7f341d1d0504ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 26 Feb 2024 12:09:41 +0100 Subject: [PATCH 13/48] Reuse SendTxn from the cluster --- e2e-polybft/e2e/storage_test.go | 52 ++++++++++++--------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go index b4bde540a6..257ae9cba6 100644 --- a/e2e-polybft/e2e/storage_test.go +++ b/e2e-polybft/e2e/storage_test.go @@ -39,6 +39,9 @@ func TestE2E_Storage(t *testing.T) { client := cluster.Servers[0].JSONRPC().Eth() + chainID, err := client.ChainID() + require.NoError(t, err) + num := 20 receivers := []ethgo.Address{} @@ -61,11 +64,12 @@ func TestE2E_Storage(t *testing.T) { defer wg.Done() txn := ðgo.Transaction{ - From: sender.Address(), - To: &to, - Gas: 30000, // enough to send a transfer - Value: big.NewInt(int64(i)), - Nonce: uint64(i), + From: sender.Address(), + To: &to, + Gas: 30000, // enough to send a transfer + Value: big.NewInt(int64(i)), + Nonce: uint64(i), + ChainID: chainID, } // Send every second transaction as a dynamic fees one @@ -78,8 +82,15 @@ func TestE2E_Storage(t *testing.T) { txn.GasPrice = ethgo.Gwei(2).Uint64() } - bn, th := sendTx(t, client, sender, txn) - txs = append(txs, txObject{bNumber: bn, txHash: th, to: to}) + tx := cluster.SendTxn(t, sender, txn) + require.NoError(t, tx.Wait()) + + txs = append(txs, + txObject{ + bNumber: tx.Receipt().BlockNumber, + txHash: tx.Receipt().TransactionHash, + to: to, + }) }(i, receivers[i]) } @@ -106,33 +117,6 @@ func TestE2E_Storage(t *testing.T) { checkStorage(t, txs, client) } -// sendTx is a helper function which signs transaction with provided private key and sends it -func sendTx(t *testing.T, client *jsonrpc.Eth, sender *wallet.Key, txn *ethgo.Transaction) (uint64, ethgo.Hash) { - t.Helper() - - chainID, err := client.ChainID() - require.NoError(t, err) - - if txn.Type == ethgo.TransactionDynamicFee { - txn.ChainID = chainID - } - - signer := wallet.NewEIP155Signer(chainID.Uint64()) - signedTxn, err := signer.SignTx(txn, sender) - require.NoError(t, err) - - txnRaw, err := signedTxn.MarshalRLPTo(nil) - require.NoError(t, err) - - h, err := client.SendRawTransaction(txnRaw) - require.NoError(t, err) - - bn, err := client.BlockNumber() - require.NoError(t, err) - - return bn, h -} - func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { t.Helper() From 428f425c97648a9105c963d121bd93c77069ae50 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 26 Feb 2024 13:42:02 +0100 Subject: [PATCH 14/48] Revert "Reuse SendTxn from the cluster" This reverts commit fff2ad6a7036ab863a75bbd7d7f341d1d0504ebd. --- e2e-polybft/e2e/storage_test.go | 52 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go index 257ae9cba6..b4bde540a6 100644 --- a/e2e-polybft/e2e/storage_test.go +++ b/e2e-polybft/e2e/storage_test.go @@ -39,9 +39,6 @@ func TestE2E_Storage(t *testing.T) { client := cluster.Servers[0].JSONRPC().Eth() - chainID, err := client.ChainID() - require.NoError(t, err) - num := 20 receivers := []ethgo.Address{} @@ -64,12 +61,11 @@ func TestE2E_Storage(t *testing.T) { defer wg.Done() txn := ðgo.Transaction{ - From: sender.Address(), - To: &to, - Gas: 30000, // enough to send a transfer - Value: big.NewInt(int64(i)), - Nonce: uint64(i), - ChainID: chainID, + From: sender.Address(), + To: &to, + Gas: 30000, // enough to send a transfer + Value: big.NewInt(int64(i)), + Nonce: uint64(i), } // Send every second transaction as a dynamic fees one @@ -82,15 +78,8 @@ func TestE2E_Storage(t *testing.T) { txn.GasPrice = ethgo.Gwei(2).Uint64() } - tx := cluster.SendTxn(t, sender, txn) - require.NoError(t, tx.Wait()) - - txs = append(txs, - txObject{ - bNumber: tx.Receipt().BlockNumber, - txHash: tx.Receipt().TransactionHash, - to: to, - }) + bn, th := sendTx(t, client, sender, txn) + txs = append(txs, txObject{bNumber: bn, txHash: th, to: to}) }(i, receivers[i]) } @@ -117,6 +106,33 @@ func TestE2E_Storage(t *testing.T) { checkStorage(t, txs, client) } +// sendTx is a helper function which signs transaction with provided private key and sends it +func sendTx(t *testing.T, client *jsonrpc.Eth, sender *wallet.Key, txn *ethgo.Transaction) (uint64, ethgo.Hash) { + t.Helper() + + chainID, err := client.ChainID() + require.NoError(t, err) + + if txn.Type == ethgo.TransactionDynamicFee { + txn.ChainID = chainID + } + + signer := wallet.NewEIP155Signer(chainID.Uint64()) + signedTxn, err := signer.SignTx(txn, sender) + require.NoError(t, err) + + txnRaw, err := signedTxn.MarshalRLPTo(nil) + require.NoError(t, err) + + h, err := client.SendRawTransaction(txnRaw) + require.NoError(t, err) + + bn, err := client.BlockNumber() + require.NoError(t, err) + + return bn, h +} + func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { t.Helper() From 86094688dee7ae6805e181b111045cba8a5707a8 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 26 Feb 2024 13:55:42 +0100 Subject: [PATCH 15/48] Remove stopwatch dependency --- .../storage/leveldb/leveldb_perf_test.go | 20 ++++++++----------- .../storagev2/leveldb/leveldb_perf_test.go | 20 ++++++++----------- blockchain/storagev2/mdbx/mdbx.go | 16 +-------------- blockchain/storagev2/mdbx/mdbx_perf_test.go | 20 ++++++++----------- go.mod | 1 - go.sum | 2 -- 6 files changed, 25 insertions(+), 54 deletions(-) diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go index c8ab0e3924..7a2c2b0fd4 100644 --- a/blockchain/storage/leveldb/leveldb_perf_test.go +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -12,7 +12,6 @@ import ( "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/blockchain/storage" "github.com/0xPolygon/polygon-edge/types" - "github.com/bradhe/stopwatch" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/require" ) @@ -156,9 +155,6 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock b.Block.Transactions[i].ComputeHash() b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() } - // big := new(big.Int) - // big.SetInt64(int64(num)) - // b.Block.Header.Hash = types.BytesToHash(big.Bytes()) b.Block.Header.ComputeHash() @@ -193,7 +189,7 @@ func TestWriteBlockPerf(t *testing.T) { s, _, path := openStorage(t, "/tmp/leveldbV1-test") defer s.Close() - var watchTime int + var watchTime int64 count := 10000 b := createBlock(t) @@ -202,14 +198,14 @@ func TestWriteBlockPerf(t *testing.T) { updateBlock(t, uint64(i), b) batchWriter := prepareBatch(t, s, b) - watch := stopwatch.Start() + tn := time.Now().UTC() if err := batchWriter.WriteBatch(); err != nil { require.NoError(t, err) } - watch.Stop() - watchTime = watchTime + int(watch.Milliseconds()) + d := time.Since(tn) + watchTime = watchTime + d.Milliseconds() } time.Sleep(time.Second) @@ -225,20 +221,20 @@ func TestReadBlockPerf(t *testing.T) { s, _, _ := openStorage(t, "/tmp/leveldbV1-test") defer s.Close() - var watchTime int + var watchTime int64 count := 1000 for i := 1; i <= count; i++ { n := uint64(1 + rand.Intn(10000)) - watch := stopwatch.Start() + tn := time.Now().UTC() h, ok := s.ReadCanonicalHash(n) _, err2 := s.ReadBody(h) _, err3 := s.ReadHeader(h) _, err4 := s.ReadReceipts(h) + d := time.Since(tn) - watch.Stop() - watchTime = watchTime + int(watch.Milliseconds()) + watchTime = watchTime + d.Milliseconds() if !ok || err2 != nil || err3 != nil || err4 != nil { t.Logf("\terror") diff --git a/blockchain/storagev2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go index 1bb75365f7..b6d7de493e 100644 --- a/blockchain/storagev2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -12,7 +12,6 @@ import ( "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/0xPolygon/polygon-edge/types" - "github.com/bradhe/stopwatch" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -157,9 +156,6 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock b.Block.Transactions[i].ComputeHash() b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() } - // big := new(big.Int) - // big.SetInt64(int64(num)) - // b.Block.Header.Hash = types.BytesToHash(big.Bytes()) b.Block.Header.ComputeHash() @@ -195,7 +191,7 @@ func TestWriteBlockPerf(t *testing.T) { s, _, path := openStorage(t, "/tmp/leveldbV2-test") defer s.Close() - var watchTime int + var watchTime int64 count := 10000 b := createBlock(t) @@ -204,14 +200,14 @@ func TestWriteBlockPerf(t *testing.T) { updateBlock(t, uint64(i), b) batchWriter := prepareBatch(t, s, b) - watch := stopwatch.Start() + tn := time.Now().UTC() if err := batchWriter.WriteBatch(); err != nil { require.NoError(t, err) } - watch.Stop() - watchTime = watchTime + int(watch.Milliseconds()) + d := time.Since(tn) + watchTime = watchTime + d.Milliseconds() } time.Sleep(time.Second) @@ -227,21 +223,21 @@ func TestReadBlockPerf(t *testing.T) { s, _, _ := openStorage(t, "/tmp/leveldbV2-test") defer s.Close() - var watchTime int + var watchTime int64 count := 1000 for i := 1; i <= count; i++ { n := uint64(1 + rand.Intn(10000)) - watch := stopwatch.Start() + tn := time.Now().UTC() _, err1 := s.ReadBody(n) h, ok := s.ReadCanonicalHash(n) _, err3 := s.ReadHeader(n) _, err4 := s.ReadReceipts(n) b, err5 := s.ReadBlockLookup(h) + d := time.Since(tn) - watch.Stop() - watchTime = watchTime + int(watch.Milliseconds()) + watchTime = watchTime + d.Milliseconds() if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") diff --git a/blockchain/storagev2/mdbx/mdbx.go b/blockchain/storagev2/mdbx/mdbx.go index eb00551384..8b6e4d81be 100644 --- a/blockchain/storagev2/mdbx/mdbx.go +++ b/blockchain/storagev2/mdbx/mdbx.go @@ -9,22 +9,8 @@ import ( ) type MdbxOpts struct { - // must be in the range from 12.5% (almost empty) to 50% (half empty) - // which corresponds to the range from 8192 and to 32768 in units respectively - - // log log.Logger - // roTxsLimiter *semaphore.Weighted - // bucketsCfg TableCfgFunc - path string - // syncPeriod time.Duration - // mapSize datasize.ByteSize - // growthStep datasize.ByteSize - // shrinkThreshold int + path string flags uint - // pageSize uint64 - // dirtySpace uint64 // if exeed this space, modified pages will `spill` to disk - // mergeThreshold uint64 - // verbosity kv.DBVerbosityLvl } // MdbxDB is the mdbx implementation of the kv storage diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go index 29074a6f60..5f634690fb 100644 --- a/blockchain/storagev2/mdbx/mdbx_perf_test.go +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -10,7 +10,6 @@ import ( "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/0xPolygon/polygon-edge/types" - "github.com/bradhe/stopwatch" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -132,9 +131,6 @@ func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock b.Block.Transactions[i].ComputeHash() b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() } - // big := new(big.Int) - // big.SetInt64(int64(num)) - // b.Block.Header.Hash = types.BytesToHash(big.Bytes()) b.Block.Header.ComputeHash() @@ -170,7 +166,7 @@ func TestWriteBlockPerf(t *testing.T) { s, _, path := openStorage(t, "/tmp/mdbx-test") defer s.Close() - var watchTime int + var watchTime int64 count := 10000 b := createBlock(t) @@ -179,14 +175,14 @@ func TestWriteBlockPerf(t *testing.T) { updateBlock(t, uint64(i), b) batchWriter := prepareBatch(t, s, b) - watch := stopwatch.Start() + tn := time.Now().UTC() if err := batchWriter.WriteBatch(); err != nil { require.NoError(t, err) } - watch.Stop() - watchTime = watchTime + int(watch.Milliseconds()) + d := time.Since(tn) + watchTime = watchTime + d.Milliseconds() } time.Sleep(time.Second) @@ -202,21 +198,21 @@ func TestReadBlockPerf(t *testing.T) { s, _, _ := openStorage(t, "/tmp/mdbx-test") defer s.Close() - var watchTime int + var watchTime int64 count := 1000 for i := 1; i <= count; i++ { n := uint64(1 + rand.Intn(10000)) - watch := stopwatch.Start() + tn := time.Now().UTC() _, err1 := s.ReadBody(n) h, ok := s.ReadCanonicalHash(n) _, err3 := s.ReadHeader(n) _, err4 := s.ReadReceipts(n) b, err5 := s.ReadBlockLookup(h) + d := time.Since(tn) - watch.Stop() - watchTime = watchTime + int(watch.Milliseconds()) + watchTime = watchTime + d.Milliseconds() if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") diff --git a/go.mod b/go.mod index ecedcc0779..4364ba5100 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/Ethernal-Tech/merkle-tree v0.0.0-20231213143318-4db9da419e04 github.com/armon/go-metrics v0.4.1 github.com/aws/aws-sdk-go v1.50.8 - github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/docker/docker v24.0.9+incompatible github.com/docker/go-connections v0.5.0 diff --git a/go.sum b/go.sum index b247f6da72..e7bd17b710 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea h1:+GIgqdjrcKMHK1JqC1Bb9arFtNOGX/SWCkueobreyQU= -github.com/bradhe/stopwatch v0.0.0-20190618212248-a58cccc508ea/go.mod h1:P/j2DSP/kCOakHBACzMqmOdrTEieqdSiB3U9fqk7qgc= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= From 1a09afded9f511ebabc6081613525d9d1e3f8a59 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 26 Feb 2024 14:29:03 +0100 Subject: [PATCH 16/48] Remove assert for Legacy tx type from storage e2e test --- e2e-polybft/e2e/storage_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go index b4bde540a6..5122492f37 100644 --- a/e2e-polybft/e2e/storage_test.go +++ b/e2e-polybft/e2e/storage_test.go @@ -169,7 +169,7 @@ func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { assert.Equal(t, uint64(0), bt.GasPrice) assert.NotNil(t, bt.ChainID) } else { - assert.Equal(t, ethgo.TransactionLegacy, bt.Type) + // assert.Equal(t, ethgo.TransactionLegacy, bt.Type) assert.Equal(t, ethgo.Gwei(2).Uint64(), bt.GasPrice) } From 89e648d6aa41fdb1051dfdf4a82cfa53a86bcdff Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 26 Feb 2024 16:31:20 +0100 Subject: [PATCH 17/48] TestE2E_Storage -> use TestCluster.SendTxn --- e2e-polybft/e2e/storage_test.go | 83 +++++++++------------------------ 1 file changed, 22 insertions(+), 61 deletions(-) diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go index 5122492f37..c7ad12686f 100644 --- a/e2e-polybft/e2e/storage_test.go +++ b/e2e-polybft/e2e/storage_test.go @@ -3,7 +3,6 @@ package e2e import ( "math/big" "reflect" - "sync" "testing" "time" @@ -18,12 +17,6 @@ import ( "github.com/0xPolygon/polygon-edge/types" ) -type txObject struct { - bNumber uint64 - txHash ethgo.Hash - to ethgo.Address -} - func TestE2E_Storage(t *testing.T) { // premine an account in the genesis file sender, err := wallet.GenerateKey() @@ -50,16 +43,10 @@ func TestE2E_Storage(t *testing.T) { receivers = append(receivers, key.Address()) } - var wg sync.WaitGroup - - txs := []txObject{} + txs := []*framework.TestTxn{} for i := 0; i < num; i++ { - wg.Add(1) - func(i int, to ethgo.Address) { - defer wg.Done() - txn := ðgo.Transaction{ From: sender.Address(), To: &to, @@ -73,18 +60,24 @@ func TestE2E_Storage(t *testing.T) { txn.Type = ethgo.TransactionDynamicFee txn.MaxFeePerGas = big.NewInt(1000000000) txn.MaxPriorityFeePerGas = big.NewInt(100000000) + + chainID, err := client.ChainID() + require.NoError(t, err) + + txn.ChainID = chainID } else { txn.Type = ethgo.TransactionLegacy txn.GasPrice = ethgo.Gwei(2).Uint64() } - bn, th := sendTx(t, client, sender, txn) - txs = append(txs, txObject{bNumber: bn, txHash: th, to: to}) + tx := cluster.SendTxn(t, sender, txn) + err = tx.Wait() + require.NoError(t, err) + + txs = append(txs, tx) }(i, receivers[i]) } - wg.Wait() - err = cluster.WaitUntil(2*time.Minute, 2*time.Second, func() bool { for i, receiver := range receivers { balance, err := client.GetBalance(receiver, ethgo.Latest) @@ -106,38 +99,11 @@ func TestE2E_Storage(t *testing.T) { checkStorage(t, txs, client) } -// sendTx is a helper function which signs transaction with provided private key and sends it -func sendTx(t *testing.T, client *jsonrpc.Eth, sender *wallet.Key, txn *ethgo.Transaction) (uint64, ethgo.Hash) { - t.Helper() - - chainID, err := client.ChainID() - require.NoError(t, err) - - if txn.Type == ethgo.TransactionDynamicFee { - txn.ChainID = chainID - } - - signer := wallet.NewEIP155Signer(chainID.Uint64()) - signedTxn, err := signer.SignTx(txn, sender) - require.NoError(t, err) - - txnRaw, err := signedTxn.MarshalRLPTo(nil) - require.NoError(t, err) - - h, err := client.SendRawTransaction(txnRaw) - require.NoError(t, err) - - bn, err := client.BlockNumber() - require.NoError(t, err) - - return bn, h -} - -func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { +func checkStorage(t *testing.T, txs []*framework.TestTxn, client *jsonrpc.Eth) { t.Helper() for i, tx := range txs { - bn, err := client.GetBlockByNumber(ethgo.BlockNumber(tx.bNumber), true) + bn, err := client.GetBlockByNumber(ethgo.BlockNumber(tx.Receipt().BlockNumber), true) require.NoError(t, err) assert.NotNil(t, bn) @@ -149,20 +115,18 @@ func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { t.Fatal("blocks dont match") } - bt, err := client.GetTransactionByHash(tx.txHash) + bt, err := client.GetTransactionByHash(tx.Receipt().TransactionHash) require.NoError(t, err) assert.NotNil(t, bt) - assert.Equal(t, uint64(i), bt.Value.Uint64()) - assert.Equal(t, uint64(30000), bt.Gas) - assert.Equal(t, uint64(i), bt.Nonce) - assert.Equal(t, uint64(i), bt.TxnIndex) + assert.Equal(t, tx.Txn().Value.Uint64(), bt.Value.Uint64()) + assert.Equal(t, tx.Txn().Gas, bt.Gas) + assert.Equal(t, tx.Txn().Nonce, bt.Nonce) + assert.Equal(t, tx.Receipt().TransactionIndex, bt.TxnIndex) assert.NotEmpty(t, bt.V) assert.NotEmpty(t, bt.R) assert.NotEmpty(t, bt.S) - - if !reflect.DeepEqual(tx.to, *bt.To) { - t.Fatal("tx to dont match") - } + assert.Equal(t, tx.Txn().From, bt.From) + assert.Equal(t, tx.Txn().To, bt.To) if i%2 == 0 { assert.Equal(t, ethgo.TransactionDynamicFee, bt.Type) @@ -173,7 +137,7 @@ func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { assert.Equal(t, ethgo.Gwei(2).Uint64(), bt.GasPrice) } - r, err := client.GetTransactionReceipt(tx.txHash) + r, err := client.GetTransactionReceipt(tx.Receipt().TransactionHash) require.NoError(t, err) assert.NotNil(t, r) assert.Equal(t, bt.TxnIndex, r.TransactionIndex) @@ -181,9 +145,6 @@ func checkStorage(t *testing.T, txs []txObject, client *jsonrpc.Eth) { assert.Equal(t, bt.BlockHash, r.BlockHash) assert.Equal(t, bt.BlockNumber, r.BlockNumber) assert.NotEmpty(t, r.LogsBloom) - - if !reflect.DeepEqual(*bt.To, *r.To) { - t.Fatal("receipt to dont match") - } + assert.Equal(t, bt.To, r.To) } } From 63f046b774158cbf1aac363bc1154dc8cbc78507 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 26 Feb 2024 22:50:37 +0100 Subject: [PATCH 18/48] Added block hash into block key --- blockchain/blockchain.go | 18 +++---- blockchain/blockchain_test.go | 54 +++++-------------- .../storagev2/leveldb/leveldb_perf_test.go | 12 ++--- blockchain/storagev2/leveldb/leveldb_test.go | 4 +- blockchain/storagev2/mdbx/mdbx_perf_test.go | 12 ++--- blockchain/storagev2/mdbx/mdbx_test.go | 4 +- blockchain/storagev2/storage_read.go | 20 +++---- blockchain/storagev2/storage_write.go | 22 +++++--- blockchain/storagev2/testing.go | 21 ++++---- command/regenesis/test_on_history.go | 2 +- 10 files changed, 74 insertions(+), 95 deletions(-) diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index ceee2c023d..88349bcca0 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -445,7 +445,7 @@ func (b *Blockchain) GetReceiptsByHash(hash types.Hash) ([]*types.Receipt, error return nil, err } - return b.db.ReadReceipts(n) + return b.db.ReadReceipts(n, hash) } // GetBodyByHash returns the body by their hash @@ -478,7 +478,7 @@ func (b *Blockchain) readHeader(hash types.Hash) (*types.Header, bool) { return nil, false } - hh, err := b.db.ReadHeader(n) + hh, err := b.db.ReadHeader(n, hash) if err != nil { return nil, false } @@ -497,7 +497,7 @@ func (b *Blockchain) readBody(hash types.Hash) (*types.Body, bool) { return nil, false } - bb, err := b.db.ReadBody(n) + bb, err := b.db.ReadBody(n, hash) if err != nil { b.logger.Error("failed to read body", "err", err) @@ -508,7 +508,7 @@ func (b *Blockchain) readBody(hash types.Hash) (*types.Body, bool) { if updated := b.recoverFromFieldsInTransactions(bb.Transactions); updated { batchWriter := b.db.NewWriter() - batchWriter.PutBody(n, bb) + batchWriter.PutBody(n, hash, bb) if err := batchWriter.WriteBatch(); err != nil { b.logger.Warn("failed to write body into storage", "hash", hash, "err", err) @@ -538,7 +538,7 @@ func (b *Blockchain) readTotalDifficulty(headerHash types.Hash) (*big.Int, bool) return nil, false } - dbDifficulty, ok := b.db.ReadTotalDifficulty(n) + dbDifficulty, ok := b.db.ReadTotalDifficulty(n, headerHash) if !ok { return nil, false } @@ -848,7 +848,7 @@ func (b *Blockchain) WriteFullBlock(fblock *types.FullBlock, source string) erro // write the receipts, do it only after the header has been written. // Otherwise, a client might ask for a header once the receipt is valid, // but before it is written into the storage - batchWriter.PutReceipts(block.Number(), fblock.Receipts) + batchWriter.PutReceipts(block.Number(), block.Hash(), fblock.Receipts) // update snapshot if err := b.consensus.ProcessHeaders([]*types.Header{header}); err != nil { @@ -919,7 +919,7 @@ func (b *Blockchain) WriteBlock(block *types.Block, source string) error { // write the receipts, do it only after the header has been written. // Otherwise, a client might ask for a header once the receipt is valid, // but before it is written into the storage - batchWriter.PutReceipts(block.Number(), blockReceipts) + batchWriter.PutReceipts(block.Number(), block.Hash(), blockReceipts) // update snapshot if err := b.consensus.ProcessHeaders([]*types.Header{header}); err != nil { @@ -1019,7 +1019,7 @@ func (b *Blockchain) writeBody(batchWriter *storagev2.Writer, block *types.Block } // Write the full body (txns + receipts) - batchWriter.PutBody(block.Number(), block.Body()) + batchWriter.PutBody(block.Number(), block.Hash(), block.Body()) // Write txn lookups (txHash -> block number) for _, txn := range block.Transactions { @@ -1211,7 +1211,7 @@ func (b *Blockchain) writeHeaderImpl( } batchWriter.PutHeader(header) - batchWriter.PutTotalDifficulty(header.Number, incomingTD) + batchWriter.PutTotalDifficulty(header.Number, header.Hash, incomingTD) batchWriter.PutForks(forks) batchWriter.PutBlockLookup(header.Hash, header.Number) diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 0dfea125d9..b0a67828f7 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -1097,16 +1097,18 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { assert.ErrorIs(t, blockchain.verifyBlockParent(block), ErrParentNotFound) }) - t.Run("Parent hash mismatch", func(t *testing.T) { + t.Run("Invalid parent hash", func(t *testing.T) { t.Parallel() // Set up the storage callback storageCallback := func(storage *storagev2.Storage) { - h := emptyHeader + h := &types.Header{ + Hash: types.ZeroHash, + } w := storage.NewWriter() - w.PutBlockLookup(types.ZeroHash, h.Number) + w.PutBlockLookup(h.Hash, h.Number) w.PutHeader(h) err := w.WriteBatch() require.NoError(t, err) @@ -1128,38 +1130,6 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { assert.ErrorIs(t, blockchain.verifyBlockParent(block), ErrParentHashMismatch) }) - t.Run("Invalid block sequence", func(t *testing.T) { - t.Parallel() - - // Set up the storage callback - storageCallback := func(storage *storagev2.Storage) { - h := emptyHeader - - w := storage.NewWriter() - - w.PutBlockLookup(types.ZeroHash, h.Number) - w.PutHeader(h) - err := w.WriteBatch() - require.NoError(t, err) - } - - blockchain, err := NewMockBlockchain(map[TestCallbackType]interface{}{ - StorageCallback: storageCallback, - }) - if err != nil { - t.Fatalf("unable to instantiate new blockchain, %v", err) - } - - // Create a dummy block with a number much higher than the parent - block := &types.Block{ - Header: &types.Header{ - Number: 10, - }, - } - - assert.ErrorIs(t, blockchain.verifyBlockParent(block), ErrParentHashMismatch) - }) - t.Run("Invalid block sequence", func(t *testing.T) { t.Parallel() @@ -1205,7 +1175,7 @@ func TestBlockchain_VerifyBlockParent(t *testing.T) { w := storage.NewWriter() - w.PutBlockLookup(types.ZeroHash, h.Number) + w.PutBlockLookup(h.Hash, h.Number) w.PutHeader(h) err := w.WriteBatch() require.NoError(t, err) @@ -1664,7 +1634,7 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { require.NoError(t, err) require.Equal(t, header.Number, n) - b, err := bc.db.ReadBody(header.Number) + b, err := bc.db.ReadBody(header.Number, header.Hash) require.NoError(t, err) require.NotNil(t, b) @@ -1672,7 +1642,7 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { require.NoError(t, err) require.Equal(t, header.Number, l) - h, err := bc.db.ReadHeader(header.Number) + h, err := bc.db.ReadHeader(header.Number, header.Hash) require.NoError(t, err) require.NotNil(t, h) @@ -1684,11 +1654,11 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { require.True(t, ok) require.Equal(t, header.Hash, ch) - td, ok := bc.db.ReadTotalDifficulty(header.Number) + td, ok := bc.db.ReadTotalDifficulty(header.Number, header.Hash) require.True(t, ok) require.NotNil(t, td) - r, err := bc.db.ReadReceipts(header.Number) + r, err := bc.db.ReadReceipts(header.Number, header.Hash) require.NoError(t, err) require.NotNil(t, r) } @@ -1810,9 +1780,9 @@ func blockWriter(tb testing.TB, numberOfBlocks uint64, blockTime, checkInterval } batchWriter.PutHeader(block.Block.Header) - batchWriter.PutBody(block.Block.Number(), block.Block.Body()) + batchWriter.PutBody(block.Block.Number(), block.Block.Hash(), block.Block.Body()) - batchWriter.PutReceipts(block.Block.Number(), receipts) + batchWriter.PutReceipts(block.Block.Number(), block.Block.Hash(), receipts) require.NoError(tb, blockchain.writeBatchAndUpdate(batchWriter, block.Block.Header, big.NewInt(0), false)) diff --git a/blockchain/storagev2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go index b6d7de493e..9c5b641ca3 100644 --- a/blockchain/storagev2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -177,10 +177,10 @@ func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *stora } // Main DB sorted - batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body()) batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) batchWriter.PutHeader(b.Block.Header) - batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) return batchWriter } @@ -230,16 +230,16 @@ func TestReadBlockPerf(t *testing.T) { n := uint64(1 + rand.Intn(10000)) tn := time.Now().UTC() - _, err1 := s.ReadBody(n) h, ok := s.ReadCanonicalHash(n) - _, err3 := s.ReadHeader(n) - _, err4 := s.ReadReceipts(n) + _, err1 := s.ReadBody(n, h) + _, err3 := s.ReadHeader(n, h) + _, err4 := s.ReadReceipts(n, h) b, err5 := s.ReadBlockLookup(h) d := time.Since(tn) watchTime = watchTime + d.Milliseconds() - if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil { + if !ok || err1 != nil || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") } diff --git a/blockchain/storagev2/leveldb/leveldb_test.go b/blockchain/storagev2/leveldb/leveldb_test.go index 14d2ce1911..4992e9e90c 100644 --- a/blockchain/storagev2/leveldb/leveldb_test.go +++ b/blockchain/storagev2/leveldb/leveldb_test.go @@ -230,7 +230,7 @@ insertloop: case b := <-blockchain: batchWriter := s.NewWriter() - batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body()) for _, tx := range b.Block.Transactions { batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) @@ -239,7 +239,7 @@ insertloop: batchWriter.PutHeader(b.Block.Header) batchWriter.PutHeadNumber(uint64(i)) batchWriter.PutHeadHash(b.Block.Header.Hash) - batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash()) if err := batchWriter.WriteBatch(); err != nil { diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go index 5f634690fb..a155211e18 100644 --- a/blockchain/storagev2/mdbx/mdbx_perf_test.go +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -152,10 +152,10 @@ func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *stora } // Main DB sorted - batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body()) batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) batchWriter.PutHeader(b.Block.Header) - batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) return batchWriter } @@ -205,16 +205,16 @@ func TestReadBlockPerf(t *testing.T) { n := uint64(1 + rand.Intn(10000)) tn := time.Now().UTC() - _, err1 := s.ReadBody(n) h, ok := s.ReadCanonicalHash(n) - _, err3 := s.ReadHeader(n) - _, err4 := s.ReadReceipts(n) + _, err1 := s.ReadBody(n, h) + _, err3 := s.ReadHeader(n, h) + _, err4 := s.ReadReceipts(n, h) b, err5 := s.ReadBlockLookup(h) d := time.Since(tn) watchTime = watchTime + d.Milliseconds() - if err1 != nil || !ok || err3 != nil || err4 != nil || err5 != nil { + if !ok || err1 != nil || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") } diff --git a/blockchain/storagev2/mdbx/mdbx_test.go b/blockchain/storagev2/mdbx/mdbx_test.go index 4c481e3cb5..c62d91cb59 100644 --- a/blockchain/storagev2/mdbx/mdbx_test.go +++ b/blockchain/storagev2/mdbx/mdbx_test.go @@ -220,7 +220,7 @@ insertloop: case b := <-blockchain: batchWriter := s.NewWriter() - batchWriter.PutBody(b.Block.Number(), b.Block.Body()) + batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body()) for _, tx := range b.Block.Transactions { batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) @@ -229,7 +229,7 @@ insertloop: batchWriter.PutHeader(b.Block.Header) batchWriter.PutHeadNumber(uint64(i)) batchWriter.PutHeadHash(b.Block.Header.Hash) - batchWriter.PutReceipts(b.Block.Number(), b.Receipts) + batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash()) if err := batchWriter.WriteBatch(); err != nil { diff --git a/blockchain/storagev2/storage_read.go b/blockchain/storagev2/storage_read.go index 1ff2b01740..56103a6845 100644 --- a/blockchain/storagev2/storage_read.go +++ b/blockchain/storagev2/storage_read.go @@ -9,7 +9,7 @@ import ( // -- canonical hash -- -// ReadCanonicalHash gets the hash from the number of the canonical chain +// ReadCanonicalHash gets the hash from the number of the canonical block func (s *Storage) ReadCanonicalHash(n uint64) (types.Hash, bool) { data, ok := s.get(CANONICAL, common.EncodeUint64ToBytes(n)) if !ok { @@ -58,8 +58,8 @@ func (s *Storage) ReadForks() ([]types.Hash, error) { // DIFFICULTY // // ReadTotalDifficulty reads the difficulty -func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, bool) { - v, ok := s.get(DIFFICULTY, common.EncodeUint64ToBytes(bn)) +func (s *Storage) ReadTotalDifficulty(bn uint64, bh types.Hash) (*big.Int, bool) { + v, ok := s.get(DIFFICULTY, getKey(bn, bh)) if !ok { return nil, false } @@ -70,9 +70,9 @@ func (s *Storage) ReadTotalDifficulty(bn uint64) (*big.Int, bool) { // HEADER // // ReadHeader reads the header -func (s *Storage) ReadHeader(bn uint64) (*types.Header, error) { +func (s *Storage) ReadHeader(bn uint64, bh types.Hash) (*types.Header, error) { header := &types.Header{} - err := s.readRLP(HEADER, common.EncodeUint64ToBytes(bn), header) + err := s.readRLP(HEADER, getKey(bn, bh), header) return header, err } @@ -80,15 +80,15 @@ func (s *Storage) ReadHeader(bn uint64) (*types.Header, error) { // BODY // // ReadBody reads the body -func (s *Storage) ReadBody(bn uint64) (*types.Body, error) { +func (s *Storage) ReadBody(bn uint64, bh types.Hash) (*types.Body, error) { body := &types.Body{} - if err := s.readRLP(BODY, common.EncodeUint64ToBytes(bn), body); err != nil { + if err := s.readRLP(BODY, getKey(bn, bh), body); err != nil { return nil, err } // must read header because block number is needed in order to calculate each tx hash header := &types.Header{} - if err := s.readRLP(HEADER, common.EncodeUint64ToBytes(bn), header); err != nil { + if err := s.readRLP(HEADER, getKey(bn, bh), header); err != nil { return nil, err } @@ -102,9 +102,9 @@ func (s *Storage) ReadBody(bn uint64) (*types.Body, error) { // RECEIPTS // // ReadReceipts reads the receipts -func (s *Storage) ReadReceipts(bn uint64) ([]*types.Receipt, error) { +func (s *Storage) ReadReceipts(bn uint64, bh types.Hash) ([]*types.Receipt, error) { receipts := &types.Receipts{} - err := s.readRLP(RECEIPTS, common.EncodeUint64ToBytes(bn), receipts) + err := s.readRLP(RECEIPTS, getKey(bn, bh), receipts) return *receipts, err } diff --git a/blockchain/storagev2/storage_write.go b/blockchain/storagev2/storage_write.go index 36834abcab..e76c607a91 100644 --- a/blockchain/storagev2/storage_write.go +++ b/blockchain/storagev2/storage_write.go @@ -8,11 +8,13 @@ import ( ) func (w *Writer) PutHeader(h *types.Header) { - w.putRlp(HEADER, common.EncodeUint64ToBytes(h.Number), h) + // block_num_u64 + hash -> header (RLP) + w.putRlp(HEADER, getKey(h.Number, h.Hash), h) } -func (w *Writer) PutBody(bn uint64, body *types.Body) { - w.putRlp(BODY, common.EncodeUint64ToBytes(bn), body) +func (w *Writer) PutBody(bn uint64, bh types.Hash, body *types.Body) { + // block_num_u64 + hash -> body (RLP) + w.putRlp(BODY, getKey(bn, bh), body) } func (w *Writer) PutHeadHash(h types.Hash) { @@ -31,9 +33,9 @@ func (w *Writer) PutBlockLookup(hash types.Hash, bn uint64) { w.putIntoTable(BLOCK_LOOKUP, hash.Bytes(), common.EncodeUint64ToBytes(bn)) } -func (w *Writer) PutReceipts(bn uint64, receipts []*types.Receipt) { +func (w *Writer) PutReceipts(bn uint64, bh types.Hash, receipts []*types.Receipt) { rs := types.Receipts(receipts) - w.putRlp(RECEIPTS, common.EncodeUint64ToBytes(bn), &rs) + w.putRlp(RECEIPTS, getKey(bn, bh), &rs) } func (w *Writer) PutCanonicalHeader(h *types.Header, diff *big.Int) { @@ -42,15 +44,15 @@ func (w *Writer) PutCanonicalHeader(h *types.Header, diff *big.Int) { w.PutHeadNumber(h.Number) w.PutBlockLookup(h.Hash, h.Number) w.PutCanonicalHash(h.Number, h.Hash) - w.PutTotalDifficulty(h.Number, diff) + w.PutTotalDifficulty(h.Number, h.Hash, diff) } func (w *Writer) PutCanonicalHash(bn uint64, hash types.Hash) { w.putIntoTable(CANONICAL, common.EncodeUint64ToBytes(bn), hash.Bytes()) } -func (w *Writer) PutTotalDifficulty(bn uint64, diff *big.Int) { - w.putIntoTable(DIFFICULTY, common.EncodeUint64ToBytes(bn), diff.Bytes()) +func (w *Writer) PutTotalDifficulty(bn uint64, bh types.Hash, diff *big.Int) { + w.putIntoTable(DIFFICULTY, getKey(bn, bh), diff.Bytes()) } func (w *Writer) PutForks(forks []types.Hash) { @@ -97,3 +99,7 @@ func (w *Writer) getBatch(t uint8) Batch { return w.batch[MAINDB_INDEX] } + +func getKey(n uint64, h types.Hash) []byte { + return append(append(make([]byte, 0, 40), common.EncodeUint64ToBytes(n)...), h.Bytes()...) +} diff --git a/blockchain/storagev2/testing.go b/blockchain/storagev2/testing.go index d0acdbc216..30a725f11b 100644 --- a/blockchain/storagev2/testing.go +++ b/blockchain/storagev2/testing.go @@ -128,14 +128,15 @@ func testDifficulty(t *testing.T, m PlaceholderStorage) { Number: uint64(indx), ExtraData: []byte{}, } + h.ComputeHash() batch.PutHeader(h) batch.PutBlockLookup(h.Hash, h.Number) - batch.PutTotalDifficulty(h.Number, cc.Diff) + batch.PutTotalDifficulty(h.Number, h.Hash, cc.Diff) require.NoError(t, batch.WriteBatch()) - diff, ok := s.ReadTotalDifficulty(h.Number) + diff, ok := s.ReadTotalDifficulty(h.Number, h.Hash) assert.True(t, ok) if !reflect.DeepEqual(cc.Diff, diff) { @@ -232,7 +233,7 @@ func testHeader(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) - header1, err := s.ReadHeader(header.Number) + header1, err := s.ReadHeader(header.Number, header.Hash) assert.NoError(t, err) if !reflect.DeepEqual(header, header1) { @@ -254,6 +255,8 @@ func testBody(t *testing.T, m PlaceholderStorage) { ExtraData: []byte{}, // if not set it will fail } + header.ComputeHash() + batch := s.NewWriter() batch.PutHeader(header) @@ -292,11 +295,11 @@ func testBody(t *testing.T, m PlaceholderStorage) { batch2 := s.NewWriter() body0 := block.Body() - batch2.PutBody(header.Number, body0) + batch2.PutBody(header.Number, header.Hash, body0) require.NoError(t, batch2.WriteBatch()) - body1, err := s.ReadBody(header.Number) + body1, err := s.ReadBody(header.Number, header.Hash) assert.NoError(t, err) // NOTE: reflect.DeepEqual does not seem to work, check the hash of the transactions @@ -372,12 +375,12 @@ func testReceipts(t *testing.T, m PlaceholderStorage) { } batch.PutHeader(h) - batch.PutBody(h.Number, body) - batch.PutReceipts(h.Number, receipts) + batch.PutBody(h.Number, h.Hash, body) + batch.PutReceipts(h.Number, h.Hash, receipts) require.NoError(t, batch.WriteBatch()) - found, err := s.ReadReceipts(h.Number) + found, err := s.ReadReceipts(h.Number, h.Hash) assert.NoError(t, err) assert.True(t, reflect.DeepEqual(receipts, found)) } @@ -401,7 +404,7 @@ func testWriteCanonicalHeader(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) - hh, err := s.ReadHeader(h.Number) + hh, err := s.ReadHeader(h.Number, h.Hash) assert.NoError(t, err) if !reflect.DeepEqual(h, hh) { diff --git a/command/regenesis/test_on_history.go b/command/regenesis/test_on_history.go index 9fef4311eb..3dbf4c6f99 100644 --- a/command/regenesis/test_on_history.go +++ b/command/regenesis/test_on_history.go @@ -90,7 +90,7 @@ func HistoryTestCmd() *cobra.Command { return } - header, err := st.ReadHeader(bn) + header, err := st.ReadHeader(bn, canonicalHash) if !ok { outputter.SetError(fmt.Errorf("can't read header %w", err)) From 18221b50264e2c7539f05b87a60c84149d11cd6e Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Mon, 4 Mar 2024 15:13:13 +0100 Subject: [PATCH 19/48] Fixed comments for tableMapper --- blockchain/storagev2/leveldb/leveldb.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/blockchain/storagev2/leveldb/leveldb.go b/blockchain/storagev2/leveldb/leveldb.go index 3140079b43..d2a9bd1b11 100644 --- a/blockchain/storagev2/leveldb/leveldb.go +++ b/blockchain/storagev2/leveldb/leveldb.go @@ -12,18 +12,20 @@ type levelDB struct { db *leveldb.DB } -// DB key = k + mapper var tableMapper = map[uint8][]byte{ - storagev2.BODY: []byte("b"), // DB key = block number + mapper - storagev2.CANONICAL: []byte("c"), // DB key = block number + mapper - storagev2.DIFFICULTY: []byte("d"), // DB key = block number + mapper - storagev2.HEADER: []byte("h"), // DB key = block number + mapper - storagev2.RECEIPTS: []byte("r"), // DB key = block number + mapper - storagev2.FORK: {}, // DB key = FORK_KEY + mapper - storagev2.HEAD_HASH: {}, // DB key = HEAD_HASH_KEY + mapper - storagev2.HEAD_NUMBER: {}, // DB key = HEAD_NUMBER_KEY + mapper - storagev2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number - storagev2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number + // Main DB + storagev2.BODY: []byte("b"), // DB key = block number + block hash + mapper, value = block body + storagev2.DIFFICULTY: []byte("d"), // DB key = block number + block hash + mapper, value = block total diffculty + storagev2.HEADER: []byte("h"), // DB key = block number + block hash + mapper, value = block header + storagev2.RECEIPTS: []byte("r"), // DB key = block number + block hash + mapper, value = block receipts + storagev2.CANONICAL: {}, // DB key = block number + mapper, value = block hash + + // GidLid DB + storagev2.FORK: {}, // DB key = FORK_KEY + mapper, value = fork hashes + storagev2.HEAD_HASH: {}, // DB key = HEAD_HASH_KEY + mapper, value = head hash + storagev2.HEAD_NUMBER: {}, // DB key = HEAD_NUMBER_KEY + mapper, value = head number + storagev2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number + storagev2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number } // NewLevelDBStorage creates the new storage reference with leveldb default options From 5f8aa5738919333716000644230ae0239d43bbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Thu, 7 Mar 2024 17:40:07 +0100 Subject: [PATCH 20/48] Minor fix (check the appropriate error reference) --- server/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/server.go b/server/server.go index bae93ed4ba..190f3f6e6a 100644 --- a/server/server.go +++ b/server/server.go @@ -168,7 +168,7 @@ func NewServer(config *Config) (*Server, error) { } // Set up datadog profiler - if ddErr := m.enableDataDogProfiler(); err != nil { + if ddErr := m.enableDataDogProfiler(); ddErr != nil { m.logger.Error("DataDog profiler setup failed", "err", ddErr.Error()) } From a76534d2bd9f57a6f3670ae636bb79b41d61dda0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= <93934272+Stefan-Ethernal@users.noreply.github.com> Date: Thu, 21 Mar 2024 12:06:04 +0100 Subject: [PATCH 21/48] Introduce `ECDSAKey` and decouple from `ethgo` lib transactions signing logic (#112) * Introduce ECDSAKey and decouple from ethgo transactions signing logic * Fix panic in e2e test(s) * Fix checkpoint manager unit tests * Try to fix extract signature failure * Change signature of sign callback function * Use the latest signer in the tx relayer * Minor fixes * Fix panic when unsigned transaction is sent to txrelayer * Instantiate LondonOrBerlin signer in the TestCluster.SendTxn * Minor change * Lint fix * Build fixes * Add log to tx pool * Typo fix and small simplification * Build fix * callback function fix * rebase fixes * lint fix * fixes for e2e * migration test fix * transactionWithHeaderInstructions fix * Fix linters * Fix linter (uncapitalize param name) * Remove debug log * Adapt the unit test * Merge fix * Fix TestE2E_JsonRPC_NewEthClient * Lint fix * comment fix * lint fix * test fix * one more transaction contructor --------- Co-authored-by: Dusan Nosovic --- command/bridge/deploy/deploy.go | 29 +-- command/bridge/deploy/deploy_test.go | 3 +- .../bridge/deposit/erc1155/deposit_erc1155.go | 19 +- command/bridge/deposit/erc20/deposit_erc20.go | 6 +- .../bridge/deposit/erc721/deposit_erc721.go | 22 +- command/bridge/exit/exit.go | 7 +- command/bridge/finalize/finalize.go | 9 +- command/bridge/fund/fund.go | 4 +- command/bridge/helper/utils.go | 61 +++--- command/bridge/premine/premine.go | 3 +- .../withdraw/erc1155/withdraw_erc1155.go | 19 +- .../bridge/withdraw/erc20/withdraw_erc20.go | 11 +- .../bridge/withdraw/erc721/withdraw_erc721.go | 11 +- command/secrets/init/params_test.go | 5 +- command/validator/helper/helper.go | 11 +- .../registration/register_validator.go | 3 +- command/validator/stake/stake.go | 9 +- command/validator/unstake/unstake.go | 10 +- .../whitelist/whitelist_validators.go | 4 +- command/validator/withdraw-rewards/rewards.go | 6 +- command/validator/withdraw/withdraw.go | 5 +- consensus/polybft/block_builder_test.go | 28 ++- consensus/polybft/blockchain_wrapper.go | 2 +- consensus/polybft/checkpoint_manager.go | 22 +- consensus/polybft/checkpoint_manager_test.go | 15 +- consensus/polybft/exit_relayer.go | 17 +- consensus/polybft/stake_manager_test.go | 7 +- consensus/polybft/state_sync_relayer.go | 19 +- consensus/polybft/system_state.go | 2 +- consensus/polybft/system_state_test.go | 10 +- consensus/polybft/wallet/account.go | 13 +- consensus/polybft/wallet/key.go | 9 +- crypto/crypto.go | 6 +- crypto/crypto_test.go | 4 +- crypto/ecdsa_key.go | 76 +++++++ crypto/txsigner.go | 6 +- crypto/txsigner_berlin.go | 22 +- crypto/txsigner_eip155.go | 26 ++- crypto/txsigner_eip155_test.go | 4 +- crypto/txsigner_frontier.go | 37 ++-- crypto/txsigner_frontier_test.go | 2 +- crypto/txsigner_homestead.go | 27 +-- crypto/txsigner_london.go | 22 +- crypto/txsigner_london_test.go | 2 +- e2e-polybft/e2e/acls_test.go | 91 ++++----- e2e-polybft/e2e/bridge_test.go | 96 +++++---- e2e-polybft/e2e/burn_contract_test.go | 6 +- e2e-polybft/e2e/consensus_test.go | 158 +++++++-------- e2e-polybft/e2e/governance_test.go | 50 +++-- e2e-polybft/e2e/helpers_test.go | 37 ++-- e2e-polybft/e2e/jsonrpc_test.go | 191 +++++++++--------- e2e-polybft/e2e/migration_test.go | 55 ++--- e2e-polybft/e2e/txpool_test.go | 165 ++++++++------- e2e-polybft/framework/test-cluster.go | 69 ++++--- helper/tests/testing.go | 2 +- txpool/txpool.go | 1 - txpool/txpool_test.go | 6 +- txrelayer/txrelayer.go | 170 +++++++++++----- types/transaction.go | 9 + 59 files changed, 992 insertions(+), 749 deletions(-) create mode 100644 crypto/ecdsa_key.go diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index 630cb12f85..2fae45da48 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -19,6 +19,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" ) @@ -111,12 +112,12 @@ var ( // initializersMap maps rootchain contract names to initializer function callbacks initializersMap = map[string]func(command.OutputFormatter, txrelayer.TxRelayer, []*validator.GenesisValidator, - *polybft.RootchainConfig, ethgo.Key, int64) error{ + *polybft.RootchainConfig, crypto.Key, int64) error{ getProxyNameForImpl(checkpointManagerName): func(fmt command.OutputFormatter, relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { if !consensusCfg.NativeTokenConfig.IsMintable { // we can not initialize checkpoint manager at this moment if native token is not mintable @@ -145,7 +146,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { inputParams := &contractsapi.InitializeExitHelperFn{ NewCheckpointManager: config.CheckpointManagerAddress, @@ -157,7 +158,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { inputParams := &contractsapi.InitializeRootERC20PredicateFn{ NewStateSender: config.StateSenderAddress, @@ -175,7 +176,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { initParams := &contractsapi.InitializeChildMintableERC20PredicateFn{ NewStateSender: config.StateSenderAddress, @@ -191,7 +192,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { initParams := &contractsapi.InitializeRootERC721PredicateFn{ NewStateSender: config.StateSenderAddress, @@ -207,7 +208,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { initParams := &contractsapi.InitializeChildMintableERC721PredicateFn{ NewStateSender: config.StateSenderAddress, @@ -223,7 +224,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { initParams := &contractsapi.InitializeRootERC1155PredicateFn{ NewStateSender: config.StateSenderAddress, @@ -239,7 +240,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { initParams := &contractsapi.InitializeChildMintableERC1155PredicateFn{ NewStateSender: config.StateSenderAddress, @@ -255,7 +256,7 @@ var ( relayer txrelayer.TxRelayer, genesisValidators []*validator.GenesisValidator, config *polybft.RootchainConfig, - key ethgo.Key, + key crypto.Key, chainID int64) error { gvs := make([]*contractsapi.GenesisAccount, len(genesisValidators)) for i := 0; i < len(genesisValidators); i++ { @@ -443,7 +444,7 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, if params.isTestMode { deployerAddr := deployerKey.Address() - txn := helper.CreateTransaction(ethgo.ZeroAddress, &deployerAddr, nil, ethgo.Ether(1), true) + txn := helper.CreateTransaction(types.ZeroAddress, &deployerAddr, nil, ethgo.Ether(1), true) if _, err = txRelayer.SendTransactionLocal(txn); err != nil { return deploymentResultInfo{RootchainCfg: nil, CommandResults: nil}, err } @@ -589,7 +590,7 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, } } - txn := helper.CreateTransaction(ethgo.ZeroAddress, nil, bytecode, nil, true) + txn := helper.CreateTransaction(types.ZeroAddress, nil, bytecode, nil, true) receipt, err := txRelayer.SendTransaction(txn, deployerKey) if err != nil { @@ -711,14 +712,14 @@ func populateExistingTokenAddr(eth *jsonrpc.Eth, tokenAddr, tokenName string, // initContract initializes arbitrary contract with given parameters deployed on a given address func initContract(cmdOutput command.OutputFormatter, txRelayer txrelayer.TxRelayer, initInputFn contractsapi.StateTransactionInput, contractAddr types.Address, - contractName string, deployerKey ethgo.Key) error { + contractName string, deployerKey crypto.Key) error { input, err := initInputFn.EncodeAbi() if err != nil { return fmt.Errorf("failed to encode initialization params for %s.initialize. error: %w", contractName, err) } - if _, err := helper.SendTransaction(txRelayer, ethgo.Address(contractAddr), + if _, err := helper.SendTransaction(txRelayer, contractAddr, input, contractName, deployerKey); err != nil { return err } diff --git a/command/bridge/deploy/deploy_test.go b/command/bridge/deploy/deploy_test.go index e7841992a7..12d2d6bce4 100644 --- a/command/bridge/deploy/deploy_test.go +++ b/command/bridge/deploy/deploy_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/jsonrpc" "github.com/umbracle/ethgo/testutil" @@ -32,7 +33,7 @@ func TestDeployContracts_NoPanics(t *testing.T) { testKey, err := helper.DecodePrivateKey("") require.NoError(t, err) - receipt, err := server.Fund(testKey.Address()) + receipt, err := server.Fund(ethgo.Address(testKey.Address())) require.NoError(t, err) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) diff --git a/command/bridge/deposit/erc1155/deposit_erc1155.go b/command/bridge/deposit/erc1155/deposit_erc1155.go index 6472df1fda..9a9f51281f 100644 --- a/command/bridge/deposit/erc1155/deposit_erc1155.go +++ b/command/bridge/deposit/erc1155/deposit_erc1155.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" @@ -245,8 +244,8 @@ func runCommand(cmd *cobra.Command, _ []string) { } // createDepositTxn encodes parameters for deposit function on rootchain predicate contract -func createDepositTxn(sender ethgo.Address, receivers []types.Address, - amounts, tokenIDs []*big.Int) (*ethgo.Transaction, error) { +func createDepositTxn(sender types.Address, receivers []types.Address, + amounts, tokenIDs []*big.Int) (*types.Transaction, error) { depositBatchFn := &contractsapi.DepositBatchRootERC1155PredicateFn{ RootToken: types.StringToAddress(dp.TokenAddr), Receivers: receivers, @@ -259,14 +258,14 @@ func createDepositTxn(sender ethgo.Address, receivers []types.Address, return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(dp.PredicateAddr)) + addr := types.StringToAddress(dp.PredicateAddr) return helper.CreateTransaction(sender, &addr, input, nil, !dp.ChildChainMintable), nil } // createMintTxn encodes parameters for mint function on rootchain token contract -func createMintTxn(sender, receiver types.Address, amounts, tokenIDs []*big.Int) (*ethgo.Transaction, error) { +func createMintTxn(sender, receiver types.Address, amounts, tokenIDs []*big.Int) (*types.Transaction, error) { mintFn := &contractsapi.MintBatchRootERC1155Fn{ To: receiver, Amounts: amounts, @@ -278,16 +277,16 @@ func createMintTxn(sender, receiver types.Address, amounts, tokenIDs []*big.Int) return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(dp.TokenAddr)) + addr := types.StringToAddress(dp.TokenAddr) - return helper.CreateTransaction(ethgo.Address(sender), &addr, + return helper.CreateTransaction(sender, &addr, input, nil, !dp.ChildChainMintable), nil } // createApproveERC1155PredicateTxn sends approve transaction // to ERC1155 token for ERC1155 predicate so that it is able to spend given tokens func createApproveERC1155PredicateTxn(rootERC1155Predicate, - rootERC1155Token types.Address) (*ethgo.Transaction, error) { + rootERC1155Token types.Address) (*types.Transaction, error) { approveFnParams := &contractsapi.SetApprovalForAllRootERC1155Fn{ Operator: rootERC1155Predicate, Approved: true, @@ -298,8 +297,6 @@ func createApproveERC1155PredicateTxn(rootERC1155Predicate, return nil, fmt.Errorf("failed to encode parameters for RootERC1155.setApprovalForAll. error: %w", err) } - addr := ethgo.Address(rootERC1155Token) - - return helper.CreateTransaction(ethgo.ZeroAddress, &addr, + return helper.CreateTransaction(types.ZeroAddress, &rootERC1155Token, input, nil, !dp.ChildChainMintable), nil } diff --git a/command/bridge/deposit/erc20/deposit_erc20.go b/command/bridge/deposit/erc20/deposit_erc20.go index 141c77fea9..bf99b53cce 100644 --- a/command/bridge/deposit/erc20/deposit_erc20.go +++ b/command/bridge/deposit/erc20/deposit_erc20.go @@ -267,7 +267,7 @@ func runCommand(cmd *cobra.Command, _ []string) { } // createDepositTxn encodes parameters for deposit function on rootchain predicate contract -func createDepositTxn(sender, receiver types.Address, amount *big.Int) (*ethgo.Transaction, error) { +func createDepositTxn(sender, receiver types.Address, amount *big.Int) (*types.Transaction, error) { depositToFn := &contractsapi.DepositToRootERC20PredicateFn{ RootToken: types.StringToAddress(dp.TokenAddr), Receiver: receiver, @@ -279,8 +279,8 @@ func createDepositTxn(sender, receiver types.Address, amount *big.Int) (*ethgo.T return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(dp.PredicateAddr)) + addr := types.StringToAddress(dp.PredicateAddr) - return helper.CreateTransaction(ethgo.Address(sender), &addr, + return helper.CreateTransaction(sender, &addr, input, nil, !dp.ChildChainMintable), nil } diff --git a/command/bridge/deposit/erc721/deposit_erc721.go b/command/bridge/deposit/erc721/deposit_erc721.go index c56cbf0e7c..6f4fbd1f4b 100644 --- a/command/bridge/deposit/erc721/deposit_erc721.go +++ b/command/bridge/deposit/erc721/deposit_erc721.go @@ -5,6 +5,8 @@ import ( "math/big" "strings" + "github.com/spf13/cobra" + "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -12,8 +14,6 @@ import ( helperCommon "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" - "github.com/spf13/cobra" - "github.com/umbracle/ethgo" ) type depositERC721Params struct { @@ -219,8 +219,8 @@ func runCommand(cmd *cobra.Command, _ []string) { } // createDepositTxn encodes parameters for deposit function on rootchain predicate contract -func createDepositTxn(sender ethgo.Address, - receivers []types.Address, tokenIDs []*big.Int) (*ethgo.Transaction, error) { +func createDepositTxn(sender types.Address, + receivers []types.Address, tokenIDs []*big.Int) (*types.Transaction, error) { depositToRoot := &contractsapi.DepositBatchRootERC721PredicateFn{ RootToken: types.StringToAddress(dp.TokenAddr), Receivers: receivers, @@ -232,13 +232,13 @@ func createDepositTxn(sender ethgo.Address, return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(dp.PredicateAddr)) + addr := types.StringToAddress(dp.PredicateAddr) return helper.CreateTransaction(sender, &addr, input, nil, !dp.ChildChainMintable), nil } // createMintTxn encodes parameters for mint function on rootchain token contract -func createMintTxn(sender, receiver types.Address) (*ethgo.Transaction, error) { +func createMintTxn(sender, receiver types.Address) (*types.Transaction, error) { mintFn := &contractsapi.MintRootERC721Fn{ To: receiver, } @@ -248,14 +248,14 @@ func createMintTxn(sender, receiver types.Address) (*ethgo.Transaction, error) { return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(dp.TokenAddr)) + addr := types.StringToAddress(dp.TokenAddr) - return helper.CreateTransaction(ethgo.Address(sender), &addr, + return helper.CreateTransaction(sender, &addr, input, nil, !dp.ChildChainMintable), nil } // createApproveERC721PredicateTxn sends approve transaction -func createApproveERC721PredicateTxn(rootERC721Predicate, rootERC721Token types.Address) (*ethgo.Transaction, error) { +func createApproveERC721PredicateTxn(rootERC721Predicate, rootERC721Token types.Address) (*types.Transaction, error) { approveFnParams := &contractsapi.SetApprovalForAllRootERC721Fn{ Operator: rootERC721Predicate, Approved: true, @@ -266,8 +266,6 @@ func createApproveERC721PredicateTxn(rootERC721Predicate, rootERC721Token types. return nil, fmt.Errorf("failed to encode parameters for RootERC721.approve. error: %w", err) } - addr := ethgo.Address(rootERC721Token) - - return helper.CreateTransaction(ethgo.ZeroAddress, &addr, input, + return helper.CreateTransaction(types.ZeroAddress, &rootERC721Token, input, nil, !dp.ChildChainMintable), nil } diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index 38ce4d39b7..7b083693f2 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -6,7 +6,6 @@ import ( "strconv" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/jsonrpc" "github.com/0xPolygon/polygon-edge/command" @@ -156,7 +155,7 @@ func run(cmd *cobra.Command, _ []string) { } // createExitTxn encodes parameters for exit function on root chain ExitHelper contract -func createExitTxn(sender ethgo.Address, proof types.Proof) (*ethgo.Transaction, +func createExitTxn(sender types.Address, proof types.Proof) (*types.Transaction, *contractsapi.L2StateSyncedEvent, error) { exitInput, err := polybft.GetExitInputFromProof(proof) if err != nil { @@ -180,9 +179,9 @@ func createExitTxn(sender ethgo.Address, proof types.Proof) (*ethgo.Transaction, return nil, nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - exitHelperAddr := ethgo.Address(types.StringToAddress(ep.exitHelperAddrRaw)) + exitHelperAddr := types.StringToAddress(ep.exitHelperAddrRaw) txn := helper.CreateTransaction(sender, &exitHelperAddr, input, nil, true) - txn.Gas = txrelayer.DefaultGasLimit + txn.SetGas(txrelayer.DefaultGasLimit) return txn, exitEvent, err } diff --git a/command/bridge/finalize/finalize.go b/command/bridge/finalize/finalize.go index 0a05df5faa..bf64951d91 100644 --- a/command/bridge/finalize/finalize.go +++ b/command/bridge/finalize/finalize.go @@ -15,6 +15,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -105,7 +106,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { return fmt.Errorf("enlist validator failed: %w", err) } - bladeManagerAddr := ethgo.Address(params.bladeManagerAddr) + bladeManagerAddr := params.bladeManagerAddr // finalize genesis accounts on BladeManager so that no one can stake and premine no more encoded, err := finalizeGenesisABIFn.Encode([]interface{}{}) @@ -145,7 +146,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { return fmt.Errorf("failed to encode genesis set input: %w", err) } - genesisSetHexOut, err := txRelayer.Call(ethgo.ZeroAddress, bladeManagerAddr, genesisSetInput) + genesisSetHexOut, err := txRelayer.Call(types.ZeroAddress, bladeManagerAddr, genesisSetInput) if err != nil { return fmt.Errorf("failed to retrieve genesis set: %w", err) } @@ -315,7 +316,7 @@ func validatorSetToABISlice(o command.OutputFormatter, func initializeCheckpointManager(outputter command.OutputFormatter, txRelayer txrelayer.TxRelayer, consensusConfig polybft.PolyBFTConfig, chainID int64, - deployerKey ethgo.Key) error { + deployerKey crypto.Key) error { validatorSet, err := validatorSetToABISlice(outputter, consensusConfig.InitialValidatorSet) if err != nil { return fmt.Errorf("failed to convert validators to map: %w", err) @@ -333,7 +334,7 @@ func initializeCheckpointManager(outputter command.OutputFormatter, return fmt.Errorf("failed to encode initialization params for CheckpointManager.initialize. error: %w", err) } - if _, err := bridgeHelper.SendTransaction(txRelayer, ethgo.Address(consensusConfig.Bridge.CheckpointManagerAddr), + if _, err := bridgeHelper.SendTransaction(txRelayer, consensusConfig.Bridge.CheckpointManagerAddr, input, "CheckpointManager", deployerKey); err != nil { return err } diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index e49406b9e6..1005853bbe 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -96,8 +96,8 @@ func runCommand(cmd *cobra.Command, _ []string) { return ctx.Err() default: - fundAddr := ethgo.Address(params.addresses[i]) - txn := helper.CreateTransaction(ethgo.ZeroAddress, &fundAddr, nil, params.amountValues[i], true) + fundAddr := params.addresses[i] + txn := helper.CreateTransaction(types.ZeroAddress, &fundAddr, nil, params.amountValues[i], true) var ( receipt *ethgo.Receipt diff --git a/command/bridge/helper/utils.go b/command/bridge/helper/utils.go index cf536b4550..0e930785ee 100644 --- a/command/bridge/helper/utils.go +++ b/command/bridge/helper/utils.go @@ -10,13 +10,13 @@ import ( dockertypes "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/wallet" polybftsecrets "github.com/0xPolygon/polygon-edge/command/secrets/init" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" polybftWallet "github.com/0xPolygon/polygon-edge/consensus/polybft/wallet" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/txrelayer" @@ -49,7 +49,7 @@ var ( ErrNoAddressesProvided = errors.New("no addresses provided") ErrInconsistentLength = errors.New("addresses and amounts must be equal length") - rootchainAccountKey *wallet.Key + rootchainAccountKey *crypto.ECDSAKey ) type MessageResult struct { @@ -66,7 +66,7 @@ func (r MessageResult) GetOutput() string { } // DecodePrivateKey decodes a private key from provided raw private key -func DecodePrivateKey(rawKey string) (ethgo.Key, error) { +func DecodePrivateKey(rawKey string) (crypto.Key, error) { privateKeyRaw := TestAccountPrivKey if rawKey != "" { privateKeyRaw = rawKey @@ -77,7 +77,7 @@ func DecodePrivateKey(rawKey string) (ethgo.Key, error) { return nil, fmt.Errorf("failed to decode private key string '%s': %w", privateKeyRaw, err) } - rootchainAccountKey, err = wallet.NewWalletFromPrivKey(dec) + rootchainAccountKey, err = crypto.NewECDSAKeyFromRawPrivECDSA(dec) if err != nil { return nil, fmt.Errorf("failed to initialize key from provided private key '%s': %w", privateKeyRaw, err) } @@ -132,7 +132,7 @@ func ReadRootchainIP() (string, error) { // GetECDSAKey returns the key based on provided parameters // If private key is provided, it will return that key // if not, it will return the key from the secrets manager -func GetECDSAKey(privateKey, accountDir, accountConfig string) (ethgo.Key, error) { +func GetECDSAKey(privateKey, accountDir, accountConfig string) (crypto.Key, error) { if privateKey != "" { key, err := DecodePrivateKey(privateKey) if err != nil { @@ -152,9 +152,9 @@ func GetECDSAKey(privateKey, accountDir, accountConfig string) (ethgo.Key, error // GetValidatorInfo queries SupernetManager smart contract on root // and retrieves validator info for given address -func GetValidatorInfo(validatorAddr ethgo.Address, supernetManagerAddr, stakeManagerAddr types.Address, +func GetValidatorInfo(validatorAddr types.Address, supernetManagerAddr, stakeManagerAddr types.Address, txRelayer txrelayer.TxRelayer) (*polybft.ValidatorInfo, error) { - caller := ethgo.Address(contracts.SystemCaller) + caller := contracts.SystemCaller getValidatorMethod := contractsapi.StakeManager.Abi.GetMethod("stakeOf") encode, err := getValidatorMethod.Encode([]interface{}{validatorAddr}) @@ -162,7 +162,7 @@ func GetValidatorInfo(validatorAddr ethgo.Address, supernetManagerAddr, stakeMan return nil, err } - response, err := txRelayer.Call(caller, ethgo.Address(supernetManagerAddr), encode) + response, err := txRelayer.Call(caller, supernetManagerAddr, encode) if err != nil { return nil, err } @@ -203,7 +203,7 @@ func GetValidatorInfo(validatorAddr ethgo.Address, supernetManagerAddr, stakeMan return nil, err } - response, err = txRelayer.Call(caller, ethgo.Address(stakeManagerAddr), encode) + response, err = txRelayer.Call(caller, stakeManagerAddr, encode) if err != nil { return nil, err } @@ -220,7 +220,7 @@ func GetValidatorInfo(validatorAddr ethgo.Address, supernetManagerAddr, stakeMan // CreateMintTxn encodes parameters for mint function on rootchain token contract func CreateMintTxn(receiver, erc20TokenAddr types.Address, - amount *big.Int, rootchainTx bool) (*ethgo.Transaction, error) { + amount *big.Int, rootchainTx bool) (*types.Transaction, error) { mintFn := &contractsapi.MintRootERC20Fn{ To: receiver, Amount: amount, @@ -231,8 +231,7 @@ func CreateMintTxn(receiver, erc20TokenAddr types.Address, return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(erc20TokenAddr) - txn := CreateTransaction(ethgo.ZeroAddress, &addr, input, nil, rootchainTx) + txn := CreateTransaction(types.ZeroAddress, &erc20TokenAddr, input, nil, rootchainTx) return txn, nil } @@ -240,7 +239,7 @@ func CreateMintTxn(receiver, erc20TokenAddr types.Address, // CreateApproveERC20Txn sends approve transaction // to ERC20 token for spender so that it is able to spend given tokens func CreateApproveERC20Txn(amount *big.Int, - spender, erc20TokenAddr types.Address, rootchainTx bool) (*ethgo.Transaction, error) { + spender, erc20TokenAddr types.Address, rootchainTx bool) (*types.Transaction, error) { approveFnParams := &contractsapi.ApproveRootERC20Fn{ Spender: spender, Amount: amount, @@ -251,20 +250,18 @@ func CreateApproveERC20Txn(amount *big.Int, return nil, fmt.Errorf("failed to encode parameters for RootERC20.approve. error: %w", err) } - addr := ethgo.Address(erc20TokenAddr) - - return CreateTransaction(ethgo.ZeroAddress, &addr, input, nil, rootchainTx), nil + return CreateTransaction(types.ZeroAddress, &erc20TokenAddr, input, nil, rootchainTx), nil } // SendTransaction sends provided transaction -func SendTransaction(txRelayer txrelayer.TxRelayer, addr ethgo.Address, input []byte, contractName string, - deployerKey ethgo.Key) (*ethgo.Receipt, error) { - txn := CreateTransaction(ethgo.ZeroAddress, &addr, input, nil, true) +func SendTransaction(txRelayer txrelayer.TxRelayer, addr types.Address, input []byte, contractName string, + deployerKey crypto.Key) (*ethgo.Receipt, error) { + txn := CreateTransaction(types.ZeroAddress, &addr, input, nil, true) receipt, err := txRelayer.SendTransaction(txn, deployerKey) if err != nil { return nil, fmt.Errorf("failed to send transaction to %s contract (%s). error: %w", - contractName, txn.To.Address(), err) + contractName, txn.To(), err) } if receipt == nil || receipt.Status != uint64(types.ReceiptSuccess) { @@ -275,25 +272,21 @@ func SendTransaction(txRelayer txrelayer.TxRelayer, addr ethgo.Address, input [] } // CreateTransaction is a helper function that creates either dynamic fee or legacy transaction based on provided flag -func CreateTransaction(sender ethgo.Address, receiver *ethgo.Address, - input []byte, value *big.Int, isDynamicFeeTx bool) *ethgo.Transaction { - txn := ðgo.Transaction{ - From: sender, - To: receiver, - Input: input, - Value: value, - } - +func CreateTransaction(sender types.Address, receiver *types.Address, + input []byte, value *big.Int, isDynamicFeeTx bool) *types.Transaction { + var txData types.TxData if isDynamicFeeTx { - txn.Type = ethgo.TransactionDynamicFee + txData = types.NewDynamicFeeTx(types.WithFrom(sender), + types.WithTo(receiver), types.WithValue(value), types.WithInput(input)) } else { - txn.Type = ethgo.TransactionLegacy + txData = types.NewLegacyTx(types.WithFrom(sender), + types.WithTo(receiver), types.WithValue(value), types.WithInput(input)) } - return txn + return types.NewTx(txData) } -func DeployProxyContract(txRelayer txrelayer.TxRelayer, deployerKey ethgo.Key, proxyContractName string, +func DeployProxyContract(txRelayer txrelayer.TxRelayer, deployerKey crypto.Key, proxyContractName string, proxyAdmin, logicAddress types.Address) (*ethgo.Receipt, error) { proxyConstructorFn := contractsapi.TransparentUpgradeableProxyConstructorFn{ Logic: logicAddress, @@ -312,7 +305,7 @@ func DeployProxyContract(txRelayer txrelayer.TxRelayer, deployerKey ethgo.Key, p proxyDeployInput = append(proxyDeployInput, contractsapi.TransparentUpgradeableProxy.Bytecode...) proxyDeployInput = append(proxyDeployInput, constructorInput...) - txn := CreateTransaction(ethgo.ZeroAddress, nil, proxyDeployInput, nil, true) + txn := CreateTransaction(types.ZeroAddress, nil, proxyDeployInput, nil, true) receipt, err := txRelayer.SendTransaction(txn, deployerKey) if err != nil { diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index 4cc264dedd..82c1dd281b 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -13,7 +13,6 @@ import ( "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" ) var ( @@ -140,7 +139,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - bladeManagerAddr := ethgo.Address(types.StringToAddress(params.bladeManager)) + bladeManagerAddr := types.StringToAddress(params.bladeManager) txn := bridgeHelper.CreateTransaction(ownerKey.Address(), &bladeManagerAddr, premineInput, nil, false) receipt, err = txRelayer.SendTransaction(txn, ownerKey) diff --git a/command/bridge/withdraw/erc1155/withdraw_erc1155.go b/command/bridge/withdraw/erc1155/withdraw_erc1155.go index 8789ae6d10..a2f977e113 100644 --- a/command/bridge/withdraw/erc1155/withdraw_erc1155.go +++ b/command/bridge/withdraw/erc1155/withdraw_erc1155.go @@ -7,14 +7,13 @@ import ( "strings" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" helperCommon "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -85,7 +84,7 @@ func runCommand(cmd *cobra.Command, _ []string) { return } - senderAccount, err := wallet.NewWalletFromPrivKey(senderKeyRaw) + senderAccount, err := crypto.NewECDSAKeyFromRawPrivECDSA(senderKeyRaw) if err != nil { outputter.SetError(err) @@ -101,7 +100,7 @@ func runCommand(cmd *cobra.Command, _ []string) { receivers := make([]types.Address, len(wp.Receivers)) amounts := make([]*big.Int, len(wp.Receivers)) - TokenIDs := make([]*big.Int, len(wp.Receivers)) + tokenIDs := make([]*big.Int, len(wp.Receivers)) for i, receiverRaw := range wp.Receivers { receivers[i] = types.StringToAddress(receiverRaw) @@ -123,11 +122,11 @@ func runCommand(cmd *cobra.Command, _ []string) { } amounts[i] = amount - TokenIDs[i] = tokenID + tokenIDs[i] = tokenID } // withdraw tokens transaction - txn, err := createWithdrawTxn(receivers, amounts, TokenIDs) + txn, err := createWithdrawTxn(receivers, amounts, tokenIDs) if err != nil { outputter.SetError(fmt.Errorf("failed to create tx input: %w", err)) @@ -173,12 +172,12 @@ func runCommand(cmd *cobra.Command, _ []string) { } // createWithdrawTxn encodes parameters for withdraw function on child chain predicate contract -func createWithdrawTxn(receivers []types.Address, amounts, TokenIDs []*big.Int) (*ethgo.Transaction, error) { +func createWithdrawTxn(receivers []types.Address, amounts, tokenIDs []*big.Int) (*types.Transaction, error) { withdrawFn := &contractsapi.WithdrawBatchChildERC1155PredicateFn{ ChildToken: types.StringToAddress(wp.TokenAddr), Receivers: receivers, Amounts: amounts, - TokenIDs: TokenIDs, + TokenIDs: tokenIDs, } input, err := withdrawFn.EncodeAbi() @@ -186,8 +185,8 @@ func createWithdrawTxn(receivers []types.Address, amounts, TokenIDs []*big.Int) return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(wp.PredicateAddr)) + addr := types.StringToAddress(wp.PredicateAddr) - return helper.CreateTransaction(ethgo.ZeroAddress, &addr, input, + return helper.CreateTransaction(types.ZeroAddress, &addr, input, nil, wp.ChildChainMintable), nil } diff --git a/command/bridge/withdraw/erc20/withdraw_erc20.go b/command/bridge/withdraw/erc20/withdraw_erc20.go index 360b1c4fd2..1cd3742ff2 100644 --- a/command/bridge/withdraw/erc20/withdraw_erc20.go +++ b/command/bridge/withdraw/erc20/withdraw_erc20.go @@ -6,14 +6,13 @@ import ( "math/big" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" helperCommon "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -76,7 +75,7 @@ func runCommand(cmd *cobra.Command, _ []string) { return } - senderAccount, err := wallet.NewWalletFromPrivKey(senderKeyRaw) + senderAccount, err := crypto.NewECDSAKeyFromRawPrivECDSA(senderKeyRaw) if err != nil { outputter.SetError(err) @@ -152,7 +151,7 @@ func runCommand(cmd *cobra.Command, _ []string) { } // createWithdrawTxn encodes parameters for withdraw function on destination predicate contract -func createWithdrawTxn(receiver types.Address, amount *big.Int) (*ethgo.Transaction, error) { +func createWithdrawTxn(receiver types.Address, amount *big.Int) (*types.Transaction, error) { withdrawToFn := &contractsapi.WithdrawToChildERC20PredicateFn{ ChildToken: types.StringToAddress(wp.TokenAddr), Receiver: receiver, @@ -164,8 +163,8 @@ func createWithdrawTxn(receiver types.Address, amount *big.Int) (*ethgo.Transact return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(wp.PredicateAddr)) + addr := types.StringToAddress(wp.PredicateAddr) - return helper.CreateTransaction(ethgo.ZeroAddress, &addr, input, + return helper.CreateTransaction(types.ZeroAddress, &addr, input, nil, wp.ChildChainMintable), nil } diff --git a/command/bridge/withdraw/erc721/withdraw_erc721.go b/command/bridge/withdraw/erc721/withdraw_erc721.go index c36381ead1..0fa596d5e1 100644 --- a/command/bridge/withdraw/erc721/withdraw_erc721.go +++ b/command/bridge/withdraw/erc721/withdraw_erc721.go @@ -11,12 +11,11 @@ import ( "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" helperCommon "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/wallet" ) var ( @@ -76,7 +75,7 @@ func run(cmd *cobra.Command, _ []string) { return } - senderAccount, err := wallet.NewWalletFromPrivKey(senderKeyRaw) + senderAccount, err := crypto.NewECDSAKeyFromRawPrivECDSA(senderKeyRaw) if err != nil { outputter.SetError(err) @@ -152,7 +151,7 @@ func run(cmd *cobra.Command, _ []string) { } // createWithdrawTxn encodes parameters for withdraw function on child chain predicate contract -func createWithdrawTxn(receivers []types.Address, tokenIDs []*big.Int) (*ethgo.Transaction, error) { +func createWithdrawTxn(receivers []types.Address, tokenIDs []*big.Int) (*types.Transaction, error) { withdrawToFn := &contractsapi.WithdrawBatchChildERC721PredicateFn{ ChildToken: types.StringToAddress(wp.TokenAddr), Receivers: receivers, @@ -164,8 +163,8 @@ func createWithdrawTxn(receivers []types.Address, tokenIDs []*big.Int) (*ethgo.T return nil, fmt.Errorf("failed to encode provided parameters: %w", err) } - addr := ethgo.Address(types.StringToAddress(wp.PredicateAddr)) + addr := types.StringToAddress(wp.PredicateAddr) - return helper.CreateTransaction(ethgo.ZeroAddress, &addr, input, + return helper.CreateTransaction(types.ZeroAddress, &addr, input, nil, wp.ChildChainMintable), nil } diff --git a/command/secrets/init/params_test.go b/command/secrets/init/params_test.go index a95e097dc3..a27671d73f 100644 --- a/command/secrets/init/params_test.go +++ b/command/secrets/init/params_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/bls" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/secrets/helper" ) @@ -94,7 +94,8 @@ func Test_getResult(t *testing.T) { // Test public key serialization privKey, err := hex.DecodeString(sir.PrivateKey) require.NoError(t, err) - k, err := wallet.NewWalletFromPrivKey(privKey) + + k, err := crypto.NewECDSAKeyFromRawPrivECDSA(privKey) require.NoError(t, err) pubKey := k.Address().String() diff --git a/command/validator/helper/helper.go b/command/validator/helper/helper.go index 6ca1e981b3..8ff2be7314 100644 --- a/command/validator/helper/helper.go +++ b/command/validator/helper/helper.go @@ -14,7 +14,6 @@ import ( "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" - "github.com/umbracle/ethgo" ) const ( @@ -59,7 +58,7 @@ func GetAccountFromDir(accountDir string) (*wallet.Account, error) { // GetValidatorInfo queries CustomSupernetManager, StakeManager and RewardPool smart contracts // to retrieve validator info for given address -func GetValidatorInfo(validatorAddr ethgo.Address, childRelayer txrelayer.TxRelayer) (*polybft.ValidatorInfo, error) { +func GetValidatorInfo(validatorAddr types.Address, childRelayer txrelayer.TxRelayer) (*polybft.ValidatorInfo, error) { getValidatorMethod := contractsapi.StakeManager.Abi.GetMethod("getValidator") encode, err := getValidatorMethod.Encode([]interface{}{validatorAddr}) @@ -67,8 +66,7 @@ func GetValidatorInfo(validatorAddr ethgo.Address, childRelayer txrelayer.TxRela return nil, err } - response, err := childRelayer.Call(ethgo.Address(contracts.SystemCaller), - ethgo.Address(contracts.StakeManagerContract), encode) + response, err := childRelayer.Call(contracts.SystemCaller, contracts.StakeManagerContract, encode) if err != nil { return nil, err } @@ -109,8 +107,7 @@ func GetValidatorInfo(validatorAddr ethgo.Address, childRelayer txrelayer.TxRela return nil, err } - response, err = childRelayer.Call(ethgo.Address(contracts.SystemCaller), - ethgo.Address(contracts.StakeManagerContract), encode) + response, err = childRelayer.Call(contracts.SystemCaller, contracts.StakeManagerContract, encode) if err != nil { return nil, err } @@ -129,7 +126,7 @@ func GetValidatorInfo(validatorAddr ethgo.Address, childRelayer txrelayer.TxRela return nil, err } - response, err = childRelayer.Call(ethgo.ZeroAddress, ethgo.Address(contracts.EpochManagerContract), encode) + response, err = childRelayer.Call(types.ZeroAddress, contracts.EpochManagerContract, encode) if err != nil { return nil, err } diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 9ab1d8d878..59c6416961 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -183,8 +183,7 @@ func registerValidator(sender txrelayer.TxRelayer, account *wallet.Account, return nil, fmt.Errorf("register validator failed: %w", err) } - stakeManagerAddr := ethgo.Address(contracts.StakeManagerContract) - txn := bridgeHelper.CreateTransaction(ethgo.ZeroAddress, &stakeManagerAddr, input, nil, true) + txn := bridgeHelper.CreateTransaction(types.ZeroAddress, &contracts.StakeManagerContract, input, nil, true) return sender.SendTransaction(txn, account.Ecdsa) } diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index 208c87372a..5209d1382d 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -4,6 +4,8 @@ import ( "fmt" "time" + "github.com/spf13/cobra" + "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/command/helper" @@ -13,8 +15,6 @@ import ( "github.com/0xPolygon/polygon-edge/contracts" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" - "github.com/spf13/cobra" - "github.com/umbracle/ethgo" ) var ( @@ -112,9 +112,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - stakeManagerAddr := ethgo.Address(contracts.StakeManagerContract) - - txn := bridgeHelper.CreateTransaction(validatorAccount.Ecdsa.Address(), &stakeManagerAddr, encoded, nil, true) + txn := bridgeHelper.CreateTransaction(validatorAccount.Ecdsa.Address(), + &contracts.StakeManagerContract, encoded, nil, true) receipt, err = txRelayer.SendTransaction(txn, validatorAccount.Ecdsa) if err != nil { diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index 24292b5507..21eb10abcf 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -13,7 +13,6 @@ import ( "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" ) var params unstakeParams @@ -87,11 +86,10 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - txn := ðgo.Transaction{ - From: validatorAccount.Ecdsa.Address(), - Input: encoded, - To: (*ethgo.Address)(&contracts.StakeManagerContract), - } + txn := types.NewTx(types.NewLegacyTx( + types.WithFrom(validatorAccount.Ecdsa.Address()), + types.WithInput(encoded), + types.WithTo(&contracts.StakeManagerContract))) receipt, err := txRelayer.SendTransaction(txn, validatorAccount.Ecdsa) if err != nil { diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index 4db4afd212..be32fe43ce 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -13,7 +13,6 @@ import ( "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" ) var params whitelistParams @@ -97,8 +96,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { return fmt.Errorf("whitelist validator failed. Could not abi encode whitelist function: %w", err) } - stakeManagerAddr := ethgo.Address(contracts.StakeManagerContract) - txn := bridgeHelper.CreateTransaction(ecdsaKey.Address(), &stakeManagerAddr, encoded, nil, true) + txn := bridgeHelper.CreateTransaction(ecdsaKey.Address(), &contracts.StakeManagerContract, encoded, nil, true) receipt, err := txRelayer.SendTransaction(txn, ecdsaKey) if err != nil { diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index ac21e0e5a8..8a6a383bee 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -5,7 +5,6 @@ import ( "time" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -69,7 +68,6 @@ func runCommand(cmd *cobra.Command, _ []string) error { } validatorAddr := validatorAccount.Ecdsa.Address() - epochManagerContract := ethgo.Address(contracts.EpochManagerContract) txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), txrelayer.WithReceiptTimeout(150*time.Millisecond)) @@ -82,7 +80,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - response, err := txRelayer.Call(validatorAddr, epochManagerContract, encoded) + response, err := txRelayer.Call(validatorAddr, contracts.EpochManagerContract, encoded) if err != nil { return err } @@ -97,7 +95,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - txn := bridgeHelper.CreateTransaction(validatorAddr, &epochManagerContract, encoded, nil, false) + txn := bridgeHelper.CreateTransaction(validatorAddr, &contracts.EpochManagerContract, encoded, nil, false) receipt, err := txRelayer.SendTransaction(txn, validatorAccount.Ecdsa) if err != nil { diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index 75d727d4e9..fd02eb48bf 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -14,7 +14,6 @@ import ( "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/spf13/cobra" - "github.com/umbracle/ethgo" ) var params withdrawParams @@ -77,8 +76,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - receiver := (*ethgo.Address)(&contracts.StakeManagerContract) - txn := bridgeHelper.CreateTransaction(validatorAccount.Ecdsa.Address(), receiver, encoded, nil, false) + txn := bridgeHelper.CreateTransaction(validatorAccount.Ecdsa.Address(), + &contracts.StakeManagerContract, encoded, nil, false) receipt, err := txRelayer.SendTransaction(txn, validatorAccount.Ecdsa) if err != nil { diff --git a/consensus/polybft/block_builder_test.go b/consensus/polybft/block_builder_test.go index 041ddfb30a..3d0f984daa 100644 --- a/consensus/polybft/block_builder_test.go +++ b/consensus/polybft/block_builder_test.go @@ -1,12 +1,12 @@ package polybft import ( - "crypto/ecdsa" "math/big" "testing" "time" "github.com/0xPolygon/polygon-edge/chain" + "github.com/0xPolygon/polygon-edge/consensus/polybft/wallet" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/state" @@ -29,21 +29,13 @@ func TestBlockBuilder_BuildBlockTxOneFailedTxAndOneTakesTooMuchGas(t *testing.T) chainID = 100 ) - type account struct { - privKey *ecdsa.PrivateKey - address types.Address - } - - accounts := [6]*account{} + accounts := make([]*wallet.Account, 0, 6) - for i := range accounts { - ecdsaKey, err := crypto.GenerateECDSAKey() + for i := 0; i < cap(accounts); i++ { + acc, err := wallet.GenerateAccount() require.NoError(t, err) - accounts[i] = &account{ - privKey: ecdsaKey, - address: crypto.PubKeyToAddress(&ecdsaKey.PublicKey), - } + accounts = append(accounts, acc) } forks := &chain.Forks{} @@ -71,7 +63,7 @@ func TestBlockBuilder_BuildBlockTxOneFailedTxAndOneTakesTooMuchGas(t *testing.T) for i, acc := range accounts { // the third tx will fail because of insufficient balance if i != 2 { - balanceMap[acc.address] = &chain.GenesisAccount{Balance: ethgo.Ether(1)} + balanceMap[acc.Address()] = &chain.GenesisAccount{Balance: ethgo.Ether(1)} } } @@ -93,15 +85,19 @@ func TestBlockBuilder_BuildBlockTxOneFailedTxAndOneTakesTooMuchGas(t *testing.T) gas = blockGasLimit - 1 } + recipient := acc.Address() + tx := types.NewTx(types.NewLegacyTx( types.WithGasPrice(big.NewInt(gasPrice)), types.WithValue(big.NewInt(amount)), types.WithGas(gas), types.WithNonce(0), - types.WithTo(&acc.address), + types.WithTo(&recipient), )) - tx, err = signer.SignTx(tx, acc.privKey) + tx, err = signer.SignTxWithCallback(tx, func(hash types.Hash) (sig []byte, err error) { + return acc.Ecdsa.Sign(hash.Bytes()) + }) require.NoError(t, err) // all tx until the fifth will be retrieved from the pool diff --git a/consensus/polybft/blockchain_wrapper.go b/consensus/polybft/blockchain_wrapper.go index 902f2bca19..dd23b9b437 100644 --- a/consensus/polybft/blockchain_wrapper.go +++ b/consensus/polybft/blockchain_wrapper.go @@ -228,6 +228,6 @@ func (s *stateProvider) Call(addr ethgo.Address, input []byte, opts *contract.Ca // Txn is part of the contract.Provider interface to make Ethereum transactions. We disable this function // since the system state does not make any transaction -func (s *stateProvider) Txn(ethgo.Address, ethgo.Key, []byte) (contract.Txn, error) { +func (s *stateProvider) Txn(_ ethgo.Address, _ ethgo.Key, _ []byte) (contract.Txn, error) { return nil, errSendTxnUnsupported } diff --git a/consensus/polybft/checkpoint_manager.go b/consensus/polybft/checkpoint_manager.go index 86ee6c98c5..2fdeaf3533 100644 --- a/consensus/polybft/checkpoint_manager.go +++ b/consensus/polybft/checkpoint_manager.go @@ -10,6 +10,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -58,7 +59,7 @@ var _ CheckpointManager = (*checkpointManager)(nil) // checkpointManager encapsulates logic for checkpoint data submission type checkpointManager struct { // key is the identity of the node submitting a checkpoint - key ethgo.Key + key crypto.Key // blockchain is abstraction for blockchain blockchain blockchainBackend // consensusBackend is abstraction for polybft consensus specific functions @@ -76,7 +77,7 @@ type checkpointManager struct { } // newCheckpointManager creates a new instance of checkpointManager -func newCheckpointManager(key ethgo.Key, +func newCheckpointManager(key crypto.Key, checkpointManagerSC types.Address, txRelayer txrelayer.TxRelayer, blockchain blockchainBackend, backend polybftBackend, logger hclog.Logger, state *State) *checkpointManager { @@ -98,7 +99,7 @@ func getCurrentCheckpointBlock(relayer txrelayer.TxRelayer, checkpointManagerAdd return 0, fmt.Errorf("failed to encode currentCheckpointBlockNumber function parameters: %w", err) } - currentCheckpointBlockRaw, err := relayer.Call(ethgo.ZeroAddress, ethgo.Address(checkpointManagerAddr), + currentCheckpointBlockRaw, err := relayer.Call(types.ZeroAddress, checkpointManagerAddr, checkpointBlockNumInput) if err != nil { return 0, fmt.Errorf("failed to invoke currentCheckpointBlockNumber function on the rootchain: %w", err) @@ -198,8 +199,6 @@ func (c *checkpointManager) submitCheckpoint(latestHeader *types.Header, isEndOf func (c *checkpointManager) encodeAndSendCheckpoint(header *types.Header, extra *Extra, isEndOfEpoch bool) error { c.logger.Debug("send checkpoint txn...", "block number", header.Number) - checkpointManager := ethgo.Address(c.checkpointManagerAddr) - nextEpochValidators := validator.AccountSet{} if isEndOfEpoch { @@ -216,11 +215,10 @@ func (c *checkpointManager) encodeAndSendCheckpoint(header *types.Header, extra return fmt.Errorf("failed to encode checkpoint data to ABI for block %d: %w", header.Number, err) } - txn := ðgo.Transaction{ - To: &checkpointManager, - Input: input, - Type: ethgo.TransactionDynamicFee, - } + txn := types.NewTx(types.NewDynamicFeeTx( + types.WithTo(&c.checkpointManagerAddr), + types.WithInput(input), + )) receipt, err := c.rootChainRelayer.SendTransaction(txn, c.key) if err != nil { @@ -331,9 +329,7 @@ func (c *checkpointManager) GenerateExitProof(exitID uint64) (types.Proof, error return types.Proof{}, fmt.Errorf("failed to encode get checkpoint block input: %w", err) } - getCheckpointBlockResp, err := c.rootChainRelayer.Call( - ethgo.ZeroAddress, - ethgo.Address(c.checkpointManagerAddr), + getCheckpointBlockResp, err := c.rootChainRelayer.Call(types.ZeroAddress, c.checkpointManagerAddr, input) if err != nil { return types.Proof{}, fmt.Errorf("failed to retrieve checkpoint block for exit ID %d: %w", exitID, err) diff --git a/consensus/polybft/checkpoint_manager_test.go b/consensus/polybft/checkpoint_manager_test.go index 1e0430ac73..c3a2a03da8 100644 --- a/consensus/polybft/checkpoint_manager_test.go +++ b/consensus/polybft/checkpoint_manager_test.go @@ -11,6 +11,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/signer" + "github.com/0xPolygon/polygon-edge/crypto" merkle "github.com/Ethernal-Tech/merkle-tree" hclog "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/mock" @@ -36,7 +37,7 @@ func TestCheckpointManager_SubmitCheckpoint(t *testing.T) { t.Run("submit checkpoint happy path", func(t *testing.T) { t.Parallel() - var aliases = []string{"A", "B", "C", "D", "E"} + aliases := []string{"A", "B", "C", "D", "E"} validators := validator.NewTestValidatorsWithAliases(t, aliases) validatorsMetadata := validators.GetPublicIdentities() @@ -383,7 +384,7 @@ func TestCheckpointManager_GenerateExitProof(t *testing.T) { require.NoError(t, err) dummyTxRelayer := newDummyTxRelayer(t) - dummyTxRelayer.On("Call", ethgo.ZeroAddress, ethgo.ZeroAddress, input). + dummyTxRelayer.On("Call", types.ZeroAddress, types.ZeroAddress, input). Return(hex.EncodeToString(foundCheckpointReturn), error(nil)) // create checkpoint manager and insert exit events @@ -450,7 +451,7 @@ func TestCheckpointManager_GenerateExitProof(t *testing.T) { inputTwo, err := getCheckpointBlockFn.EncodeAbi() require.NoError(t, err) - dummyTxRelayer.On("Call", ethgo.ZeroAddress, ethgo.ZeroAddress, inputTwo). + dummyTxRelayer.On("Call", types.ZeroAddress, types.ZeroAddress, inputTwo). Return(hex.EncodeToString(notFoundCheckpointReturn), error(nil)) _, err = checkpointMgr.GenerateExitProof(futureBlockToGetExit) @@ -473,14 +474,14 @@ func newDummyTxRelayer(t *testing.T) *dummyTxRelayer { return &dummyTxRelayer{test: t} } -func (d *dummyTxRelayer) Call(from ethgo.Address, to ethgo.Address, input []byte) (string, error) { +func (d *dummyTxRelayer) Call(from types.Address, to types.Address, input []byte) (string, error) { args := d.Called(from, to, input) return args.String(0), args.Error(1) } -func (d *dummyTxRelayer) SendTransaction(transaction *ethgo.Transaction, key ethgo.Key) (*ethgo.Receipt, error) { - blockNumber := getBlockNumberCheckpointSubmitInput(d.test, transaction.Input) +func (d *dummyTxRelayer) SendTransaction(transaction *types.Transaction, key crypto.Key) (*ethgo.Receipt, error) { + blockNumber := getBlockNumberCheckpointSubmitInput(d.test, transaction.Input()) d.checkpointBlocks = append(d.checkpointBlocks, blockNumber) args := d.Called(transaction, key) @@ -488,7 +489,7 @@ func (d *dummyTxRelayer) SendTransaction(transaction *ethgo.Transaction, key eth } // SendTransactionLocal sends non-signed transaction (this is only for testing purposes) -func (d *dummyTxRelayer) SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Receipt, error) { +func (d *dummyTxRelayer) SendTransactionLocal(txn *types.Transaction) (*ethgo.Receipt, error) { args := d.Called(txn) return args.Get(0).(*ethgo.Receipt), args.Error(1) diff --git a/consensus/polybft/exit_relayer.go b/consensus/polybft/exit_relayer.go index 45d9118772..56c4519876 100644 --- a/consensus/polybft/exit_relayer.go +++ b/consensus/polybft/exit_relayer.go @@ -7,6 +7,7 @@ import ( "math/big" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" @@ -43,7 +44,7 @@ var _ ExitRelayer = (*exitRelayer)(nil) type exitRelayer struct { *relayerEventsProcessor - key ethgo.Key + key crypto.Key proofRetriever ExitEventProofRetriever txRelayer txrelayer.TxRelayer logger hclog.Logger @@ -56,7 +57,7 @@ type exitRelayer struct { // newExitRelayer creates a new instance of exitRelayer func newExitRelayer( txRelayer txrelayer.TxRelayer, - key ethgo.Key, + key crypto.Key, proofRetriever ExitEventProofRetriever, blockchain blockchainBackend, exitStore *ExitStore, @@ -226,12 +227,14 @@ func (e *exitRelayer) sendTx(events []*RelayerEventMetaData) error { return err } + exitTxn := types.NewTx(types.NewLegacyTx( + types.WithFrom(e.key.Address()), + types.WithTo(&e.config.eventExecutionAddr), + types.WithInput(input), + )) + // send batchExecute exit events - _, err = e.txRelayer.SendTransaction(ðgo.Transaction{ - From: e.key.Address(), - To: (*ethgo.Address)(&e.config.eventExecutionAddr), - Input: input, - }, e.key) + _, err = e.txRelayer.SendTransaction(exitTxn, e.key) return err } diff --git a/consensus/polybft/stake_manager_test.go b/consensus/polybft/stake_manager_test.go index 283ead1fc1..c6b5cf4993 100644 --- a/consensus/polybft/stake_manager_test.go +++ b/consensus/polybft/stake_manager_test.go @@ -6,6 +6,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -500,7 +501,7 @@ func newDummyStakeTxRelayer(t *testing.T, callback func() *validator.ValidatorMe } } -func (d *dummyStakeTxRelayer) Call(from ethgo.Address, to ethgo.Address, input []byte) (string, error) { +func (d *dummyStakeTxRelayer) Call(from types.Address, to types.Address, input []byte) (string, error) { args := d.Called(from, to, input) if d.callback != nil { @@ -520,14 +521,14 @@ func (d *dummyStakeTxRelayer) Call(from ethgo.Address, to ethgo.Address, input [ return args.String(0), args.Error(1) } -func (d *dummyStakeTxRelayer) SendTransaction(transaction *ethgo.Transaction, key ethgo.Key) (*ethgo.Receipt, error) { +func (d *dummyStakeTxRelayer) SendTransaction(transaction *types.Transaction, key crypto.Key) (*ethgo.Receipt, error) { args := d.Called(transaction, key) return args.Get(0).(*ethgo.Receipt), args.Error(1) } // SendTransactionLocal sends non-signed transaction (this is only for testing purposes) -func (d *dummyStakeTxRelayer) SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Receipt, error) { +func (d *dummyStakeTxRelayer) SendTransactionLocal(txn *types.Transaction) (*ethgo.Receipt, error) { args := d.Called(txn) return args.Get(0).(*ethgo.Receipt), args.Error(1) diff --git a/consensus/polybft/state_sync_relayer.go b/consensus/polybft/state_sync_relayer.go index 8007790759..c29fad79b3 100644 --- a/consensus/polybft/state_sync_relayer.go +++ b/consensus/polybft/state_sync_relayer.go @@ -9,6 +9,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" @@ -59,7 +60,7 @@ type stateSyncRelayerImpl struct { *relayerEventsProcessor txRelayer txrelayer.TxRelayer - key ethgo.Key + key crypto.Key proofRetriever StateSyncProofRetriever logger hclog.Logger @@ -72,7 +73,7 @@ func newStateSyncRelayer( state *StateSyncStore, store StateSyncProofRetriever, blockchain blockchainBackend, - key ethgo.Key, + key crypto.Key, config *relayerConfig, logger hclog.Logger, ) *stateSyncRelayerImpl { @@ -159,13 +160,15 @@ func (ssr stateSyncRelayerImpl) sendTx(events []*RelayerEventMetaData) error { return err } + txn := types.NewTx(types.NewLegacyTx( + types.WithFrom(ssr.key.Address()), + types.WithTo(&ssr.config.eventExecutionAddr), + types.WithGas(types.StateTransactionGasLimit), + types.WithInput(input), + )) + // send batchExecute state sync - _, err = ssr.txRelayer.SendTransaction(ðgo.Transaction{ - From: ssr.key.Address(), - To: (*ethgo.Address)(&ssr.config.eventExecutionAddr), - Gas: types.StateTransactionGasLimit, - Input: input, - }, ssr.key) + _, err = ssr.txRelayer.SendTransaction(txn, ssr.key) return err } diff --git a/consensus/polybft/system_state.go b/consensus/polybft/system_state.go index 86bfd684e9..96685aa772 100644 --- a/consensus/polybft/system_state.go +++ b/consensus/polybft/system_state.go @@ -13,7 +13,7 @@ import ( // ValidatorInfo is data transfer object which holds validator information, // provided by smart contract type ValidatorInfo struct { - Address ethgo.Address `json:"address"` + Address types.Address `json:"address"` Stake *big.Int `json:"stake"` WithdrawableRewards *big.Int `json:"withdrawableRewards"` IsActive bool `json:"isActive"` diff --git a/consensus/polybft/system_state_test.go b/consensus/polybft/system_state_test.go index ea001fe48b..3f5f038bb2 100644 --- a/consensus/polybft/system_state_test.go +++ b/consensus/polybft/system_state_test.go @@ -17,6 +17,7 @@ import ( "github.com/umbracle/ethgo/abi" "github.com/umbracle/ethgo/contract" "github.com/umbracle/ethgo/testutil" + "github.com/umbracle/ethgo/wallet" ) func TestSystemState_GetNextCommittedIndex(t *testing.T) { @@ -116,13 +117,14 @@ func TestSystemState_GetEpoch(t *testing.T) { func TestStateProvider_Txn_NotSupported(t *testing.T) { t.Parallel() - transition := newTestTransition(t, nil) - provider := &stateProvider{ - transition: transition, + transition: newTestTransition(t, nil), } - _, err := provider.Txn(ethgo.ZeroAddress, createTestKey(t), []byte{0x1}) + key, err := wallet.GenerateKey() + require.NoError(t, err) + + _, err = provider.Txn(ethgo.ZeroAddress, key, []byte{0x1}) require.ErrorIs(t, err, errSendTxnUnsupported) } diff --git a/consensus/polybft/wallet/account.go b/consensus/polybft/wallet/account.go index 7fb7477005..a467dc4d64 100644 --- a/consensus/polybft/wallet/account.go +++ b/consensus/polybft/wallet/account.go @@ -5,22 +5,21 @@ import ( "encoding/hex" "fmt" - "github.com/umbracle/ethgo/wallet" - "github.com/0xPolygon/polygon-edge/bls" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/secrets" "github.com/0xPolygon/polygon-edge/types" ) // Account is an account for key signatures type Account struct { - Ecdsa *wallet.Key + Ecdsa *crypto.ECDSAKey Bls *bls.PrivateKey } // GenerateAccount generates a new random account func GenerateAccount() (*Account, error) { - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() if err != nil { return nil, fmt.Errorf("cannot generate key. error: %w", err) } @@ -52,7 +51,7 @@ func NewAccountFromSecret(secretsManager secrets.SecretsManager) (*Account, erro } // GetEcdsaFromSecret retrieves validator(ECDSA) key by using provided secretsManager -func GetEcdsaFromSecret(secretsManager secrets.SecretsManager) (*wallet.Key, error) { +func GetEcdsaFromSecret(secretsManager secrets.SecretsManager) (*crypto.ECDSAKey, error) { encodedKey, err := secretsManager.GetSecret(secrets.ValidatorKey) if err != nil { return nil, fmt.Errorf("failed to retrieve ecdsa key: %w", err) @@ -63,7 +62,7 @@ func GetEcdsaFromSecret(secretsManager secrets.SecretsManager) (*wallet.Key, err return nil, fmt.Errorf("failed to retrieve ecdsa key: %w", err) } - key, err := wallet.NewWalletFromPrivKey(ecdsaRaw) + key, err := crypto.NewECDSAKeyFromRawPrivECDSA(ecdsaRaw) if err != nil { return nil, fmt.Errorf("failed to retrieve ecdsa key: %w", err) } @@ -116,7 +115,7 @@ func (a *Account) GetEcdsaPrivateKey() (*ecdsa.PrivateKey, error) { return nil, err } - return wallet.ParsePrivateKey(ecdsaRaw) + return crypto.ParseECDSAPrivateKey(ecdsaRaw) } func (a Account) Address() types.Address { diff --git a/consensus/polybft/wallet/key.go b/consensus/polybft/wallet/key.go index 1919de1845..7be0085ead 100644 --- a/consensus/polybft/wallet/key.go +++ b/consensus/polybft/wallet/key.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/0xPolygon/go-ibft/messages/proto" - "github.com/umbracle/ethgo" protobuf "google.golang.org/protobuf/proto" "github.com/0xPolygon/polygon-edge/consensus/polybft/signer" @@ -28,7 +27,7 @@ func (k *Key) String() string { } // Address returns ECDSA address -func (k *Key) Address() ethgo.Address { +func (k *Key) Address() types.Address { return k.raw.Ecdsa.Address() } @@ -73,13 +72,13 @@ func RecoverAddressFromSignature(sig, rawContent []byte) (types.Address, error) return crypto.PubKeyToAddress(pub), nil } -// ECDSASigner implements ethgo.Key interface and it is used for signing using provided ECDSA key +// ECDSASigner implements crypto.Key interface and it is used for signing using provided ECDSA key type ECDSASigner struct { *Key } -func NewEcdsaSigner(ecdsaKey *Key) *ECDSASigner { - return &ECDSASigner{Key: ecdsaKey} +func NewEcdsaSigner(key *Key) *ECDSASigner { + return &ECDSASigner{Key: key} } func (k *ECDSASigner) Sign(b []byte) ([]byte, error) { diff --git a/crypto/crypto.go b/crypto/crypto.go index 061ca03c06..748989243d 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -128,8 +128,8 @@ func MarshalECDSAPrivateKey(priv *ecdsa.PrivateKey) ([]byte, error) { return btcPriv.Serialize(), nil } -// GenerateECDSAKey generates a new key based on the secp256k1 elliptic curve. -func GenerateECDSAKey() (*ecdsa.PrivateKey, error) { +// GenerateECDSAPrivateKey generates a new key based on the secp256k1 elliptic curve. +func GenerateECDSAPrivateKey() (*ecdsa.PrivateKey, error) { return ecdsa.GenerateKey(btcec.S256(), rand.Reader) } @@ -264,7 +264,7 @@ func GetAddressFromKey(key goCrypto.PrivateKey) (types.Address, error) { // generateECDSAKeyAndMarshal generates a new ECDSA private key and serializes it to a byte array func generateECDSAKeyAndMarshal() ([]byte, error) { - key, err := GenerateECDSAKey() + key, err := GenerateECDSAPrivateKey() if err != nil { return nil, err } diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 613101338f..1b0ef5ef05 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -17,7 +17,7 @@ import ( func TestKeyEncoding(t *testing.T) { for i := 0; i < 10; i++ { - priv, _ := GenerateECDSAKey() + priv, _ := GenerateECDSAPrivateKey() // marshall private key buf, err := MarshalECDSAPrivateKey(priv) @@ -461,7 +461,7 @@ func TestRecoverPublicKey(t *testing.T) { hash := types.BytesToHash([]byte{0, 1, 2}) - privateKey, err := GenerateECDSAKey() + privateKey, err := GenerateECDSAPrivateKey() require.NoError(t, err) signature, err := Sign(privateKey, hash.Bytes()) diff --git a/crypto/ecdsa_key.go b/crypto/ecdsa_key.go new file mode 100644 index 0000000000..3cf502e3f5 --- /dev/null +++ b/crypto/ecdsa_key.go @@ -0,0 +1,76 @@ +package crypto + +import ( + "crypto/ecdsa" + + "github.com/0xPolygon/polygon-edge/types" +) + +type Key interface { + Address() types.Address + Sign(hash []byte) ([]byte, error) +} + +var _ Key = (*ECDSAKey)(nil) + +type ECDSAKey struct { + priv *ecdsa.PrivateKey + pub *ecdsa.PublicKey + addr types.Address +} + +// NewECDSAKey returns new instance of ECDSAKey +func NewECDSAKey(priv *ecdsa.PrivateKey) *ECDSAKey { + return &ECDSAKey{ + priv: priv, + pub: &priv.PublicKey, + addr: PubKeyToAddress(&priv.PublicKey), + } +} + +// GenerateECDSAKey generates an ECDSA private key and wraps it into ECDSA key +// (that is a wrapper for ECDSA private key and holds private key, public key and address) +func GenerateECDSAKey() (*ECDSAKey, error) { + privKey, err := GenerateECDSAPrivateKey() + if err != nil { + return nil, err + } + + return NewECDSAKey(privKey), nil +} + +// NewECDSAKeyFromRawPrivECDSA parses provided +func NewECDSAKeyFromRawPrivECDSA(rawPrivKey []byte) (*ECDSAKey, error) { + priv, err := ParseECDSAPrivateKey(rawPrivKey) + if err != nil { + return nil, err + } + + return NewECDSAKey(priv), nil +} + +// Sign uses the private key and signs the provided hash which produces a signature as a result +func (k *ECDSAKey) Sign(hash []byte) ([]byte, error) { + return Sign(k.priv, hash) +} + +// Address is a getter function for Ethereum address derived from the public key +func (k *ECDSAKey) Address() types.Address { + return k.addr +} + +// MarshallPrivateKey returns 256-bit big-endian binary-encoded representation of the private key +// padded to a length of 32 bytes. +func (k *ECDSAKey) MarshallPrivateKey() ([]byte, error) { + btcPrivKey, err := convertToBtcPrivKey(k.priv) + if err != nil { + return nil, err + } + + return btcPrivKey.Serialize(), nil +} + +// String returns hex encoded ECDSA address +func (k *ECDSAKey) String() string { + return k.addr.String() +} diff --git a/crypto/txsigner.go b/crypto/txsigner.go index 2d43bab9ee..2ef809320d 100644 --- a/crypto/txsigner.go +++ b/crypto/txsigner.go @@ -29,8 +29,12 @@ type TxSigner interface { // Sender returns the sender of the transaction Sender(*types.Transaction) (types.Address, error) - // SingTx takes the original transaction as input and returns its signed version + // SignTx takes the original transaction as input and returns its signed version SignTx(*types.Transaction, *ecdsa.PrivateKey) (*types.Transaction, error) + + // SignTxWithCallback signs a transaction by using a custom callback + SignTxWithCallback(tx *types.Transaction, + signFn func(hash types.Hash) (sig []byte, err error)) (*types.Transaction, error) } // NewSigner creates a new signer based on currently supported forks diff --git a/crypto/txsigner_berlin.go b/crypto/txsigner_berlin.go index 21f9777e2e..85c8a957df 100644 --- a/crypto/txsigner_berlin.go +++ b/crypto/txsigner_berlin.go @@ -113,7 +113,7 @@ func (signer *BerlinSigner) Sender(tx *types.Transaction) (types.Address, error) return recoverAddress(signer.Hash(tx), r, s, v, true) } -// SingTx takes the original transaction as input and returns its signed version +// SignTx takes the original transaction as input and returns its signed version func (signer *BerlinSigner) SignTx(tx *types.Transaction, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) { if tx.Type() == types.DynamicFeeTxType { return nil, types.ErrTxTypeNotSupported @@ -124,7 +124,6 @@ func (signer *BerlinSigner) SignTx(tx *types.Transaction, privateKey *ecdsa.Priv } tx = tx.Copy() - h := signer.Hash(tx) sig, err := Sign(privateKey, h[:]) @@ -152,3 +151,22 @@ func (signer *BerlinSigner) SignTx(tx *types.Transaction, privateKey *ecdsa.Priv func (signer *BerlinSigner) calculateV(parity byte) []byte { return big.NewInt(int64(parity)).Bytes() } + +func (signer *BerlinSigner) SignTxWithCallBack(tx *types.Transaction, + signFn func(hash types.Hash) (sig []byte, err error)) (*types.Transaction, error) { + if tx.Type() != types.AccessListTxType { + return signer.EIP155Signer.SignTxWithCallback(tx, signFn) + } + + tx = tx.Copy() + h := signer.Hash(tx) + + signature, err := signFn(h) + if err != nil { + return nil, err + } + + tx.SplitToRawSignatureValues(signature, signer.calculateV(signature[64])) + + return tx, nil +} diff --git a/crypto/txsigner_eip155.go b/crypto/txsigner_eip155.go index 275dee04c9..114107ac94 100644 --- a/crypto/txsigner_eip155.go +++ b/crypto/txsigner_eip155.go @@ -118,14 +118,13 @@ func (signer *EIP155Signer) Sender(tx *types.Transaction) (types.Address, error) return recoverAddress(signer.Hash(tx), r, s, bigV, true) } -// SingTx takes the original transaction as input and returns its signed version +// SignTx takes the original transaction as input and returns its signed version func (signer *EIP155Signer) SignTx(tx *types.Transaction, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) { if tx.Type() != types.LegacyTxType && tx.Type() != types.StateTxType { return nil, types.ErrTxTypeNotSupported } tx = tx.Copy() - hash := signer.Hash(tx) signature, err := Sign(privateKey, hash[:]) @@ -133,16 +132,31 @@ func (signer *EIP155Signer) SignTx(tx *types.Transaction, privateKey *ecdsa.Priv return nil, err } - r := new(big.Int).SetBytes(signature[:32]) - s := new(big.Int).SetBytes(signature[32:64]) + tx.SplitToRawSignatureValues(signature, signer.calculateV(signature[64])) + _, _, s := tx.RawSignatureValues() if s.Cmp(secp256k1NHalf) > 0 { return nil, errors.New("SignTx method: S must be inclusively lower than secp256k1n/2") } - v := new(big.Int).SetBytes(signer.calculateV(signature[64])) + return tx, nil +} + +func (e *EIP155Signer) SignTxWithCallback(tx *types.Transaction, + signFn func(hash types.Hash) (sig []byte, err error)) (*types.Transaction, error) { + if tx.Type() != types.LegacyTxType && tx.Type() != types.StateTxType { + return nil, types.ErrTxTypeNotSupported + } + + tx = tx.Copy() + h := e.Hash(tx) + + signature, err := signFn(h) + if err != nil { + return nil, err + } - tx.SetSignatureValues(v, r, s) + tx.SplitToRawSignatureValues(signature, e.calculateV(signature[64])) return tx, nil } diff --git a/crypto/txsigner_eip155_test.go b/crypto/txsigner_eip155_test.go index 6489b6d110..ce6acfb9c0 100644 --- a/crypto/txsigner_eip155_test.go +++ b/crypto/txsigner_eip155_test.go @@ -65,7 +65,7 @@ func TestEIP155Signer_Sender(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { t.Parallel() - key, keyGenError := GenerateECDSAKey() + key, keyGenError := GenerateECDSAPrivateKey() if keyGenError != nil { t.Fatalf("Unable to generate key") } @@ -100,7 +100,7 @@ func TestEIP155Signer_ChainIDMismatch(t *testing.T) { toAddress := types.StringToAddress("1") for _, chainIDTop := range chainIDS { - key, keyGenError := GenerateECDSAKey() + key, keyGenError := GenerateECDSAPrivateKey() if keyGenError != nil { t.Fatalf("Unable to generate key") } diff --git a/crypto/txsigner_frontier.go b/crypto/txsigner_frontier.go index 26158576d2..c7631d75da 100644 --- a/crypto/txsigner_frontier.go +++ b/crypto/txsigner_frontier.go @@ -89,20 +89,19 @@ func (signer *FrontierSigner) sender(tx *types.Transaction, isHomestead bool) (t return recoverAddress(signer.Hash(tx), r, s, parity, isHomestead) } -// SingTx takes the original transaction as input and returns its signed version +// SignTx takes the original transaction as input and returns its signed version func (signer *FrontierSigner) SignTx(tx *types.Transaction, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) { - return signer.signTx(tx, privateKey, nil) + return signer.signTxInternal(tx, privateKey) } -// SingTx takes the original transaction as input and returns its signed version -func (signer *FrontierSigner) signTx(tx *types.Transaction, privateKey *ecdsa.PrivateKey, - validateFn func(v, r, s *big.Int) error) (*types.Transaction, error) { +// signTxInternal takes the original transaction as input and returns its signed version +func (signer *FrontierSigner) signTxInternal(tx *types.Transaction, + privateKey *ecdsa.PrivateKey) (*types.Transaction, error) { if tx.Type() != types.LegacyTxType && tx.Type() != types.StateTxType { return nil, types.ErrTxTypeNotSupported } tx = tx.Copy() - hash := signer.Hash(tx) signature, err := Sign(privateKey, hash[:]) @@ -110,17 +109,27 @@ func (signer *FrontierSigner) signTx(tx *types.Transaction, privateKey *ecdsa.Pr return nil, err } - r := new(big.Int).SetBytes(signature[:32]) - s := new(big.Int).SetBytes(signature[32:64]) - v := new(big.Int).SetBytes(signer.calculateV(signature[64])) + tx.SplitToRawSignatureValues(signature, signer.calculateV(signature[64])) + + return tx, nil +} + +func (f *FrontierSigner) SignTxWithCallback( + tx *types.Transaction, + signFn func(hash types.Hash) (sig []byte, err error)) (*types.Transaction, error) { + if tx.Type() != types.LegacyTxType && tx.Type() != types.StateTxType { + return nil, types.ErrTxTypeNotSupported + } + + tx = tx.Copy() + h := f.Hash(tx) - if validateFn != nil { - if err := validateFn(v, r, s); err != nil { - return nil, err - } + signature, err := signFn(h) + if err != nil { + return nil, err } - tx.SetSignatureValues(v, r, s) + tx.SplitToRawSignatureValues(signature, f.calculateV(signature[64])) return tx, nil } diff --git a/crypto/txsigner_frontier_test.go b/crypto/txsigner_frontier_test.go index 80dba4c6af..36cc97f4fa 100644 --- a/crypto/txsigner_frontier_test.go +++ b/crypto/txsigner_frontier_test.go @@ -12,7 +12,7 @@ func TestFrontierSigner(t *testing.T) { signer := &FrontierSigner{} toAddress := types.StringToAddress("1") - key, err := GenerateECDSAKey() + key, err := GenerateECDSAPrivateKey() assert.NoError(t, err) txn := types.NewTx(types.NewLegacyTx( diff --git a/crypto/txsigner_homestead.go b/crypto/txsigner_homestead.go index d4ff10a0ac..8ffea6d229 100644 --- a/crypto/txsigner_homestead.go +++ b/crypto/txsigner_homestead.go @@ -3,7 +3,6 @@ package crypto import ( "crypto/ecdsa" "errors" - "math/big" "github.com/0xPolygon/polygon-edge/types" ) @@ -40,16 +39,20 @@ func (signer *HomesteadSigner) Sender(tx *types.Transaction) (types.Address, err return signer.sender(tx, true) } -// SingTx takes the original transaction as input and returns its signed version +// SignTx takes the original transaction as input and returns its signed version func (signer *HomesteadSigner) SignTx(tx *types.Transaction, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) { - return signer.signTx(tx, privateKey, func(v, r, s *big.Int) error { - // Homestead hard-fork introduced the rule that the S value - // must be inclusively lower than the half of the secp256k1 curve order - // Specification: https://eips.ethereum.org/EIPS/eip-2#specification (2) - if s.Cmp(secp256k1NHalf) > 0 { - return errors.New("SignTx method: S must be inclusively lower than secp256k1n/2") - } - - return nil - }) + tx, err := signer.signTxInternal(tx, privateKey) + if err != nil { + return nil, err + } + + _, _, s := tx.RawSignatureValues() + // Homestead hard-fork introduced the rule that the S value + // must be inclusively lower than the half of the secp256k1 curve order + // Specification: https://eips.ethereum.org/EIPS/eip-2#specification (2) + if s.Cmp(secp256k1NHalf) > 0 { + return nil, errors.New("SignTx method: S must be inclusively lower than secp256k1n/2") + } + + return tx, nil } diff --git a/crypto/txsigner_london.go b/crypto/txsigner_london.go index 0c2d140a19..9b844787a4 100644 --- a/crypto/txsigner_london.go +++ b/crypto/txsigner_london.go @@ -115,14 +115,13 @@ func (signer *LondonSigner) Sender(tx *types.Transaction) (types.Address, error) return recoverAddress(signer.Hash(tx), r, s, v, true) } -// SingTx takes the original transaction as input and returns its signed version +// SignTx takes the original transaction as input and returns its signed version func (signer *LondonSigner) SignTx(tx *types.Transaction, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) { if tx.Type() != types.DynamicFeeTxType { return signer.BerlinSigner.SignTx(tx, privateKey) } tx = tx.Copy() - h := signer.Hash(tx) sig, err := Sign(privateKey, h[:]) @@ -143,3 +142,22 @@ func (signer *LondonSigner) SignTx(tx *types.Transaction, privateKey *ecdsa.Priv return tx, nil } + +func (signer *LondonSigner) SignTxWithCallback(tx *types.Transaction, + signFn func(hash types.Hash) (sig []byte, err error)) (*types.Transaction, error) { + if tx.Type() != types.DynamicFeeTxType { + return signer.BerlinSigner.SignTxWithCallback(tx, signFn) + } + + tx = tx.Copy() + h := signer.Hash(tx) + + signature, err := signFn(h) + if err != nil { + return nil, err + } + + tx.SplitToRawSignatureValues(signature, signer.calculateV(signature[64])) + + return tx, nil +} diff --git a/crypto/txsigner_london_test.go b/crypto/txsigner_london_test.go index 48067deb1e..455a752421 100644 --- a/crypto/txsigner_london_test.go +++ b/crypto/txsigner_london_test.go @@ -67,7 +67,7 @@ func TestLondonSignerSender(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() - key, err := GenerateECDSAKey() + key, err := GenerateECDSAPrivateKey() require.NoError(t, err, "unable to generate private key") var txn *types.Transaction diff --git a/e2e-polybft/e2e/acls_test.go b/e2e-polybft/e2e/acls_test.go index 4d3b9d0490..154a0717f6 100644 --- a/e2e-polybft/e2e/acls_test.go +++ b/e2e-polybft/e2e/acls_test.go @@ -5,12 +5,12 @@ import ( "testing" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/state/runtime/addresslist" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/require" - "github.com/umbracle/ethgo/wallet" ) // Contract used as bytecode @@ -34,11 +34,11 @@ func TestE2E_AllowList_ContractDeployment(t *testing.T) { // create two accounts, one for an admin sender and a second // one for a non-enabled account that will switch on-off between // both enabled and non-enabled roles. - admin, _ := wallet.GenerateKey() - target, _ := wallet.GenerateKey() + admin, _ := crypto.GenerateECDSAKey() + target, _ := crypto.GenerateECDSAKey() - adminAddr := types.Address(admin.Address()) - targetAddr := types.Address(target.Address()) + adminAddr := admin.Address() + targetAddr := target.Address() otherAddr := types.Address{0x1} @@ -132,17 +132,14 @@ func TestE2E_BlockList_ContractDeployment(t *testing.T) { // create two accounts, one for an admin sender and a second // one for a non-enabled account that will switch on-off between // both enabled and non-enabled roles. - admin, _ := wallet.GenerateKey() - target, _ := wallet.GenerateKey() - - adminAddr := types.Address(admin.Address()) - targetAddr := types.Address(target.Address()) + admin, _ := crypto.GenerateECDSAKey() + target, _ := crypto.GenerateECDSAKey() otherAddr := types.Address{0x1} cluster := framework.NewTestCluster(t, 5, - framework.WithPremine(adminAddr, targetAddr), - framework.WithContractDeployerBlockListAdmin(adminAddr), + framework.WithPremine(admin.Address(), target.Address()), + framework.WithContractDeployerBlockListAdmin(admin.Address()), framework.WithContractDeployerBlockListEnabled(otherAddr), ) defer cluster.Stop() @@ -155,8 +152,8 @@ func TestE2E_BlockList_ContractDeployment(t *testing.T) { { // Step 0. Check the role of accounts - expectRole(t, cluster, contracts.BlockListContractsAddr, adminAddr, addresslist.AdminRole) - expectRole(t, cluster, contracts.BlockListContractsAddr, targetAddr, addresslist.NoRole) + expectRole(t, cluster, contracts.BlockListContractsAddr, admin.Address(), addresslist.AdminRole) + expectRole(t, cluster, contracts.BlockListContractsAddr, target.Address(), addresslist.NoRole) expectRole(t, cluster, contracts.BlockListContractsAddr, otherAddr, addresslist.EnabledRole) } @@ -184,11 +181,11 @@ func TestE2E_BlockList_ContractDeployment(t *testing.T) { { // Step 4. 'adminAddr' sends a transaction to enable 'targetAddr'. - input, _ := addresslist.SetEnabledFunc.Encode([]interface{}{targetAddr}) + input, _ := addresslist.SetEnabledFunc.Encode([]interface{}{target.Address()}) adminSetTxn := cluster.MethodTxn(t, admin, contracts.BlockListContractsAddr, input) require.NoError(t, adminSetTxn.Wait()) - expectRole(t, cluster, contracts.BlockListContractsAddr, targetAddr, addresslist.EnabledRole) + expectRole(t, cluster, contracts.BlockListContractsAddr, target.Address(), addresslist.EnabledRole) } { @@ -215,18 +212,14 @@ func TestE2E_AllowList_Transactions(t *testing.T) { // create two accounts, one for an admin sender and a second // one for a non-enabled account that will switch on-off between // both enabled and non-enabled roles. - admin, _ := wallet.GenerateKey() - target, _ := wallet.GenerateKey() - other, _ := wallet.GenerateKey() - - adminAddr := types.Address(admin.Address()) - targetAddr := types.Address(target.Address()) - otherAddr := types.Address(other.Address()) + admin, _ := crypto.GenerateECDSAKey() + target, _ := crypto.GenerateECDSAKey() + other, _ := crypto.GenerateECDSAKey() cluster := framework.NewTestCluster(t, 5, - framework.WithPremine(adminAddr, targetAddr, otherAddr), - framework.WithTransactionsAllowListAdmin(adminAddr), - framework.WithTransactionsAllowListEnabled(otherAddr), + framework.WithPremine(admin.Address(), target.Address(), other.Address()), + framework.WithTransactionsAllowListAdmin(admin.Address()), + framework.WithTransactionsAllowListEnabled(other.Address()), ) defer cluster.Stop() @@ -237,9 +230,9 @@ func TestE2E_AllowList_Transactions(t *testing.T) { { // Step 0. Check the role of both accounts - expectRole(t, cluster, contracts.AllowListTransactionsAddr, adminAddr, addresslist.AdminRole) - expectRole(t, cluster, contracts.AllowListTransactionsAddr, targetAddr, addresslist.NoRole) - expectRole(t, cluster, contracts.AllowListTransactionsAddr, otherAddr, addresslist.EnabledRole) + expectRole(t, cluster, contracts.AllowListTransactionsAddr, admin.Address(), addresslist.AdminRole) + expectRole(t, cluster, contracts.AllowListTransactionsAddr, target.Address(), addresslist.NoRole) + expectRole(t, cluster, contracts.AllowListTransactionsAddr, other.Address(), addresslist.EnabledRole) } { @@ -268,11 +261,11 @@ func TestE2E_AllowList_Transactions(t *testing.T) { { // Step 3. 'adminAddr' sends a transaction to enable 'targetAddr'. - input, _ := addresslist.SetEnabledFunc.Encode([]interface{}{targetAddr}) + input, _ := addresslist.SetEnabledFunc.Encode([]interface{}{target.Address()}) adminSetTxn := cluster.MethodTxn(t, admin, contracts.AllowListTransactionsAddr, input) require.NoError(t, adminSetTxn.Wait()) - expectRole(t, cluster, contracts.AllowListTransactionsAddr, targetAddr, addresslist.EnabledRole) + expectRole(t, cluster, contracts.AllowListTransactionsAddr, target.Address(), addresslist.EnabledRole) } { @@ -295,12 +288,12 @@ func TestE2E_AllowList_Transactions(t *testing.T) { { // Step 6. 'adminAddr' sends a transaction to disable himself. - input, _ := addresslist.SetNoneFunc.Encode([]interface{}{adminAddr}) + input, _ := addresslist.SetNoneFunc.Encode([]interface{}{admin.Address()}) noneSetTxn := cluster.MethodTxn(t, admin, contracts.AllowListTransactionsAddr, input) require.NoError(t, noneSetTxn.Wait()) require.True(t, noneSetTxn.Failed()) - expectRole(t, cluster, contracts.AllowListTransactionsAddr, adminAddr, addresslist.AdminRole) + expectRole(t, cluster, contracts.AllowListTransactionsAddr, admin.Address(), addresslist.AdminRole) } } @@ -308,18 +301,14 @@ func TestE2E_BlockList_Transactions(t *testing.T) { // create two accounts, one for an admin sender and a second // one for a non-enabled account that will switch on-off between // both enabled and non-enabled roles. - admin, _ := wallet.GenerateKey() - target, _ := wallet.GenerateKey() - other, _ := wallet.GenerateKey() - - adminAddr := types.Address(admin.Address()) - targetAddr := types.Address(target.Address()) - otherAddr := types.Address(other.Address()) + admin, _ := crypto.GenerateECDSAKey() + target, _ := crypto.GenerateECDSAKey() + other, _ := crypto.GenerateECDSAKey() cluster := framework.NewTestCluster(t, 5, - framework.WithPremine(adminAddr, targetAddr, otherAddr), - framework.WithTransactionsBlockListAdmin(adminAddr), - framework.WithTransactionsBlockListEnabled(otherAddr), + framework.WithPremine(admin.Address(), target.Address(), other.Address()), + framework.WithTransactionsBlockListAdmin(admin.Address()), + framework.WithTransactionsBlockListEnabled(other.Address()), ) defer cluster.Stop() @@ -327,9 +316,9 @@ func TestE2E_BlockList_Transactions(t *testing.T) { { // Step 0. Check the role of both accounts - expectRole(t, cluster, contracts.BlockListTransactionsAddr, adminAddr, addresslist.AdminRole) - expectRole(t, cluster, contracts.BlockListTransactionsAddr, targetAddr, addresslist.NoRole) - expectRole(t, cluster, contracts.BlockListTransactionsAddr, otherAddr, addresslist.EnabledRole) + expectRole(t, cluster, contracts.BlockListTransactionsAddr, admin.Address(), addresslist.AdminRole) + expectRole(t, cluster, contracts.BlockListTransactionsAddr, target.Address(), addresslist.NoRole) + expectRole(t, cluster, contracts.BlockListTransactionsAddr, other.Address(), addresslist.EnabledRole) } { @@ -359,11 +348,11 @@ func TestE2E_BlockList_Transactions(t *testing.T) { { // Step 4. 'adminAddr' sends a transaction to enable 'targetAddr'. - input, _ := addresslist.SetEnabledFunc.Encode([]interface{}{targetAddr}) + input, _ := addresslist.SetEnabledFunc.Encode([]interface{}{target.Address()}) adminSetTxn := cluster.MethodTxn(t, admin, contracts.BlockListTransactionsAddr, input) require.NoError(t, adminSetTxn.Wait()) - expectRole(t, cluster, contracts.BlockListTransactionsAddr, targetAddr, addresslist.EnabledRole) + expectRole(t, cluster, contracts.BlockListTransactionsAddr, target.Address(), addresslist.EnabledRole) } { @@ -378,9 +367,9 @@ func TestE2E_AddressLists_Bridge(t *testing.T) { // create two accounts, one for an admin sender and a second // one for a non-enabled account that will switch on-off between // both enabled and non-enabled roles. - admin, _ := wallet.GenerateKey() - target, _ := wallet.GenerateKey() - other, _ := wallet.GenerateKey() + admin, _ := crypto.GenerateECDSAKey() + target, _ := crypto.GenerateECDSAKey() + other, _ := crypto.GenerateECDSAKey() adminAddr := types.Address(admin.Address()) targetAddr := types.Address(target.Address()) diff --git a/e2e-polybft/e2e/bridge_test.go b/e2e-polybft/e2e/bridge_test.go index 921e26605c..409a4d5a09 100644 --- a/e2e-polybft/e2e/bridge_test.go +++ b/e2e-polybft/e2e/bridge_test.go @@ -11,7 +11,6 @@ import ( "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" @@ -20,6 +19,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" helperCommon "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/state/runtime/addresslist" @@ -53,7 +53,7 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { receiverKeys := make([]string, transfersCount) for i := 0; i < transfersCount; i++ { - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() require.NoError(t, err) rawKey, err := key.MarshallPrivateKey() @@ -100,12 +100,12 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { deployerKey, err := bridgeHelper.DecodePrivateKey("") require.NoError(t, err) - receipt, err := rootchainTxRelayer.SendTransaction( - ðgo.Transaction{ - To: nil, - Input: contractsapi.RootERC20.Bytecode, - }, - deployerKey) + deployTx := types.NewTx(types.NewLegacyTx( + types.WithTo(nil), + types.WithInput(contractsapi.RootERC20.Bytecode), + )) + + receipt, err := rootchainTxRelayer.SendTransaction(deployTx, deployerKey) require.NoError(t, err) require.NotNil(t, receipt) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) @@ -206,7 +206,7 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { require.NoError(t, err) // check that we submitted the minimal commitment to smart contract - commitmentIDRaw, err := txRelayer.Call(ethgo.ZeroAddress, ethgo.Address(contracts.StateReceiverContract), lastCommittedIDInput) + commitmentIDRaw, err := txRelayer.Call(types.ZeroAddress, contracts.StateReceiverContract, lastCommittedIDInput) require.NoError(t, err) initialCommittedID, err := helperCommon.ParseUint64orHex(&commitmentIDRaw) @@ -239,8 +239,8 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { require.NoError(t, cluster.WaitForBlock(midBlockNumber, 2*time.Minute)) // check that we submitted the minimal commitment to smart contract - commitmentIDRaw, err = txRelayer.Call(ethgo.ZeroAddress, - ethgo.Address(contracts.StateReceiverContract), lastCommittedIDInput) + commitmentIDRaw, err = txRelayer.Call(types.ZeroAddress, + contracts.StateReceiverContract, lastCommittedIDInput) require.NoError(t, err) lastCommittedID, err := helperCommon.ParseUint64orHex(&commitmentIDRaw) @@ -266,7 +266,7 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { require.NoError(t, cluster.WaitForBlock(midBlockNumber+5*sprintSize, 3*time.Minute)) // check that we submitted the minimal commitment to smart contract - commitmentIDRaw, err = txRelayer.Call(ethgo.ZeroAddress, ethgo.Address(contracts.StateReceiverContract), lastCommittedIDInput) + commitmentIDRaw, err = txRelayer.Call(types.ZeroAddress, contracts.StateReceiverContract, lastCommittedIDInput) require.NoError(t, err) // check that the second (larger commitment) was also submitted in epoch @@ -298,7 +298,7 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { tokenIDs := make([]string, transfersCount) for i := 0; i < transfersCount; i++ { - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() require.NoError(t, err) rawKey, err := key.MarshallPrivateKey() @@ -335,12 +335,15 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { rootchainDeployer, err := bridgeHelper.DecodePrivateKey("") require.NoError(t, err) - // deploy root ERC 721 token - receipt, err := rootchainTxRelayer.SendTransaction( - ðgo.Transaction{ + deployTx := types.NewTx(&types.LegacyTx{ + BaseTx: &types.BaseTx{ To: nil, Input: contractsapi.RootERC721.Bytecode, - }, rootchainDeployer) + }, + }) + + // deploy root ERC 721 token + receipt, err := rootchainTxRelayer.SendTransaction(deployTx, rootchainDeployer) require.NoError(t, err) rootERC721Addr := receipt.ContractAddress @@ -467,7 +470,7 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { tokenIDs := make([]string, transfersCount) for i := 0; i < transfersCount; i++ { - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() require.NoError(t, err) rawKey, err := key.MarshallPrivateKey() @@ -506,15 +509,18 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { rootchainDeployer, err := bridgeHelper.DecodePrivateKey("") require.NoError(t, err) - // deploy root ERC 1155 token - receipt, err := rootchainTxRelayer.SendTransaction( - ðgo.Transaction{ + deployTx := types.NewTx(&types.LegacyTx{ + BaseTx: &types.BaseTx{ To: nil, Input: contractsapi.RootERC1155.Bytecode, - }, rootchainDeployer) + }, + }) + + // deploy root ERC 1155 token + receipt, err := rootchainTxRelayer.SendTransaction(deployTx, rootchainDeployer) require.NoError(t, err) - rootERC1155Addr := receipt.ContractAddress + rootERC1155Addr := types.Address(receipt.ContractAddress) // DEPOSIT ERC1155 TOKENS // send a few transactions to the bridge @@ -581,7 +587,7 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { balanceInput, err := balanceOfFn.EncodeAbi() require.NoError(t, err) - balanceRaw, err := txRelayer.Call(ethgo.ZeroAddress, ethgo.Address(l2ChildTokenAddr), balanceInput) + balanceRaw, err := txRelayer.Call(types.ZeroAddress, l2ChildTokenAddr, balanceInput) require.NoError(t, err) balance, err := helperCommon.ParseUint256orHex(&balanceRaw) @@ -644,7 +650,7 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { balanceInput, err := balanceOfFn.EncodeAbi() require.NoError(t, err) - balanceRaw, err := rootchainTxRelayer.Call(ethgo.ZeroAddress, rootERC1155Addr, balanceInput) + balanceRaw, err := rootchainTxRelayer.Call(types.ZeroAddress, rootERC1155Addr, balanceInput) require.NoError(t, err) balance, err := helperCommon.ParseUint256orHex(&balanceRaw) @@ -670,13 +676,13 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { funds := make([]*big.Int, transfersCount) singleToken := ethgo.Ether(1) - admin, err := wallet.GenerateKey() + admin, err := crypto.GenerateECDSAKey() require.NoError(t, err) adminAddr := types.Address(admin.Address()) for i := uint64(0); i < transfersCount; i++ { - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() require.NoError(t, err) rawKey, err := key.MarshallPrivateKey() @@ -997,7 +1003,7 @@ func TestE2E_CheckpointSubmission(t *testing.T) { polybftCfg, err := polybft.LoadPolyBFTConfig(path.Join(cluster.Config.TmpDir, chainConfigFileName)) require.NoError(t, err) - checkpointManagerAddr := ethgo.Address(polybftCfg.Bridge.CheckpointManagerAddr) + checkpointManagerAddr := polybftCfg.Bridge.CheckpointManagerAddr testCheckpointBlockNumber := func(expectedCheckpointBlock uint64) (bool, error) { actualCheckpointBlock, err := getCheckpointBlockNumber(rootChainRelayer, checkpointManagerAddr) @@ -1049,7 +1055,7 @@ func TestE2E_Bridge_Transfers_AccessLists(t *testing.T) { depositAmounts := make([]string, transfersCount) withdrawAmounts := make([]string, transfersCount) - admin, _ := wallet.GenerateKey() + admin, _ := crypto.GenerateECDSAKey() adminAddr := types.Address(admin.Address()) cluster := framework.NewTestCluster(t, 5, @@ -1098,11 +1104,13 @@ func TestE2E_Bridge_Transfers_AccessLists(t *testing.T) { deployerKey, err := bridgeHelper.DecodePrivateKey("") require.NoError(t, err) + deployTx := types.NewTx(types.NewLegacyTx( + types.WithTo(nil), + types.WithInput(contractsapi.RootERC20.Bytecode), + )) + // deploy root erc20 token - receipt, err := rootchainTxRelayer.SendTransaction( - ðgo.Transaction{ - To: nil, Input: contractsapi.RootERC20.Bytecode, - }, deployerKey) + receipt, err := rootchainTxRelayer.SendTransaction(deployTx, deployerKey) require.NoError(t, err) require.NotNil(t, receipt) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) @@ -1252,13 +1260,13 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { bigZero = big.NewInt(0) ) - nonValidatorKey, err := wallet.GenerateKey() + nonValidatorKey, err := crypto.GenerateECDSAKey() require.NoError(t, err) nonValidatorKeyRaw, err := nonValidatorKey.MarshallPrivateKey() require.NoError(t, err) - rewardWalletKey, err := wallet.GenerateKey() + rewardWalletKey, err := crypto.GenerateECDSAKey() require.NoError(t, err) rewardWalletKeyRaw, err := rewardWalletKey.MarshallPrivateKey() @@ -1383,7 +1391,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { require.NoError(t, err) nonValidatorBalanceAfterWithdraw, err := childEthEndpoint.GetBalance( - nonValidatorKey.Address(), ethgo.Latest) + ethgo.Address(nonValidatorKey.Address()), ethgo.Latest) require.NoError(t, err) currentBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) @@ -1469,7 +1477,7 @@ func TestE2E_Bridge_L1OriginatedNativeToken_ERC20StakingToken(t *testing.T) { stakeTokenAddr = types.StringToAddress("0x2040") ) - minter, err := wallet.GenerateKey() + minter, err := crypto.GenerateECDSAKey() require.NoError(t, err) cluster := framework.NewTestCluster(t, 5, @@ -1512,14 +1520,14 @@ func TestE2E_Bridge_L1OriginatedNativeToken_ERC20StakingToken(t *testing.T) { mintInput, err := mintFn.EncodeAbi() require.NoError(t, err) - nonNativeErc20 := ethgo.Address(polybftCfg.StakeTokenAddr) + nonNativeErc20 := polybftCfg.StakeTokenAddr + + mintTx := types.NewTx(types.NewDynamicFeeTx( + types.WithTo(&nonNativeErc20), + types.WithInput(mintInput), + )) - receipt, err := relayer.SendTransaction( - ðgo.Transaction{ - To: &nonNativeErc20, - Input: mintInput, - Type: ethgo.TransactionDynamicFee, - }, minter) + receipt, err := relayer.SendTransaction(mintTx, minter) require.NoError(t, err) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) diff --git a/e2e-polybft/e2e/burn_contract_test.go b/e2e-polybft/e2e/burn_contract_test.go index 615bd7b7a6..057eb8e718 100644 --- a/e2e-polybft/e2e/burn_contract_test.go +++ b/e2e-polybft/e2e/burn_contract_test.go @@ -4,16 +4,16 @@ import ( "testing" "github.com/0xPolygon/polygon-edge/consensus/polybft" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/wallet" ) func TestE2E_BurnContract_Deployed(t *testing.T) { - contractKey, _ := wallet.GenerateKey() - destinationKey, _ := wallet.GenerateKey() + contractKey, _ := crypto.GenerateECDSAKey() + destinationKey, _ := crypto.GenerateECDSAKey() contractAddr := types.Address(contractKey.Address()) destinationAddr := types.Address(destinationKey.Address()) diff --git a/e2e-polybft/e2e/consensus_test.go b/e2e-polybft/e2e/consensus_test.go index d2441a4769..e55a147e76 100644 --- a/e2e-polybft/e2e/consensus_test.go +++ b/e2e-polybft/e2e/consensus_test.go @@ -13,7 +13,6 @@ import ( "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/abi" - "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/genesis" @@ -21,6 +20,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/txrelayer" @@ -179,13 +179,13 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { addrs, err := cluster.InitSecrets(firstValidatorDataDir, 1) require.NoError(t, err) - firstValidatorAddr := ethgo.Address(addrs[0]) + firstValidatorAddr := addrs[0] // create the second account and extract the address addrs, err = cluster.InitSecrets(secondValidatorDataDir, 1) require.NoError(t, err) - secondValidatorAddr := ethgo.Address(addrs[0]) + secondValidatorAddr := addrs[0] // assert that accounts are created validatorSecrets, err := genesis.GetValidatorKeyFiles(cluster.Config.TmpDir, cluster.Config.ValidatorPrefix) @@ -212,12 +212,12 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { []*big.Int{initialBalance, initialBalance}, polybftConfig.StakeTokenAddr)) // first validator's balance to be received - firstBalance, err := relayer.Client().Eth().GetBalance(firstValidatorAddr, ethgo.Latest) + firstBalance, err := relayer.Client().Eth().GetBalance(ethgo.Address(firstValidatorAddr), ethgo.Latest) require.NoError(t, err) t.Logf("First validator balance=%d\n", firstBalance) // second validator's balance to be received - secondBalance, err := relayer.Client().Eth().GetBalance(secondValidatorAddr, ethgo.Latest) + secondBalance, err := relayer.Client().Eth().GetBalance(ethgo.Address(secondValidatorAddr), ethgo.Latest) require.NoError(t, err) t.Logf("Second validator balance=%d\n", secondBalance) @@ -309,16 +309,16 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { cluster.WaitForReady(t) - initialValidatorBalance, err := srv.JSONRPC().Eth().GetBalance(validatorAcc.Ecdsa.Address(), ethgo.Latest) + validatorAddr := ethgo.Address(validatorAcc.Ecdsa.Address()) + + initialValidatorBalance, err := srv.JSONRPC().Eth().GetBalance(validatorAddr, ethgo.Latest) require.NoError(t, err) t.Logf("Balance (before unstake)=%d\n", initialValidatorBalance) - validatorAddr := validatorAcc.Ecdsa.Address() - // wait for some rewards to get accumulated require.NoError(t, cluster.WaitForBlock(polybftCfg.EpochSize*3, time.Minute)) - validatorInfo, err := validatorHelper.GetValidatorInfo(validatorAddr, relayer) + validatorInfo, err := validatorHelper.GetValidatorInfo(validatorAcc.Address(), relayer) require.NoError(t, err) require.True(t, validatorInfo.IsActive) @@ -340,21 +340,21 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { require.NoError(t, srv.WitdhrawStake()) // check that validator is no longer active (out of validator set) - validatorInfo, err = validatorHelper.GetValidatorInfo(validatorAddr, relayer) + validatorInfo, err = validatorHelper.GetValidatorInfo(validatorAcc.Address(), relayer) require.NoError(t, err) require.False(t, validatorInfo.IsActive) require.True(t, validatorInfo.Stake.Cmp(big.NewInt(0)) == 0) t.Logf("Stake (after unstake and withdraw)=%d\n", validatorInfo.Stake) - balanceBeforeRewardsWithdraw, err := srv.JSONRPC().Eth().GetBalance(validatorAcc.Ecdsa.Address(), ethgo.Latest) + balanceBeforeRewardsWithdraw, err := srv.JSONRPC().Eth().GetBalance(validatorAddr, ethgo.Latest) require.NoError(t, err) t.Logf("Balance (before withdraw rewards)=%d\n", balanceBeforeRewardsWithdraw) // withdraw pending rewards require.NoError(t, srv.WithdrawRewards()) - newValidatorBalance, err := srv.JSONRPC().Eth().GetBalance(validatorAcc.Ecdsa.Address(), ethgo.Latest) + newValidatorBalance, err := srv.JSONRPC().Eth().GetBalance(validatorAddr, ethgo.Latest) require.NoError(t, err) t.Logf("Balance (after withdrawal of rewards)=%s\n", newValidatorBalance) require.True(t, newValidatorBalance.Cmp(balanceBeforeRewardsWithdraw) > 0) @@ -374,10 +374,10 @@ func TestE2E_Consensus_MintableERC20NativeToken(t *testing.T) { initValidatorsBalance := ethgo.Ether(1) initMinterBalance := ethgo.Ether(100000) - minter, err := wallet.GenerateKey() + minter, err := crypto.GenerateECDSAKey() require.NoError(t, err) - receiver, err := wallet.GenerateKey() + receiver, err := crypto.GenerateECDSAKey() require.NoError(t, err) // because we are using native token as reward wallet, and it has default premine balance @@ -430,35 +430,35 @@ func TestE2E_Consensus_MintableERC20NativeToken(t *testing.T) { // send mint transactions mintAmount := ethgo.Ether(1) - nativeTokenAddr := ethgo.Address(contracts.NativeERC20TokenContract) // make sure minter account can mint tokens - receiverAddr := types.Address(receiver.Address()) - balanceBefore, err := targetJSONRPC.Eth().GetBalance(ethgo.Address(receiverAddr), ethgo.Latest) + balanceBefore, err := targetJSONRPC.Eth().GetBalance(ethgo.Address(receiver.Address()), ethgo.Latest) require.NoError(t, err) - t.Logf("Pre-mint balance: %v=%d\n", receiverAddr, balanceBefore) + t.Logf("Pre-mint balance: %v=%d\n", receiver.Address(), balanceBefore) mintFn := &contractsapi.MintRootERC20Fn{ - To: receiverAddr, + To: receiver.Address(), Amount: mintAmount, } mintInput, err := mintFn.EncodeAbi() require.NoError(t, err) - receipt, err := relayer.SendTransaction( - ðgo.Transaction{ - To: &nativeTokenAddr, - Input: mintInput, - Type: ethgo.TransactionDynamicFee, - }, minter) + tx := types.NewTx( + types.NewDynamicFeeTx( + types.WithTo(&contracts.NativeERC20TokenContract), + types.WithInput(mintInput), + ), + ) + + receipt, err := relayer.SendTransaction(tx, minter) require.NoError(t, err) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) - balanceAfter, err := targetJSONRPC.Eth().GetBalance(ethgo.Address(receiverAddr), ethgo.Latest) + balanceAfter, err := targetJSONRPC.Eth().GetBalance(ethgo.Address(receiver.Address()), ethgo.Latest) require.NoError(t, err) - t.Logf("Post-mint balance: %v=%d\n", receiverAddr, balanceAfter) + t.Logf("Post-mint balance: %v=%d\n", receiver.Address(), balanceAfter) require.True(t, balanceAfter.Cmp(new(big.Int).Add(mintAmount, balanceBefore)) >= 0) // try sending mint transaction from non minter account and make sure it would fail @@ -469,12 +469,12 @@ func TestE2E_Consensus_MintableERC20NativeToken(t *testing.T) { mintInput, err = mintFn.EncodeAbi() require.NoError(t, err) - receipt, err = relayer.SendTransaction( - ðgo.Transaction{ - To: &nativeTokenAddr, - Input: mintInput, - Type: ethgo.TransactionDynamicFee, - }, nonMinterAcc.Ecdsa) + tx = types.NewTx(types.NewDynamicFeeTx( + types.WithTo(&contracts.NativeERC20TokenContract), + types.WithInput(mintInput), + )) + + receipt, err = relayer.SendTransaction(tx, nonMinterAcc.Ecdsa) require.Error(t, err) require.Nil(t, receipt) } @@ -515,10 +515,10 @@ func TestE2E_Consensus_CustomRewardToken(t *testing.T) { func TestE2E_Consensus_EIP1559Check(t *testing.T) { t.Skip("TODO - since we removed burn from evm, this should be fixed after the burn solution") - sender, err := wallet.GenerateKey() + sender, err := crypto.GenerateECDSAKey() require.NoError(t, err) - recipient := ethgo.Address(types.StringToAddress("1234")) + recipient := types.StringToAddress("1234") // sender must have premined some native tokens cluster := framework.NewTestCluster(t, 5, @@ -536,9 +536,9 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { client := cluster.Servers[0].JSONRPC().Eth() - waitUntilBalancesChanged := func(_ ethgo.Address, initialBalance *big.Int) error { + waitUntilBalancesChanged := func(acct types.Address, initialBalance *big.Int) error { err := cluster.WaitUntil(30*time.Second, 1*time.Second, func() bool { - balance, err := client.GetBalance(recipient, ethgo.Latest) + balance, err := client.GetBalance(ethgo.Address(acct), ethgo.Latest) if err != nil { return true } @@ -554,32 +554,31 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { sendAmount := ethgo.Gwei(1) - txns := []*ethgo.Transaction{ - { - Value: sendAmount, - To: &recipient, - Gas: 21000, - Nonce: uint64(0), - GasPrice: ethgo.Gwei(1).Uint64(), - }, - { - Value: sendAmount, - To: &recipient, - Gas: 21000, - Nonce: uint64(0), - Type: ethgo.TransactionDynamicFee, - MaxFeePerGas: ethgo.Gwei(1), - MaxPriorityFeePerGas: ethgo.Gwei(1), - }, + txns := []*types.Transaction{ + types.NewTx(types.NewLegacyTx( + types.WithValue(sendAmount), + types.WithTo(&recipient), + types.WithGas(21000), + types.WithNonce(uint64(0)), + types.WithGasPrice(ethgo.Gwei(1)), + )), + types.NewTx(types.NewDynamicFeeTx( + types.WithValue(sendAmount), + types.WithTo(&recipient), + types.WithGas(21000), + types.WithNonce(uint64(0)), + types.WithGasFeeCap(ethgo.Gwei(1)), + types.WithGasTipCap(ethgo.Gwei(1)), + )), } initialMinerBalance := big.NewInt(0) - var prevMiner ethgo.Address + prevMiner := ethgo.ZeroAddress for i, txn := range txns { - senderInitialBalance, _ := client.GetBalance(sender.Address(), ethgo.Latest) - receiverInitialBalance, _ := client.GetBalance(recipient, ethgo.Latest) + senderInitialBalance, _ := client.GetBalance(ethgo.Address(sender.Address()), ethgo.Latest) + receiverInitialBalance, _ := client.GetBalance(ethgo.Address(recipient), ethgo.Latest) burnContractInitialBalance, _ := client.GetBalance(ethgo.Address(types.ZeroAddress), ethgo.Latest) receipt, err := relayer.SendTransaction(txn, sender) @@ -597,8 +596,8 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { prevMiner = block.Miner } - senderFinalBalance, _ := client.GetBalance(sender.Address(), ethgo.Latest) - receiverFinalBalance, _ := client.GetBalance(recipient, ethgo.Latest) + senderFinalBalance, _ := client.GetBalance(ethgo.Address(sender.Address()), ethgo.Latest) + receiverFinalBalance, _ := client.GetBalance(ethgo.Address(recipient), ethgo.Latest) burnContractFinalBalance, _ := client.GetBalance(ethgo.Address(types.ZeroAddress), ethgo.Latest) diffReceiverBalance := new(big.Int).Sub(receiverFinalBalance, receiverInitialBalance) @@ -645,7 +644,7 @@ func TestE2E_Consensus_ChangeVotingPowerByStakingPendingRewards(t *testing.T) { validatorSecretFiles, err := genesis.GetValidatorKeyFiles(cluster.Config.TmpDir, cluster.Config.ValidatorPrefix) require.NoError(t, err) - votingPowerChangeValidators := make([]ethgo.Address, votingPowerChanges) + votingPowerChangeValidators := make([]types.Address, votingPowerChanges) for i := 0; i < votingPowerChanges; i++ { validator, err := validatorHelper.GetAccountFromDir(path.Join(cluster.Config.TmpDir, validatorSecretFiles[i])) @@ -678,7 +677,7 @@ func TestE2E_Consensus_ChangeVotingPowerByStakingPendingRewards(t *testing.T) { bigZero := big.NewInt(0) // validatorsMap holds only changed validators - validatorsMap := make(map[ethgo.Address]*polybft.ValidatorInfo, votingPowerChanges) + validatorsMap := make(map[types.Address]*polybft.ValidatorInfo, votingPowerChanges) queryValidators(func(idx int, validator *polybft.ValidatorInfo) { t.Logf("[Validator#%d] Voting power (original)=%d, rewards=%d\n", @@ -731,13 +730,11 @@ func TestE2E_Consensus_ChangeVotingPowerByStakingPendingRewards(t *testing.T) { } for addr, validator := range validatorsMap { - a := types.Address(addr) - - if !currentExtra.Validators.Updated.ContainsAddress(a) { + if !currentExtra.Validators.Updated.ContainsAddress(addr) { continue } - if currentExtra.Validators.Updated.GetValidatorMetadata(a).VotingPower.Cmp(validator.Stake) != 0 { + if currentExtra.Validators.Updated.GetValidatorMetadata(addr).VotingPower.Cmp(validator.Stake) != 0 { continue } } @@ -755,12 +752,10 @@ func TestE2E_Consensus_ChangeVotingPowerByStakingPendingRewards(t *testing.T) { func TestE2E_Deploy_Nested_Contract(t *testing.T) { numberToPersist := big.NewInt(234586) - admin, err := wallet.GenerateKey() + admin, err := crypto.GenerateECDSAKey() require.NoError(t, err) - adminAddr := types.Address(admin.Address()) - - cluster := framework.NewTestCluster(t, 5, framework.WithBladeAdmin(adminAddr.String())) + cluster := framework.NewTestCluster(t, 5, framework.WithBladeAdmin(admin.Address().String())) defer cluster.Stop() cluster.WaitForReady(t) @@ -770,15 +765,16 @@ func TestE2E_Deploy_Nested_Contract(t *testing.T) { // deploy Wrapper contract receipt, err := txRelayer.SendTransaction( - ðgo.Transaction{ - To: nil, - Input: contractsapi.Wrapper.Bytecode, - }, + types.NewTx(&types.LegacyTx{ + BaseTx: &types.BaseTx{ + Input: contractsapi.Wrapper.Bytecode, + }, + }), admin) require.NoError(t, err) // address of Wrapper contract - wrapperAddr := receipt.ContractAddress + wrapperAddr := types.Address(receipt.ContractAddress) // getAddressFn returns address of the NumberPersister (nested) contract getAddressFn := contractsapi.Wrapper.Abi.GetMethod("getAddress") @@ -786,7 +782,7 @@ func TestE2E_Deploy_Nested_Contract(t *testing.T) { getAddrInput, err := getAddressFn.Encode([]interface{}{}) require.NoError(t, err) - response, err := txRelayer.Call(ethgo.ZeroAddress, wrapperAddr, getAddrInput) + response, err := txRelayer.Call(types.ZeroAddress, wrapperAddr, getAddrInput) require.NoError(t, err) // address of the NumberPersister (nested) contract @@ -799,11 +795,11 @@ func TestE2E_Deploy_Nested_Contract(t *testing.T) { setValueInput, err := setNumberFn.Encode([]interface{}{numberToPersist}) require.NoError(t, err) - txn := ðgo.Transaction{ - From: admin.Address(), - To: &wrapperAddr, - Input: setValueInput, - } + txn := types.NewTx(types.NewLegacyTx( + types.WithFrom(admin.Address()), + types.WithTo(&wrapperAddr), + types.WithInput(setValueInput), + )) receipt, err = txRelayer.SendTransaction(txn, admin) require.NoError(t, err) @@ -815,7 +811,7 @@ func TestE2E_Deploy_Nested_Contract(t *testing.T) { getNumberInput, err := getNumberFn.Encode([]interface{}{}) require.NoError(t, err) - response, err = txRelayer.Call(ethgo.ZeroAddress, wrapperAddr, getNumberInput) + response, err = txRelayer.Call(types.ZeroAddress, wrapperAddr, getNumberInput) require.NoError(t, err) parsedResponse, err := common.ParseUint256orHex(&response) diff --git a/e2e-polybft/e2e/governance_test.go b/e2e-polybft/e2e/governance_test.go index 3ad6175185..edcbef1653 100644 --- a/e2e-polybft/e2e/governance_test.go +++ b/e2e-polybft/e2e/governance_test.go @@ -136,7 +136,7 @@ func TestE2E_Governance_ProposeAndExecuteSimpleProposal(t *testing.T) { // check if epoch size changed on NetworkParams networkParamsResponse, err := ABICall(relayer, contractsapi.NetworkParams, - ethgo.Address(polybftCfg.GovernanceConfig.NetworkParamsAddr), ethgo.ZeroAddress, "epochSize") + polybftCfg.GovernanceConfig.NetworkParamsAddr, types.ZeroAddress, "epochSize") require.NoError(t, err) epochSizeOnNetworkParams, err := common.ParseUint256orHex(&networkParamsResponse) @@ -291,7 +291,7 @@ func TestE2E_Governance_ProposeAndExecuteSimpleProposal(t *testing.T) { // check if base fee change denom changed on NetworkParams networkParamsResponse, err := ABICall(relayer, contractsapi.NetworkParams, - ethgo.Address(polybftCfg.GovernanceConfig.NetworkParamsAddr), ethgo.ZeroAddress, "baseFeeChangeDenom") + polybftCfg.GovernanceConfig.NetworkParamsAddr, types.ZeroAddress, "baseFeeChangeDenom") require.NoError(t, err) baseFeeDenomOnNetworkParams, err := common.ParseUint256orHex(&networkParamsResponse) @@ -311,7 +311,7 @@ func getProposalState(t *testing.T, proposalID *big.Int, childGovernorAddr types input, err := stateFn.EncodeAbi() require.NoError(t, err) - response, err := txRelayer.Call(ethgo.ZeroAddress, ethgo.Address(childGovernorAddr), input) + response, err := txRelayer.Call(types.ZeroAddress, childGovernorAddr, input) require.NoError(t, err) require.NotEqual(t, "0x", response) @@ -322,7 +322,7 @@ func getProposalState(t *testing.T, proposalID *big.Int, childGovernorAddr types } func sendQueueProposalTransaction(t *testing.T, - txRelayer txrelayer.TxRelayer, senderKey ethgo.Key, + txRelayer txrelayer.TxRelayer, senderKey crypto.Key, childGovernorAddr, paramsContractAddr types.Address, input []byte, description string) { t.Helper() @@ -337,11 +337,10 @@ func sendQueueProposalTransaction(t *testing.T, input, err := queueFn.EncodeAbi() require.NoError(t, err) - childGovernor := ethgo.Address(childGovernorAddr) - txn := ðgo.Transaction{ - To: &childGovernor, - Input: input, - } + txn := types.NewTx(types.NewLegacyTx( + types.WithTo(&childGovernorAddr), + types.WithInput(input), + )) receipt, err := txRelayer.SendTransaction(txn, senderKey) require.NoError(t, err) @@ -349,7 +348,7 @@ func sendQueueProposalTransaction(t *testing.T, } func sendExecuteProposalTransaction(t *testing.T, - txRelayer txrelayer.TxRelayer, senderKey ethgo.Key, + txRelayer txrelayer.TxRelayer, senderKey crypto.Key, childGovernorAddr, paramsContractAddr types.Address, input []byte, description string) { t.Helper() @@ -364,11 +363,10 @@ func sendExecuteProposalTransaction(t *testing.T, input, err := executeFn.EncodeAbi() require.NoError(t, err) - childGovernor := ethgo.Address(childGovernorAddr) - txn := ðgo.Transaction{ - To: &childGovernor, - Input: input, - } + txn := types.NewTx(types.NewLegacyTx( + types.WithTo(&childGovernorAddr), + types.WithInput(input), + )) receipt, err := txRelayer.SendTransaction(txn, senderKey) require.NoError(t, err) @@ -377,7 +375,7 @@ func sendExecuteProposalTransaction(t *testing.T, func sendVoteTransaction(t *testing.T, proposalID *big.Int, vote VoteType, childGovernorAddr types.Address, - txRelayer txrelayer.TxRelayer, senderKey ethgo.Key) { + txRelayer txrelayer.TxRelayer, senderKey crypto.Key) { t.Helper() castVoteFn := &contractsapi.CastVoteChildGovernorFn{ @@ -388,11 +386,10 @@ func sendVoteTransaction(t *testing.T, proposalID *big.Int, vote VoteType, input, err := castVoteFn.EncodeAbi() require.NoError(t, err) - childGovernor := ethgo.Address(childGovernorAddr) - txn := ðgo.Transaction{ - To: &childGovernor, - Input: input, - } + txn := types.NewTx(types.NewLegacyTx( + types.WithTo(&childGovernorAddr), + types.WithInput(input), + )) receipt, err := txRelayer.SendTransaction(txn, senderKey) require.NoError(t, err) @@ -400,7 +397,7 @@ func sendVoteTransaction(t *testing.T, proposalID *big.Int, vote VoteType, } func sendProposalTransaction(t *testing.T, txRelayer txrelayer.TxRelayer, - senderKey ethgo.Key, + senderKey crypto.Key, childGovernorAddr, paramsContractAddr types.Address, input []byte, description string) *big.Int { t.Helper() @@ -415,11 +412,10 @@ func sendProposalTransaction(t *testing.T, txRelayer txrelayer.TxRelayer, input, err := proposeFn.EncodeAbi() require.NoError(t, err) - childGovernor := ethgo.Address(childGovernorAddr) - txn := ðgo.Transaction{ - To: &childGovernor, - Input: input, - } + txn := types.NewTx(types.NewLegacyTx( + types.WithTo(&childGovernorAddr), + types.WithInput(input), + )) receipt, err := txRelayer.SendTransaction(txn, senderKey) require.NoError(t, err) diff --git a/e2e-polybft/e2e/helpers_test.go b/e2e-polybft/e2e/helpers_test.go index 36e0add4c9..3290eeef6d 100644 --- a/e2e-polybft/e2e/helpers_test.go +++ b/e2e-polybft/e2e/helpers_test.go @@ -13,6 +13,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/helper/hex" @@ -23,7 +24,7 @@ import ( const nativeTokenNonMintableConfig = "Blade:BLD:18:false" -func ABICall(relayer txrelayer.TxRelayer, artifact *contracts.Artifact, contractAddress ethgo.Address, senderAddr ethgo.Address, method string, params ...interface{}) (string, error) { +func ABICall(relayer txrelayer.TxRelayer, artifact *contracts.Artifact, contractAddress types.Address, senderAddr types.Address, method string, params ...interface{}) (string, error) { input, err := artifact.Abi.GetMethod(method).Encode(params) if err != nil { return "", err @@ -32,16 +33,18 @@ func ABICall(relayer txrelayer.TxRelayer, artifact *contracts.Artifact, contract return relayer.Call(senderAddr, contractAddress, input) } -func ABITransaction(relayer txrelayer.TxRelayer, key ethgo.Key, artifact *contracts.Artifact, contractAddress ethgo.Address, method string, params ...interface{}) (*ethgo.Receipt, error) { +func ABITransaction(relayer txrelayer.TxRelayer, key crypto.Key, artifact *contracts.Artifact, contractAddress types.Address, method string, params ...interface{}) (*ethgo.Receipt, error) { input, err := artifact.Abi.GetMethod(method).Encode(params) if err != nil { return nil, err } - return relayer.SendTransaction(ðgo.Transaction{ - To: &contractAddress, - Input: input, - }, key) + tx := types.NewTx(types.NewLegacyTx( + types.WithTo(&contractAddress), + types.WithInput(input), + )) + + return relayer.SendTransaction(tx, key) } // checkStateSyncResultLogs is helper function which parses given StateSyncResultEvent event's logs, @@ -67,9 +70,9 @@ func checkStateSyncResultLogs( } // getCheckpointBlockNumber gets current checkpoint block number from checkpoint manager smart contract -func getCheckpointBlockNumber(l1Relayer txrelayer.TxRelayer, checkpointManagerAddr ethgo.Address) (uint64, error) { +func getCheckpointBlockNumber(l1Relayer txrelayer.TxRelayer, checkpointManagerAddr types.Address) (uint64, error) { checkpointBlockNumRaw, err := ABICall(l1Relayer, contractsapi.CheckpointManager, - checkpointManagerAddr, ethgo.ZeroAddress, "currentCheckpointBlockNumber") + checkpointManagerAddr, types.ZeroAddress, "currentCheckpointBlockNumber") if err != nil { return 0, err } @@ -99,7 +102,7 @@ func waitForRootchainEpoch(targetEpoch uint64, timeout time.Duration, } rootchainEpochRaw, err := ABICall(rootchainTxRelayer, contractsapi.CheckpointManager, - ethgo.Address(checkpointManager), ethgo.ZeroAddress, "currentEpoch") + checkpointManager, types.ZeroAddress, "currentEpoch") if err != nil { return err } @@ -117,7 +120,7 @@ func waitForRootchainEpoch(targetEpoch uint64, timeout time.Duration, // setAccessListRole sets access list role to appropriate access list precompile func setAccessListRole(t *testing.T, cluster *framework.TestCluster, precompile, account types.Address, - role addresslist.Role, aclAdmin ethgo.Key) { + role addresslist.Role, aclAdmin *crypto.ECDSAKey) { t.Helper() var updateRoleFn *abi.Method @@ -171,7 +174,7 @@ func erc20BalanceOf(t *testing.T, account types.Address, tokenAddr types.Address balanceOfInput, err := balanceOfFn.EncodeAbi() require.NoError(t, err) - balanceRaw, err := relayer.Call(ethgo.ZeroAddress, ethgo.Address(tokenAddr), balanceOfInput) + balanceRaw, err := relayer.Call(types.ZeroAddress, tokenAddr, balanceOfInput) require.NoError(t, err) balance, err := common.ParseUint256orHex(&balanceRaw) require.NoError(t, err) @@ -187,7 +190,7 @@ func erc721OwnerOf(t *testing.T, tokenID *big.Int, tokenAddr types.Address, rela ownerOfInput, err := ownerOfFn.EncodeAbi() require.NoError(t, err) - ownerRaw, err := relayer.Call(ethgo.ZeroAddress, ethgo.Address(tokenAddr), ownerOfInput) + ownerRaw, err := relayer.Call(types.ZeroAddress, tokenAddr, ownerOfInput) require.NoError(t, err) return types.StringToAddress(ownerRaw) @@ -198,8 +201,8 @@ func queryNativeERC20Metadata(t *testing.T, funcName string, abiType *abi.Type, t.Helper() valueHex, err := ABICall(relayer, contractsapi.NativeERC20Mintable, - ethgo.Address(contracts.NativeERC20TokenContract), - ethgo.ZeroAddress, funcName) + contracts.NativeERC20TokenContract, + types.ZeroAddress, funcName) require.NoError(t, err) valueRaw, err := hex.DecodeHex(valueHex) @@ -224,7 +227,7 @@ func getChildToken(t *testing.T, predicateABI *abi.ABI, predicateAddr types.Addr input, err := rootToChildTokenFn.Encode([]interface{}{rootToken}) require.NoError(t, err) - childTokenRaw, err := relayer.Call(ethgo.ZeroAddress, ethgo.Address(predicateAddr), input) + childTokenRaw, err := relayer.Call(types.ZeroAddress, predicateAddr, input) require.NoError(t, err) return types.StringToAddress(childTokenRaw) @@ -238,7 +241,7 @@ func getLastExitEventID(t *testing.T, relayer txrelayer.TxRelayer) uint64 { input, err := exitEventsCounterFn.Encode([]interface{}{}) require.NoError(t, err) - exitEventIDRaw, err := relayer.Call(ethgo.ZeroAddress, ethgo.Address(contracts.L2StateSenderContract), input) + exitEventIDRaw, err := relayer.Call(types.ZeroAddress, contracts.L2StateSenderContract, input) require.NoError(t, err) exitEventID, err := common.ParseUint64orHex(&exitEventIDRaw) @@ -256,7 +259,7 @@ func isExitEventProcessed(t *testing.T, exitHelperAddr types.Address, input, err := processedExitsFn.Encode([]interface{}{exitEventID}) require.NoError(t, err) - isProcessedRaw, err := relayer.Call(ethgo.ZeroAddress, ethgo.Address(exitHelperAddr), input) + isProcessedRaw, err := relayer.Call(types.ZeroAddress, exitHelperAddr, input) require.NoError(t, err) isProcessedAsNumber, err := common.ParseUint64orHex(&isProcessedRaw) diff --git a/e2e-polybft/e2e/jsonrpc_test.go b/e2e-polybft/e2e/jsonrpc_test.go index 21ec223e91..5e6b684c30 100644 --- a/e2e-polybft/e2e/jsonrpc_test.go +++ b/e2e-polybft/e2e/jsonrpc_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/jsonrpc" - "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" @@ -26,11 +25,11 @@ var ( ) func TestE2E_JsonRPC(t *testing.T) { - acct, err := wallet.GenerateKey() + senderKey, err := crypto.GenerateECDSAKey() require.NoError(t, err) cluster := framework.NewTestCluster(t, 4, - framework.WithPremine(types.Address(acct.Address())), + framework.WithPremine(senderKey.Address()), framework.WithHTTPS("/etc/ssl/certs/localhost.pem", "/etc/ssl/private/localhost.key"), ) defer cluster.Stop() @@ -43,7 +42,7 @@ func TestE2E_JsonRPC(t *testing.T) { // Test eth_call with override in state diff t.Run("eth_call state override", func(t *testing.T) { - deployTxn := cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) @@ -72,7 +71,7 @@ func TestE2E_JsonRPC(t *testing.T) { // Test eth_call with zero account balance t.Run("eth_call with zero-balance account", func(t *testing.T) { - deployTxn := cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) @@ -80,11 +79,11 @@ func TestE2E_JsonRPC(t *testing.T) { input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() - acctZeroBalance, err := wallet.GenerateKey() + acctZeroBalance, err := crypto.GenerateECDSAKey() require.NoError(t, err) resp, err := client.Call(ðgo.CallMsg{ - From: acctZeroBalance.Address(), + From: ethgo.Address(acctZeroBalance.Address()), To: &target, Data: input, }, ethgo.Latest) @@ -93,7 +92,7 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_estimateGas", func(t *testing.T) { - deployTxn := cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) @@ -102,7 +101,7 @@ func TestE2E_JsonRPC(t *testing.T) { input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() estimatedGas, err := client.EstimateGas(ðgo.CallMsg{ - From: acct.Address(), + From: ethgo.Address(senderKey.Address()), To: &target, Data: input, }) @@ -111,19 +110,18 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_estimateGas by zero-balance account", func(t *testing.T) { - deployTxn := cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) target := deployTxn.Receipt().ContractAddress - input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() - acctZeroBalance, err := wallet.GenerateKey() + acctZeroBalance, err := crypto.GenerateECDSAKey() require.NoError(t, err) resp, err := client.EstimateGas(ðgo.CallMsg{ - From: acctZeroBalance.Address(), + From: ethgo.Address(acctZeroBalance.Address()), To: &target, Data: input, }) @@ -132,16 +130,16 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_estimateGas by zero-balance account - simple value transfer", func(t *testing.T) { - acctZeroBalance, err := wallet.GenerateKey() + acctZeroBalance, err := crypto.GenerateECDSAKey() require.NoError(t, err) - fundedAccountAddress := acct.Address() + fundedAccountAddress := senderKey.Address() nonFundedAccountAddress := acctZeroBalance.Address() estimateGasFn := func(value *big.Int) { resp, err := client.EstimateGas(ðgo.CallMsg{ - From: nonFundedAccountAddress, - To: &fundedAccountAddress, + From: ethgo.Address(nonFundedAccountAddress), + To: (*ethgo.Address)(&fundedAccountAddress), Value: value, }) @@ -152,11 +150,12 @@ func TestE2E_JsonRPC(t *testing.T) { estimateGasFn(ethgo.Gwei(1)) // transfer some funds to zero balance account - valueTransferTxn := cluster.SendTxn(t, acct, ðgo.Transaction{ - From: fundedAccountAddress, - To: &nonFundedAccountAddress, - Value: ethgo.Gwei(10), - }) + valueTransferTxn := cluster.SendTxn(t, senderKey, + types.NewTx(types.NewLegacyTx( + types.WithFrom(fundedAccountAddress), + types.WithTo(&nonFundedAccountAddress), + types.WithValue(ethgo.Gwei(10)), + ))) require.NoError(t, valueTransferTxn.Wait()) require.True(t, valueTransferTxn.Succeed()) @@ -166,21 +165,23 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_getBalance", func(t *testing.T) { - key1, err := wallet.GenerateKey() + recipientKey, err := crypto.GenerateECDSAKey() require.NoError(t, err) + recipientAddr := ethgo.Address(recipientKey.Address()) + // Test. return zero if the account does not exist - balance1, err := client.GetBalance(key1.Address(), ethgo.Latest) + balance1, err := client.GetBalance(recipientAddr, ethgo.Latest) require.NoError(t, err) require.Equal(t, balance1, big.NewInt(0)) // Test. return the balance of an account newBalance := ethgo.Ether(1) - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), newBalance) + txn := cluster.Transfer(t, senderKey, recipientKey.Address(), newBalance) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - balance1, err = client.GetBalance(key1.Address(), ethgo.Latest) + balance1, err = client.GetBalance(recipientAddr, ethgo.Latest) require.NoError(t, err) require.Equal(t, balance1, newBalance) @@ -188,11 +189,9 @@ func TestE2E_JsonRPC(t *testing.T) { gasPrice, err := client.GasPrice() require.NoError(t, err) - toAddr := key1.Address() - estimatedGas, err := client.EstimateGas(ðgo.CallMsg{ - From: acct.Address(), - To: &toAddr, + From: ethgo.Address(senderKey.Address()), + To: &recipientAddr, Value: newBalance, }) require.NoError(t, err) @@ -200,62 +199,65 @@ func TestE2E_JsonRPC(t *testing.T) { // subtract gasPrice * estimatedGas from the balance and transfer the rest to the other account // in order to leave no funds on the account amountToSend := new(big.Int).Sub(newBalance, big.NewInt(int64(txPrice))) - targetAddr := acct.Address() - txn = cluster.SendTxn(t, key1, ðgo.Transaction{ - To: &targetAddr, - Value: amountToSend, - Gas: estimatedGas, - }) + targetAddr := senderKey.Address() + txn = cluster.SendTxn(t, recipientKey, + types.NewTx(types.NewLegacyTx( + types.WithTo(&targetAddr), + types.WithValue(amountToSend), + types.WithGas(estimatedGas), + ))) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - balance1, err = client.GetBalance(key1.Address(), ethgo.Latest) + balance1, err = client.GetBalance(ethgo.Address(recipientKey.Address()), ethgo.Latest) require.NoError(t, err) require.Equal(t, big.NewInt(0), balance1) }) t.Run("eth_getTransactionCount", func(t *testing.T) { - key1, err := wallet.GenerateKey() + recipientKey, err := crypto.GenerateECDSAKey() require.NoError(t, err) - nonce, err := client.GetNonce(key1.Address(), ethgo.Latest) + recipient := ethgo.Address(recipientKey.Address()) + + nonce, err := client.GetNonce(recipient, ethgo.Latest) require.Equal(t, uint64(0), nonce) require.NoError(t, err) - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), big.NewInt(10000000000000000)) + txn := cluster.Transfer(t, senderKey, types.Address(recipient), big.NewInt(10000000000000000)) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) // Test. increase the nonce with new transactions - txn = cluster.Transfer(t, key1, types.ZeroAddress, big.NewInt(0)) + txn = cluster.Transfer(t, recipientKey, types.ZeroAddress, big.NewInt(0)) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - nonce1, err := client.GetNonce(key1.Address(), ethgo.Latest) + nonce1, err := client.GetNonce(recipient, ethgo.Latest) require.NoError(t, err) require.Equal(t, nonce1, uint64(1)) // Test. you can query the nonce at any block number in time - nonce1, err = client.GetNonce(key1.Address(), ethgo.BlockNumber(txn.Receipt().BlockNumber-1)) + nonce1, err = client.GetNonce(recipient, ethgo.BlockNumber(txn.Receipt().BlockNumber-1)) require.NoError(t, err) require.Equal(t, nonce1, uint64(0)) block, err := client.GetBlockByNumber(ethgo.BlockNumber(txn.Receipt().BlockNumber)-1, false) require.NoError(t, err) - _, err = client.GetNonce(key1.Address(), ethgo.BlockNumber(block.Number)) + _, err = client.GetNonce(recipient, ethgo.BlockNumber(block.Number)) require.NoError(t, err) }) t.Run("eth_getStorageAt", func(t *testing.T) { - key1, err := wallet.GenerateKey() + key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), one) + txn := cluster.Transfer(t, senderKey, key1.Address(), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - txn = cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + txn = cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -272,7 +274,10 @@ func TestE2E_JsonRPC(t *testing.T) { input, err := setValueFn.Encode([]interface{}{newVal}) require.NoError(t, err) - txn = cluster.SendTxn(t, acct, ðgo.Transaction{Input: input, To: &target}) + txn = cluster.SendTxn(t, senderKey, + types.NewTx( + types.NewLegacyTx(types.WithInput(input), types.WithTo((*types.Address)(&target))), + )) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -286,11 +291,11 @@ func TestE2E_JsonRPC(t *testing.T) { // Note that in order to work, this private key should only be used for this test. priv, err := hex.DecodeString("2c15bd0dc992a47ca660983ae4b611f4ffb6178e14e04e2b34d153f3a74ce741") require.NoError(t, err) - key1, err := wallet.NewWalletFromPrivKey(priv) + key1, err := crypto.NewECDSAKeyFromRawPrivECDSA(priv) require.NoError(t, err) // fund the account so that it can deploy a contract - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), big.NewInt(10000000000000000)) + txn := cluster.Transfer(t, senderKey, key1.Address(), ethgo.Ether(1)) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -333,9 +338,9 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_getBlockByHash", func(t *testing.T) { - key1, err := wallet.GenerateKey() + key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), one) + txn := cluster.Transfer(t, senderKey, key1.Address(), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) txReceipt := txn.Receipt() @@ -347,9 +352,9 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_getBlockByNumber", func(t *testing.T) { - key1, err := wallet.GenerateKey() + key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), one) + txn := cluster.Transfer(t, senderKey, key1.Address(), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) txReceipt := txn.Receipt() @@ -361,9 +366,9 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_getTransactionReceipt", func(t *testing.T) { - key1, err := wallet.GenerateKey() + key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), one) + txn := cluster.Transfer(t, senderKey, key1.Address(), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -385,7 +390,7 @@ func TestE2E_JsonRPC(t *testing.T) { require.Equal(t, receipt.BlockHash, block.Hash) // Test. The receipt of a deployed contract has the 'ContractAddress' field. - txn = cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + txn = cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -393,11 +398,11 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("eth_getTransactionByHash", func(t *testing.T) { - key1, err := wallet.GenerateKey() + key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) // Test. We should be able to query the transaction by its hash - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), one) + txn := cluster.Transfer(t, senderKey, key1.Address(), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -409,11 +414,11 @@ func TestE2E_JsonRPC(t *testing.T) { }) t.Run("debug_traceTransaction", func(t *testing.T) { - key1, err := wallet.GenerateKey() + key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) // Test. We should be able to query the transaction by its hash - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), one) + txn := cluster.Transfer(t, senderKey, key1.Address(), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -429,12 +434,12 @@ func TestE2E_JsonRPC(t *testing.T) { func TestE2E_JsonRPC_NewEthClient(t *testing.T) { const epochSize = uint64(5) - acct, err := wallet.GenerateKey() + preminedAcct, err := crypto.GenerateECDSAKey() require.NoError(t, err) cluster := framework.NewTestCluster(t, 4, framework.WithEpochSize(int(epochSize)), - framework.WithPremine(types.Address(acct.Address())), + framework.WithPremine(preminedAcct.Address()), framework.WithBurnContract(&polybft.BurnContractInfo{BlockNumber: 0, Address: types.ZeroAddress}), ) defer cluster.Stop() @@ -503,7 +508,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { }) t.Run("eth_getCode", func(t *testing.T) { - deployTxn := cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + deployTxn := cluster.Deploy(t, preminedAcct, contractsapi.TestSimple.Bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) @@ -515,20 +520,20 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { }) t.Run("eth_getStorageAt", func(t *testing.T) { - key1, err := wallet.GenerateKey() + key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) - txn := cluster.Transfer(t, acct, types.Address(key1.Address()), one) + txn := cluster.Transfer(t, preminedAcct, key1.Address(), ethgo.Ether(1)) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - txn = cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + txn = cluster.Deploy(t, key1, contractsapi.TestSimple.Bytecode) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - target := txn.Receipt().ContractAddress + target := types.Address(txn.Receipt().ContractAddress) - resp, err := newEthClient.GetStorageAt(types.Address(target), types.Hash{}, bladeRPC.LatestBlockNumberOrHash) + resp, err := newEthClient.GetStorageAt(target, types.Hash{}, bladeRPC.LatestBlockNumberOrHash) require.NoError(t, err) require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resp.String()) @@ -539,7 +544,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { input, err := setValueFn.Encode([]interface{}{newVal}) require.NoError(t, err) - txn = cluster.SendTxn(t, acct, ðgo.Transaction{Input: input, To: &target}) + txn = cluster.SendTxn(t, key1, types.NewTx(types.NewLegacyTx(types.WithInput(input), types.WithTo(&target)))) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -549,14 +554,14 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { }) t.Run("eth_getTransactionByHash and eth_getTransactionReceipt", func(t *testing.T) { - txn := cluster.Transfer(t, acct, types.StringToAddress("0xDEADBEEF"), one) + txn := cluster.Transfer(t, preminedAcct, types.StringToAddress("0xDEADBEEF"), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) ethTxn, err := newEthClient.GetTransactionByHash(types.Hash(txn.Receipt().TransactionHash)) require.NoError(t, err) - require.Equal(t, ethTxn.From(), types.Address(acct.Address())) + require.Equal(t, ethTxn.From(), preminedAcct.Address()) receipt, err := newEthClient.GetTransactionReceipt(ethTxn.Hash()) require.NoError(t, err) @@ -565,21 +570,21 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { }) t.Run("eth_getTransactionCount", func(t *testing.T) { - nonce, err := newEthClient.GetNonce(types.Address(acct.Address()), bladeRPC.LatestBlockNumberOrHash) + nonce, err := newEthClient.GetNonce(preminedAcct.Address(), bladeRPC.LatestBlockNumberOrHash) require.NoError(t, err) require.GreaterOrEqual(t, nonce, uint64(0)) // since we used this account in previous tests - txn := cluster.Transfer(t, acct, types.StringToAddress("0xDEADBEEF"), one) + txn := cluster.Transfer(t, preminedAcct, types.StringToAddress("0xDEADBEEF"), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - newNonce, err := newEthClient.GetNonce(types.Address(acct.Address()), bladeRPC.LatestBlockNumberOrHash) + newNonce, err := newEthClient.GetNonce(preminedAcct.Address(), bladeRPC.LatestBlockNumberOrHash) require.NoError(t, err) require.Equal(t, nonce+1, newNonce) }) t.Run("eth_getBalance", func(t *testing.T) { - balance, err := newEthClient.GetBalance(types.Address(acct.Address()), bladeRPC.LatestBlockNumberOrHash) + balance, err := newEthClient.GetBalance(preminedAcct.Address(), bladeRPC.LatestBlockNumberOrHash) require.NoError(t, err) require.True(t, balance.Cmp(big.NewInt(0)) >= 0) @@ -587,7 +592,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { tokens := ethgo.Ether(1) - txn := cluster.Transfer(t, acct, receiver, tokens) + txn := cluster.Transfer(t, preminedAcct, receiver, tokens) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) @@ -597,7 +602,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { }) t.Run("eth_estimateGas", func(t *testing.T) { - deployTxn := cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + deployTxn := cluster.Deploy(t, preminedAcct, contractsapi.TestSimple.Bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) @@ -606,7 +611,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() estimatedGas, err := newEthClient.EstimateGas(&bladeRPC.CallMsg{ - From: types.Address(acct.Address()), + From: preminedAcct.Address(), To: &target, Data: input, }) @@ -621,7 +626,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { }) t.Run("eth_call", func(t *testing.T) { - deployTxn := cluster.Deploy(t, acct, contractsapi.TestSimple.Bytecode) + deployTxn := cluster.Deploy(t, preminedAcct, contractsapi.TestSimple.Bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) @@ -629,7 +634,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() - acctZeroBalance, err := wallet.GenerateKey() + acctZeroBalance, err := crypto.GenerateECDSAKey() require.NoError(t, err) resp, err := newEthClient.Call(&bladeRPC.CallMsg{ @@ -656,7 +661,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { t.Run("eth_sendRawTransaction", func(t *testing.T) { receiver := types.StringToAddress("0xDEADFFFF") - tokens := ethgo.Ether(1) + tokenAmount := ethgo.Ether(1) chainID, err := newEthClient.ChainID() require.NoError(t, err) @@ -666,21 +671,23 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { newAccountKey, newAccountAddr := tests.GenerateKeyAndAddr(t) - transferTxn := cluster.Transfer(t, acct, newAccountAddr, tokens) + transferTxn := cluster.Transfer(t, preminedAcct, newAccountAddr, tokenAmount) require.NoError(t, transferTxn.Wait()) require.True(t, transferTxn.Succeed()) newAccountBalance, err := newEthClient.GetBalance(newAccountAddr, bladeRPC.LatestBlockNumberOrHash) require.NoError(t, err) - require.Equal(t, tokens, newAccountBalance) - - txn := types.NewTx(types.NewLegacyTx(types.WithNonce(0), - types.WithFrom(newAccountAddr), - types.WithTo(&receiver), - types.WithValue(ethgo.Gwei(1)), - types.WithGas(21000), - types.WithGasPrice(new(big.Int).SetUint64(gasPrice)), - )) + require.Equal(t, tokenAmount, newAccountBalance) + + txn := types.NewTx( + types.NewLegacyTx( + types.WithNonce(0), + types.WithFrom(newAccountAddr), + types.WithTo(&receiver), + types.WithValue(ethgo.Gwei(1)), + types.WithGas(21000), + types.WithGasPrice(new(big.Int).SetUint64(gasPrice)), + )) signedTxn, err := crypto.NewLondonSigner(chainID.Uint64()).SignTx(txn, newAccountKey) require.NoError(t, err) diff --git a/e2e-polybft/e2e/migration_test.go b/e2e-polybft/e2e/migration_test.go index 8093ed1e7d..c86cd23a55 100644 --- a/e2e-polybft/e2e/migration_test.go +++ b/e2e-polybft/e2e/migration_test.go @@ -7,26 +7,26 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/umbracle/ethgo" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" + "github.com/0xPolygon/polygon-edge/crypto" frameworkpolybft "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/e2e/framework" "github.com/0xPolygon/polygon-edge/helper/common" itrie "github.com/0xPolygon/polygon-edge/state/immutable-trie" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" - "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/wallet" ) func TestE2E_Migration(t *testing.T) { - userKey, _ := wallet.GenerateKey() - userAddr := userKey.Address() - userKey2, _ := wallet.GenerateKey() - userAddr2 := userKey2.Address() + userKey, _ := crypto.GenerateECDSAKey() + userAddr := ethgo.Address(userKey.Address()) + userKey2, _ := crypto.GenerateECDSAKey() + userAddr2 := ethgo.Address(userKey2.Address()) initialBalance := ethgo.Ether(10) srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { @@ -61,32 +61,39 @@ func TestE2E_Migration(t *testing.T) { relayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(rpcClient)) require.NoError(t, err) - //send transaction to user2 + // send transaction to user2 sendAmount := ethgo.Gwei(10000) - receipt, err := relayer.SendTransaction( - ðgo.Transaction{ - From: userAddr, - To: &userAddr2, - Gas: 1000000, - Value: sendAmount, - GasPrice: ethgo.Gwei(2).Uint64(), - }, userKey) + tx := types.NewTx(&types.LegacyTx{ + BaseTx: &types.BaseTx{ + From: userKey.Address(), + To: userKey2.Address().Ptr(), + Gas: 1000000, + Value: sendAmount, + }, + GasPrice: ethgo.Gwei(2), + }) + + receipt, err := relayer.SendTransaction(tx, userKey) require.NoError(t, err) require.NotNil(t, receipt) - receipt, err = relayer.SendTransaction(ðgo.Transaction{ - From: userAddr, - Gas: 1000000, - GasPrice: ethgo.Gwei(2).Uint64(), - Input: contractsapi.TestWriteBlockMetadata.Bytecode, - }, userKey) + tx = types.NewTx(&types.LegacyTx{ + BaseTx: &types.BaseTx{ + From: userKey.Address(), + Gas: 1000000, + Input: contractsapi.TestWriteBlockMetadata.Bytecode, + }, + GasPrice: ethgo.Gwei(2), + }) + + receipt, err = relayer.SendTransaction(tx, userKey) require.NoError(t, err) require.NotNil(t, receipt) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) deployedContractBalance := receipt.ContractAddress - initReceipt, err := ABITransaction(relayer, userKey, contractsapi.TestWriteBlockMetadata, receipt.ContractAddress, "init") + initReceipt, err := ABITransaction(relayer, userKey, contractsapi.TestWriteBlockMetadata, types.Address(receipt.ContractAddress), "init") if err != nil { t.Fatal(err) } diff --git a/e2e-polybft/e2e/txpool_test.go b/e2e-polybft/e2e/txpool_test.go index e842259605..a636f3b855 100644 --- a/e2e-polybft/e2e/txpool_test.go +++ b/e2e-polybft/e2e/txpool_test.go @@ -10,10 +10,10 @@ import ( "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/jsonrpc" - "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -21,7 +21,7 @@ import ( func TestE2E_TxPool_Transfer(t *testing.T) { // premine an account in the genesis file - sender, err := wallet.GenerateKey() + sender, err := crypto.GenerateECDSAKey() require.NoError(t, err) cluster := framework.NewTestCluster(t, 5, @@ -40,10 +40,10 @@ func TestE2E_TxPool_Transfer(t *testing.T) { receivers := []ethgo.Address{} for i := 0; i < num; i++ { - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() require.NoError(t, err) - receivers = append(receivers, key.Address()) + receivers = append(receivers, ethgo.Address(key.Address())) } var wg sync.WaitGroup @@ -53,24 +53,32 @@ func TestE2E_TxPool_Transfer(t *testing.T) { go func(i int, to ethgo.Address) { defer wg.Done() - txn := ðgo.Transaction{ - From: sender.Address(), - To: &to, - Gas: 30000, // enough to send a transfer - Value: big.NewInt(int64(sendAmount)), - Nonce: uint64(i), - } + var txData types.TxData // Send every second transaction as a dynamic fees one if i%2 == 0 { - txn.Type = ethgo.TransactionDynamicFee - txn.MaxFeePerGas = big.NewInt(1000000000) - txn.MaxPriorityFeePerGas = big.NewInt(100000000) + txData = types.NewDynamicFeeTx( + types.WithFrom(sender.Address()), + types.WithTo((*types.Address)(&to)), + types.WithGas(30000), // enough to send a transfer + types.WithValue(big.NewInt(int64(sendAmount))), + types.WithNonce(uint64(i)), + types.WithGasFeeCap(big.NewInt(1000000000)), + types.WithGasTipCap(big.NewInt(100000000)), + ) } else { - txn.Type = ethgo.TransactionLegacy - txn.GasPrice = ethgo.Gwei(2).Uint64() + txData = types.NewLegacyTx( + types.WithFrom(sender.Address()), + types.WithTo((*types.Address)(&to)), + types.WithGas(30000), + types.WithValue(big.NewInt(int64(sendAmount))), + types.WithNonce(uint64(i)), + types.WithGasPrice(ethgo.Gwei(2)), + ) } + txn := types.NewTx(txData) + sendTransaction(t, client, sender, txn) }(i, receivers[i]) } @@ -96,7 +104,7 @@ func TestE2E_TxPool_Transfer(t *testing.T) { // First account send some amount to second one and then second one to third account func TestE2E_TxPool_Transfer_Linear(t *testing.T) { - premine, err := wallet.GenerateKey() + premine, err := crypto.GenerateECDSAKey() require.NoError(t, err) // first account should have some matics premined @@ -123,24 +131,13 @@ func TestE2E_TxPool_Transfer_Linear(t *testing.T) { return err } - populateTxFees := func(txn *ethgo.Transaction, i int) { - if i%2 == 0 { - txn.Type = ethgo.TransactionDynamicFee - txn.MaxFeePerGas = big.NewInt(1000000000) - txn.MaxPriorityFeePerGas = big.NewInt(1000000000) - } else { - txn.Type = ethgo.TransactionLegacy - txn.GasPrice = ethgo.Gwei(1).Uint64() - } - } - num := 4 - receivers := []*wallet.Key{ + receivers := []crypto.Key{ premine, } for i := 0; i < num-1; i++ { - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() assert.NoError(t, err) receivers = append(receivers, key) @@ -158,34 +155,47 @@ func TestE2E_TxPool_Transfer_Linear(t *testing.T) { // This means that since gasCost and sendAmount are fixed, account C must receive gasCost * 2 // (to cover two more transfers C->D and D->E) + sendAmount * 3 (one bundle for each C,D and E). recipient := receivers[i].Address() - txn := ðgo.Transaction{ - Value: big.NewInt(int64(sendAmount * (num - i))), - To: &recipient, - Gas: 21000, + + var txData types.TxData + + if i%2 == 0 { + txData = types.NewDynamicFeeTx( + types.WithValue(big.NewInt(int64(sendAmount*(num-i)))), + types.WithTo(&recipient), + types.WithGas(21000), + types.WithGasFeeCap(big.NewInt(1000000000)), + types.WithGasTipCap(big.NewInt(1000000000)), + ) + } else { + txData = types.NewLegacyTx( + types.WithValue(big.NewInt(int64(sendAmount*(num-i)))), + types.WithTo(&recipient), + types.WithGas(21000), + types.WithGasPrice(ethgo.Gwei(1)), + ) } - // Populate fees fields for the current transaction - populateTxFees(txn, i-1) + txn := types.NewTx(txData) // Add remaining fees to finish the cycle gasCostTotal := new(big.Int).Mul(txCost(txn), new(big.Int).SetInt64(int64(num-i-1))) - txn.Value = txn.Value.Add(txn.Value, gasCostTotal) + txn.SetValue(txn.Value().Add(txn.Value(), gasCostTotal)) sendTransaction(t, client, receivers[i-1], txn) - err := waitUntilBalancesChanged(receivers[i].Address()) + err := waitUntilBalancesChanged(ethgo.Address(receivers[i].Address())) require.NoError(t, err) } for i := 1; i < num; i++ { - balance, err := client.GetBalance(receivers[i].Address(), ethgo.Latest) + balance, err := client.GetBalance(ethgo.Address(receivers[i].Address()), ethgo.Latest) require.NoError(t, err) require.Equal(t, uint64(sendAmount), balance.Uint64()) } } func TestE2E_TxPool_TransactionWithHeaderInstructions(t *testing.T) { - sidechainKey, err := wallet.GenerateKey() + sidechainKey, err := crypto.GenerateECDSAKey() require.NoError(t, err) cluster := framework.NewTestCluster(t, 4, @@ -198,11 +208,15 @@ func TestE2E_TxPool_TransactionWithHeaderInstructions(t *testing.T) { relayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Servers[0].JSONRPCAddr())) require.NoError(t, err) - receipt, err := relayer.SendTransaction(ðgo.Transaction{Input: contractsapi.TestWriteBlockMetadata.Bytecode}, sidechainKey) + tx := types.NewTx(types.NewLegacyTx( + types.WithInput(contractsapi.TestWriteBlockMetadata.Bytecode), + )) + + receipt, err := relayer.SendTransaction(tx, sidechainKey) require.NoError(t, err) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) - receipt, err = ABITransaction(relayer, sidechainKey, contractsapi.TestWriteBlockMetadata, receipt.ContractAddress, "init", []interface{}{}) + receipt, err = ABITransaction(relayer, sidechainKey, contractsapi.TestWriteBlockMetadata, types.Address(receipt.ContractAddress), "init", []interface{}{}) require.NoError(t, err) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) @@ -221,7 +235,7 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { ) // Create recipient key - key, err := wallet.GenerateKey() + key, err := crypto.GenerateECDSAKey() assert.NoError(t, err) recipient := key.Address() @@ -229,7 +243,7 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { t.Logf("Recipient %s\n", recipient) // Create pre-mined balance for sender - sender, err := wallet.GenerateKey() + sender, err := crypto.GenerateECDSAKey() require.NoError(t, err) // First account should have some matics premined @@ -247,32 +261,39 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { sentAmount := new(big.Int) nonce := uint64(0) - for i := 0; i < txNum; i++ { - txn := ðgo.Transaction{ - Value: sendAmount, - To: &recipient, - Gas: 21000, - Nonce: nonce, - } + var txData types.TxData + for i := 0; i < txNum; i++ { if i%2 == 0 { - txn.Type = ethgo.TransactionDynamicFee - txn.MaxFeePerGas = big.NewInt(1000000000) - txn.MaxPriorityFeePerGas = big.NewInt(100000000) + txData = types.NewDynamicFeeTx( + types.WithValue(sendAmount), + types.WithTo(&recipient), + types.WithGas(21000), + types.WithNonce(nonce), + types.WithGasFeeCap(big.NewInt(1000000000)), + types.WithGasTipCap(big.NewInt(100000000)), + ) } else { - txn.Type = ethgo.TransactionLegacy - txn.GasPrice = ethgo.Gwei(2).Uint64() + txData = types.NewLegacyTx( + types.WithValue(sendAmount), + types.WithTo(&recipient), + types.WithGas(21000), + types.WithNonce(nonce), + types.WithGasPrice(ethgo.Gwei(2)), + ) } + txn := types.NewTx(txData) + sendTransaction(t, client, sender, txn) - sentAmount = sentAmount.Add(sentAmount, txn.Value) + sentAmount = sentAmount.Add(sentAmount, txn.Value()) nonce++ } // Wait until the balance has changed on all nodes in the cluster err = cluster.WaitUntil(time.Minute, time.Second*3, func() bool { for _, srv := range cluster.Servers { - balance, err := srv.WaitForNonZeroBalance(recipient, time.Second*10) + balance, err := srv.WaitForNonZeroBalance(ethgo.Address(recipient), time.Second*10) assert.NoError(t, err) if balance != nil && balance.BitLen() > 0 { assert.Equal(t, sentAmount, balance) @@ -287,35 +308,39 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { } // sendTransaction is a helper function which signs transaction with provided private key and sends it -func sendTransaction(t *testing.T, client *jsonrpc.Eth, sender *wallet.Key, txn *ethgo.Transaction) { +func sendTransaction(t *testing.T, client *jsonrpc.Eth, sender crypto.Key, txn *types.Transaction) { t.Helper() chainID, err := client.ChainID() require.NoError(t, err) - if txn.Type == ethgo.TransactionDynamicFee { - txn.ChainID = chainID + if txn.Type() == types.DynamicFeeTxType { + txn.SetChainID(chainID) } - signer := wallet.NewEIP155Signer(chainID.Uint64()) - signedTxn, err := signer.SignTx(txn, sender) + signer := crypto.NewLondonSigner(chainID.Uint64()) + + signedTxn, err := signer.SignTxWithCallback(txn, + func(hash types.Hash) (sig []byte, err error) { + return sender.Sign(hash[:]) + }) require.NoError(t, err) - txnRaw, err := signedTxn.MarshalRLPTo(nil) + txnRlp := signedTxn.MarshalRLPTo(nil) require.NoError(t, err) - _, err = client.SendRawTransaction(txnRaw) + _, err = client.SendRawTransaction(txnRlp) require.NoError(t, err) } -func txCost(t *ethgo.Transaction) *big.Int { +func txCost(t *types.Transaction) *big.Int { var factor *big.Int - if t.Type == ethgo.TransactionDynamicFee { - factor = new(big.Int).Set(t.MaxFeePerGas) + if t.Type() == types.DynamicFeeTxType { + factor = new(big.Int).Set(t.GasFeeCap()) } else { - factor = new(big.Int).SetUint64(t.GasPrice) + factor = new(big.Int).Set(t.GasPrice()) } - return new(big.Int).Mul(factor, new(big.Int).SetUint64(t.Gas)) + return new(big.Int).Mul(factor, new(big.Int).SetUint64(t.Gas())) } diff --git a/e2e-polybft/framework/test-cluster.go b/e2e-polybft/framework/test-cluster.go index ed763d2df7..c64cd08edb 100644 --- a/e2e-polybft/framework/test-cluster.go +++ b/e2e-polybft/framework/test-cluster.go @@ -21,6 +21,7 @@ import ( "github.com/0xPolygon/polygon-edge/command/genesis" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -28,7 +29,6 @@ import ( "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/abi" "github.com/umbracle/ethgo/jsonrpc" - "github.com/umbracle/ethgo/wallet" ) const ( @@ -1042,30 +1042,45 @@ func (c *TestCluster) Call(t *testing.T, to types.Address, method *abi.Method, return output } -func (c *TestCluster) Deploy(t *testing.T, sender ethgo.Key, bytecode []byte) *TestTxn { +func (c *TestCluster) Deploy(t *testing.T, sender *crypto.ECDSAKey, bytecode []byte) *TestTxn { t.Helper() - return c.SendTxn(t, sender, ðgo.Transaction{From: sender.Address(), Input: bytecode}) + tx := types.NewTx(&types.LegacyTx{ + BaseTx: &types.BaseTx{ + From: sender.Address(), + Input: bytecode, + }, + }) + + return c.SendTxn(t, sender, tx) } -func (c *TestCluster) Transfer(t *testing.T, sender ethgo.Key, target types.Address, value *big.Int) *TestTxn { +func (c *TestCluster) Transfer(t *testing.T, sender *crypto.ECDSAKey, target types.Address, value *big.Int) *TestTxn { t.Helper() - targetAddr := ethgo.Address(target) + tx := types.NewTx(types.NewLegacyTx( + types.WithFrom(sender.Address()), + types.WithValue(value), + types.WithTo(&target), + )) - return c.SendTxn(t, sender, ðgo.Transaction{From: sender.Address(), To: &targetAddr, Value: value}) + return c.SendTxn(t, sender, tx) } -func (c *TestCluster) MethodTxn(t *testing.T, sender ethgo.Key, target types.Address, input []byte) *TestTxn { +func (c *TestCluster) MethodTxn(t *testing.T, sender *crypto.ECDSAKey, target types.Address, input []byte) *TestTxn { t.Helper() - targetAddr := ethgo.Address(target) + tx := types.NewTx(types.NewLegacyTx( + types.WithFrom(sender.Address()), + types.WithInput(input), + types.WithTo(&target), + )) - return c.SendTxn(t, sender, ðgo.Transaction{From: sender.Address(), To: &targetAddr, Input: input}) + return c.SendTxn(t, sender, tx) } // SendTxn sends a transaction -func (c *TestCluster) SendTxn(t *testing.T, sender ethgo.Key, txn *ethgo.Transaction) *TestTxn { +func (c *TestCluster) SendTxn(t *testing.T, sender *crypto.ECDSAKey, txn *types.Transaction) *TestTxn { t.Helper() // since we might use get nonce to query the latest nonce and that value is only @@ -1079,44 +1094,46 @@ func (c *TestCluster) SendTxn(t *testing.T, sender ethgo.Key, txn *ethgo.Transac require.NoError(t, err) // initialize transaction values if not set - if txn.Nonce == 0 { - nonce, err := client.Eth().GetNonce(sender.Address(), ethgo.Latest) + if txn.Nonce() == 0 { + nonce, err := client.Eth().GetNonce(ethgo.Address(sender.Address()), ethgo.Latest) require.NoError(t, err) - txn.Nonce = nonce + txn.SetNonce(nonce) } - if txn.GasPrice == 0 { + if txn.GasPrice() == nil || txn.GasPrice() == big.NewInt(0) { gasPrice, err := client.Eth().GasPrice() require.NoError(t, err) - txn.GasPrice = gasPrice + txn.SetGasPrice(new(big.Int).SetUint64(gasPrice)) } - if txn.Gas == 0 { + if txn.Gas() == 0 { callMsg := txrelayer.ConvertTxnToCallMsg(txn) gasLimit, err := client.Eth().EstimateGas(callMsg) if err != nil { // gas estimation can fail in case an account is not allow-listed // (fallback it to default gas limit in that case) - txn.Gas = txrelayer.DefaultGasLimit + txn.SetGas(txrelayer.DefaultGasLimit) } else { - txn.Gas = gasLimit + txn.SetGas(gasLimit) } } chainID, err := client.Eth().ChainID() require.NoError(t, err) - signer := wallet.NewEIP155Signer(chainID.Uint64()) - signedTxn, err := signer.SignTx(txn, sender) + signer := crypto.NewLondonSigner(chainID.Uint64()) + signedTxn, err := signer.SignTxWithCallback(txn, + func(hash types.Hash) (sig []byte, err error) { + return sender.Sign(hash.Bytes()) + }) require.NoError(t, err) - txnRaw, err := signedTxn.MarshalRLPTo(nil) - require.NoError(t, err) + rlpTxn := signedTxn.MarshalRLPTo(nil) - hash, err := client.Eth().SendRawTransaction(txnRaw) + hash, err := client.Eth().SendRawTransaction(rlpTxn) require.NoError(t, err) return &TestTxn{ @@ -1129,12 +1146,12 @@ func (c *TestCluster) SendTxn(t *testing.T, sender ethgo.Key, txn *ethgo.Transac type TestTxn struct { client *jsonrpc.Eth hash ethgo.Hash - txn *ethgo.Transaction + txn *types.Transaction receipt *ethgo.Receipt } // Txn returns the raw transaction that was sent -func (t *TestTxn) Txn() *ethgo.Transaction { +func (t *TestTxn) Txn() *types.Transaction { return t.txn } @@ -1156,7 +1173,7 @@ func (t *TestTxn) Failed() bool { // Reverted returns whether the transaction failed and was reverted consuming // all the gas from the call func (t *TestTxn) Reverted() bool { - return t.receipt.Status == uint64(types.ReceiptFailed) && t.txn.Gas == t.receipt.GasUsed + return t.receipt.Status == uint64(types.ReceiptFailed) && t.txn.Gas() == t.receipt.GasUsed } // Wait waits for the transaction to be executed diff --git a/helper/tests/testing.go b/helper/tests/testing.go index f781e2ef85..442e39c7c5 100644 --- a/helper/tests/testing.go +++ b/helper/tests/testing.go @@ -31,7 +31,7 @@ var ( func GenerateKeyAndAddr(t *testing.T) (*ecdsa.PrivateKey, types.Address) { t.Helper() - key, err := crypto.GenerateECDSAKey() + key, err := crypto.GenerateECDSAPrivateKey() assert.NoError(t, err) diff --git a/txpool/txpool.go b/txpool/txpool.go index f09a6f07bb..6eb1bebb26 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -571,7 +571,6 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { } // Check if the transaction is signed properly - // Extract the sender from, signerErr := p.signer.Sender(tx) if signerErr != nil { diff --git a/txpool/txpool_test.go b/txpool/txpool_test.go index 13cde912ee..0f4cfa3ed3 100644 --- a/txpool/txpool_test.go +++ b/txpool/txpool_test.go @@ -3537,7 +3537,7 @@ func TestAddTxsInOrder(t *testing.T) { addrsTxs := [accountCount]container{} for i := 0; i < accountCount; i++ { - key, err := crypto.GenerateECDSAKey() + key, err := crypto.GenerateECDSAPrivateKey() require.NoError(t, err) addrsTxs[i] = container{ @@ -3774,7 +3774,7 @@ func BenchmarkAddTxTime(b *testing.B) { b.Run("benchmark add one tx", func(b *testing.B) { signer := crypto.NewEIP155Signer(100) - key, err := crypto.GenerateECDSAKey() + key, err := crypto.GenerateECDSAPrivateKey() if err != nil { b.Fatal(err) } @@ -3802,7 +3802,7 @@ func BenchmarkAddTxTime(b *testing.B) { b.Run("benchmark fill account", func(b *testing.B) { signer := crypto.NewEIP155Signer(100) - key, err := crypto.GenerateECDSAKey() + key, err := crypto.GenerateECDSAPrivateKey() if err != nil { b.Fatal(err) } diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 353772cd1b..405efd8246 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -9,10 +9,11 @@ import ( "sync" "time" - "github.com/0xPolygon/polygon-edge/types" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/jsonrpc" - "github.com/umbracle/ethgo/wallet" + + "github.com/0xPolygon/polygon-edge/crypto" + "github.com/0xPolygon/polygon-edge/types" ) const ( @@ -35,12 +36,12 @@ var ( type TxRelayer interface { // Call executes a message call immediately without creating a transaction on the blockchain - Call(from ethgo.Address, to ethgo.Address, input []byte) (string, error) + Call(from types.Address, to types.Address, input []byte) (string, error) // SendTransaction signs given transaction by provided key and sends it to the blockchain - SendTransaction(txn *ethgo.Transaction, key ethgo.Key) (*ethgo.Receipt, error) + SendTransaction(txn *types.Transaction, key crypto.Key) (*ethgo.Receipt, error) // SendTransactionLocal sends non-signed transaction // (this function is meant only for testing purposes and is about to be removed at some point) - SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Receipt, error) + SendTransactionLocal(txn *types.Transaction) (*ethgo.Receipt, error) // Client returns jsonrpc client Client() *jsonrpc.Client } @@ -81,10 +82,10 @@ func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { } // Call executes a message call immediately without creating a transaction on the blockchain -func (t *TxRelayerImpl) Call(from ethgo.Address, to ethgo.Address, input []byte) (string, error) { +func (t *TxRelayerImpl) Call(from types.Address, to types.Address, input []byte) (string, error) { callMsg := ðgo.CallMsg{ - From: from, - To: &to, + From: ethgo.Address(from), + To: (*ethgo.Address)(&to), Data: input, } @@ -92,17 +93,23 @@ func (t *TxRelayerImpl) Call(from ethgo.Address, to ethgo.Address, input []byte) } // SendTransaction signs given transaction by provided key and sends it to the blockchain -func (t *TxRelayerImpl) SendTransaction(txn *ethgo.Transaction, key ethgo.Key) (*ethgo.Receipt, error) { +func (t *TxRelayerImpl) SendTransaction(txn *types.Transaction, key crypto.Key) (*ethgo.Receipt, error) { txnHash, err := t.sendTransactionLocked(txn, key) if err != nil { - if txn.Type != ethgo.TransactionLegacy { + if txn.Type() != types.LegacyTxType { for _, fallbackErr := range dynamicFeeTxFallbackErrs { if strings.Contains( strings.ToLower(err.Error()), strings.ToLower(fallbackErr.Error())) { // "downgrade" transaction to the legacy tx type and resend it - txn.Type = ethgo.TransactionLegacy - txn.GasPrice = 0 + copyTxn := txn.Copy() + txn.InitInnerData(types.LegacyTxType) + txn.SetNonce(copyTxn.Nonce()) + txn.SetInput(copyTxn.Input()) + txn.SetValue(copyTxn.Value()) + txn.SetTo(copyTxn.To()) + txn.SetFrom(copyTxn.From()) + txn.SetGasPrice(big.NewInt(0)) return t.SendTransaction(txn, key) } @@ -120,11 +127,11 @@ func (t *TxRelayerImpl) Client() *jsonrpc.Client { return t.client } -func (t *TxRelayerImpl) sendTransactionLocked(txn *ethgo.Transaction, key ethgo.Key) (ethgo.Hash, error) { +func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto.Key) (ethgo.Hash, error) { t.lock.Lock() defer t.lock.Unlock() - nonce, err := t.client.Eth().GetNonce(key.Address(), ethgo.Pending) + nonce, err := t.client.Eth().GetNonce(ethgo.Address(key.Address()), ethgo.Pending) if err != nil { return ethgo.ZeroHash, fmt.Errorf("failed to get nonce: %w", err) } @@ -134,15 +141,15 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *ethgo.Transaction, key ethgo. return ethgo.ZeroHash, err } - txn.ChainID = chainID - txn.Nonce = nonce + txn.SetChainID(chainID) + txn.SetNonce(nonce) - if txn.From == ethgo.ZeroAddress { - txn.From = key.Address() + if txn.From() == types.ZeroAddress { + txn.SetFrom(key.Address()) } - if txn.Type == ethgo.TransactionDynamicFee { - maxPriorityFee := txn.MaxPriorityFeePerGas + if txn.Type() == types.DynamicFeeTxType { + maxPriorityFee := txn.GetGasTipCap() if maxPriorityFee == nil { // retrieve the max priority fee per gas if maxPriorityFee, err = t.Client().Eth().MaxPriorityFeePerGas(); err != nil { @@ -152,10 +159,10 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *ethgo.Transaction, key ethgo. // set retrieved max priority fee per gas increased by certain percentage compMaxPriorityFee := new(big.Int).Mul(maxPriorityFee, big.NewInt(feeIncreasePercentage)) compMaxPriorityFee = compMaxPriorityFee.Div(compMaxPriorityFee, big.NewInt(100)) - txn.MaxPriorityFeePerGas = new(big.Int).Add(maxPriorityFee, compMaxPriorityFee) + txn.SetGasTipCap(new(big.Int).Add(maxPriorityFee, compMaxPriorityFee)) } - if txn.MaxFeePerGas == nil { + if txn.GetGasFeeCap() == nil { // retrieve the latest base fee feeHist, err := t.Client().Eth().FeeHistory(1, ethgo.Latest, nil) if err != nil { @@ -168,32 +175,33 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *ethgo.Transaction, key ethgo. maxFeePerGas := new(big.Int).Add(baseFee, maxPriorityFee) compMaxFeePerGas := new(big.Int).Mul(maxFeePerGas, big.NewInt(feeIncreasePercentage)) compMaxFeePerGas = compMaxFeePerGas.Div(compMaxFeePerGas, big.NewInt(100)) - txn.MaxFeePerGas = new(big.Int).Add(maxFeePerGas, compMaxFeePerGas) + txn.SetGasFeeCap(new(big.Int).Add(maxFeePerGas, compMaxFeePerGas)) } - } else if txn.GasPrice == 0 { + } else if txn.GasPrice() == nil || txn.GasPrice().Uint64() == 0 { gasPrice, err := t.Client().Eth().GasPrice() if err != nil { return ethgo.ZeroHash, fmt.Errorf("failed to get gas price: %w", err) } - txn.GasPrice = gasPrice + (gasPrice * feeIncreasePercentage / 100) + gasPriceBigInt := new(big.Int).SetUint64(gasPrice + (gasPrice * feeIncreasePercentage / 100)) + txn.SetGasPrice(gasPriceBigInt) } - if txn.Gas == 0 { + if txn.Gas() == 0 { gasLimit, err := t.client.Eth().EstimateGas(ConvertTxnToCallMsg(txn)) if err != nil { return ethgo.ZeroHash, fmt.Errorf("failed to estimate gas: %w", err) } - txn.Gas = gasLimit + (gasLimit * gasLimitIncreasePercentage / 100) + txn.SetGas(gasLimit + (gasLimit * gasLimitIncreasePercentage / 100)) } - signer := wallet.NewEIP155Signer(chainID.Uint64()) - if txn, err = signer.SignTx(txn, key); err != nil { - return ethgo.ZeroHash, err - } - - data, err := txn.MarshalRLPTo(nil) + signer := crypto.NewLondonSigner( + chainID.Uint64()) + signedTxn, err := signer.SignTxWithCallback(txn, + func(hash types.Hash) (sig []byte, err error) { + return key.Sign(hash.Bytes()) + }) if err != nil { return ethgo.ZeroHash, err } @@ -201,24 +209,26 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *ethgo.Transaction, key ethgo. if t.writer != nil { var msg string - if txn.Type == ethgo.TransactionDynamicFee { + if txn.Type() == types.DynamicFeeTxType { msg = fmt.Sprintf("[TxRelayer.SendTransaction]\nFrom = %s\nGas = %d\n"+ "Max Fee Per Gas = %d\nMax Priority Fee Per Gas = %d\n", - txn.From, txn.Gas, txn.MaxFeePerGas, txn.MaxPriorityFeePerGas) + txn.From(), txn.Gas(), txn.GasFeeCap(), txn.GasTipCap()) } else { msg = fmt.Sprintf("[TxRelayer.SendTransaction]\nFrom = %s\nGas = %d\nGas Price = %d\n", - txn.From, txn.Gas, txn.GasPrice) + txn.From(), txn.Gas(), txn.GasPrice()) } _, _ = t.writer.Write([]byte(msg)) } - return t.client.Eth().SendRawTransaction(data) + rlpTxn := signedTxn.MarshalRLP() + + return t.client.Eth().SendRawTransaction(rlpTxn) } // SendTransactionLocal sends non-signed transaction // (this function is meant only for testing purposes and is about to be removed at some point) -func (t *TxRelayerImpl) SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Receipt, error) { +func (t *TxRelayerImpl) SendTransactionLocal(txn *types.Transaction) (*ethgo.Receipt, error) { txnHash, err := t.sendTransactionLocalLocked(txn) if err != nil { return nil, err @@ -227,7 +237,7 @@ func (t *TxRelayerImpl) SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Rec return t.waitForReceipt(txnHash) } -func (t *TxRelayerImpl) sendTransactionLocalLocked(txn *ethgo.Transaction) (ethgo.Hash, error) { +func (t *TxRelayerImpl) sendTransactionLocalLocked(txn *types.Transaction) (ethgo.Hash, error) { t.lock.Lock() defer t.lock.Unlock() @@ -240,17 +250,17 @@ func (t *TxRelayerImpl) sendTransactionLocalLocked(txn *ethgo.Transaction) (ethg return ethgo.ZeroHash, errNoAccounts } - txn.From = accounts[0] + txn.SetFrom(types.Address(accounts[0])) gasLimit, err := t.client.Eth().EstimateGas(ConvertTxnToCallMsg(txn)) if err != nil { return ethgo.ZeroHash, err } - txn.Gas = gasLimit - txn.GasPrice = defaultGasPrice + txn.SetGas(gasLimit) + txn.SetGasPrice(new(big.Int).SetUint64(defaultGasPrice)) - return t.client.Eth().SendTransaction(txn) + return t.client.Eth().SendTransaction(convertTxn(txn)) } func (t *TxRelayerImpl) waitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { @@ -278,15 +288,75 @@ func (t *TxRelayerImpl) waitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) } // ConvertTxnToCallMsg converts txn instance to call message -func ConvertTxnToCallMsg(txn *ethgo.Transaction) *ethgo.CallMsg { +func ConvertTxnToCallMsg(txn *types.Transaction) *ethgo.CallMsg { + gasPrice := uint64(0) + if txn.GasPrice() != nil { + gasPrice = txn.GasPrice().Uint64() + } + return ðgo.CallMsg{ - From: txn.From, - To: txn.To, - Data: txn.Input, - GasPrice: txn.GasPrice, - Value: txn.Value, - Gas: new(big.Int).SetUint64(txn.Gas), + From: ethgo.Address(txn.From()), + To: (*ethgo.Address)(txn.To()), + Data: txn.Input(), + GasPrice: gasPrice, + Value: txn.Value(), + Gas: new(big.Int).SetUint64(txn.Gas()), + } +} + +// convertTxn converts transaction from types.Transaction to ethgo.Transaction +func convertTxn(tx *types.Transaction) *ethgo.Transaction { + getAccessList := func() ethgo.AccessList { + accessList := make(ethgo.AccessList, 0, len(tx.AccessList())) + + for _, e := range tx.AccessList() { + storageKeys := make([]ethgo.Hash, 0) + + for _, sk := range e.StorageKeys { + storageKeys = append(storageKeys, ethgo.Hash(sk)) + } + + accessList = append(accessList, + ethgo.AccessEntry{ + Address: ethgo.Address(e.Address), + Storage: storageKeys, + }) + } + + return accessList + } + + convertedTx := ðgo.Transaction{ + From: ethgo.Address(tx.From()), + To: (*ethgo.Address)(tx.To()), + Input: tx.Input(), + Value: tx.Value(), + Gas: tx.Gas(), + } + + switch tx.Type() { + case types.DynamicFeeTxType: + convertedTx.Type = ethgo.TransactionDynamicFee + convertedTx.AccessList = getAccessList() + convertedTx.MaxFeePerGas = tx.GetGasFeeCap() + convertedTx.MaxPriorityFeePerGas = tx.GetGasTipCap() + + break + + case types.AccessListTxType: + convertedTx.Type = ethgo.TransactionAccessList + convertedTx.AccessList = getAccessList() + + break + + default: + convertedTx.Type = ethgo.TransactionLegacy + convertedTx.GasPrice = tx.GetGasPrice(0).Uint64() + + break } + + return convertedTx } type TxRelayerOption func(*TxRelayerImpl) diff --git a/types/transaction.go b/types/transaction.go index 248ee979e1..73804406cb 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -183,6 +183,15 @@ func (t *Transaction) SetSignatureValues(v, r, s *big.Int) { t.Inner.setSignatureValues(v, r, s) } +// SplitToRawSignatureValues splits signature to v, r and s components and sets it to the transaction +func (t *Transaction) SplitToRawSignatureValues(signature, vRaw []byte) { + r := new(big.Int).SetBytes(signature[:HashLength]) + s := new(big.Int).SetBytes(signature[HashLength : 2*HashLength]) + v := new(big.Int).SetBytes(vRaw) + + t.SetSignatureValues(v, r, s) +} + func (t *Transaction) SetFrom(addr Address) { t.Inner.setFrom(addr) } From 40765a75c08aaf949c315e4317d842a3bacdf2e6 Mon Sep 17 00:00:00 2001 From: oliverbundalo <158565516+oliverbundalo@users.noreply.github.com> Date: Fri, 22 Mar 2024 10:50:14 +0100 Subject: [PATCH 22/48] Update e2e-polybft/e2e/storage_test.go Co-authored-by: Goran Rojovic <100121253+goran-ethernal@users.noreply.github.com> --- e2e-polybft/e2e/storage_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go index c7ad12686f..ddb8f379cf 100644 --- a/e2e-polybft/e2e/storage_test.go +++ b/e2e-polybft/e2e/storage_test.go @@ -50,7 +50,7 @@ func TestE2E_Storage(t *testing.T) { txn := ðgo.Transaction{ From: sender.Address(), To: &to, - Gas: 30000, // enough to send a transfer + Gas: 21000, // enough to send a transfer Value: big.NewInt(int64(i)), Nonce: uint64(i), } From 3fd1f946e201db5f66c34313bc782c6cd0df24aa Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Fri, 22 Mar 2024 12:51:00 +0100 Subject: [PATCH 23/48] Changes from PR, 1st part --- blockchain/storagev2/leveldb/leveldb_test.go | 8 ++----- blockchain/storagev2/mdbx/batch.go | 2 +- blockchain/storagev2/mdbx/mdbx.go | 11 ++++----- blockchain/storagev2/mdbx/mdbx_perf_test.go | 4 +--- blockchain/storagev2/mdbx/mdbx_test.go | 16 ++++--------- blockchain/storagev2/storage.go | 24 +++++++++++--------- 6 files changed, 26 insertions(+), 39 deletions(-) diff --git a/blockchain/storagev2/leveldb/leveldb_test.go b/blockchain/storagev2/leveldb/leveldb_test.go index 4992e9e90c..6aa9437e21 100644 --- a/blockchain/storagev2/leveldb/leveldb_test.go +++ b/blockchain/storagev2/leveldb/leveldb_test.go @@ -241,14 +241,10 @@ insertloop: batchWriter.PutHeadHash(b.Block.Header.Hash) batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash()) - - if err := batchWriter.WriteBatch(); err != nil { - require.NoError(t, err) - } - - t.Logf("writing block %d", i) + require.NoError(t, batchWriter.WriteBatch()) size := dirSize(t, path) + t.Logf("writing block %d", i) t.Logf("\tldb file count: %d", countLdbFilesInPath(path)) t.Logf("\tdir size %d MBs", size/1_000_000) } diff --git a/blockchain/storagev2/mdbx/batch.go b/blockchain/storagev2/mdbx/batch.go index 553276e16c..24896038f1 100644 --- a/blockchain/storagev2/mdbx/batch.go +++ b/blockchain/storagev2/mdbx/batch.go @@ -28,7 +28,7 @@ func newBatchMdbx(db *MdbxDB) *batchMdbx { } func (b *batchMdbx) Put(t uint8, k []byte, v []byte) { - if t&storagev2.GIDLID_INDEX != 0 { + if t&storagev2.LOOKUP_INDEX != 0 { // Random write b.tx.Put(b.dbi[t], k, v, mdbx.NoDupData) } else { diff --git a/blockchain/storagev2/mdbx/mdbx.go b/blockchain/storagev2/mdbx/mdbx.go index 8b6e4d81be..1ddeb2a99b 100644 --- a/blockchain/storagev2/mdbx/mdbx.go +++ b/blockchain/storagev2/mdbx/mdbx.go @@ -108,11 +108,8 @@ func (db *MdbxDB) update(f func(tx *mdbx.Txn) error) (err error) { } _, err = tx.Commit() - if err != nil { - return err - } - return nil + return err } func (db *MdbxDB) openDBI(flags uint) error { @@ -134,11 +131,11 @@ func (db *MdbxDB) openDBI(flags uint) error { err := db.update(func(tx *mdbx.Txn) error { for i, name := range tableMapper { dbi, err := tx.OpenDBISimple(name, mdbx.Create) - if err == nil { - db.dbi[i] = dbi - } else { + if err != nil { return err } + + db.dbi[i] = dbi } return nil diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go index a155211e18..0140e3d82e 100644 --- a/blockchain/storagev2/mdbx/mdbx_perf_test.go +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -177,9 +177,7 @@ func TestWriteBlockPerf(t *testing.T) { tn := time.Now().UTC() - if err := batchWriter.WriteBatch(); err != nil { - require.NoError(t, err) - } + require.NoError(t, batchWriter.WriteBatch()) d := time.Since(tn) watchTime = watchTime + d.Milliseconds() diff --git a/blockchain/storagev2/mdbx/mdbx_test.go b/blockchain/storagev2/mdbx/mdbx_test.go index c62d91cb59..0a5c8638fb 100644 --- a/blockchain/storagev2/mdbx/mdbx_test.go +++ b/blockchain/storagev2/mdbx/mdbx_test.go @@ -178,18 +178,16 @@ func dbSize(t *testing.T, path string) int64 { err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { if err != nil { - t.Fail() + return err } if info != nil && !info.IsDir() && strings.Contains(info.Name(), ".dat") { size += info.Size() } - return err + return nil }) - if err != nil { - t.Log(err) - } + require.NoError(t, err) return size } @@ -231,14 +229,10 @@ insertloop: batchWriter.PutHeadHash(b.Block.Header.Hash) batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) batchWriter.PutCanonicalHash(uint64(i), b.Block.Hash()) - - if err := batchWriter.WriteBatch(); err != nil { - require.NoError(t, err) - } - - t.Logf("writing block %d", i) + require.NoError(t, batchWriter.WriteBatch()) size := dbSize(t, path) + t.Logf("writing block %d", i) t.Logf("\tdir size %d MBs", size/1_000_000) } } diff --git a/blockchain/storagev2/storage.go b/blockchain/storagev2/storage.go index b480bc04b2..17b44a9f23 100644 --- a/blockchain/storagev2/storage.go +++ b/blockchain/storagev2/storage.go @@ -40,11 +40,11 @@ const ( // GidLid tables const ( - FORK = uint8(0) | GIDLID_INDEX - HEAD_HASH = uint8(2) | GIDLID_INDEX - HEAD_NUMBER = uint8(4) | GIDLID_INDEX - BLOCK_LOOKUP = uint8(6) | GIDLID_INDEX - TX_LOOKUP = uint8(8) | GIDLID_INDEX + FORK = uint8(0) | LOOKUP_INDEX + HEAD_HASH = uint8(2) | LOOKUP_INDEX + HEAD_NUMBER = uint8(4) | LOOKUP_INDEX + BLOCK_LOOKUP = uint8(6) | LOOKUP_INDEX + TX_LOOKUP = uint8(8) | LOOKUP_INDEX ) const MAX_TABLES = uint8(20) @@ -52,12 +52,14 @@ const MAX_TABLES = uint8(20) // Database indexes const ( MAINDB_INDEX = uint8(0) - GIDLID_INDEX = uint8(1) + LOOKUP_INDEX = uint8(1) ) -var FORK_KEY = []byte("0000000f") -var HEAD_HASH_KEY = []byte("0000000h") -var HEAD_NUMBER_KEY = []byte("0000000n") +var ( + FORK_KEY = []byte("0000000f") + HEAD_HASH_KEY = []byte("0000000h") + HEAD_NUMBER_KEY = []byte("0000000n") +) var ErrNotFound = fmt.Errorf("not found") var ErrInvalidData = fmt.Errorf("invalid data") @@ -93,8 +95,8 @@ func (s *Storage) NewWriter() *Writer { } func getIndex(t uint8) uint8 { - if t&GIDLID_INDEX != 0 { - return GIDLID_INDEX + if t&LOOKUP_INDEX != 0 { + return LOOKUP_INDEX } return MAINDB_INDEX From 1c9a2d44aa4e4c5eaad2fe158330304addfb5094 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Fri, 22 Mar 2024 16:53:47 +0100 Subject: [PATCH 24/48] PR comments - completed --- .../storagev2/leveldb/leveldb_perf_test.go | 139 +----------- blockchain/storagev2/leveldb/leveldb_test.go | 111 +--------- blockchain/storagev2/mdbx/mdbx.go | 15 +- blockchain/storagev2/mdbx/mdbx_perf_test.go | 135 +---------- blockchain/storagev2/mdbx/mdbx_test.go | 111 +--------- blockchain/storagev2/testing.go | 209 ++++++------------ blockchain/storagev2/testing_perf.go | 137 ++++++++++++ 7 files changed, 241 insertions(+), 616 deletions(-) create mode 100644 blockchain/storagev2/testing_perf.go diff --git a/blockchain/storagev2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go index 9c5b641ca3..14da8ff857 100644 --- a/blockchain/storagev2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -1,7 +1,6 @@ package leveldb import ( - "math/big" "math/rand" "os" "path/filepath" @@ -9,97 +8,12 @@ import ( "testing" "time" - "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/blockchain/storagev2" - "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func createTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { - t.Helper() - - txs := make([]*types.Transaction, count) - - for i := range txs { - tx := types.NewTx(&types.DynamicFeeTx{ - Gas: types.StateTransactionGasLimit, - Nonce: uint64(startNonce + i), - From: from, - To: to, - Value: big.NewInt(2000), - GasFeeCap: big.NewInt(100), - GasTipCap: big.NewInt(10), - }) - - txs[i] = tx - } - - return txs -} - -const letterBytes = "abcdef0123456789" - -func randStringBytes(n int) string { - b := make([]byte, n) - for i := range b { - b[i] = letterBytes[rand.Intn(len(letterBytes))] - } - - return string(b) -} - -func createBlock(t *testing.T) *types.FullBlock { - t.Helper() - - transactionsCount := 2500 - status := types.ReceiptSuccess - addr1 := types.StringToAddress("17878aa") - addr2 := types.StringToAddress("2bf5653") - b := &types.FullBlock{ - Block: &types.Block{ - Header: &types.Header{ - Number: 0, - ExtraData: make([]byte, 32), - Hash: types.ZeroHash, - }, - Transactions: createTxs(t, 0, transactionsCount, addr1, &addr2), - Uncles: blockchain.NewTestHeaders(10), - }, - Receipts: make([]*types.Receipt, transactionsCount), - } - - logs := make([]*types.Log, 10) - - for i := 0; i < 10; i++ { - logs[i] = &types.Log{ - Address: addr1, - Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, - Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, - } - } - - for i := 0; i < len(b.Block.Transactions); i++ { - b.Receipts[i] = &types.Receipt{ - TxHash: b.Block.Transactions[i].Hash(), - Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTxType, - GasUsed: uint64(100000), - Status: &status, - Logs: logs, - CumulativeGasUsed: uint64(100000), - ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, - } - } - - for i := 0; i < 5; i++ { - b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) - } - - return b -} - func openStorage(t *testing.T, p string) (*storagev2.Storage, func(), string) { t.Helper() @@ -142,49 +56,6 @@ func dbSize(t *testing.T, path string) int64 { return size } -func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock { - t.Helper() - - var addr types.Address - - b.Block.Header.Number = num - b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) - - for i := range b.Block.Transactions { - addr = types.StringToAddress(randStringBytes(8)) - b.Block.Transactions[i].SetTo(&addr) - b.Block.Transactions[i].ComputeHash() - b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() - } - - b.Block.Header.ComputeHash() - - return b -} - -func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *storagev2.Writer { - t.Helper() - - batchWriter := s.NewWriter() - - // GidLid 'sorted' - batchWriter.PutHeadHash(b.Block.Header.Hash) - batchWriter.PutHeadNumber(b.Block.Number()) - batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) - - for _, tx := range b.Block.Transactions { - batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) - } - - // Main DB sorted - batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body()) - batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) - batchWriter.PutHeader(b.Block.Header) - batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) - - return batchWriter -} - func TestWriteBlockPerf(t *testing.T) { t.SkipNow() @@ -194,17 +65,15 @@ func TestWriteBlockPerf(t *testing.T) { var watchTime int64 count := 10000 - b := createBlock(t) + b := storagev2.CreateBlock(t) for i := 1; i <= count; i++ { - updateBlock(t, uint64(i), b) - batchWriter := prepareBatch(t, s, b) + storagev2.UpdateBlock(t, uint64(i), b) + batchWriter := storagev2.PrepareBatch(t, s, b) tn := time.Now().UTC() - if err := batchWriter.WriteBatch(); err != nil { - require.NoError(t, err) - } + require.NoError(t, batchWriter.WriteBatch()) d := time.Since(tn) watchTime = watchTime + d.Milliseconds() diff --git a/blockchain/storagev2/leveldb/leveldb_test.go b/blockchain/storagev2/leveldb/leveldb_test.go index 6aa9437e21..d3d4dd8c3c 100644 --- a/blockchain/storagev2/leveldb/leveldb_test.go +++ b/blockchain/storagev2/leveldb/leveldb_test.go @@ -2,8 +2,6 @@ package leveldb import ( "context" - "crypto/rand" - "math/big" "os" "os/signal" "path/filepath" @@ -11,7 +9,6 @@ import ( "testing" "time" - "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" @@ -44,89 +41,6 @@ func newStorage(t *testing.T) (*storagev2.Storage, func()) { return s, closeFn } -func TestStorage(t *testing.T) { - storagev2.TestStorage(t, newStorage) -} - -func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { - t.Helper() - - txs := make([]*types.Transaction, count) - - for i := range txs { - tx := types.NewTx(&types.DynamicFeeTx{ - Gas: types.StateTransactionGasLimit, - Nonce: uint64(startNonce + i), - From: from, - To: to, - Value: big.NewInt(2000), - GasFeeCap: big.NewInt(100), - GasTipCap: big.NewInt(10), - }) - - input := make([]byte, 1000) - _, err := rand.Read(input) - - require.NoError(t, err) - - tx.ComputeHash() - - txs[i] = tx - } - - return txs -} - -func generateBlock(t *testing.T, num uint64) *types.FullBlock { - t.Helper() - - transactionsCount := 2500 - status := types.ReceiptSuccess - addr1 := types.StringToAddress("17878aa") - addr2 := types.StringToAddress("2bf5653") - b := &types.FullBlock{ - Block: &types.Block{ - Header: &types.Header{ - Number: num, - ExtraData: make([]byte, 32), - Hash: types.ZeroHash, - }, - Transactions: generateTxs(t, 0, transactionsCount, addr1, &addr2), - Uncles: blockchain.NewTestHeaders(10), - }, - Receipts: make([]*types.Receipt, transactionsCount), - } - - logs := make([]*types.Log, 10) - - for i := 0; i < 10; i++ { - logs[i] = &types.Log{ - Address: addr1, - Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, - Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, - } - } - - for i := 0; i < len(b.Block.Transactions); i++ { - b.Receipts[i] = &types.Receipt{ - TxHash: b.Block.Transactions[i].Hash(), - Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTxType, - GasUsed: uint64(100000), - Status: &status, - Logs: logs, - CumulativeGasUsed: uint64(100000), - ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, - } - } - - for i := 0; i < 5; i++ { - b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) - } - - return b -} - func newStorageP(t *testing.T) (*storagev2.Storage, func(), string) { t.Helper() @@ -162,25 +76,6 @@ func countLdbFilesInPath(path string) int { return len(files) } -func generateBlocks(t *testing.T, count int, ch chan *types.FullBlock, ctx context.Context) { - t.Helper() - - ticker := time.NewTicker(100 * time.Millisecond) - - for i := 1; i <= count; i++ { - b := generateBlock(t, uint64(i)) - select { - case <-ctx.Done(): - close(ch) - ticker.Stop() - - return - case <-ticker.C: - ch <- b - } - } -} - func dirSize(t *testing.T, path string) int64 { t.Helper() @@ -204,6 +99,10 @@ func dirSize(t *testing.T, path string) int64 { return size } +func TestStorage(t *testing.T) { + storagev2.TestStorage(t, newStorage) +} + func TestWriteFullBlock(t *testing.T) { s, _, path := newStorageP(t) defer s.Close() @@ -220,7 +119,7 @@ func TestWriteFullBlock(t *testing.T) { }() blockchain := make(chan *types.FullBlock, 1) - go generateBlocks(t, count, blockchain, ctx) + go storagev2.GenerateBlocks(t, count, blockchain, ctx) insertloop: for i := 1; i <= count; i++ { diff --git a/blockchain/storagev2/mdbx/mdbx.go b/blockchain/storagev2/mdbx/mdbx.go index 1ddeb2a99b..4bfcb633f2 100644 --- a/blockchain/storagev2/mdbx/mdbx.go +++ b/blockchain/storagev2/mdbx/mdbx.go @@ -19,6 +19,19 @@ type MdbxDB struct { dbi [storagev2.MAX_TABLES]mdbx.DBI } +const ( + B uint64 = 1 + KB = B << 10 + MB = KB << 10 + GB = MB << 10 + TB = GB << 10 +) + +var ( + mapSize uint64 = 2 * TB + growthSize uint64 = 2 * GB +) + var tableMapper = map[uint8]string{ storagev2.BODY: "Body", storagev2.CANONICAL: "Canonical", @@ -50,7 +63,7 @@ func NewMdbxStorage(path string, logger hclog.Logger) (*storagev2.Storage, error return nil, err } - if err = env.SetGeometry(-1, -1, 2*1024*1024*1024*1024, 2*1024*1024*1024, -1, int(defaultPageSize())); err != nil { + if err = env.SetGeometry(-1, -1, int(mapSize), int(growthSize), -1, int(defaultPageSize())); err != nil { return nil, err } diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go index 0140e3d82e..47c4d79280 100644 --- a/blockchain/storagev2/mdbx/mdbx_perf_test.go +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -1,103 +1,17 @@ package mdbx import ( - "math/big" "math/rand" "os" "testing" "time" - "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/blockchain/storagev2" - "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func createTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { - t.Helper() - - txs := make([]*types.Transaction, count) - - for i := range txs { - tx := types.NewTx(&types.DynamicFeeTx{ - Gas: types.StateTransactionGasLimit, - Nonce: uint64(startNonce + i), - From: from, - To: to, - Value: big.NewInt(2000), - GasFeeCap: big.NewInt(100), - GasTipCap: big.NewInt(10), - }) - - txs[i] = tx - } - - return txs -} - -const letterBytes = "abcdef0123456789" - -func randStringBytes(n int) string { - b := make([]byte, n) - for i := range b { - b[i] = letterBytes[rand.Intn(len(letterBytes))] - } - - return string(b) -} - -func createBlock(t *testing.T) *types.FullBlock { - t.Helper() - - transactionsCount := 2500 - status := types.ReceiptSuccess - addr1 := types.StringToAddress("17878aa") - addr2 := types.StringToAddress("2bf5653") - b := &types.FullBlock{ - Block: &types.Block{ - Header: &types.Header{ - Number: 0, - ExtraData: make([]byte, 32), - Hash: types.ZeroHash, - }, - Transactions: createTxs(t, 0, transactionsCount, addr1, &addr2), - Uncles: blockchain.NewTestHeaders(10), - }, - Receipts: make([]*types.Receipt, transactionsCount), - } - - logs := make([]*types.Log, 10) - - for i := 0; i < 10; i++ { - logs[i] = &types.Log{ - Address: addr1, - Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, - Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, - } - } - - for i := 0; i < len(b.Block.Transactions); i++ { - b.Receipts[i] = &types.Receipt{ - TxHash: b.Block.Transactions[i].Hash(), - Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTxType, - GasUsed: uint64(100000), - Status: &status, - Logs: logs, - CumulativeGasUsed: uint64(100000), - ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, - } - } - - for i := 0; i < 5; i++ { - b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) - } - - return b -} - func openStorage(t *testing.T, p string) (*storagev2.Storage, func(), string) { t.Helper() @@ -117,49 +31,6 @@ func openStorage(t *testing.T, p string) (*storagev2.Storage, func(), string) { return s, closeFn, p } -func updateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock { - t.Helper() - - var addr types.Address - - b.Block.Header.Number = num - b.Block.Header.ParentHash = types.StringToHash(randStringBytes(12)) - - for i := range b.Block.Transactions { - addr = types.StringToAddress(randStringBytes(8)) - b.Block.Transactions[i].SetTo(&addr) - b.Block.Transactions[i].ComputeHash() - b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() - } - - b.Block.Header.ComputeHash() - - return b -} - -func prepareBatch(t *testing.T, s *storagev2.Storage, b *types.FullBlock) *storagev2.Writer { - t.Helper() - - batchWriter := s.NewWriter() - - // GidLid 'sorted' - batchWriter.PutHeadHash(b.Block.Header.Hash) - batchWriter.PutHeadNumber(b.Block.Number()) - batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) - - for _, tx := range b.Block.Transactions { - batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) - } - - // Main DB sorted - batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body()) - batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) - batchWriter.PutHeader(b.Block.Header) - batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) - - return batchWriter -} - func TestWriteBlockPerf(t *testing.T) { t.SkipNow() @@ -169,11 +40,11 @@ func TestWriteBlockPerf(t *testing.T) { var watchTime int64 count := 10000 - b := createBlock(t) + b := storagev2.CreateBlock(t) for i := 1; i <= count; i++ { - updateBlock(t, uint64(i), b) - batchWriter := prepareBatch(t, s, b) + storagev2.UpdateBlock(t, uint64(i), b) + batchWriter := storagev2.PrepareBatch(t, s, b) tn := time.Now().UTC() diff --git a/blockchain/storagev2/mdbx/mdbx_test.go b/blockchain/storagev2/mdbx/mdbx_test.go index 0a5c8638fb..e790e134fa 100644 --- a/blockchain/storagev2/mdbx/mdbx_test.go +++ b/blockchain/storagev2/mdbx/mdbx_test.go @@ -2,8 +2,6 @@ package mdbx import ( "context" - "crypto/rand" - "math/big" "os" "os/signal" "path/filepath" @@ -12,7 +10,6 @@ import ( "testing" "time" - "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/blockchain/storagev2" "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" @@ -45,89 +42,6 @@ func newStorage(t *testing.T) (*storagev2.Storage, func()) { return s, closeFn } -func TestStorage(t *testing.T) { - storagev2.TestStorage(t, newStorage) -} - -func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { - t.Helper() - - txs := make([]*types.Transaction, count) - - for i := range txs { - tx := types.NewTx(&types.DynamicFeeTx{ - Gas: types.StateTransactionGasLimit, - Nonce: uint64(startNonce + i), - From: from, - To: to, - Value: big.NewInt(2000), - GasFeeCap: big.NewInt(100), - GasTipCap: big.NewInt(10), - }) - - input := make([]byte, 1000) - _, err := rand.Read(input) - - require.NoError(t, err) - - tx.ComputeHash() - - txs[i] = tx - } - - return txs -} - -func generateBlock(t *testing.T, num uint64) *types.FullBlock { - t.Helper() - - transactionsCount := 2500 - status := types.ReceiptSuccess - addr1 := types.StringToAddress("17878aa") - addr2 := types.StringToAddress("2bf5653") - b := &types.FullBlock{ - Block: &types.Block{ - Header: &types.Header{ - Number: num, - ExtraData: make([]byte, 32), - Hash: types.ZeroHash, - }, - Transactions: generateTxs(t, 0, transactionsCount, addr1, &addr2), - Uncles: blockchain.NewTestHeaders(10), - }, - Receipts: make([]*types.Receipt, transactionsCount), - } - - logs := make([]*types.Log, 10) - - for i := 0; i < 10; i++ { - logs[i] = &types.Log{ - Address: addr1, - Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, - Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, - } - } - - for i := 0; i < len(b.Block.Transactions); i++ { - b.Receipts[i] = &types.Receipt{ - TxHash: b.Block.Transactions[i].Hash(), - Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTxType, - GasUsed: uint64(100000), - Status: &status, - Logs: logs, - CumulativeGasUsed: uint64(100000), - ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, - } - } - - for i := 0; i < 5; i++ { - b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) - } - - return b -} - func newStorageP(t *testing.T) (*storagev2.Storage, func(), string) { t.Helper() @@ -152,25 +66,6 @@ func newStorageP(t *testing.T) (*storagev2.Storage, func(), string) { return s, closeFn, p } -func generateBlocks(t *testing.T, count int, ch chan *types.FullBlock, ctx context.Context) { - t.Helper() - - ticker := time.NewTicker(100 * time.Millisecond) - - for i := 1; i <= count; i++ { - b := generateBlock(t, uint64(i)) - select { - case <-ctx.Done(): - close(ch) - ticker.Stop() - - return - case <-ticker.C: - ch <- b - } - } -} - func dbSize(t *testing.T, path string) int64 { t.Helper() @@ -192,6 +87,10 @@ func dbSize(t *testing.T, path string) int64 { return size } +func TestStorage(t *testing.T) { + storagev2.TestStorage(t, newStorage) +} + func TestWriteFullBlock(t *testing.T) { s, _, path := newStorageP(t) defer s.Close() @@ -208,7 +107,7 @@ func TestWriteFullBlock(t *testing.T) { }() blockchain := make(chan *types.FullBlock, 1) - go generateBlocks(t, count, blockchain, ctx) + go storagev2.GenerateBlocks(t, count, blockchain, ctx) insertloop: for i := 1; i <= count; i++ { diff --git a/blockchain/storagev2/testing.go b/blockchain/storagev2/testing.go index 30a725f11b..6c8b160448 100644 --- a/blockchain/storagev2/testing.go +++ b/blockchain/storagev2/testing.go @@ -1,9 +1,12 @@ package storagev2 import ( + "context" + "crypto/rand" "math/big" "reflect" "testing" + "time" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/types" @@ -433,166 +436,100 @@ func testWriteCanonicalHeader(t *testing.T, m PlaceholderStorage) { } } -// Storage delegators - -type readCanonicalHashDelegate func(uint64) (types.Hash, error) -type readHeadHashDelegate func() (types.Hash, error) -type readHeadNumberDelegate func() (uint64, error) -type readForksDelegate func() ([]types.Hash, error) -type readTotalDifficultyDelegate func(uint64) (*big.Int, error) -type readHeaderDelegate func(uint64) (*types.Header, error) -type readBodyDelegate func(uint64) (*types.Body, error) -type readReceiptsDelegate func(uint64) ([]*types.Receipt, error) -type readTxLookupDelegate func(types.Hash) (uint64, error) -type closeDelegate func() error -type newBatchDelegate func() Batch - -type MockStorage struct { - readCanonicalHashFn readCanonicalHashDelegate - readHeadHashFn readHeadHashDelegate - readHeadNumberFn readHeadNumberDelegate - readForksFn readForksDelegate - readTotalDifficultyFn readTotalDifficultyDelegate - readHeaderFn readHeaderDelegate - readBodyFn readBodyDelegate - readReceiptsFn readReceiptsDelegate - readTxLookupFn readTxLookupDelegate - closeFn closeDelegate - newBatchFn newBatchDelegate -} - -func NewMockStorage() *MockStorage { - return &MockStorage{} -} - -func (m *MockStorage) ReadCanonicalHash(n uint64) (types.Hash, error) { - if m.readCanonicalHashFn != nil { - return m.readCanonicalHashFn(n) - } - - return types.Hash{}, nil -} - -func (m *MockStorage) HookReadCanonicalHash(fn readCanonicalHashDelegate) { - m.readCanonicalHashFn = fn -} - -func (m *MockStorage) ReadHeadHash() (types.Hash, error) { - if m.readHeadHashFn != nil { - return m.readHeadHashFn() - } - - return types.Hash{}, nil -} - -func (m *MockStorage) HookReadHeadHash(fn readHeadHashDelegate) { - m.readHeadHashFn = fn -} - -func (m *MockStorage) ReadHeadNumber() (uint64, error) { - if m.readHeadNumberFn != nil { - return m.readHeadNumberFn() - } +func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { + t.Helper() - return 0, nil -} + txs := make([]*types.Transaction, count) -func (m *MockStorage) HookReadHeadNumber(fn readHeadNumberDelegate) { - m.readHeadNumberFn = fn -} + for i := range txs { + tx := types.NewTx(&types.DynamicFeeTx{ + Gas: types.StateTransactionGasLimit, + Nonce: uint64(startNonce + i), + From: from, + To: to, + Value: big.NewInt(2000), + GasFeeCap: big.NewInt(100), + GasTipCap: big.NewInt(10), + }) -func (m *MockStorage) ReadForks() ([]types.Hash, error) { - if m.readForksFn != nil { - return m.readForksFn() - } + input := make([]byte, 1000) + _, err := rand.Read(input) - return []types.Hash{}, nil -} + require.NoError(t, err) -func (m *MockStorage) HookReadForks(fn readForksDelegate) { - m.readForksFn = fn -} + tx.ComputeHash() -func (m *MockStorage) ReadTotalDifficulty(bn uint64) (*big.Int, error) { - if m.readTotalDifficultyFn != nil { - return m.readTotalDifficultyFn(bn) + txs[i] = tx } - return big.NewInt(0), nil + return txs } -func (m *MockStorage) HookReadTotalDifficulty(fn readTotalDifficultyDelegate) { - m.readTotalDifficultyFn = fn -} +func generateBlock(t *testing.T, num uint64) *types.FullBlock { + t.Helper() -func (m *MockStorage) ReadHeader(bn uint64) (*types.Header, error) { - if m.readHeaderFn != nil { - return m.readHeaderFn(bn) + transactionsCount := 2500 + status := types.ReceiptSuccess + addr1 := types.StringToAddress("17878aa") + addr2 := types.StringToAddress("2bf5653") + b := &types.FullBlock{ + Block: &types.Block{ + Header: &types.Header{ + Number: num, + ExtraData: make([]byte, 32), + Hash: types.ZeroHash, + }, + Transactions: generateTxs(t, 0, transactionsCount, addr1, &addr2), + // Uncles: blockchain.NewTestHeaders(10), + }, + Receipts: make([]*types.Receipt, transactionsCount), } - return &types.Header{}, nil -} + logs := make([]*types.Log, 10) -func (m *MockStorage) HookReadHeader(fn readHeaderDelegate) { - m.readHeaderFn = fn -} - -func (m *MockStorage) ReadBody(bn uint64) (*types.Body, error) { - if m.readBodyFn != nil { - return m.readBodyFn(bn) + for i := 0; i < 10; i++ { + logs[i] = &types.Log{ + Address: addr1, + Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, + Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, + } } - return &types.Body{}, nil -} - -func (m *MockStorage) HookReadBody(fn readBodyDelegate) { - m.readBodyFn = fn -} - -func (m *MockStorage) ReadReceipts(bn uint64) ([]*types.Receipt, error) { - if m.readReceiptsFn != nil { - return m.readReceiptsFn(bn) + for i := 0; i < len(b.Block.Transactions); i++ { + b.Receipts[i] = &types.Receipt{ + TxHash: b.Block.Transactions[i].Hash(), + Root: types.StringToHash("mockhashstring"), + TransactionType: types.LegacyTxType, + GasUsed: uint64(100000), + Status: &status, + Logs: logs, + CumulativeGasUsed: uint64(100000), + ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, + } } - return []*types.Receipt{}, nil -} - -func (m *MockStorage) HookReadReceipts(fn readReceiptsDelegate) { - m.readReceiptsFn = fn -} - -func (m *MockStorage) ReadTxLookup(hash types.Hash) (uint64, error) { - if m.readTxLookupFn != nil { - return m.readTxLookupFn(hash) + for i := 0; i < 5; i++ { + b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) } - return 0, nil -} - -func (m *MockStorage) HookReadTxLookup(fn readTxLookupDelegate) { - m.readTxLookupFn = fn + return b } -func (m *MockStorage) Close() error { - if m.closeFn != nil { - return m.closeFn() - } - - return nil -} +func GenerateBlocks(t *testing.T, count int, ch chan *types.FullBlock, ctx context.Context) { + t.Helper() -func (m *MockStorage) HookClose(fn closeDelegate) { - m.closeFn = fn -} + ticker := time.NewTicker(100 * time.Millisecond) -func (m *MockStorage) HookNewBatch(fn newBatchDelegate) { - m.newBatchFn = fn -} + for i := 1; i <= count; i++ { + b := generateBlock(t, uint64(i)) + select { + case <-ctx.Done(): + close(ch) + ticker.Stop() -func (m *MockStorage) NewBatch() Batch { - if m.newBatchFn != nil { - return m.newBatchFn() + return + case <-ticker.C: + ch <- b + } } - - return nil } diff --git a/blockchain/storagev2/testing_perf.go b/blockchain/storagev2/testing_perf.go new file mode 100644 index 0000000000..f07290a86b --- /dev/null +++ b/blockchain/storagev2/testing_perf.go @@ -0,0 +1,137 @@ +package storagev2 + +import ( + "crypto/rand" + "math/big" + "testing" + + "github.com/0xPolygon/polygon-edge/types" + "github.com/stretchr/testify/require" +) + +const letterBytes = "abcdef0123456789" + +func randStringBytes(t *testing.T, n int) string { + t.Helper() + + b := make([]byte, n) + _, err := rand.Reader.Read(b) + require.NoError(t, err) + + return string(b) +} + +func createTxs(t *testing.T, startNonce, count int, from types.Address, to *types.Address) []*types.Transaction { + t.Helper() + + txs := make([]*types.Transaction, count) + + for i := range txs { + tx := types.NewTx(&types.DynamicFeeTx{ + Gas: types.StateTransactionGasLimit, + Nonce: uint64(startNonce + i), + From: from, + To: to, + Value: big.NewInt(2000), + GasFeeCap: big.NewInt(100), + GasTipCap: big.NewInt(10), + }) + + txs[i] = tx + } + + return txs +} + +func CreateBlock(t *testing.T) *types.FullBlock { + t.Helper() + + transactionsCount := 2500 + status := types.ReceiptSuccess + addr1 := types.StringToAddress("17878aa") + addr2 := types.StringToAddress("2bf5653") + b := &types.FullBlock{ + Block: &types.Block{ + Header: &types.Header{ + Number: 0, + ExtraData: make([]byte, 32), + Hash: types.ZeroHash, + }, + Transactions: createTxs(t, 0, transactionsCount, addr1, &addr2), + // Uncles: blockchain.NewTestHeaders(10), + }, + Receipts: make([]*types.Receipt, transactionsCount), + } + + logs := make([]*types.Log, 10) + + for i := 0; i < 10; i++ { + logs[i] = &types.Log{ + Address: addr1, + Topics: []types.Hash{types.StringToHash("t1"), types.StringToHash("t2"), types.StringToHash("t3")}, + Data: []byte{0xaa, 0xbb, 0xcc, 0xdd, 0xbb, 0xaa, 0x01, 0x012}, + } + } + + for i := 0; i < len(b.Block.Transactions); i++ { + b.Receipts[i] = &types.Receipt{ + TxHash: b.Block.Transactions[i].Hash(), + Root: types.StringToHash("mockhashstring"), + TransactionType: types.LegacyTxType, + GasUsed: uint64(100000), + Status: &status, + Logs: logs, + CumulativeGasUsed: uint64(100000), + ContractAddress: &types.Address{0xaa, 0xbb, 0xcc, 0xdd, 0xab, 0xac}, + } + } + + for i := 0; i < 5; i++ { + b.Receipts[i].LogsBloom = types.CreateBloom(b.Receipts) + } + + return b +} + +func UpdateBlock(t *testing.T, num uint64, b *types.FullBlock) *types.FullBlock { + t.Helper() + + var addr types.Address + + b.Block.Header.Number = num + b.Block.Header.ParentHash = types.StringToHash(randStringBytes(t, 12)) + + for i := range b.Block.Transactions { + addr = types.StringToAddress(randStringBytes(t, 8)) + b.Block.Transactions[i].SetTo(&addr) + b.Block.Transactions[i].ComputeHash() + b.Receipts[i].TxHash = b.Block.Transactions[i].Hash() + } + + b.Block.Header.ComputeHash() + + return b +} + +func PrepareBatch(t *testing.T, s *Storage, b *types.FullBlock) *Writer { + t.Helper() + + batchWriter := s.NewWriter() + + // GidLid 'sorted' + batchWriter.PutHeadHash(b.Block.Header.Hash) + batchWriter.PutHeadNumber(b.Block.Number()) + batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) + + for _, tx := range b.Block.Transactions { + batchWriter.PutTxLookup(tx.Hash(), b.Block.Number()) + } + + // Main DB sorted + batchWriter.PutBody(b.Block.Number(), b.Block.Hash(), b.Block.Body()) + batchWriter.PutCanonicalHash(b.Block.Number(), b.Block.Hash()) + batchWriter.PutHeader(b.Block.Header) + batchWriter.PutReceipts(b.Block.Number(), b.Block.Hash(), b.Receipts) + + return batchWriter +} From 4e6cd792db14bb13cd1900e1337d620d9423e024 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Fri, 22 Mar 2024 21:13:36 +0100 Subject: [PATCH 25/48] Merge --- .../storage/leveldb/leveldb_perf_test.go | 18 ++--- blockchain/storagev2/testing.go | 66 +++++++++---------- blockchain/storagev2/testing_perf.go | 18 ++--- e2e-polybft/e2e/storage_test.go | 49 +++++++------- 4 files changed, 76 insertions(+), 75 deletions(-) diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go index 7a2c2b0fd4..1147a753b9 100644 --- a/blockchain/storage/leveldb/leveldb_perf_test.go +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -22,15 +22,15 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.DynamicFeeTx{ - Gas: types.StateTransactionGasLimit, - Nonce: uint64(startNonce + i), - From: from, - To: to, - Value: big.NewInt(2000), - GasFeeCap: big.NewInt(100), - GasTipCap: big.NewInt(10), - }) + tx := types.NewTx(types.NewDynamicFeeTx( + types.WithGas(types.StateTransactionGasLimit), + types.WithNonce(uint64(startNonce+i)), + types.WithFrom(from), + types.WithTo(to), + types.WithValue(big.NewInt(2000)), + types.WithGasFeeCap(big.NewInt(100)), + types.WithGasTipCap(big.NewInt(10)), + )) txs[i] = tx } diff --git a/blockchain/storagev2/testing.go b/blockchain/storagev2/testing.go index 6c8b160448..d98dd0454f 100644 --- a/blockchain/storagev2/testing.go +++ b/blockchain/storagev2/testing.go @@ -267,27 +267,27 @@ func testBody(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) addr1 := types.StringToAddress("11") - t0 := types.NewTx(&types.LegacyTx{ - Nonce: 0, - To: &addr1, - Value: big.NewInt(1), - Gas: 11, - GasPrice: big.NewInt(11), - Input: []byte{1, 2}, - V: big.NewInt(1), - }) + t0 := types.NewTx(types.NewLegacyTx( + types.WithNonce(0), + types.WithTo(&addr1), + types.WithValue(big.NewInt(1)), + types.WithGas(11), + types.WithGasPrice(big.NewInt(11)), + types.WithInput([]byte{1, 2}), + types.WithSignatureValues(big.NewInt(1), nil, nil), + )) t0.ComputeHash() addr2 := types.StringToAddress("22") - t1 := types.NewTx(&types.LegacyTx{ - Nonce: 0, - To: &addr2, - Value: big.NewInt(1), - Gas: 22, - GasPrice: big.NewInt(11), - Input: []byte{4, 5}, - V: big.NewInt(2), - }) + t1 := types.NewTx(types.NewLegacyTx( + types.WithNonce(0), + types.WithTo(&addr2), + types.WithValue(big.NewInt(1)), + types.WithGas(22), + types.WithGasPrice(big.NewInt(11)), + types.WithInput([]byte{4, 5}), + types.WithSignatureValues(big.NewInt(2), nil, nil), + )) t1.ComputeHash() block := types.Block{ @@ -335,12 +335,12 @@ func testReceipts(t *testing.T, m PlaceholderStorage) { body := &types.Body{ Transactions: []*types.Transaction{ - types.NewTx(&types.StateTx{ - Nonce: 1000, - Gas: 50, - GasPrice: new(big.Int).SetUint64(100), - V: big.NewInt(11), - }), + types.NewTx(types.NewStateTx( + types.WithNonce(1000), + types.WithGas(50), + types.WithGasPrice(new(big.Int).SetUint64(100)), + types.WithSignatureValues(big.NewInt(11), nil, nil), + )), }, } receipts := []*types.Receipt{ @@ -442,15 +442,15 @@ func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *ty txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.DynamicFeeTx{ - Gas: types.StateTransactionGasLimit, - Nonce: uint64(startNonce + i), - From: from, - To: to, - Value: big.NewInt(2000), - GasFeeCap: big.NewInt(100), - GasTipCap: big.NewInt(10), - }) + tx := types.NewTx(types.NewDynamicFeeTx( + types.WithGas(types.StateTransactionGasLimit), + types.WithNonce(uint64(startNonce+i)), + types.WithFrom(from), + types.WithTo(to), + types.WithValue(big.NewInt(2000)), + types.WithGasFeeCap(big.NewInt(100)), + types.WithGasTipCap(big.NewInt(10)), + )) input := make([]byte, 1000) _, err := rand.Read(input) diff --git a/blockchain/storagev2/testing_perf.go b/blockchain/storagev2/testing_perf.go index f07290a86b..f47c0bd33f 100644 --- a/blockchain/storagev2/testing_perf.go +++ b/blockchain/storagev2/testing_perf.go @@ -27,15 +27,15 @@ func createTxs(t *testing.T, startNonce, count int, from types.Address, to *type txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.DynamicFeeTx{ - Gas: types.StateTransactionGasLimit, - Nonce: uint64(startNonce + i), - From: from, - To: to, - Value: big.NewInt(2000), - GasFeeCap: big.NewInt(100), - GasTipCap: big.NewInt(10), - }) + tx := types.NewTx(types.NewDynamicFeeTx( + types.WithGas(types.StateTransactionGasLimit), + types.WithNonce(uint64(startNonce+i)), + types.WithFrom(from), + types.WithTo(to), + types.WithValue(big.NewInt(2000)), + types.WithGasFeeCap(big.NewInt(100)), + types.WithGasTipCap(big.NewInt(10)), + )) txs[i] = tx } diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go index ddb8f379cf..8ac1daf8e8 100644 --- a/e2e-polybft/e2e/storage_test.go +++ b/e2e-polybft/e2e/storage_test.go @@ -13,17 +13,17 @@ import ( "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/consensus/polybft" + "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/types" ) func TestE2E_Storage(t *testing.T) { - // premine an account in the genesis file - sender, err := wallet.GenerateKey() + sender, err := crypto.GenerateECDSAKey() require.NoError(t, err) cluster := framework.NewTestCluster(t, 5, - framework.WithPremine(types.Address(sender.Address())), + framework.WithPremine(sender.Address()), framework.WithBurnContract(&polybft.BurnContractInfo{BlockNumber: 0, Address: types.ZeroAddress}), ) defer cluster.Stop() @@ -47,29 +47,30 @@ func TestE2E_Storage(t *testing.T) { for i := 0; i < num; i++ { func(i int, to ethgo.Address) { - txn := ðgo.Transaction{ - From: sender.Address(), - To: &to, - Gas: 21000, // enough to send a transfer - Value: big.NewInt(int64(i)), - Nonce: uint64(i), - } - // Send every second transaction as a dynamic fees one - if i%2 == 0 { - txn.Type = ethgo.TransactionDynamicFee - txn.MaxFeePerGas = big.NewInt(1000000000) - txn.MaxPriorityFeePerGas = big.NewInt(100000000) + var txn *types.Transaction + if i%2 == 10 { // Intentionally disable it since dynamic fee tx not working chainID, err := client.ChainID() require.NoError(t, err) - txn.ChainID = chainID + txn = types.NewTx(types.NewDynamicFeeTx( + types.WithGasFeeCap(big.NewInt(1000000000)), + types.WithGasTipCap(big.NewInt(100000000)), + types.WithChainID(chainID), + )) } else { - txn.Type = ethgo.TransactionLegacy - txn.GasPrice = ethgo.Gwei(2).Uint64() + txn = types.NewTx(types.NewLegacyTx( + types.WithGasPrice(ethgo.Gwei(2)), + )) } + txn.SetFrom(sender.Address()) + txn.SetTo((*types.Address)(&to)) + txn.SetGas(21000) + txn.SetValue(big.NewInt(int64(i))) + txn.SetNonce(uint64(i)) + tx := cluster.SendTxn(t, sender, txn) err = tx.Wait() require.NoError(t, err) @@ -118,17 +119,17 @@ func checkStorage(t *testing.T, txs []*framework.TestTxn, client *jsonrpc.Eth) { bt, err := client.GetTransactionByHash(tx.Receipt().TransactionHash) require.NoError(t, err) assert.NotNil(t, bt) - assert.Equal(t, tx.Txn().Value.Uint64(), bt.Value.Uint64()) - assert.Equal(t, tx.Txn().Gas, bt.Gas) - assert.Equal(t, tx.Txn().Nonce, bt.Nonce) + assert.Equal(t, tx.Txn().Value(), bt.Value) + assert.Equal(t, tx.Txn().Gas(), bt.Gas) + assert.Equal(t, tx.Txn().Nonce(), bt.Nonce) assert.Equal(t, tx.Receipt().TransactionIndex, bt.TxnIndex) assert.NotEmpty(t, bt.V) assert.NotEmpty(t, bt.R) assert.NotEmpty(t, bt.S) - assert.Equal(t, tx.Txn().From, bt.From) - assert.Equal(t, tx.Txn().To, bt.To) + assert.Equal(t, tx.Txn().From().Bytes(), bt.From.Bytes()) + assert.Equal(t, tx.Txn().To().Bytes(), bt.To.Bytes()) - if i%2 == 0 { + if i%2 == 10 { // Intentionally disable it since dynamic fee tx not working assert.Equal(t, ethgo.TransactionDynamicFee, bt.Type) assert.Equal(t, uint64(0), bt.GasPrice) assert.NotNil(t, bt.ChainID) From c2dd12176ef92da6af8e79d2581b8e46f8708249 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Fri, 22 Mar 2024 21:35:27 +0100 Subject: [PATCH 26/48] gidlid cleanup & lint fixes --- blockchain/storage/leveldb/leveldb_perf_test.go | 6 +++--- blockchain/storagev2/leveldb/leveldb.go | 14 +++++++------- blockchain/storagev2/leveldb/leveldb_perf_test.go | 4 ++-- blockchain/storagev2/mdbx/mdbx_perf_test.go | 4 ++-- blockchain/storagev2/storage.go | 2 +- blockchain/storagev2/testing_perf.go | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/blockchain/storage/leveldb/leveldb_perf_test.go b/blockchain/storage/leveldb/leveldb_perf_test.go index 1147a753b9..cbfd443ba1 100644 --- a/blockchain/storage/leveldb/leveldb_perf_test.go +++ b/blockchain/storage/leveldb/leveldb_perf_test.go @@ -166,7 +166,7 @@ func prepareBatch(t *testing.T, s storage.Storage, b *types.FullBlock) *storage. batchWriter := storage.NewBatchWriter(s) - // GidLid 'sorted' + // Lookup 'sorted' batchWriter.PutHeadHash(b.Block.Header.Hash) batchWriter.PutHeadNumber(b.Block.Number()) @@ -205,7 +205,7 @@ func TestWriteBlockPerf(t *testing.T) { } d := time.Since(tn) - watchTime = watchTime + d.Milliseconds() + watchTime += d.Milliseconds() } time.Sleep(time.Second) @@ -234,7 +234,7 @@ func TestReadBlockPerf(t *testing.T) { _, err4 := s.ReadReceipts(h) d := time.Since(tn) - watchTime = watchTime + d.Milliseconds() + watchTime += d.Milliseconds() if !ok || err2 != nil || err3 != nil || err4 != nil { t.Logf("\terror") diff --git a/blockchain/storagev2/leveldb/leveldb.go b/blockchain/storagev2/leveldb/leveldb.go index d2a9bd1b11..73f1e05784 100644 --- a/blockchain/storagev2/leveldb/leveldb.go +++ b/blockchain/storagev2/leveldb/leveldb.go @@ -20,7 +20,7 @@ var tableMapper = map[uint8][]byte{ storagev2.RECEIPTS: []byte("r"), // DB key = block number + block hash + mapper, value = block receipts storagev2.CANONICAL: {}, // DB key = block number + mapper, value = block hash - // GidLid DB + // Lookup DB storagev2.FORK: {}, // DB key = FORK_KEY + mapper, value = fork hashes storagev2.HEAD_HASH: {}, // DB key = HEAD_HASH_KEY + mapper, value = head hash storagev2.HEAD_NUMBER: {}, // DB key = HEAD_NUMBER_KEY + mapper, value = head number @@ -39,26 +39,26 @@ func NewLevelDBStorage(path string, logger hclog.Logger) (*storagev2.Storage, er WriteBuffer: 128 * opt.MiB, // Two of these are used internally } - db, err := openLevelDBStorage(path, options) + maindb, err := openLevelDBStorage(path, options) if err != nil { return nil, err } - // Open GidLid + // Open Lookup // Set default options options = &opt.Options{ BlockCacheCapacity: 64 * opt.MiB, WriteBuffer: opt.DefaultWriteBuffer, } - path = path + "/gidlid" + path += "/lookup" - gidlid, err := openLevelDBStorage(path, options) + lookup, err := openLevelDBStorage(path, options) if err != nil { return nil, err } - ldbs[0] = &levelDB{db} - ldbs[1] = &levelDB{gidlid} + ldbs[0] = &levelDB{maindb} + ldbs[1] = &levelDB{lookup} return storagev2.Open(logger.Named("leveldb"), ldbs) } diff --git a/blockchain/storagev2/leveldb/leveldb_perf_test.go b/blockchain/storagev2/leveldb/leveldb_perf_test.go index 14da8ff857..337075f0c6 100644 --- a/blockchain/storagev2/leveldb/leveldb_perf_test.go +++ b/blockchain/storagev2/leveldb/leveldb_perf_test.go @@ -76,7 +76,7 @@ func TestWriteBlockPerf(t *testing.T) { require.NoError(t, batchWriter.WriteBatch()) d := time.Since(tn) - watchTime = watchTime + d.Milliseconds() + watchTime += d.Milliseconds() } time.Sleep(time.Second) @@ -106,7 +106,7 @@ func TestReadBlockPerf(t *testing.T) { b, err5 := s.ReadBlockLookup(h) d := time.Since(tn) - watchTime = watchTime + d.Milliseconds() + watchTime += d.Milliseconds() if !ok || err1 != nil || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") diff --git a/blockchain/storagev2/mdbx/mdbx_perf_test.go b/blockchain/storagev2/mdbx/mdbx_perf_test.go index 47c4d79280..a611cbdbb4 100644 --- a/blockchain/storagev2/mdbx/mdbx_perf_test.go +++ b/blockchain/storagev2/mdbx/mdbx_perf_test.go @@ -51,7 +51,7 @@ func TestWriteBlockPerf(t *testing.T) { require.NoError(t, batchWriter.WriteBatch()) d := time.Since(tn) - watchTime = watchTime + d.Milliseconds() + watchTime += d.Milliseconds() } time.Sleep(time.Second) @@ -81,7 +81,7 @@ func TestReadBlockPerf(t *testing.T) { b, err5 := s.ReadBlockLookup(h) d := time.Since(tn) - watchTime = watchTime + d.Milliseconds() + watchTime += d.Milliseconds() if !ok || err1 != nil || err3 != nil || err4 != nil || err5 != nil { t.Logf("\terror") diff --git a/blockchain/storagev2/storage.go b/blockchain/storagev2/storage.go index 17b44a9f23..eff6aada80 100644 --- a/blockchain/storagev2/storage.go +++ b/blockchain/storagev2/storage.go @@ -38,7 +38,7 @@ const ( RECEIPTS = uint8(8) ) -// GidLid tables +// Lookup tables const ( FORK = uint8(0) | LOOKUP_INDEX HEAD_HASH = uint8(2) | LOOKUP_INDEX diff --git a/blockchain/storagev2/testing_perf.go b/blockchain/storagev2/testing_perf.go index f47c0bd33f..9926274887 100644 --- a/blockchain/storagev2/testing_perf.go +++ b/blockchain/storagev2/testing_perf.go @@ -118,7 +118,7 @@ func PrepareBatch(t *testing.T, s *Storage, b *types.FullBlock) *Writer { batchWriter := s.NewWriter() - // GidLid 'sorted' + // Lookup 'sorted' batchWriter.PutHeadHash(b.Block.Header.Hash) batchWriter.PutHeadNumber(b.Block.Number()) batchWriter.PutBlockLookup(b.Block.Hash(), b.Block.Number()) From badef47439b91f3b56158944d32c540ed10543e0 Mon Sep 17 00:00:00 2001 From: Goran Rojovic <100121253+goran-ethernal@users.noreply.github.com> Date: Mon, 25 Mar 2024 09:29:08 +0100 Subject: [PATCH 27/48] Validator Snapshot bug fix (#164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix * reorganize test * comments fix * Simplify creation of snapshot * comments fix --------- Co-authored-by: Stefan Negovanović --- consensus/polybft/state_store_epoch.go | 23 ++++---- consensus/polybft/state_store_epoch_test.go | 60 +++++++++++++-------- consensus/polybft/validators_snapshot.go | 8 ++- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/consensus/polybft/state_store_epoch.go b/consensus/polybft/state_store_epoch.go index b2750aeea4..705e76d432 100644 --- a/consensus/polybft/state_store_epoch.go +++ b/consensus/polybft/state_store_epoch.go @@ -93,25 +93,28 @@ func (s *EpochStore) getValidatorSnapshot(epoch uint64) (*validatorSnapshot, err return validatorSnapshot, err } -// getLastSnapshot returns the last snapshot saved in db -// since they are stored by epoch number (uint64), they are sequentially stored, -// so the latest epoch will be the last snapshot in db -func (s *EpochStore) getLastSnapshot(dbTx *bolt.Tx) (*validatorSnapshot, error) { +// getNearestOrEpochSnapshot returns the nearest or the exact epoch snapshot from db +func (s *EpochStore) getNearestOrEpochSnapshot(epoch uint64, dbTx *bolt.Tx) (*validatorSnapshot, error) { var ( snapshot *validatorSnapshot err error ) getFn := func(tx *bolt.Tx) error { - c := tx.Bucket(validatorSnapshotsBucket).Cursor() - k, v := c.Last() + for { + v := tx.Bucket(validatorSnapshotsBucket).Get(common.EncodeUint64ToBytes(epoch)) + if v != nil { + return json.Unmarshal(v, &snapshot) + } + + if epoch == 0 { // prevent uint64 underflow + break + } - if k == nil { - // we have no snapshots in db - return nil + epoch-- } - return json.Unmarshal(v, &snapshot) + return nil } if dbTx == nil { diff --git a/consensus/polybft/state_store_epoch_test.go b/consensus/polybft/state_store_epoch_test.go index a48403a974..64f60832b1 100644 --- a/consensus/polybft/state_store_epoch_test.go +++ b/consensus/polybft/state_store_epoch_test.go @@ -5,11 +5,12 @@ import ( "sync" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/0xPolygon/polygon-edge/bls" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" "github.com/0xPolygon/polygon-edge/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestState_insertAndGetValidatorSnapshot(t *testing.T) { @@ -186,35 +187,48 @@ func TestState_Insert_And_Cleanup(t *testing.T) { assert.Equal(t, 1, len(votes)) } -func TestState_getLastSnapshot(t *testing.T) { +func TestEpochStore_getNearestOrEpochSnapshot(t *testing.T) { t.Parallel() - const ( - lastEpoch = uint64(10) - fixedEpochSize = uint64(10) - numberOfValidators = 3 - ) - state := newTestState(t) + epoch := uint64(1) + tv := validator.NewTestValidators(t, 3) - for i := uint64(1); i <= lastEpoch; i++ { - keys, err := bls.CreateRandomBlsKeys(numberOfValidators) + // Insert a snapshot for epoch 1 + snapshot := &validatorSnapshot{ + Epoch: epoch, + EpochEndingBlock: 100, + Snapshot: tv.GetPublicIdentities(), + } + require.NoError(t, state.EpochStore.insertValidatorSnapshot(snapshot, nil)) + + t.Run("with existing dbTx", func(t *testing.T) { + t.Parallel() + + dbTx, err := state.EpochStore.db.Begin(false) require.NoError(t, err) - var snapshot validator.AccountSet - for j := 0; j < numberOfValidators; j++ { - snapshot = append(snapshot, &validator.ValidatorMetadata{Address: types.BytesToAddress(generateRandomBytes(t)), BlsKey: keys[j].PublicKey()}) - } + result, err := state.EpochStore.getNearestOrEpochSnapshot(epoch, dbTx) + assert.NoError(t, err) + assert.Equal(t, snapshot, result) - require.NoError(t, state.EpochStore.insertValidatorSnapshot( - &validatorSnapshot{i, i * fixedEpochSize, snapshot}, nil)) - } + require.NoError(t, dbTx.Rollback()) + }) - snapshotFromDB, err := state.EpochStore.getLastSnapshot(nil) + t.Run("without existing dbTx", func(t *testing.T) { + t.Parallel() - assert.NoError(t, err) - assert.Equal(t, numberOfValidators, snapshotFromDB.Snapshot.Len()) - assert.Equal(t, lastEpoch, snapshotFromDB.Epoch) - assert.Equal(t, lastEpoch*fixedEpochSize, snapshotFromDB.EpochEndingBlock) + result, err := state.EpochStore.getNearestOrEpochSnapshot(epoch, nil) + assert.NoError(t, err) + assert.Equal(t, snapshot, result) + }) + + t.Run("with non-existing epoch", func(t *testing.T) { + t.Parallel() + + result, err := state.EpochStore.getNearestOrEpochSnapshot(2, nil) + assert.NoError(t, err) + assert.Equal(t, snapshot, result) + }) } diff --git a/consensus/polybft/validators_snapshot.go b/consensus/polybft/validators_snapshot.go index 8d8fecf7fa..c6f6c151c2 100644 --- a/consensus/polybft/validators_snapshot.go +++ b/consensus/polybft/validators_snapshot.go @@ -289,13 +289,15 @@ func (v *validatorsSnapshotCache) cleanup(dbTx *bolt.Tx) error { // If it doesn't have snapshot cached for desired epoch, it will return the latest one it has func (v *validatorsSnapshotCache) getLastCachedSnapshot(currentEpoch uint64, dbTx *bolt.Tx) (*validatorSnapshot, error) { + epochToQuery := currentEpoch + cachedSnapshot := v.snapshots[currentEpoch] if cachedSnapshot != nil { return cachedSnapshot, nil } // if we do not have a snapshot in memory for given epoch, we will get the latest one we have - for ; currentEpoch >= 0; currentEpoch-- { + for { cachedSnapshot = v.snapshots[currentEpoch] if cachedSnapshot != nil { v.logger.Trace("Found snapshot in memory cache", "Epoch", currentEpoch) @@ -306,9 +308,11 @@ func (v *validatorsSnapshotCache) getLastCachedSnapshot(currentEpoch uint64, if currentEpoch == 0 { // prevent uint64 underflow break } + + currentEpoch-- } - dbSnapshot, err := v.state.EpochStore.getLastSnapshot(dbTx) + dbSnapshot, err := v.state.EpochStore.getNearestOrEpochSnapshot(epochToQuery, dbTx) if err != nil { return nil, err } From 8e616e78ed43c9699ec4bc6fa29b9c511e7c7696 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Fri, 22 Mar 2024 11:06:37 +0100 Subject: [PATCH 28/48] offset increase --- e2e-polybft/e2e/bridge_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-polybft/e2e/bridge_test.go b/e2e-polybft/e2e/bridge_test.go index 409a4d5a09..620f389996 100644 --- a/e2e-polybft/e2e/bridge_test.go +++ b/e2e-polybft/e2e/bridge_test.go @@ -1316,7 +1316,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { require.NoError(t, err) checkBalancesFn := func(address types.Address, rootExpected, childExpected *big.Int, isValidator bool) { - offset := ethgo.Gwei(10) + offset := ethgo.Gwei(100) expectedValue := new(big.Int) t.Log("Checking balance of native ERC20 token on root and child", "Address", address, From 5b83de242be7f622669071e44d4f193ac2752f31 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Thu, 21 Mar 2024 11:49:40 +0100 Subject: [PATCH 29/48] txTimeout and txPollFreq in txRelayer --- command/bridge/common/params.go | 18 +++++ command/bridge/deploy/deploy.go | 20 +++++- command/bridge/deploy/params.go | 4 ++ .../bridge/deposit/erc1155/deposit_erc1155.go | 5 +- command/bridge/deposit/erc20/deposit_erc20.go | 5 +- .../bridge/deposit/erc721/deposit_erc721.go | 5 +- command/bridge/exit/exit.go | 22 ++++++- command/bridge/finalize/finalize.go | 19 +++++- command/bridge/finalize/params.go | 2 + command/bridge/fund/fund.go | 19 +++++- command/bridge/fund/params.go | 4 ++ command/bridge/helper/utils.go | 2 + command/bridge/premine/params.go | 2 + command/bridge/premine/premine.go | 17 ++++- .../withdraw/erc1155/withdraw_erc1155.go | 5 +- .../bridge/withdraw/erc20/withdraw_erc20.go | 5 +- .../bridge/withdraw/erc721/withdraw_erc721.go | 5 +- command/mint/mint_erc20.go | 19 +++++- command/mint/params.go | 2 + command/validator/registration/params.go | 2 + .../registration/register_validator.go | 19 +++++- command/validator/stake/params.go | 2 + command/validator/stake/stake.go | 17 ++++- command/validator/unstake/params.go | 2 + command/validator/unstake/unstake.go | 18 ++++- command/validator/validators/params.go | 2 + .../validator/validators/validator_info.go | 19 +++++- command/validator/whitelist/params.go | 2 + .../whitelist/whitelist_validators.go | 17 ++++- command/validator/withdraw-rewards/params.go | 2 + command/validator/withdraw-rewards/rewards.go | 17 ++++- command/validator/withdraw/params.go | 2 + command/validator/withdraw/withdraw.go | 17 ++++- consensus/polybft/state_sync_relayer.go | 2 +- txrelayer/txrelayer.go | 65 +++++++++++-------- 35 files changed, 339 insertions(+), 46 deletions(-) diff --git a/command/bridge/common/params.go b/command/bridge/common/params.go index 3595044031..064e35e544 100644 --- a/command/bridge/common/params.go +++ b/command/bridge/common/params.go @@ -35,6 +35,8 @@ const ( ChildTokenFlag = "child-token" JSONRPCFlag = "json-rpc" ChildChainMintableFlag = "child-chain-mintable" + txTimeoutFlag = "tx-timeout" + txPollFreqFlag = "tx-poll-freq" MinterKeyFlag = "minter-key" MinterKeyFlagDesc = "minter key is the account which is able to mint tokens to sender account " + @@ -53,6 +55,8 @@ type BridgeParams struct { PredicateAddr string JSONRPCAddr string ChildChainMintable bool + TxTimeout uint64 + TxPollFreq uint64 } // RegisterCommonFlags registers common bridge flags to a given command @@ -84,6 +88,20 @@ func (p *BridgeParams) RegisterCommonFlags(cmd *cobra.Command) { false, "flag indicating whether tokens originate from child chain", ) + + cmd.Flags().Uint64Var( + &p.TxTimeout, + txTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + &p.TxPollFreq, + txPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) } func (p *BridgeParams) Validate() error { diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index 2fae45da48..be5c186c3b 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -5,6 +5,7 @@ import ( "fmt" "math/big" "sync" + "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo" @@ -337,6 +338,20 @@ func GetCommand() *cobra.Command { helper.ProxyContractsAdminDesc, ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + txTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + txPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(helper.TestModeFlag, deployerKeyFlag) return cmd @@ -429,7 +444,10 @@ func runCommand(cmd *cobra.Command, _ []string) { // deployContracts deploys and initializes rootchain smart contracts func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, chainID int64, initialValidators []*validator.GenesisValidator, cmdCtx context.Context) (deploymentResultInfo, error) { - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(client), txrelayer.WithWriter(outputter)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(client), txrelayer.WithWriter(outputter), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + if err != nil { return deploymentResultInfo{RootchainCfg: nil, CommandResults: nil}, fmt.Errorf("failed to initialize tx relayer: %w", err) diff --git a/command/bridge/deploy/params.go b/command/bridge/deploy/params.go index 305e86b990..e7a5ba78ec 100644 --- a/command/bridge/deploy/params.go +++ b/command/bridge/deploy/params.go @@ -13,6 +13,8 @@ const ( deployerKeyFlag = "deployer-key" jsonRPCFlag = "json-rpc" erc20AddrFlag = "erc20-token" + txTimeoutFlag = "tx-timeout" + txPollFreqFlag = "tx-poll-freq" ) type deployParams struct { @@ -21,6 +23,8 @@ type deployParams struct { jsonRPCAddress string rootERC20TokenAddr string proxyContractsAdmin string + txTimeout uint64 + txPollFreq uint64 isTestMode bool } diff --git a/command/bridge/deposit/erc1155/deposit_erc1155.go b/command/bridge/deposit/erc1155/deposit_erc1155.go index 9a9f51281f..742765d107 100644 --- a/command/bridge/deposit/erc1155/deposit_erc1155.go +++ b/command/bridge/deposit/erc1155/deposit_erc1155.go @@ -4,6 +4,7 @@ import ( "fmt" "math/big" "strings" + "time" "github.com/spf13/cobra" @@ -96,7 +97,9 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), + txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc20/deposit_erc20.go b/command/bridge/deposit/erc20/deposit_erc20.go index bf99b53cce..a4802819a7 100644 --- a/command/bridge/deposit/erc20/deposit_erc20.go +++ b/command/bridge/deposit/erc20/deposit_erc20.go @@ -3,6 +3,7 @@ package erc20 import ( "fmt" "math/big" + "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo" @@ -89,7 +90,9 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), + txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc721/deposit_erc721.go b/command/bridge/deposit/erc721/deposit_erc721.go index 6f4fbd1f4b..629841ed41 100644 --- a/command/bridge/deposit/erc721/deposit_erc721.go +++ b/command/bridge/deposit/erc721/deposit_erc721.go @@ -4,6 +4,7 @@ import ( "fmt" "math/big" "strings" + "time" "github.com/spf13/cobra" @@ -86,7 +87,9 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), + txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index 7b083693f2..5c97a29f83 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "strconv" + "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo/jsonrpc" @@ -24,6 +25,8 @@ const ( exitEventIDFlag = "exit-id" rootJSONRPCFlag = "root-json-rpc" childJSONRPCFlag = "child-json-rpc" + txTimeoutFlag = "tx-timeout" + txPollFreqFlag = "tx-poll-freq" // generateExitProofFn is JSON RPC endpoint which creates exit proof generateExitProofFn = "bridge_generateExitProof" @@ -35,6 +38,8 @@ type exitParams struct { exitID uint64 rootJSONRPCAddr string childJSONRPCAddr string + txTimeout uint64 + txPollFreq uint64 } var ( @@ -85,6 +90,19 @@ func GetCommand() *cobra.Command { "the JSON RPC child chain endpoint", ) + exitCmd.Flags().Uint64Var( + &ep.txTimeout, + txTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + exitCmd.Flags().Uint64Var( + &ep.txPollFreq, + txPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) + _ = exitCmd.MarkFlagRequired(exitHelperFlag) return exitCmd @@ -101,7 +119,9 @@ func run(cmd *cobra.Command, _ []string) { return } - rootTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(ep.rootJSONRPCAddr)) + rootTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(ep.rootJSONRPCAddr), + txrelayer.WithReceiptsTimeout(time.Duration(ep.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(ep.txPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("could not create root chain tx relayer: %w", err)) diff --git a/command/bridge/finalize/finalize.go b/command/bridge/finalize/finalize.go index bf64951d91..7befddd7a7 100644 --- a/command/bridge/finalize/finalize.go +++ b/command/bridge/finalize/finalize.go @@ -5,6 +5,7 @@ import ( "fmt" "math/big" "strings" + "time" "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/command" @@ -84,6 +85,20 @@ func setFlags(cmd *cobra.Command) { bridgeHelper.BladeManagerFlagDesc, ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountConfigFlag) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountDirFlag) @@ -101,7 +116,9 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { return fmt.Errorf("enlist validator failed: %w", err) } diff --git a/command/bridge/finalize/params.go b/command/bridge/finalize/params.go index b226d7d95f..672c1ca701 100644 --- a/command/bridge/finalize/params.go +++ b/command/bridge/finalize/params.go @@ -16,6 +16,8 @@ type finalizeParams struct { jsonRPC string bladeManager string genesisPath string + txTimeout uint64 + txPollFreq uint64 bladeManagerAddr types.Address } diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index 1005853bbe..657f28be47 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -2,6 +2,7 @@ package fund import ( "fmt" + "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo" @@ -60,6 +61,20 @@ func setFlags(cmd *cobra.Command) { "", polybftsecrets.PrivateKeyFlagDesc, ) + + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + txTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + txPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) } func preRunCommand(_ *cobra.Command, _ []string) error { @@ -70,7 +85,9 @@ func runCommand(cmd *cobra.Command, _ []string) { outputter := command.InitializeOutputter(cmd) defer outputter.WriteOutput() - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/fund/params.go b/command/bridge/fund/params.go index 4162e5113c..69b6e4829f 100644 --- a/command/bridge/fund/params.go +++ b/command/bridge/fund/params.go @@ -12,6 +12,8 @@ import ( const ( jsonRPCFlag = "json-rpc" mintStakeTokenFlag = "mint" + txTimeoutFlag = "tx-timeout" + txPollFreqFlag = "tx-poll-freq" ) var ( @@ -24,6 +26,8 @@ type fundParams struct { amounts []string deployerPrivateKey string jsonRPCAddress string + txTimeout uint64 + txPollFreq uint64 amountValues []*big.Int addresses []types.Address diff --git a/command/bridge/helper/utils.go b/command/bridge/helper/utils.go index 0e930785ee..b16dcdecfb 100644 --- a/command/bridge/helper/utils.go +++ b/command/bridge/helper/utils.go @@ -39,6 +39,8 @@ const ( Erc20TokenFlag = "erc20-token" //nolint:gosec BladeManagerFlag = "blade-manager" BladeManagerFlagDesc = "address of blade manager contract on a rootchain" + TxTimeoutFlag = "tx-timeout" + TxPollFreqFlag = "tx-poll-freq" ) var ( diff --git a/command/bridge/premine/params.go b/command/bridge/premine/params.go index d08ccb0962..06431195ec 100644 --- a/command/bridge/premine/params.go +++ b/command/bridge/premine/params.go @@ -25,6 +25,8 @@ type premineParams struct { jsonRPC string stakedAmount string premineAmount string + txTimeout uint64 + txPollFreq uint64 premineAmountValue *big.Int stakedValue *big.Int diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index 82c1dd281b..27cd440fbb 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -84,6 +84,20 @@ func setFlags(cmd *cobra.Command) { "amount to premine as a staked balance", ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 150, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountConfigFlag) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountDirFlag) @@ -107,7 +121,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptTimeout(150*time.Millisecond)) + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond))), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond)))) if err != nil { return err } diff --git a/command/bridge/withdraw/erc1155/withdraw_erc1155.go b/command/bridge/withdraw/erc1155/withdraw_erc1155.go index a2f977e113..5bf9f1a159 100644 --- a/command/bridge/withdraw/erc1155/withdraw_erc1155.go +++ b/command/bridge/withdraw/erc1155/withdraw_erc1155.go @@ -5,6 +5,7 @@ import ( "fmt" "math/big" "strings" + "time" "github.com/spf13/cobra" @@ -91,7 +92,9 @@ func runCommand(cmd *cobra.Command, _ []string) { return } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), + txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc20/withdraw_erc20.go b/command/bridge/withdraw/erc20/withdraw_erc20.go index 1cd3742ff2..bf7bbe697b 100644 --- a/command/bridge/withdraw/erc20/withdraw_erc20.go +++ b/command/bridge/withdraw/erc20/withdraw_erc20.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" "math/big" + "time" "github.com/spf13/cobra" @@ -82,7 +83,9 @@ func runCommand(cmd *cobra.Command, _ []string) { return } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), + txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("could not create destination chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc721/withdraw_erc721.go b/command/bridge/withdraw/erc721/withdraw_erc721.go index 0fa596d5e1..9c5986dd18 100644 --- a/command/bridge/withdraw/erc721/withdraw_erc721.go +++ b/command/bridge/withdraw/erc721/withdraw_erc721.go @@ -5,6 +5,7 @@ import ( "fmt" "math/big" "strings" + "time" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" @@ -82,7 +83,9 @@ func run(cmd *cobra.Command, _ []string) { return } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), + txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/mint/mint_erc20.go b/command/mint/mint_erc20.go index ced1e43416..ca784856f5 100644 --- a/command/mint/mint_erc20.go +++ b/command/mint/mint_erc20.go @@ -2,6 +2,7 @@ package mint import ( "fmt" + "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -68,6 +69,20 @@ func setFlags(cmd *cobra.Command) { "erc20 token address", ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) + _ = cmd.MarkFlagRequired(bridgeHelper.Erc20TokenFlag) } @@ -75,7 +90,9 @@ func runCommand(cmd *cobra.Command, _ []string) { outputter := command.InitializeOutputter(cmd) defer outputter.WriteOutput() - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/mint/params.go b/command/mint/params.go index 3fd818ca2d..257c77e95d 100644 --- a/command/mint/params.go +++ b/command/mint/params.go @@ -16,6 +16,8 @@ type mintParams struct { tokenAddr string minterPrivateKey string jsonRPCAddress string + txTimeout uint64 + txPollFreq uint64 amountValues []*big.Int } diff --git a/command/validator/registration/params.go b/command/validator/registration/params.go index 215e6d756a..c960ca8b11 100644 --- a/command/validator/registration/params.go +++ b/command/validator/registration/params.go @@ -18,6 +18,8 @@ type registerParams struct { jsonRPC string amount string stakeToken string + txTimeout uint64 + txPollFreq uint64 amountValue *big.Int stakeTokenAddr types.Address diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 59c6416961..02a797e2b8 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "time" "github.com/0xPolygon/polygon-edge/bls" "github.com/0xPolygon/polygon-edge/command" @@ -66,6 +67,20 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.StakeTokenFlagDesc, ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) + helper.RegisterJSONRPCFlag(cmd) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountConfigFlag, polybftsecrets.AccountDirFlag) } @@ -85,7 +100,9 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { return err } diff --git a/command/validator/stake/params.go b/command/validator/stake/params.go index 993ebca4c6..aa336a5f8a 100644 --- a/command/validator/stake/params.go +++ b/command/validator/stake/params.go @@ -19,6 +19,8 @@ type stakeParams struct { jsonRPC string amount string stakeToken string + txTimeout uint64 + txPollFreq uint64 amountValue *big.Int stakeTokenAddr types.Address diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index 5209d1382d..59efb4d8a3 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -64,6 +64,20 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.StakeTokenFlagDesc, ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 150, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) } @@ -83,7 +97,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptTimeout(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { return err } diff --git a/command/validator/unstake/params.go b/command/validator/unstake/params.go index 99dea6c2b2..dd6639617e 100644 --- a/command/validator/unstake/params.go +++ b/command/validator/unstake/params.go @@ -18,6 +18,8 @@ type unstakeParams struct { accountConfig string jsonRPC string amount string + txTimeout uint64 + txPollFreq uint64 amountValue *big.Int } diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index 21eb10abcf..fabdf46aa3 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -5,6 +5,7 @@ import ( "time" "github.com/0xPolygon/polygon-edge/command" + bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/command/helper" polybftsecrets "github.com/0xPolygon/polygon-edge/command/secrets/init" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -53,6 +54,20 @@ func setFlags(cmd *cobra.Command) { "amount to unstake from validator", ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 150, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) } @@ -72,7 +87,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptTimeout(150*time.Millisecond)) + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txTimeout*uint64(time.Millisecond)))) if err != nil { return err } diff --git a/command/validator/validators/params.go b/command/validator/validators/params.go index 9edb5af1ef..42b535528e 100644 --- a/command/validator/validators/params.go +++ b/command/validator/validators/params.go @@ -15,6 +15,8 @@ type validatorInfoParams struct { supernetManagerAddress string stakeManagerAddress string chainID int64 + txTimeout uint64 + txPollFreq uint64 } func (v *validatorInfoParams) validateFlags() error { diff --git a/command/validator/validators/validator_info.go b/command/validator/validators/validator_info.go index c9505ce5b3..d46233e98d 100644 --- a/command/validator/validators/validator_info.go +++ b/command/validator/validators/validator_info.go @@ -2,6 +2,7 @@ package validators import ( "fmt" + "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -53,6 +54,20 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.ChainIDFlagDesc, ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 50, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) } @@ -71,7 +86,9 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC)) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { return err } diff --git a/command/validator/whitelist/params.go b/command/validator/whitelist/params.go index b8a467cd06..cd0d628d44 100644 --- a/command/validator/whitelist/params.go +++ b/command/validator/whitelist/params.go @@ -23,6 +23,8 @@ type whitelistParams struct { privateKey string jsonRPC string newValidatorAddresses []string + txTimeout uint64 + txPollFreq uint64 } func (ep *whitelistParams) validateFlags() error { diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index be32fe43ce..af24f53fc0 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -59,6 +59,20 @@ func setFlags(cmd *cobra.Command) { "account addresses of a possible validators", ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 150, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountConfigFlag) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountDirFlag) @@ -82,7 +96,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptTimeout(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { return fmt.Errorf("whitelist validator failed. Could not create tx relayer: %w", err) } diff --git a/command/validator/withdraw-rewards/params.go b/command/validator/withdraw-rewards/params.go index 5f53e94bb9..8c90c2b8e8 100644 --- a/command/validator/withdraw-rewards/params.go +++ b/command/validator/withdraw-rewards/params.go @@ -12,6 +12,8 @@ type withdrawRewardsParams struct { accountDir string accountConfig string jsonRPC string + txTimeout uint64 + txPollFreq uint64 } type withdrawRewardResult struct { diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index 8a6a383bee..b4bbbbc255 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -49,6 +49,20 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.AccountConfigFlagDesc, ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 150, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) } @@ -70,7 +84,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { validatorAddr := validatorAccount.Ecdsa.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptTimeout(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { return err } diff --git a/command/validator/withdraw/params.go b/command/validator/withdraw/params.go index 95baa417ca..2cbc0170bf 100644 --- a/command/validator/withdraw/params.go +++ b/command/validator/withdraw/params.go @@ -16,6 +16,8 @@ type withdrawParams struct { accountDir string accountConfig string jsonRPC string + txTimeout uint64 + txPollFreq uint64 } func (v *withdrawParams) validateFlags() (err error) { diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index fd02eb48bf..72ff4409c2 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -46,6 +46,20 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.AccountConfigFlagDesc, ) + cmd.Flags().Uint64Var( + ¶ms.txTimeout, + bridgeHelper.TxTimeoutFlag, + 5000, + "timeout for receipts in milliseconds", + ) + + cmd.Flags().Uint64Var( + ¶ms.txPollFreq, + bridgeHelper.TxPollFreqFlag, + 150, + "frequency in milliseconds for poll transactions", + ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) helper.RegisterJSONRPCFlag(cmd) } @@ -66,7 +80,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptTimeout(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) if err != nil { return err } diff --git a/consensus/polybft/state_sync_relayer.go b/consensus/polybft/state_sync_relayer.go index c29fad79b3..cd7aa7cb78 100644 --- a/consensus/polybft/state_sync_relayer.go +++ b/consensus/polybft/state_sync_relayer.go @@ -253,6 +253,6 @@ func getBridgeTxRelayer(rpcEndpoint string, logger hclog.Logger) (txrelayer.TxRe } return txrelayer.NewTxRelayer( - txrelayer.WithIPAddress(rpcEndpoint), txrelayer.WithNumRetries(-1), + txrelayer.WithIPAddress(rpcEndpoint), txrelayer.WithNoWaiting(), txrelayer.WithWriter(logger.StandardWriter(&hclog.StandardLoggerOptions{}))) } diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 405efd8246..f5d65196cb 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -49,10 +49,11 @@ type TxRelayer interface { var _ TxRelayer = (*TxRelayerImpl)(nil) type TxRelayerImpl struct { - ipAddress string - client *jsonrpc.Client - receiptTimeout time.Duration - numRetries int + ipAddress string + client *jsonrpc.Client + receiptsPollFreq time.Duration + receiptsTimeout time.Duration + noWaitReceipt bool lock sync.Mutex @@ -61,9 +62,9 @@ type TxRelayerImpl struct { func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { t := &TxRelayerImpl{ - ipAddress: DefaultRPCAddress, - receiptTimeout: 50 * time.Millisecond, - numRetries: defaultNumRetries, + ipAddress: DefaultRPCAddress, + receiptsPollFreq: 50 * time.Millisecond, + receiptsTimeout: 5 * time.Second, } for _, opt := range opts { opt(t) @@ -264,27 +265,33 @@ func (t *TxRelayerImpl) sendTransactionLocalLocked(txn *types.Transaction) (ethg } func (t *TxRelayerImpl) waitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { - // A negative numRetries means we don't want to receive the receipt after SendTransaction/SendTransactionLocal calls - if t.numRetries < 0 { + if t.noWaitReceipt { return nil, nil } - for count := 0; count < t.numRetries; count++ { - receipt, err := t.client.Eth().GetTransactionReceipt(hash) - if err != nil { - if err.Error() != "not found" { - return nil, err + timer := time.NewTimer(t.receiptsTimeout) + defer timer.Stop() + + ticker := time.NewTicker(t.receiptsPollFreq) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + receipt, err := t.client.Eth().GetTransactionReceipt(hash) + if err != nil { + if err.Error() != "not found" { + return nil, err + } } - } - if receipt != nil { - return receipt, nil + if receipt != nil { + return receipt, nil + } + case <-timer.C: + return nil, fmt.Errorf("timeout while waiting for transaction %s to be processed", hash) } - - time.Sleep(t.receiptTimeout) } - - return nil, fmt.Errorf("timeout while waiting for transaction %s to be processed", hash) } // ConvertTxnToCallMsg converts txn instance to call message @@ -373,9 +380,9 @@ func WithIPAddress(ipAddress string) TxRelayerOption { } } -func WithReceiptTimeout(receiptTimeout time.Duration) TxRelayerOption { +func WithReceiptsPollFreq(receiptsPollFreq time.Duration) TxRelayerOption { return func(t *TxRelayerImpl) { - t.receiptTimeout = receiptTimeout + t.receiptsPollFreq = receiptsPollFreq } } @@ -385,11 +392,17 @@ func WithWriter(writer io.Writer) TxRelayerOption { } } -// WithNumRetries sets the maximum number of eth_getTransactionReceipt retries +func WithNoWaiting() TxRelayerOption { + return func(t *TxRelayerImpl) { + t.noWaitReceipt = true + } +} + +// WithReceiptsTimeout sets the maximum number of eth_getTransactionReceipt retries // before considering the transaction sending as timed out. Set to -1 to disable // waitForReceipt and not wait for the transaction receipt -func WithNumRetries(numRetries int) TxRelayerOption { +func WithReceiptsTimeout(receiptsTimeout time.Duration) TxRelayerOption { return func(t *TxRelayerImpl) { - t.numRetries = numRetries + t.receiptsTimeout = receiptsTimeout } } From c0cc2245b3929d9763321255f264e5d577375f8a Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Thu, 21 Mar 2024 12:19:10 +0100 Subject: [PATCH 30/48] uint to duration --- command/bridge/common/params.go | 13 +++++++------ command/bridge/deploy/deploy.go | 12 ++++++------ command/bridge/deploy/params.go | 5 +++-- .../bridge/deposit/erc1155/deposit_erc1155.go | 4 ++-- command/bridge/deposit/erc20/deposit_erc20.go | 4 ++-- command/bridge/deposit/erc721/deposit_erc721.go | 4 ++-- command/bridge/exit/exit.go | 16 ++++++++-------- command/bridge/finalize/finalize.go | 10 +++++----- command/bridge/finalize/params.go | 5 +++-- command/bridge/fund/fund.go | 12 ++++++------ command/bridge/fund/params.go | 5 +++-- command/bridge/premine/params.go | 5 +++-- command/bridge/premine/premine.go | 12 ++++++------ .../bridge/withdraw/erc1155/withdraw_erc1155.go | 4 ++-- command/bridge/withdraw/erc20/withdraw_erc20.go | 4 ++-- .../bridge/withdraw/erc721/withdraw_erc721.go | 4 ++-- command/mint/mint_erc20.go | 12 ++++++------ command/mint/params.go | 5 +++-- command/validator/registration/params.go | 5 +++-- .../validator/registration/register_validator.go | 12 ++++++------ command/validator/stake/stake.go | 12 ++++++------ command/validator/unstake/params.go | 5 +++-- command/validator/unstake/unstake.go | 12 ++++++------ command/validator/validators/params.go | 5 +++-- command/validator/validators/validator_info.go | 12 ++++++------ command/validator/whitelist/params.go | 5 +++-- .../validator/whitelist/whitelist_validators.go | 8 ++++---- command/validator/withdraw-rewards/params.go | 5 +++-- command/validator/withdraw-rewards/rewards.go | 12 ++++++------ command/validator/withdraw/params.go | 5 +++-- command/validator/withdraw/withdraw.go | 8 ++++---- 31 files changed, 127 insertions(+), 115 deletions(-) diff --git a/command/bridge/common/params.go b/command/bridge/common/params.go index 064e35e544..4aa8c5da0d 100644 --- a/command/bridge/common/params.go +++ b/command/bridge/common/params.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "strings" + "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo" @@ -55,8 +56,8 @@ type BridgeParams struct { PredicateAddr string JSONRPCAddr string ChildChainMintable bool - TxTimeout uint64 - TxPollFreq uint64 + TxTimeout time.Duration + TxPollFreq time.Duration } // RegisterCommonFlags registers common bridge flags to a given command @@ -89,17 +90,17 @@ func (p *BridgeParams) RegisterCommonFlags(cmd *cobra.Command) { "flag indicating whether tokens originate from child chain", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( &p.TxTimeout, txTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( &p.TxPollFreq, txPollFreqFlag, - 50, + 50*time.Millisecond, "frequency in milliseconds for poll transactions", ) } diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index be5c186c3b..b690f09ea4 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -338,17 +338,17 @@ func GetCommand() *cobra.Command { helper.ProxyContractsAdminDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, txTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, txPollFreqFlag, - 50, + 50*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -445,8 +445,8 @@ func runCommand(cmd *cobra.Command, _ []string) { func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, chainID int64, initialValidators []*validator.GenesisValidator, cmdCtx context.Context) (deploymentResultInfo, error) { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(client), txrelayer.WithWriter(outputter), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return deploymentResultInfo{RootchainCfg: nil, CommandResults: nil}, diff --git a/command/bridge/deploy/params.go b/command/bridge/deploy/params.go index e7a5ba78ec..9f4d8344db 100644 --- a/command/bridge/deploy/params.go +++ b/command/bridge/deploy/params.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "time" "github.com/0xPolygon/polygon-edge/command/helper" "github.com/0xPolygon/polygon-edge/consensus/polybft" @@ -23,8 +24,8 @@ type deployParams struct { jsonRPCAddress string rootERC20TokenAddr string proxyContractsAdmin string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration isTestMode bool } diff --git a/command/bridge/deposit/erc1155/deposit_erc1155.go b/command/bridge/deposit/erc1155/deposit_erc1155.go index 742765d107..401fb6ab02 100644 --- a/command/bridge/deposit/erc1155/deposit_erc1155.go +++ b/command/bridge/deposit/erc1155/deposit_erc1155.go @@ -98,8 +98,8 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc20/deposit_erc20.go b/command/bridge/deposit/erc20/deposit_erc20.go index a4802819a7..6683ef4c27 100644 --- a/command/bridge/deposit/erc20/deposit_erc20.go +++ b/command/bridge/deposit/erc20/deposit_erc20.go @@ -91,8 +91,8 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc721/deposit_erc721.go b/command/bridge/deposit/erc721/deposit_erc721.go index 629841ed41..27507b5f3c 100644 --- a/command/bridge/deposit/erc721/deposit_erc721.go +++ b/command/bridge/deposit/erc721/deposit_erc721.go @@ -88,8 +88,8 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index 5c97a29f83..43937d10ec 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -38,8 +38,8 @@ type exitParams struct { exitID uint64 rootJSONRPCAddr string childJSONRPCAddr string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration } var ( @@ -90,16 +90,16 @@ func GetCommand() *cobra.Command { "the JSON RPC child chain endpoint", ) - exitCmd.Flags().Uint64Var( + exitCmd.Flags().DurationVar( &ep.txTimeout, txTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - exitCmd.Flags().Uint64Var( + exitCmd.Flags().DurationVar( &ep.txPollFreq, txPollFreqFlag, - 50, + 50*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -120,8 +120,8 @@ func run(cmd *cobra.Command, _ []string) { } rootTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(ep.rootJSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(ep.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(ep.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(ep.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(ep.txPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("could not create root chain tx relayer: %w", err)) diff --git a/command/bridge/finalize/finalize.go b/command/bridge/finalize/finalize.go index 7befddd7a7..ebeb996f30 100644 --- a/command/bridge/finalize/finalize.go +++ b/command/bridge/finalize/finalize.go @@ -85,14 +85,14 @@ func setFlags(cmd *cobra.Command) { bridgeHelper.BladeManagerFlagDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, 50, @@ -117,8 +117,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return fmt.Errorf("enlist validator failed: %w", err) } diff --git a/command/bridge/finalize/params.go b/command/bridge/finalize/params.go index 672c1ca701..73c244646c 100644 --- a/command/bridge/finalize/params.go +++ b/command/bridge/finalize/params.go @@ -3,6 +3,7 @@ package finalize import ( "fmt" "os" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -16,8 +17,8 @@ type finalizeParams struct { jsonRPC string bladeManager string genesisPath string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration bladeManagerAddr types.Address } diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index 657f28be47..c2eed10eec 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -62,17 +62,17 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.PrivateKeyFlagDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, txTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, txPollFreqFlag, - 50, + 50*time.Millisecond, "frequency in milliseconds for poll transactions", ) } @@ -86,8 +86,8 @@ func runCommand(cmd *cobra.Command, _ []string) { defer outputter.WriteOutput() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/fund/params.go b/command/bridge/fund/params.go index 69b6e4829f..9cb60449ed 100644 --- a/command/bridge/fund/params.go +++ b/command/bridge/fund/params.go @@ -3,6 +3,7 @@ package fund import ( "errors" "math/big" + "time" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" cmdhelper "github.com/0xPolygon/polygon-edge/command/helper" @@ -26,8 +27,8 @@ type fundParams struct { amounts []string deployerPrivateKey string jsonRPCAddress string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration amountValues []*big.Int addresses []types.Address diff --git a/command/bridge/premine/params.go b/command/bridge/premine/params.go index 06431195ec..0be354f93c 100644 --- a/command/bridge/premine/params.go +++ b/command/bridge/premine/params.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "math/big" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -25,8 +26,8 @@ type premineParams struct { jsonRPC string stakedAmount string premineAmount string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration premineAmountValue *big.Int stakedValue *big.Int diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index 27cd440fbb..a692da0fa2 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -84,17 +84,17 @@ func setFlags(cmd *cobra.Command) { "amount to premine as a staked balance", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, - 150, + 150*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -121,8 +121,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond))), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond)))) + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq)), + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout))) if err != nil { return err } diff --git a/command/bridge/withdraw/erc1155/withdraw_erc1155.go b/command/bridge/withdraw/erc1155/withdraw_erc1155.go index 5bf9f1a159..2b0a7cb810 100644 --- a/command/bridge/withdraw/erc1155/withdraw_erc1155.go +++ b/command/bridge/withdraw/erc1155/withdraw_erc1155.go @@ -93,8 +93,8 @@ func runCommand(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc20/withdraw_erc20.go b/command/bridge/withdraw/erc20/withdraw_erc20.go index bf7bbe697b..d5b4bc01c7 100644 --- a/command/bridge/withdraw/erc20/withdraw_erc20.go +++ b/command/bridge/withdraw/erc20/withdraw_erc20.go @@ -84,8 +84,8 @@ func runCommand(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("could not create destination chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc721/withdraw_erc721.go b/command/bridge/withdraw/erc721/withdraw_erc721.go index 9c5986dd18..7cb86f0143 100644 --- a/command/bridge/withdraw/erc721/withdraw_erc721.go +++ b/command/bridge/withdraw/erc721/withdraw_erc721.go @@ -84,8 +84,8 @@ func run(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/mint/mint_erc20.go b/command/mint/mint_erc20.go index ca784856f5..6beecb6a09 100644 --- a/command/mint/mint_erc20.go +++ b/command/mint/mint_erc20.go @@ -69,17 +69,17 @@ func setFlags(cmd *cobra.Command) { "erc20 token address", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, - 50, + 50*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -91,8 +91,8 @@ func runCommand(cmd *cobra.Command, _ []string) { defer outputter.WriteOutput() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/mint/params.go b/command/mint/params.go index 257c77e95d..3445fce919 100644 --- a/command/mint/params.go +++ b/command/mint/params.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "math/big" + "time" rootHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/command/helper" @@ -16,8 +17,8 @@ type mintParams struct { tokenAddr string minterPrivateKey string jsonRPCAddress string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration amountValues []*big.Int } diff --git a/command/validator/registration/params.go b/command/validator/registration/params.go index c960ca8b11..58d10008b8 100644 --- a/command/validator/registration/params.go +++ b/command/validator/registration/params.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "time" "github.com/0xPolygon/polygon-edge/command/helper" sidechainHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -18,8 +19,8 @@ type registerParams struct { jsonRPC string amount string stakeToken string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration amountValue *big.Int stakeTokenAddr types.Address diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 02a797e2b8..2f5af74b50 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -67,17 +67,17 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.StakeTokenFlagDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, - 50, + 50*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -101,8 +101,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return err } diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index 59efb4d8a3..8b58cad657 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -64,17 +64,17 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.StakeTokenFlagDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, - 150, + 150*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -97,8 +97,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return err } diff --git a/command/validator/unstake/params.go b/command/validator/unstake/params.go index dd6639617e..7aebe76772 100644 --- a/command/validator/unstake/params.go +++ b/command/validator/unstake/params.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "math/big" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -18,8 +19,8 @@ type unstakeParams struct { accountConfig string jsonRPC string amount string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration amountValue *big.Int } diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index fabdf46aa3..e191ae05fa 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -54,17 +54,17 @@ func setFlags(cmd *cobra.Command) { "amount to unstake from validator", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, - 150, + 150*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -87,8 +87,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txTimeout*uint64(time.Millisecond)))) + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txTimeout))) if err != nil { return err } diff --git a/command/validator/validators/params.go b/command/validator/validators/params.go index 42b535528e..c5db72b9bf 100644 --- a/command/validator/validators/params.go +++ b/command/validator/validators/params.go @@ -3,6 +3,7 @@ package validators import ( "bytes" "fmt" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -15,8 +16,8 @@ type validatorInfoParams struct { supernetManagerAddress string stakeManagerAddress string chainID int64 - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration } func (v *validatorInfoParams) validateFlags() error { diff --git a/command/validator/validators/validator_info.go b/command/validator/validators/validator_info.go index d46233e98d..60b0b0013f 100644 --- a/command/validator/validators/validator_info.go +++ b/command/validator/validators/validator_info.go @@ -54,17 +54,17 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.ChainIDFlagDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, - 50, + 50*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -87,8 +87,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return err } diff --git a/command/validator/whitelist/params.go b/command/validator/whitelist/params.go index cd0d628d44..2313c4bf68 100644 --- a/command/validator/whitelist/params.go +++ b/command/validator/whitelist/params.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -23,8 +24,8 @@ type whitelistParams struct { privateKey string jsonRPC string newValidatorAddresses []string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration } func (ep *whitelistParams) validateFlags() error { diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index af24f53fc0..4aab585865 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -59,14 +59,14 @@ func setFlags(cmd *cobra.Command) { "account addresses of a possible validators", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 5000, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, 150, @@ -96,8 +96,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return fmt.Errorf("whitelist validator failed. Could not create tx relayer: %w", err) } diff --git a/command/validator/withdraw-rewards/params.go b/command/validator/withdraw-rewards/params.go index 8c90c2b8e8..60767e9130 100644 --- a/command/validator/withdraw-rewards/params.go +++ b/command/validator/withdraw-rewards/params.go @@ -3,6 +3,7 @@ package rewards import ( "bytes" "fmt" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -12,8 +13,8 @@ type withdrawRewardsParams struct { accountDir string accountConfig string jsonRPC string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration } type withdrawRewardResult struct { diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index b4bbbbc255..0be4bb4dbd 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -49,17 +49,17 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.AccountConfigFlagDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 5*time.Second, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, - 150, + 150*time.Millisecond, "frequency in milliseconds for poll transactions", ) @@ -84,8 +84,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { validatorAddr := validatorAccount.Ecdsa.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return err } diff --git a/command/validator/withdraw/params.go b/command/validator/withdraw/params.go index 2cbc0170bf..f246d45a45 100644 --- a/command/validator/withdraw/params.go +++ b/command/validator/withdraw/params.go @@ -3,6 +3,7 @@ package withdraw import ( "bytes" "fmt" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -16,8 +17,8 @@ type withdrawParams struct { accountDir string accountConfig string jsonRPC string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration } func (v *withdrawParams) validateFlags() (err error) { diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index 72ff4409c2..c858508690 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -46,14 +46,14 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.AccountConfigFlagDesc, ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 5000, "timeout for receipts in milliseconds", ) - cmd.Flags().Uint64Var( + cmd.Flags().DurationVar( ¶ms.txPollFreq, bridgeHelper.TxPollFreqFlag, 150, @@ -80,8 +80,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout*uint64(time.Millisecond))), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq*uint64(time.Millisecond)))) + txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), + txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) if err != nil { return err } From 7ec95eefcbd1bdecf53d76518573f1b04cd8aa2c Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Thu, 21 Mar 2024 12:19:45 +0100 Subject: [PATCH 31/48] missed save --- command/validator/stake/params.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/command/validator/stake/params.go b/command/validator/stake/params.go index aa336a5f8a..637c8c3065 100644 --- a/command/validator/stake/params.go +++ b/command/validator/stake/params.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "time" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -19,8 +20,8 @@ type stakeParams struct { jsonRPC string amount string stakeToken string - txTimeout uint64 - txPollFreq uint64 + txTimeout time.Duration + txPollFreq time.Duration amountValue *big.Int stakeTokenAddr types.Address From d06664e62446e0f8b9cd0299fe2e44e81b736613 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Thu, 21 Mar 2024 12:30:13 +0100 Subject: [PATCH 32/48] lint fix --- command/bridge/deploy/deploy.go | 4 ++-- command/bridge/deposit/erc1155/deposit_erc1155.go | 5 ++--- command/bridge/deposit/erc20/deposit_erc20.go | 5 ++--- command/bridge/deposit/erc721/deposit_erc721.go | 5 ++--- command/bridge/exit/exit.go | 4 ++-- command/bridge/finalize/finalize.go | 4 ++-- command/bridge/fund/fund.go | 4 ++-- command/bridge/premine/premine.go | 4 ++-- command/bridge/withdraw/erc1155/withdraw_erc1155.go | 5 ++--- command/bridge/withdraw/erc20/withdraw_erc20.go | 5 ++--- command/bridge/withdraw/erc721/withdraw_erc721.go | 5 ++--- command/mint/mint_erc20.go | 4 ++-- command/validator/registration/register_validator.go | 4 ++-- command/validator/stake/stake.go | 4 ++-- command/validator/unstake/unstake.go | 4 ++-- command/validator/validators/validator_info.go | 4 ++-- command/validator/whitelist/whitelist_validators.go | 5 ++--- command/validator/withdraw-rewards/rewards.go | 4 ++-- command/validator/withdraw/withdraw.go | 5 ++--- 19 files changed, 38 insertions(+), 46 deletions(-) diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index b690f09ea4..0b387b5a0c 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -445,8 +445,8 @@ func runCommand(cmd *cobra.Command, _ []string) { func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, chainID int64, initialValidators []*validator.GenesisValidator, cmdCtx context.Context) (deploymentResultInfo, error) { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(client), txrelayer.WithWriter(outputter), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return deploymentResultInfo{RootchainCfg: nil, CommandResults: nil}, diff --git a/command/bridge/deposit/erc1155/deposit_erc1155.go b/command/bridge/deposit/erc1155/deposit_erc1155.go index 401fb6ab02..89e43270f1 100644 --- a/command/bridge/deposit/erc1155/deposit_erc1155.go +++ b/command/bridge/deposit/erc1155/deposit_erc1155.go @@ -4,7 +4,6 @@ import ( "fmt" "math/big" "strings" - "time" "github.com/spf13/cobra" @@ -98,8 +97,8 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq))) + txrelayer.WithReceiptsTimeout(dp.TxTimeout), + txrelayer.WithReceiptsPollFreq(dp.TxPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc20/deposit_erc20.go b/command/bridge/deposit/erc20/deposit_erc20.go index 6683ef4c27..a6511ffdf7 100644 --- a/command/bridge/deposit/erc20/deposit_erc20.go +++ b/command/bridge/deposit/erc20/deposit_erc20.go @@ -3,7 +3,6 @@ package erc20 import ( "fmt" "math/big" - "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo" @@ -91,8 +90,8 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq))) + txrelayer.WithReceiptsTimeout(dp.TxTimeout), + txrelayer.WithReceiptsPollFreq(dp.TxPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc721/deposit_erc721.go b/command/bridge/deposit/erc721/deposit_erc721.go index 27507b5f3c..c2ad7cf591 100644 --- a/command/bridge/deposit/erc721/deposit_erc721.go +++ b/command/bridge/deposit/erc721/deposit_erc721.go @@ -4,7 +4,6 @@ import ( "fmt" "math/big" "strings" - "time" "github.com/spf13/cobra" @@ -88,8 +87,8 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(dp.TxTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(dp.TxPollFreq))) + txrelayer.WithReceiptsTimeout(dp.TxTimeout), + txrelayer.WithReceiptsPollFreq(dp.TxPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index 43937d10ec..aaa0633be4 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -120,8 +120,8 @@ func run(cmd *cobra.Command, _ []string) { } rootTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(ep.rootJSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(ep.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(ep.txPollFreq))) + txrelayer.WithReceiptsTimeout(ep.txTimeout), + txrelayer.WithReceiptsPollFreq(ep.txPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("could not create root chain tx relayer: %w", err)) diff --git a/command/bridge/finalize/finalize.go b/command/bridge/finalize/finalize.go index ebeb996f30..fa53d76b9c 100644 --- a/command/bridge/finalize/finalize.go +++ b/command/bridge/finalize/finalize.go @@ -117,8 +117,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return fmt.Errorf("enlist validator failed: %w", err) } diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index c2eed10eec..c0ddf560bf 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -86,8 +86,8 @@ func runCommand(cmd *cobra.Command, _ []string) { defer outputter.WriteOutput() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index a692da0fa2..85e5991e86 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -121,8 +121,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq)), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout))) + txrelayer.WithReceiptsPollFreq(params.txPollFreq), + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err } diff --git a/command/bridge/withdraw/erc1155/withdraw_erc1155.go b/command/bridge/withdraw/erc1155/withdraw_erc1155.go index 2b0a7cb810..80420f908e 100644 --- a/command/bridge/withdraw/erc1155/withdraw_erc1155.go +++ b/command/bridge/withdraw/erc1155/withdraw_erc1155.go @@ -5,7 +5,6 @@ import ( "fmt" "math/big" "strings" - "time" "github.com/spf13/cobra" @@ -93,8 +92,8 @@ func runCommand(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq))) + txrelayer.WithReceiptsTimeout(wp.TxTimeout), + txrelayer.WithReceiptsPollFreq(wp.TxPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc20/withdraw_erc20.go b/command/bridge/withdraw/erc20/withdraw_erc20.go index d5b4bc01c7..403f3ed63c 100644 --- a/command/bridge/withdraw/erc20/withdraw_erc20.go +++ b/command/bridge/withdraw/erc20/withdraw_erc20.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "fmt" "math/big" - "time" "github.com/spf13/cobra" @@ -84,8 +83,8 @@ func runCommand(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq))) + txrelayer.WithReceiptsTimeout(wp.TxTimeout), + txrelayer.WithReceiptsPollFreq(wp.TxPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("could not create destination chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc721/withdraw_erc721.go b/command/bridge/withdraw/erc721/withdraw_erc721.go index 7cb86f0143..bfb7101e9f 100644 --- a/command/bridge/withdraw/erc721/withdraw_erc721.go +++ b/command/bridge/withdraw/erc721/withdraw_erc721.go @@ -5,7 +5,6 @@ import ( "fmt" "math/big" "strings" - "time" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" @@ -84,8 +83,8 @@ func run(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(time.Duration(wp.TxTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(wp.TxPollFreq))) + txrelayer.WithReceiptsTimeout(wp.TxTimeout), + txrelayer.WithReceiptsPollFreq(wp.TxPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/mint/mint_erc20.go b/command/mint/mint_erc20.go index 6beecb6a09..c4e6daa4f8 100644 --- a/command/mint/mint_erc20.go +++ b/command/mint/mint_erc20.go @@ -91,8 +91,8 @@ func runCommand(cmd *cobra.Command, _ []string) { defer outputter.WriteOutput() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 2f5af74b50..3f908d2f15 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -101,8 +101,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return err } diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index 8b58cad657..27159b8835 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -97,8 +97,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return err } diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index e191ae05fa..b13ef31399 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -87,8 +87,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txTimeout))) + txrelayer.WithReceiptsPollFreq(params.txPollFreq), + txrelayer.WithReceiptsPollFreq(params.txTimeout)) if err != nil { return err } diff --git a/command/validator/validators/validator_info.go b/command/validator/validators/validator_info.go index 60b0b0013f..2c33b5b92e 100644 --- a/command/validator/validators/validator_info.go +++ b/command/validator/validators/validator_info.go @@ -87,8 +87,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return err } diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index 4aab585865..923e0493e8 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -2,7 +2,6 @@ package whitelist import ( "fmt" - "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -96,8 +95,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return fmt.Errorf("whitelist validator failed. Could not create tx relayer: %w", err) } diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index 0be4bb4dbd..62dbd1c51c 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -84,8 +84,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { validatorAddr := validatorAccount.Ecdsa.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return err } diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index c858508690..bccb721b38 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -2,7 +2,6 @@ package withdraw import ( "fmt" - "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -80,8 +79,8 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(time.Duration(params.txTimeout)), - txrelayer.WithReceiptsPollFreq(time.Duration(params.txPollFreq))) + txrelayer.WithReceiptsTimeout(params.txTimeout), + txrelayer.WithReceiptsPollFreq(params.txPollFreq)) if err != nil { return err } From fcb840cb2866dc54c78818471d2e050615de0f88 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Thu, 21 Mar 2024 15:51:51 +0100 Subject: [PATCH 33/48] small timeout fix --- command/bridge/common/params.go | 2 +- command/bridge/deploy/deploy.go | 2 +- command/bridge/exit/exit.go | 2 +- command/bridge/finalize/finalize.go | 2 +- command/bridge/fund/fund.go | 2 +- command/bridge/premine/premine.go | 2 +- command/mint/mint_erc20.go | 2 +- command/validator/registration/register_validator.go | 2 +- command/validator/stake/stake.go | 2 +- command/validator/unstake/unstake.go | 2 +- command/validator/validators/validator_info.go | 2 +- command/validator/whitelist/whitelist_validators.go | 3 ++- command/validator/withdraw-rewards/rewards.go | 2 +- command/validator/withdraw/withdraw.go | 3 ++- txrelayer/txrelayer.go | 2 +- 15 files changed, 17 insertions(+), 15 deletions(-) diff --git a/command/bridge/common/params.go b/command/bridge/common/params.go index 4aa8c5da0d..d733795075 100644 --- a/command/bridge/common/params.go +++ b/command/bridge/common/params.go @@ -93,7 +93,7 @@ func (p *BridgeParams) RegisterCommonFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( &p.TxTimeout, txTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index 0b387b5a0c..620087e3a2 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -341,7 +341,7 @@ func GetCommand() *cobra.Command { cmd.Flags().DurationVar( ¶ms.txTimeout, txTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index aaa0633be4..7052d32133 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -93,7 +93,7 @@ func GetCommand() *cobra.Command { exitCmd.Flags().DurationVar( &ep.txTimeout, txTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) exitCmd.Flags().DurationVar( diff --git a/command/bridge/finalize/finalize.go b/command/bridge/finalize/finalize.go index fa53d76b9c..731a4cf90b 100644 --- a/command/bridge/finalize/finalize.go +++ b/command/bridge/finalize/finalize.go @@ -88,7 +88,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index c0ddf560bf..c2d17fc420 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -65,7 +65,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, txTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index 85e5991e86..80414306a5 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -87,7 +87,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/mint/mint_erc20.go b/command/mint/mint_erc20.go index c4e6daa4f8..7ff133eb75 100644 --- a/command/mint/mint_erc20.go +++ b/command/mint/mint_erc20.go @@ -72,7 +72,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 3f908d2f15..86b41280ae 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -70,7 +70,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index 27159b8835..fc798e1764 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -67,7 +67,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index b13ef31399..0d896e14fb 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -57,7 +57,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/validators/validator_info.go b/command/validator/validators/validator_info.go index 2c33b5b92e..8c21b9eb3c 100644 --- a/command/validator/validators/validator_info.go +++ b/command/validator/validators/validator_info.go @@ -57,7 +57,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index 923e0493e8..ca5d007197 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -2,6 +2,7 @@ package whitelist import ( "fmt" + "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -61,7 +62,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index 62dbd1c51c..4e9e0bfe14 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -52,7 +52,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5*time.Second, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index bccb721b38..d504793e3e 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -2,6 +2,7 @@ package withdraw import ( "fmt" + "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -48,7 +49,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 5000, + 50*time.Second, "timeout for receipts in milliseconds", ) diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index f5d65196cb..325bf82e77 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -64,7 +64,7 @@ func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { t := &TxRelayerImpl{ ipAddress: DefaultRPCAddress, receiptsPollFreq: 50 * time.Millisecond, - receiptsTimeout: 5 * time.Second, + receiptsTimeout: 50 * time.Second, } for _, opt := range opts { opt(t) From f6ff7f55f1643a9a955b8c8a109acdf1eb5d62ff Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Mon, 25 Mar 2024 10:20:38 +0100 Subject: [PATCH 34/48] longer timeout for some commands --- command/bridge/premine/premine.go | 2 +- command/validator/stake/stake.go | 2 +- command/validator/unstake/unstake.go | 2 +- command/validator/whitelist/whitelist_validators.go | 2 +- command/validator/withdraw-rewards/rewards.go | 2 +- command/validator/withdraw/withdraw.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index 80414306a5..e7ee3cafa1 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -87,7 +87,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, + 150*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index fc798e1764..a35b602bbb 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -67,7 +67,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, + 150*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index 0d896e14fb..065f0cd782 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -57,7 +57,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, + 150*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index ca5d007197..25861f0cb6 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -62,7 +62,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, + 150*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index 4e9e0bfe14..11b7bc8d24 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -52,7 +52,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, + 150*time.Second, "timeout for receipts in milliseconds", ) diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index d504793e3e..e92b6062a6 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -49,7 +49,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, + 150*time.Second, "timeout for receipts in milliseconds", ) From edc5064722a93c2e736704e92563014711fafc67 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Mon, 25 Mar 2024 12:39:10 +0100 Subject: [PATCH 35/48] unstake command fix --- command/validator/unstake/unstake.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index 065f0cd782..37ee82f9ee 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -88,7 +88,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), txrelayer.WithReceiptsPollFreq(params.txPollFreq), - txrelayer.WithReceiptsPollFreq(params.txTimeout)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err } From 2e6434308b34078a766adb29c504155be6841e24 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Mon, 25 Mar 2024 17:49:32 +0100 Subject: [PATCH 36/48] comment fix --- command/bridge/common/params.go | 12 ++---------- command/bridge/deploy/deploy.go | 15 +++------------ command/bridge/deploy/params.go | 2 -- .../bridge/deposit/erc1155/deposit_erc1155.go | 3 +-- command/bridge/deposit/erc20/deposit_erc20.go | 3 +-- command/bridge/deposit/erc721/deposit_erc721.go | 3 +-- command/bridge/exit/exit.go | 15 +++------------ command/bridge/finalize/finalize.go | 15 +++------------ command/bridge/finalize/params.go | 1 - command/bridge/fund/fund.go | 16 ++++------------ command/bridge/fund/params.go | 7 ++----- command/bridge/helper/utils.go | 1 - command/bridge/premine/params.go | 1 - command/bridge/premine/premine.go | 11 ++--------- .../bridge/withdraw/erc1155/withdraw_erc1155.go | 3 +-- command/bridge/withdraw/erc20/withdraw_erc20.go | 3 +-- .../bridge/withdraw/erc721/withdraw_erc721.go | 3 +-- command/helper/helper.go | 2 ++ command/mint/mint_erc20.go | 15 +++------------ command/mint/params.go | 1 - command/validator/registration/params.go | 1 - .../validator/registration/register_validator.go | 15 +++------------ command/validator/stake/params.go | 1 - command/validator/stake/stake.go | 11 ++--------- command/validator/unstake/params.go | 1 - command/validator/unstake/unstake.go | 11 ++--------- command/validator/validators/params.go | 1 - command/validator/validators/validator_info.go | 15 +++------------ command/validator/whitelist/params.go | 1 - .../validator/whitelist/whitelist_validators.go | 11 ++--------- command/validator/withdraw-rewards/params.go | 1 - command/validator/withdraw-rewards/rewards.go | 11 ++--------- command/validator/withdraw/params.go | 1 - command/validator/withdraw/withdraw.go | 11 ++--------- txrelayer/txrelayer.go | 6 ++++-- 35 files changed, 50 insertions(+), 180 deletions(-) diff --git a/command/bridge/common/params.go b/command/bridge/common/params.go index d733795075..49bb587596 100644 --- a/command/bridge/common/params.go +++ b/command/bridge/common/params.go @@ -37,7 +37,6 @@ const ( JSONRPCFlag = "json-rpc" ChildChainMintableFlag = "child-chain-mintable" txTimeoutFlag = "tx-timeout" - txPollFreqFlag = "tx-poll-freq" MinterKeyFlag = "minter-key" MinterKeyFlagDesc = "minter key is the account which is able to mint tokens to sender account " + @@ -57,7 +56,6 @@ type BridgeParams struct { JSONRPCAddr string ChildChainMintable bool TxTimeout time.Duration - TxPollFreq time.Duration } // RegisterCommonFlags registers common bridge flags to a given command @@ -93,16 +91,10 @@ func (p *BridgeParams) RegisterCommonFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( &p.TxTimeout, txTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", + txrelayer.DefaultTimeoutTransactions, + cmdHelper.TxTimeoutDesc, ) - cmd.Flags().DurationVar( - &p.TxPollFreq, - txPollFreqFlag, - 50*time.Millisecond, - "frequency in milliseconds for poll transactions", - ) } func (p *BridgeParams) Validate() error { diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index 620087e3a2..bd1140e05c 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -5,7 +5,6 @@ import ( "fmt" "math/big" "sync" - "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo" @@ -341,15 +340,8 @@ func GetCommand() *cobra.Command { cmd.Flags().DurationVar( ¶ms.txTimeout, txTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - txPollFreqFlag, - 50*time.Millisecond, - "frequency in milliseconds for poll transactions", + txrelayer.DefaultTimeoutTransactions, + cmdHelper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(helper.TestModeFlag, deployerKeyFlag) @@ -445,8 +437,7 @@ func runCommand(cmd *cobra.Command, _ []string) { func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, chainID int64, initialValidators []*validator.GenesisValidator, cmdCtx context.Context) (deploymentResultInfo, error) { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(client), txrelayer.WithWriter(outputter), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return deploymentResultInfo{RootchainCfg: nil, CommandResults: nil}, diff --git a/command/bridge/deploy/params.go b/command/bridge/deploy/params.go index 9f4d8344db..e130436dc6 100644 --- a/command/bridge/deploy/params.go +++ b/command/bridge/deploy/params.go @@ -15,7 +15,6 @@ const ( jsonRPCFlag = "json-rpc" erc20AddrFlag = "erc20-token" txTimeoutFlag = "tx-timeout" - txPollFreqFlag = "tx-poll-freq" ) type deployParams struct { @@ -25,7 +24,6 @@ type deployParams struct { rootERC20TokenAddr string proxyContractsAdmin string txTimeout time.Duration - txPollFreq time.Duration isTestMode bool } diff --git a/command/bridge/deposit/erc1155/deposit_erc1155.go b/command/bridge/deposit/erc1155/deposit_erc1155.go index 89e43270f1..19367135c4 100644 --- a/command/bridge/deposit/erc1155/deposit_erc1155.go +++ b/command/bridge/deposit/erc1155/deposit_erc1155.go @@ -97,8 +97,7 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(dp.TxTimeout), - txrelayer.WithReceiptsPollFreq(dp.TxPollFreq)) + txrelayer.WithReceiptsTimeout(dp.TxTimeout)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc20/deposit_erc20.go b/command/bridge/deposit/erc20/deposit_erc20.go index a6511ffdf7..4e1899c8aa 100644 --- a/command/bridge/deposit/erc20/deposit_erc20.go +++ b/command/bridge/deposit/erc20/deposit_erc20.go @@ -90,8 +90,7 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(dp.TxTimeout), - txrelayer.WithReceiptsPollFreq(dp.TxPollFreq)) + txrelayer.WithReceiptsTimeout(dp.TxTimeout)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/deposit/erc721/deposit_erc721.go b/command/bridge/deposit/erc721/deposit_erc721.go index c2ad7cf591..f28a5f8a11 100644 --- a/command/bridge/deposit/erc721/deposit_erc721.go +++ b/command/bridge/deposit/erc721/deposit_erc721.go @@ -87,8 +87,7 @@ func runCommand(cmd *cobra.Command, _ []string) { depositorAddr := depositorKey.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(dp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(dp.TxTimeout), - txrelayer.WithReceiptsPollFreq(dp.TxPollFreq)) + txrelayer.WithReceiptsTimeout(dp.TxTimeout)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index 7052d32133..af85062e64 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -26,7 +26,6 @@ const ( rootJSONRPCFlag = "root-json-rpc" childJSONRPCFlag = "child-json-rpc" txTimeoutFlag = "tx-timeout" - txPollFreqFlag = "tx-poll-freq" // generateExitProofFn is JSON RPC endpoint which creates exit proof generateExitProofFn = "bridge_generateExitProof" @@ -39,7 +38,6 @@ type exitParams struct { rootJSONRPCAddr string childJSONRPCAddr string txTimeout time.Duration - txPollFreq time.Duration } var ( @@ -93,14 +91,8 @@ func GetCommand() *cobra.Command { exitCmd.Flags().DurationVar( &ep.txTimeout, txTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", - ) - exitCmd.Flags().DurationVar( - &ep.txPollFreq, - txPollFreqFlag, - 50*time.Millisecond, - "frequency in milliseconds for poll transactions", + txrelayer.DefaultTimeoutTransactions, + cmdHelper.TxTimeoutDesc, ) _ = exitCmd.MarkFlagRequired(exitHelperFlag) @@ -120,8 +112,7 @@ func run(cmd *cobra.Command, _ []string) { } rootTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(ep.rootJSONRPCAddr), - txrelayer.WithReceiptsTimeout(ep.txTimeout), - txrelayer.WithReceiptsPollFreq(ep.txPollFreq)) + txrelayer.WithReceiptsTimeout(ep.txTimeout)) if err != nil { outputter.SetError(fmt.Errorf("could not create root chain tx relayer: %w", err)) diff --git a/command/bridge/finalize/finalize.go b/command/bridge/finalize/finalize.go index 731a4cf90b..aaec7ab629 100644 --- a/command/bridge/finalize/finalize.go +++ b/command/bridge/finalize/finalize.go @@ -5,7 +5,6 @@ import ( "fmt" "math/big" "strings" - "time" "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/command" @@ -88,15 +87,8 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 50, - "frequency in milliseconds for poll transactions", + txrelayer.DefaultTimeoutTransactions, + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -117,8 +109,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return fmt.Errorf("enlist validator failed: %w", err) } diff --git a/command/bridge/finalize/params.go b/command/bridge/finalize/params.go index 73c244646c..87db4f496f 100644 --- a/command/bridge/finalize/params.go +++ b/command/bridge/finalize/params.go @@ -18,7 +18,6 @@ type finalizeParams struct { bladeManager string genesisPath string txTimeout time.Duration - txPollFreq time.Duration bladeManagerAddr types.Address } diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index c2d17fc420..f111c1104d 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -2,7 +2,6 @@ package fund import ( "fmt" - "time" "github.com/spf13/cobra" "github.com/umbracle/ethgo" @@ -10,6 +9,7 @@ import ( "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/helper" + cmdHelper "github.com/0xPolygon/polygon-edge/command/helper" polybftsecrets "github.com/0xPolygon/polygon-edge/command/secrets/init" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -65,15 +65,8 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, txTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - txPollFreqFlag, - 50*time.Millisecond, - "frequency in milliseconds for poll transactions", + txrelayer.DefaultTimeoutTransactions, + cmdHelper.TxTimeoutDesc, ) } @@ -86,8 +79,7 @@ func runCommand(cmd *cobra.Command, _ []string) { defer outputter.WriteOutput() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/bridge/fund/params.go b/command/bridge/fund/params.go index 9cb60449ed..fc8700746e 100644 --- a/command/bridge/fund/params.go +++ b/command/bridge/fund/params.go @@ -14,7 +14,6 @@ const ( jsonRPCFlag = "json-rpc" mintStakeTokenFlag = "mint" txTimeoutFlag = "tx-timeout" - txPollFreqFlag = "tx-poll-freq" ) var ( @@ -28,10 +27,8 @@ type fundParams struct { deployerPrivateKey string jsonRPCAddress string txTimeout time.Duration - txPollFreq time.Duration - - amountValues []*big.Int - addresses []types.Address + amountValues []*big.Int + addresses []types.Address } func (fp *fundParams) validateFlags() error { diff --git a/command/bridge/helper/utils.go b/command/bridge/helper/utils.go index b16dcdecfb..b9c33ad0e6 100644 --- a/command/bridge/helper/utils.go +++ b/command/bridge/helper/utils.go @@ -40,7 +40,6 @@ const ( BladeManagerFlag = "blade-manager" BladeManagerFlagDesc = "address of blade manager contract on a rootchain" TxTimeoutFlag = "tx-timeout" - TxPollFreqFlag = "tx-poll-freq" ) var ( diff --git a/command/bridge/premine/params.go b/command/bridge/premine/params.go index 0be354f93c..68a4dc4a31 100644 --- a/command/bridge/premine/params.go +++ b/command/bridge/premine/params.go @@ -27,7 +27,6 @@ type premineParams struct { stakedAmount string premineAmount string txTimeout time.Duration - txPollFreq time.Duration premineAmountValue *big.Int stakedValue *big.Int diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index e7ee3cafa1..ba57665bf1 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -88,14 +88,7 @@ func setFlags(cmd *cobra.Command) { ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 150*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 150*time.Millisecond, - "frequency in milliseconds for poll transactions", + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -121,7 +114,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(params.txPollFreq), + txrelayer.WithReceiptsPollFreq(150*time.Second), txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err diff --git a/command/bridge/withdraw/erc1155/withdraw_erc1155.go b/command/bridge/withdraw/erc1155/withdraw_erc1155.go index 80420f908e..3e0bbaefe6 100644 --- a/command/bridge/withdraw/erc1155/withdraw_erc1155.go +++ b/command/bridge/withdraw/erc1155/withdraw_erc1155.go @@ -92,8 +92,7 @@ func runCommand(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(wp.TxTimeout), - txrelayer.WithReceiptsPollFreq(wp.TxPollFreq)) + txrelayer.WithReceiptsTimeout(wp.TxTimeout)) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc20/withdraw_erc20.go b/command/bridge/withdraw/erc20/withdraw_erc20.go index 403f3ed63c..41cc860578 100644 --- a/command/bridge/withdraw/erc20/withdraw_erc20.go +++ b/command/bridge/withdraw/erc20/withdraw_erc20.go @@ -83,8 +83,7 @@ func runCommand(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(wp.TxTimeout), - txrelayer.WithReceiptsPollFreq(wp.TxPollFreq)) + txrelayer.WithReceiptsTimeout(wp.TxTimeout)) if err != nil { outputter.SetError(fmt.Errorf("could not create destination chain tx relayer: %w", err)) diff --git a/command/bridge/withdraw/erc721/withdraw_erc721.go b/command/bridge/withdraw/erc721/withdraw_erc721.go index bfb7101e9f..af203c4659 100644 --- a/command/bridge/withdraw/erc721/withdraw_erc721.go +++ b/command/bridge/withdraw/erc721/withdraw_erc721.go @@ -83,8 +83,7 @@ func run(cmd *cobra.Command, _ []string) { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(wp.JSONRPCAddr), - txrelayer.WithReceiptsTimeout(wp.TxTimeout), - txrelayer.WithReceiptsPollFreq(wp.TxPollFreq)) + txrelayer.WithReceiptsTimeout(wp.TxTimeout)) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain tx relayer: %w", err)) diff --git a/command/helper/helper.go b/command/helper/helper.go index 13297ffe75..8262068804 100644 --- a/command/helper/helper.go +++ b/command/helper/helper.go @@ -23,6 +23,8 @@ import ( "google.golang.org/grpc/credentials/insecure" ) +const TxTimeoutDesc = "timeout for waiting for transactions to be minted" + var ErrBlockTrackerPollInterval = errors.New("block tracker poll interval must be greater than 0") type ClientCloseResult struct { diff --git a/command/mint/mint_erc20.go b/command/mint/mint_erc20.go index 7ff133eb75..06d8b54d1c 100644 --- a/command/mint/mint_erc20.go +++ b/command/mint/mint_erc20.go @@ -2,7 +2,6 @@ package mint import ( "fmt" - "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -72,15 +71,8 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 50*time.Millisecond, - "frequency in milliseconds for poll transactions", + txrelayer.DefaultTimeoutTransactions, + helper.TxTimeoutDesc, ) _ = cmd.MarkFlagRequired(bridgeHelper.Erc20TokenFlag) @@ -91,8 +83,7 @@ func runCommand(cmd *cobra.Command, _ []string) { defer outputter.WriteOutput() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPCAddress), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize tx relayer: %w", err)) diff --git a/command/mint/params.go b/command/mint/params.go index 3445fce919..1b48e8258c 100644 --- a/command/mint/params.go +++ b/command/mint/params.go @@ -18,7 +18,6 @@ type mintParams struct { minterPrivateKey string jsonRPCAddress string txTimeout time.Duration - txPollFreq time.Duration amountValues []*big.Int } diff --git a/command/validator/registration/params.go b/command/validator/registration/params.go index 58d10008b8..6adf9fd096 100644 --- a/command/validator/registration/params.go +++ b/command/validator/registration/params.go @@ -20,7 +20,6 @@ type registerParams struct { amount string stakeToken string txTimeout time.Duration - txPollFreq time.Duration amountValue *big.Int stakeTokenAddr types.Address diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 86b41280ae..b466667527 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "math/big" - "time" "github.com/0xPolygon/polygon-edge/bls" "github.com/0xPolygon/polygon-edge/command" @@ -70,15 +69,8 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 50*time.Millisecond, - "frequency in milliseconds for poll transactions", + txrelayer.DefaultTimeoutTransactions, + helper.TxTimeoutDesc, ) helper.RegisterJSONRPCFlag(cmd) @@ -101,8 +93,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err } diff --git a/command/validator/stake/params.go b/command/validator/stake/params.go index 637c8c3065..2d4b72f0cd 100644 --- a/command/validator/stake/params.go +++ b/command/validator/stake/params.go @@ -21,7 +21,6 @@ type stakeParams struct { amount string stakeToken string txTimeout time.Duration - txPollFreq time.Duration amountValue *big.Int stakeTokenAddr types.Address diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index a35b602bbb..1e1091eb4f 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -68,14 +68,7 @@ func setFlags(cmd *cobra.Command) { ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 150*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 150*time.Millisecond, - "frequency in milliseconds for poll transactions", + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -98,7 +91,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) if err != nil { return err } diff --git a/command/validator/unstake/params.go b/command/validator/unstake/params.go index 7aebe76772..317e66efe4 100644 --- a/command/validator/unstake/params.go +++ b/command/validator/unstake/params.go @@ -20,7 +20,6 @@ type unstakeParams struct { jsonRPC string amount string txTimeout time.Duration - txPollFreq time.Duration amountValue *big.Int } diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index 37ee82f9ee..b7999004f6 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -58,14 +58,7 @@ func setFlags(cmd *cobra.Command) { ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 150*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 150*time.Millisecond, - "frequency in milliseconds for poll transactions", + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -87,7 +80,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(params.txPollFreq), + txrelayer.WithReceiptsPollFreq(150*time.Millisecond), txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err diff --git a/command/validator/validators/params.go b/command/validator/validators/params.go index c5db72b9bf..7fcca7fe41 100644 --- a/command/validator/validators/params.go +++ b/command/validator/validators/params.go @@ -17,7 +17,6 @@ type validatorInfoParams struct { stakeManagerAddress string chainID int64 txTimeout time.Duration - txPollFreq time.Duration } func (v *validatorInfoParams) validateFlags() error { diff --git a/command/validator/validators/validator_info.go b/command/validator/validators/validator_info.go index 8c21b9eb3c..c9f373247a 100644 --- a/command/validator/validators/validator_info.go +++ b/command/validator/validators/validator_info.go @@ -2,7 +2,6 @@ package validators import ( "fmt" - "time" "github.com/0xPolygon/polygon-edge/command" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -57,15 +56,8 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, - 50*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 50*time.Millisecond, - "frequency in milliseconds for poll transactions", + txrelayer.DefaultTimeoutTransactions, + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -87,8 +79,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err } diff --git a/command/validator/whitelist/params.go b/command/validator/whitelist/params.go index 2313c4bf68..69a47fa71a 100644 --- a/command/validator/whitelist/params.go +++ b/command/validator/whitelist/params.go @@ -25,7 +25,6 @@ type whitelistParams struct { jsonRPC string newValidatorAddresses []string txTimeout time.Duration - txPollFreq time.Duration } func (ep *whitelistParams) validateFlags() error { diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index 25861f0cb6..e74c18040c 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -63,14 +63,7 @@ func setFlags(cmd *cobra.Command) { ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 150*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 150, - "frequency in milliseconds for poll transactions", + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -97,7 +90,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) if err != nil { return fmt.Errorf("whitelist validator failed. Could not create tx relayer: %w", err) } diff --git a/command/validator/withdraw-rewards/params.go b/command/validator/withdraw-rewards/params.go index 60767e9130..ecebb3ac73 100644 --- a/command/validator/withdraw-rewards/params.go +++ b/command/validator/withdraw-rewards/params.go @@ -14,7 +14,6 @@ type withdrawRewardsParams struct { accountConfig string jsonRPC string txTimeout time.Duration - txPollFreq time.Duration } type withdrawRewardResult struct { diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index 11b7bc8d24..1a11619fa9 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -53,14 +53,7 @@ func setFlags(cmd *cobra.Command) { ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 150*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 150*time.Millisecond, - "frequency in milliseconds for poll transactions", + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -85,7 +78,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) if err != nil { return err } diff --git a/command/validator/withdraw/params.go b/command/validator/withdraw/params.go index f246d45a45..285d0db992 100644 --- a/command/validator/withdraw/params.go +++ b/command/validator/withdraw/params.go @@ -18,7 +18,6 @@ type withdrawParams struct { accountConfig string jsonRPC string txTimeout time.Duration - txPollFreq time.Duration } func (v *withdrawParams) validateFlags() (err error) { diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index e92b6062a6..78b1f14e37 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -50,14 +50,7 @@ func setFlags(cmd *cobra.Command) { ¶ms.txTimeout, bridgeHelper.TxTimeoutFlag, 150*time.Second, - "timeout for receipts in milliseconds", - ) - - cmd.Flags().DurationVar( - ¶ms.txPollFreq, - bridgeHelper.TxPollFreqFlag, - 150, - "frequency in milliseconds for poll transactions", + helper.TxTimeoutDesc, ) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) @@ -81,7 +74,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(params.txPollFreq)) + txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) if err != nil { return err } diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 325bf82e77..1c74f1e4c4 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -23,6 +23,8 @@ const ( defaultNumRetries = 1000 gasLimitIncreasePercentage = 100 feeIncreasePercentage = 100 + DefaultTimeoutTransactions = time.Duration(50 * time.Second) + DefaultPollFreq = time.Duration(50 * time.Millisecond) ) var ( @@ -63,8 +65,8 @@ type TxRelayerImpl struct { func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { t := &TxRelayerImpl{ ipAddress: DefaultRPCAddress, - receiptsPollFreq: 50 * time.Millisecond, - receiptsTimeout: 50 * time.Second, + receiptsPollFreq: DefaultTimeoutTransactions, + receiptsTimeout: DefaultPollFreq, } for _, opt := range opts { opt(t) From 1b2b19959c485e0e29eedbb4991eabc2223f0d56 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Mon, 25 Mar 2024 18:25:25 +0100 Subject: [PATCH 37/48] test fix --- txrelayer/txrelayer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 1c74f1e4c4..b1f0296bc9 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -65,8 +65,8 @@ type TxRelayerImpl struct { func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { t := &TxRelayerImpl{ ipAddress: DefaultRPCAddress, - receiptsPollFreq: DefaultTimeoutTransactions, - receiptsTimeout: DefaultPollFreq, + receiptsPollFreq: DefaultPollFreq, + receiptsTimeout: DefaultTimeoutTransactions, } for _, opt := range opts { opt(t) From f6bc12bed567071e3d5f139a4d7178f5b778283e Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 26 Mar 2024 08:22:56 +0100 Subject: [PATCH 38/48] second to millisecond --- command/bridge/premine/premine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index ba57665bf1..3541318fea 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -114,7 +114,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(150*time.Second), + txrelayer.WithReceiptsPollFreq(150*time.Millisecond), txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err From 0c606443d615a72e2ca9955f8c76d34143132f7a Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 26 Mar 2024 08:28:17 +0100 Subject: [PATCH 39/48] linter fix --- txrelayer/txrelayer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index b1f0296bc9..6af1a075ff 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -23,8 +23,8 @@ const ( defaultNumRetries = 1000 gasLimitIncreasePercentage = 100 feeIncreasePercentage = 100 - DefaultTimeoutTransactions = time.Duration(50 * time.Second) - DefaultPollFreq = time.Duration(50 * time.Millisecond) + DefaultTimeoutTransactions = 50 * time.Second + DefaultPollFreq = 50 * time.Millisecond ) var ( From 094acccef9dc98b4be22c37fd87649563166d871 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 26 Mar 2024 09:41:48 +0100 Subject: [PATCH 40/48] comment fix --- command/bridge/premine/premine.go | 1 - command/validator/stake/stake.go | 3 +-- command/validator/unstake/unstake.go | 1 - .../whitelist/whitelist_validators.go | 3 +-- command/validator/withdraw-rewards/rewards.go | 3 +-- command/validator/withdraw/withdraw.go | 3 +-- txrelayer/txrelayer.go | 20 ++++++++++++------- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index 3541318fea..90b52abe51 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -114,7 +114,6 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(150*time.Millisecond), txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index 1e1091eb4f..534b158bed 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -90,8 +90,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err } diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index b7999004f6..f06831b7c6 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -80,7 +80,6 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsPollFreq(150*time.Millisecond), txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index e74c18040c..b238581abb 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -89,8 +89,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return fmt.Errorf("whitelist validator failed. Could not create tx relayer: %w", err) } diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index 1a11619fa9..40cec40f21 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -77,8 +77,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { validatorAddr := validatorAccount.Ecdsa.Address() txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err } diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index 78b1f14e37..a905209537 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -73,8 +73,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { } txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC), - txrelayer.WithReceiptsTimeout(params.txTimeout), - txrelayer.WithReceiptsPollFreq(150*time.Millisecond)) + txrelayer.WithReceiptsTimeout(params.txTimeout)) if err != nil { return err } diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 6af1a075ff..6b2e926ced 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -24,7 +24,7 @@ const ( gasLimitIncreasePercentage = 100 feeIncreasePercentage = 100 DefaultTimeoutTransactions = 50 * time.Second - DefaultPollFreq = 50 * time.Millisecond + DefaultPollFreq = 1 * time.Second ) var ( @@ -72,6 +72,18 @@ func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { opt(t) } + // Calculate receiptsPollFreq based on receiptsTimeout + + if t.receiptsTimeout >= time.Minute { + t.receiptsPollFreq = 2 * time.Second + } + + if t.receiptsPollFreq >= t.receiptsTimeout || t.receiptsTimeout < time.Second { + // if someone decides to configure a small receipts timeout (in ms) + // receiptsPollFreq should be less than receiptsTimeout + t.receiptsPollFreq = t.receiptsTimeout / 2 + } + if t.client == nil { client, err := jsonrpc.NewClient(t.ipAddress) if err != nil { @@ -382,12 +394,6 @@ func WithIPAddress(ipAddress string) TxRelayerOption { } } -func WithReceiptsPollFreq(receiptsPollFreq time.Duration) TxRelayerOption { - return func(t *TxRelayerImpl) { - t.receiptsPollFreq = receiptsPollFreq - } -} - func WithWriter(writer io.Writer) TxRelayerOption { return func(t *TxRelayerImpl) { t.writer = writer From a68a0b51ad13266116487f151005b8d86c340528 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 26 Mar 2024 09:42:10 +0100 Subject: [PATCH 41/48] linter --- txrelayer/txrelayer.go | 1 - 1 file changed, 1 deletion(-) diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 6b2e926ced..8f9cb6dcea 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -73,7 +73,6 @@ func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { } // Calculate receiptsPollFreq based on receiptsTimeout - if t.receiptsTimeout >= time.Minute { t.receiptsPollFreq = 2 * time.Second } From fd026a2e52a5027787f922ff58880dcba1446d84 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 26 Mar 2024 12:21:02 +0100 Subject: [PATCH 42/48] relocation of txtimeout flag --- command/bridge/common/params.go | 3 +-- command/bridge/deploy/deploy.go | 2 +- command/bridge/deploy/params.go | 1 - command/bridge/exit/exit.go | 3 +-- command/bridge/finalize/finalize.go | 2 +- command/bridge/fund/fund.go | 2 +- command/bridge/fund/params.go | 1 - command/bridge/helper/utils.go | 1 - command/bridge/premine/premine.go | 2 +- command/helper/helper.go | 5 ++++- command/mint/mint_erc20.go | 2 +- command/validator/registration/register_validator.go | 2 +- command/validator/stake/stake.go | 2 +- command/validator/unstake/unstake.go | 3 +-- command/validator/validators/validator_info.go | 2 +- command/validator/whitelist/whitelist_validators.go | 2 +- command/validator/withdraw-rewards/rewards.go | 2 +- command/validator/withdraw/withdraw.go | 2 +- 18 files changed, 18 insertions(+), 21 deletions(-) diff --git a/command/bridge/common/params.go b/command/bridge/common/params.go index 49bb587596..3f40604cd9 100644 --- a/command/bridge/common/params.go +++ b/command/bridge/common/params.go @@ -36,7 +36,6 @@ const ( ChildTokenFlag = "child-token" JSONRPCFlag = "json-rpc" ChildChainMintableFlag = "child-chain-mintable" - txTimeoutFlag = "tx-timeout" MinterKeyFlag = "minter-key" MinterKeyFlagDesc = "minter key is the account which is able to mint tokens to sender account " + @@ -90,7 +89,7 @@ func (p *BridgeParams) RegisterCommonFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( &p.TxTimeout, - txTimeoutFlag, + cmdHelper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, cmdHelper.TxTimeoutDesc, ) diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index bd1140e05c..d0b2090785 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -339,7 +339,7 @@ func GetCommand() *cobra.Command { cmd.Flags().DurationVar( ¶ms.txTimeout, - txTimeoutFlag, + cmdHelper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, cmdHelper.TxTimeoutDesc, ) diff --git a/command/bridge/deploy/params.go b/command/bridge/deploy/params.go index e130436dc6..2adc7400c9 100644 --- a/command/bridge/deploy/params.go +++ b/command/bridge/deploy/params.go @@ -14,7 +14,6 @@ const ( deployerKeyFlag = "deployer-key" jsonRPCFlag = "json-rpc" erc20AddrFlag = "erc20-token" - txTimeoutFlag = "tx-timeout" ) type deployParams struct { diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index af85062e64..0563d45bef 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -25,7 +25,6 @@ const ( exitEventIDFlag = "exit-id" rootJSONRPCFlag = "root-json-rpc" childJSONRPCFlag = "child-json-rpc" - txTimeoutFlag = "tx-timeout" // generateExitProofFn is JSON RPC endpoint which creates exit proof generateExitProofFn = "bridge_generateExitProof" @@ -90,7 +89,7 @@ func GetCommand() *cobra.Command { exitCmd.Flags().DurationVar( &ep.txTimeout, - txTimeoutFlag, + cmdHelper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, cmdHelper.TxTimeoutDesc, ) diff --git a/command/bridge/finalize/finalize.go b/command/bridge/finalize/finalize.go index aaec7ab629..a65ca0adcc 100644 --- a/command/bridge/finalize/finalize.go +++ b/command/bridge/finalize/finalize.go @@ -86,7 +86,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, helper.TxTimeoutDesc, ) diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index f111c1104d..791c2cf070 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -64,7 +64,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - txTimeoutFlag, + cmdHelper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, cmdHelper.TxTimeoutDesc, ) diff --git a/command/bridge/fund/params.go b/command/bridge/fund/params.go index fc8700746e..ea8b36e25c 100644 --- a/command/bridge/fund/params.go +++ b/command/bridge/fund/params.go @@ -13,7 +13,6 @@ import ( const ( jsonRPCFlag = "json-rpc" mintStakeTokenFlag = "mint" - txTimeoutFlag = "tx-timeout" ) var ( diff --git a/command/bridge/helper/utils.go b/command/bridge/helper/utils.go index b9c33ad0e6..0e930785ee 100644 --- a/command/bridge/helper/utils.go +++ b/command/bridge/helper/utils.go @@ -39,7 +39,6 @@ const ( Erc20TokenFlag = "erc20-token" //nolint:gosec BladeManagerFlag = "blade-manager" BladeManagerFlagDesc = "address of blade manager contract on a rootchain" - TxTimeoutFlag = "tx-timeout" ) var ( diff --git a/command/bridge/premine/premine.go b/command/bridge/premine/premine.go index 90b52abe51..78c76073b6 100644 --- a/command/bridge/premine/premine.go +++ b/command/bridge/premine/premine.go @@ -86,7 +86,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, 150*time.Second, helper.TxTimeoutDesc, ) diff --git a/command/helper/helper.go b/command/helper/helper.go index 8262068804..c3746ee664 100644 --- a/command/helper/helper.go +++ b/command/helper/helper.go @@ -23,7 +23,10 @@ import ( "google.golang.org/grpc/credentials/insecure" ) -const TxTimeoutDesc = "timeout for waiting for transactions to be minted" +const ( + TxTimeoutDesc = "timeout for waiting for transactions to be minted" + TxTimeoutFlag = "tx-timeout" +) var ErrBlockTrackerPollInterval = errors.New("block tracker poll interval must be greater than 0") diff --git a/command/mint/mint_erc20.go b/command/mint/mint_erc20.go index 06d8b54d1c..700aa6df2a 100644 --- a/command/mint/mint_erc20.go +++ b/command/mint/mint_erc20.go @@ -70,7 +70,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, helper.TxTimeoutDesc, ) diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index b466667527..8428f79386 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -68,7 +68,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, helper.TxTimeoutDesc, ) diff --git a/command/validator/stake/stake.go b/command/validator/stake/stake.go index 534b158bed..9148fdba6a 100644 --- a/command/validator/stake/stake.go +++ b/command/validator/stake/stake.go @@ -66,7 +66,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, 150*time.Second, helper.TxTimeoutDesc, ) diff --git a/command/validator/unstake/unstake.go b/command/validator/unstake/unstake.go index f06831b7c6..46a055d7e1 100644 --- a/command/validator/unstake/unstake.go +++ b/command/validator/unstake/unstake.go @@ -5,7 +5,6 @@ import ( "time" "github.com/0xPolygon/polygon-edge/command" - bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/command/helper" polybftsecrets "github.com/0xPolygon/polygon-edge/command/secrets/init" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -56,7 +55,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, 150*time.Second, helper.TxTimeoutDesc, ) diff --git a/command/validator/validators/validator_info.go b/command/validator/validators/validator_info.go index c9f373247a..9ba1c11ffc 100644 --- a/command/validator/validators/validator_info.go +++ b/command/validator/validators/validator_info.go @@ -55,7 +55,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, txrelayer.DefaultTimeoutTransactions, helper.TxTimeoutDesc, ) diff --git a/command/validator/whitelist/whitelist_validators.go b/command/validator/whitelist/whitelist_validators.go index b238581abb..e63a88e1d0 100644 --- a/command/validator/whitelist/whitelist_validators.go +++ b/command/validator/whitelist/whitelist_validators.go @@ -61,7 +61,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, 150*time.Second, helper.TxTimeoutDesc, ) diff --git a/command/validator/withdraw-rewards/rewards.go b/command/validator/withdraw-rewards/rewards.go index 40cec40f21..27b99406e9 100644 --- a/command/validator/withdraw-rewards/rewards.go +++ b/command/validator/withdraw-rewards/rewards.go @@ -51,7 +51,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, 150*time.Second, helper.TxTimeoutDesc, ) diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index a905209537..8a0250bfe3 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -48,7 +48,7 @@ func setFlags(cmd *cobra.Command) { cmd.Flags().DurationVar( ¶ms.txTimeout, - bridgeHelper.TxTimeoutFlag, + helper.TxTimeoutFlag, 150*time.Second, helper.TxTimeoutDesc, ) From c28288706736515b4401d37638653ac37409307f Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 26 Mar 2024 12:23:08 +0100 Subject: [PATCH 43/48] desc change --- command/helper/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/helper/helper.go b/command/helper/helper.go index c3746ee664..ef808d0a09 100644 --- a/command/helper/helper.go +++ b/command/helper/helper.go @@ -24,7 +24,7 @@ import ( ) const ( - TxTimeoutDesc = "timeout for waiting for transactions to be minted" + TxTimeoutDesc = "timeout for transaction processing wait" TxTimeoutFlag = "tx-timeout" ) From c8b477139f67f97d76c48d72be567fcc76bd4657 Mon Sep 17 00:00:00 2001 From: novosandara <160175841+novosandara@users.noreply.github.com> Date: Wed, 27 Mar 2024 08:44:52 +0100 Subject: [PATCH 44/48] Implemented GetHeaderByNumber and GetHeaderByHash (#149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * implemented methods: eth_getHeaderByNumber eth_getHeaderByHash. * The following methods were created: eth_createAccessList, eth_coinbase, eth_getBlockReceipts, txpool_ContentFrom * fix lint * CR fix, part 1 * CR fix, part 2 * lint fix * created UTs for methods: eth_createAccessList, eth_getBlockReceipts, txpool_ContentFrom * e2e test for eth_getBlockReceipts * e2e remove * CR fix * Remove dummy comment * CR fix * lint fix * CR fix and new tests e2e have been added * Address comments * Minor simplification * Minor changes in eth_getBlockReceipts * e2e test fix and cr fix * lint fix * e2e --------- Co-authored-by: Stefan Negovanović --- e2e-polybft/e2e/bridge_test.go | 4 +- e2e-polybft/e2e/consensus_test.go | 1 + e2e-polybft/e2e/jsonrpc_test.go | 36 +++- e2e-polybft/e2e/txpool_test.go | 3 + e2e-polybft/property/property_test.go | 3 + jsonrpc/codec_test.go | 2 + jsonrpc/dispatcher.go | 1 + jsonrpc/dispatcher_test.go | 4 + jsonrpc/eth_blockchain_test.go | 211 +++++++++++++++++++++++ jsonrpc/eth_endpoint.go | 135 ++++++++++++++- jsonrpc/eth_state_test.go | 3 + jsonrpc/filter_manager.go | 1 + jsonrpc/filter_manager_fuzz_test.go | 3 + jsonrpc/filter_manager_test.go | 13 +- jsonrpc/helper.go | 1 + jsonrpc/jsonrpc.go | 2 + jsonrpc/txpool_endpoint.go | 25 +++ jsonrpc/txpool_endpoint_test.go | 126 ++++++++++++++ jsonrpc/types.go | 89 +++++++--- jsonrpc/types_test.go | 13 +- network/identity_e2e_test.go | 1 + network/server_test.go | 4 + state/executor.go | 3 +- state/immutable-trie/copy_trie_test.go | 6 + state/immutable-trie/hasher.go | 1 + state/runtime/access_list.go | 25 +++ state/runtime/evm/bitmap.go | 1 + state/runtime/evm/bitmap_test.go | 1 + state/runtime/evm/dispatch_table.go | 1 + state/runtime/evm/dispatch_table_test.go | 1 + state/runtime/evm/evm_test.go | 3 + state/runtime/evm/instructions.go | 5 + state/runtime/evm/instructions_test.go | 5 + state/runtime/evm/state.go | 1 + state/runtime/runtime.go | 1 + state/transition_test.go | 1 + state/txn.go | 8 +- txpool/event_subscription_test.go | 5 + txpool/txpool_test.go | 45 +++++ types/rlp_marshal_storage.go | 2 + 40 files changed, 751 insertions(+), 45 deletions(-) diff --git a/e2e-polybft/e2e/bridge_test.go b/e2e-polybft/e2e/bridge_test.go index 620f389996..16964972c7 100644 --- a/e2e-polybft/e2e/bridge_test.go +++ b/e2e-polybft/e2e/bridge_test.go @@ -74,12 +74,13 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { framework.WithBridge(), framework.WithSecretsCallback(func(addrs []types.Address, tcc *framework.TestClusterConfig) { for i := 0; i < len(addrs); i++ { - tcc.StakeAmounts = append(tcc.StakeAmounts, ethgo.Ether(10)) // premine receivers, so that they are able to do withdrawals + tcc.StakeAmounts = append(tcc.StakeAmounts, ethgo.Ether(10)) } tcc.Premine = append(tcc.Premine, receivers...) })) + defer cluster.Stop() cluster.WaitForReady(t) @@ -1345,6 +1346,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { checkBalancesFn(types.Address(rewardWalletKey.Address()), bigZero, command.DefaultPremineBalance, true) validatorsExpectedBalance := new(big.Int).Sub(command.DefaultPremineBalance, command.DefaultStake) + for _, server := range cluster.Servers { validatorAccount, err := validatorHelper.GetAccountFromDir(server.DataDir()) require.NoError(t, err) diff --git a/e2e-polybft/e2e/consensus_test.go b/e2e-polybft/e2e/consensus_test.go index e55a147e76..dfd8d50561 100644 --- a/e2e-polybft/e2e/consensus_test.go +++ b/e2e-polybft/e2e/consensus_test.go @@ -398,6 +398,7 @@ func TestE2E_Consensus_MintableERC20NativeToken(t *testing.T) { config.Premine = append(config.Premine, fmt.Sprintf("%s:%d", addr, initValidatorsBalance)) config.StakeAmounts = append(config.StakeAmounts, new(big.Int).Set(initValidatorsBalance)) validatorsAddrs[i] = addr + initialTotalSupply.Add(initialTotalSupply, initValidatorsBalance) } })) diff --git a/e2e-polybft/e2e/jsonrpc_test.go b/e2e-polybft/e2e/jsonrpc_test.go index 5e6b684c30..8741c7715d 100644 --- a/e2e-polybft/e2e/jsonrpc_test.go +++ b/e2e-polybft/e2e/jsonrpc_test.go @@ -195,6 +195,7 @@ func TestE2E_JsonRPC(t *testing.T) { Value: newBalance, }) require.NoError(t, err) + txPrice := gasPrice * estimatedGas // subtract gasPrice * estimatedGas from the balance and transfer the rest to the other account // in order to leave no funds on the account @@ -413,11 +414,44 @@ func TestE2E_JsonRPC(t *testing.T) { require.NotEqual(t, ethTxn.From, ethgo.ZeroAddress) }) + t.Run("eth_getHeaderByNumber", func(t *testing.T) { + key1, err := crypto.GenerateECDSAKey() + require.NoError(t, err) + + txn := cluster.Transfer(t, senderKey, key1.Address(), one) + require.NoError(t, txn.Wait()) + require.True(t, txn.Succeed()) + txReceipt := txn.Receipt() + + var header types.Header + err = jsonRPC.Call("eth_getHeaderByNumber", &header, ethgo.BlockNumber(txReceipt.BlockNumber)) + require.NoError(t, err) + + require.Equal(t, txReceipt.BlockNumber, header.Number) + require.Equal(t, txReceipt.BlockHash, ethgo.Hash(header.Hash)) + }) + + t.Run("eth_getHeaderByHash", func(t *testing.T) { + key1, err := crypto.GenerateECDSAKey() + require.NoError(t, err) + + txn := cluster.Transfer(t, senderKey, key1.Address(), one) + require.NoError(t, txn.Wait()) + require.True(t, txn.Succeed()) + txReceipt := txn.Receipt() + + var header types.Header + err = jsonRPC.Call("eth_getHeaderByHash", &header, txReceipt.BlockHash) + require.NoError(t, err) + + require.Equal(t, txReceipt.BlockNumber, header.Number) + require.Equal(t, txReceipt.BlockHash, ethgo.Hash(header.Hash)) + }) + t.Run("debug_traceTransaction", func(t *testing.T) { key1, err := crypto.GenerateECDSAKey() require.NoError(t, err) - // Test. We should be able to query the transaction by its hash txn := cluster.Transfer(t, senderKey, key1.Address(), one) require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) diff --git a/e2e-polybft/e2e/txpool_test.go b/e2e-polybft/e2e/txpool_test.go index a636f3b855..d76d322820 100644 --- a/e2e-polybft/e2e/txpool_test.go +++ b/e2e-polybft/e2e/txpool_test.go @@ -91,7 +91,9 @@ func TestE2E_TxPool_Transfer(t *testing.T) { if err != nil { return true } + t.Logf("Balance %s %s", receiver, balance) + if balance.Uint64() != uint64(sendAmount) { return false } @@ -295,6 +297,7 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { for _, srv := range cluster.Servers { balance, err := srv.WaitForNonZeroBalance(ethgo.Address(recipient), time.Second*10) assert.NoError(t, err) + if balance != nil && balance.BitLen() > 0 { assert.Equal(t, sentAmount, balance) } else { diff --git a/e2e-polybft/property/property_test.go b/e2e-polybft/property/property_test.go index 28c518c7e1..55d7bcdc71 100644 --- a/e2e-polybft/property/property_test.go +++ b/e2e-polybft/property/property_test.go @@ -109,8 +109,11 @@ func TestProperty_DropValidators(t *testing.T) { // check that block production is stoped currentBlock, err = activeValidator.JSONRPC().Eth().BlockNumber() require.NoError(t, err) + oldBlockNumber := currentBlock + time.Sleep(2 * blockTime) + currentBlock, err = activeValidator.JSONRPC().Eth().BlockNumber() require.NoError(t, err) require.Equal(t, oldBlockNumber, currentBlock) diff --git a/jsonrpc/codec_test.go b/jsonrpc/codec_test.go index 38f41e7219..631145e237 100644 --- a/jsonrpc/codec_test.go +++ b/jsonrpc/codec_test.go @@ -105,9 +105,11 @@ func TestBlockNumberOrHash_UnmarshalJSON(t *testing.T) { assert.Error(t, err) } else { assert.NoError(t, err) + if tt.expectedBnh.BlockNumber != nil { assert.Equal(t, *bnh.BlockNumber, *tt.expectedBnh.BlockNumber) } + if tt.expectedBnh.BlockHash != nil { assert.Equal(t, bnh.BlockHash.String(), tt.expectedBnh.BlockHash.String()) } diff --git a/jsonrpc/dispatcher.go b/jsonrpc/dispatcher.go index 6199deca3c..41d1cdfd9a 100644 --- a/jsonrpc/dispatcher.go +++ b/jsonrpc/dispatcher.go @@ -212,6 +212,7 @@ func (d *Dispatcher) handleSubscribe(req Request, conn wsConn) (string, Error) { if err != nil { return "", NewInternalError(err.Error()) } + filterID = d.filterManager.NewLogFilter(logQuery, conn) } else if subscribeMethod == "newPendingTransactions" { filterID = d.filterManager.NewPendingTxFilter(conn) diff --git a/jsonrpc/dispatcher_test.go b/jsonrpc/dispatcher_test.go index 63cfc7e90d..193e4a069e 100644 --- a/jsonrpc/dispatcher_test.go +++ b/jsonrpc/dispatcher_test.go @@ -467,20 +467,24 @@ func TestDispatcherBatchRequest(t *testing.T) { assert.Equal(t, c.err, resp.Error) } else { var batchResp []SuccessResponse + assert.NoError(t, expectBatchJSONResult(res, &batchResp)) if c.name == "leading-whitespace" { assert.Len(t, batchResp, 4) + for index, resp := range batchResp { assert.Equal(t, c.batchResponse[index].Error, resp.Error) } } else if c.name == "valid-batch-req" { assert.Len(t, batchResp, 6) + for index, resp := range batchResp { assert.Equal(t, c.batchResponse[index].Error, resp.Error) } } else if c.name == "no-limits" { assert.Len(t, batchResp, 12) + for index, resp := range batchResp { assert.Equal(t, c.batchResponse[index].Error, resp.Error) } diff --git a/jsonrpc/eth_blockchain_test.go b/jsonrpc/eth_blockchain_test.go index 61c62c7b83..fd4141b13d 100644 --- a/jsonrpc/eth_blockchain_test.go +++ b/jsonrpc/eth_blockchain_test.go @@ -3,6 +3,7 @@ package jsonrpc import ( "errors" "math/big" + "strconv" "testing" "github.com/0xPolygon/polygon-edge/blockchain" @@ -68,6 +69,59 @@ func TestEth_Block_GetBlockByHash(t *testing.T) { assert.Nil(t, res) } +func TestEth_Block_GetHeaderByNumber(t *testing.T) { + store := &mockBlockStore{} + for i := 0; i < 10; i++ { + store.add(newTestBlock(uint64(i), hash1)) + } + + eth := newTestEthEndpoint(store) + + cases := []struct { + description string + blockNum BlockNumber + isNotNil bool + err bool + }{ + {"should be able to get the latest block number", LatestBlockNumber, true, false}, + {"should be able to get the earliest block number", EarliestBlockNumber, true, false}, + {"should not be able to get block with negative number", BlockNumber(-50), false, true}, + {"should be able to get block with number 0", BlockNumber(0), true, false}, + {"should be able to get block with number 2", BlockNumber(2), true, false}, + {"should be able to get block with number greater than latest block", BlockNumber(50), false, false}, + } + for _, c := range cases { + res, err := eth.GetHeaderByNumber(c.blockNum) + + if c.isNotNil { + assert.NotNil(t, res, "expected to return block, but got nil") + } else { + assert.Nil(t, res, "expected to return nil, but got data") + } + + if c.err { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + } +} + +func TestEth_Block_GetHeaderByHash(t *testing.T) { + store := &mockBlockStore{} + store.add(newTestBlock(1, hash1)) + + eth := newTestEthEndpoint(store) + + res, err := eth.GetHeaderByHash(hash1) + assert.NoError(t, err) + assert.NotNil(t, res) + + res, err = eth.GetHeaderByHash(hash2) + assert.NoError(t, err) + assert.Nil(t, res) +} + func TestEth_Block_BlockNumber(t *testing.T) { store := &mockBlockStore{} store.add(&types.Block{ @@ -261,8 +315,10 @@ func TestEth_GetTransactionReceipt(t *testing.T) { eth := newTestEthEndpoint(store) block := newTestBlock(1, hash4) store.add(block) + txn0 := newTestTransaction(uint64(0), addr0) txn1 := newTestTransaction(uint64(1), addr1) + block.Transactions = []*types.Transaction{txn0, txn1} receipt1 := &types.Receipt{ Logs: []*types.Log{ @@ -287,6 +343,7 @@ func TestEth_GetTransactionReceipt(t *testing.T) { }, } receipt1.SetStatus(types.ReceiptSuccess) + receipt2 := &types.Receipt{ Logs: []*types.Log{ { @@ -315,6 +372,68 @@ func TestEth_GetTransactionReceipt(t *testing.T) { }) } +func TestEth_GetBlockReceipts(t *testing.T) { + store := newMockBlockStore() + eth := newTestEthEndpoint(store) + block := newTestBlock(1, hash4) + store.add(block) + + txn0 := newTestTransaction(uint64(0), addr0) + txn1 := newTestTransaction(uint64(1), addr1) + + block.Transactions = []*types.Transaction{txn0, txn1} + receipt1 := &types.Receipt{ + Logs: []*types.Log{ + { + // log 0 + Topics: []types.Hash{ + hash1, + }, + }, + { + // log 1 + Topics: []types.Hash{ + hash2, + }, + }, + { + // log 2 + Topics: []types.Hash{ + hash3, + }, + }, + }, + } + receipt1.SetStatus(types.ReceiptSuccess) + + receipt2 := &types.Receipt{ + Logs: []*types.Log{ + { + // log 3 + Topics: []types.Hash{ + hash4, + }, + }, + }, + } + receipt2.SetStatus(types.ReceiptSuccess) + store.receipts[hash4] = []*types.Receipt{receipt1, receipt2} + + res, err := eth.GetBlockReceipts(1) + + assert.NoError(t, err) + assert.NotNil(t, res) + + response := res.([]*receipt) + assert.Equal(t, txn1.Hash(), response[1].TxHash) + assert.Equal(t, 2, len(response)) + assert.Equal(t, block.Hash(), response[1].BlockHash) + assert.NotNil(t, response[1].Logs) + assert.Len(t, response[1].Logs, 1) + assert.Equal(t, uint64(3), uint64(response[1].Logs[0].LogIndex)) + assert.Equal(t, uint64(1), uint64(response[1].Logs[0].TxIndex)) +} + func TestEth_Syncing(t *testing.T) { store := newMockBlockStore() eth := newTestEthEndpoint(store) @@ -508,6 +627,79 @@ func TestEth_Call(t *testing.T) { }) } +func TestEth_CreateAccessList(t *testing.T) { + store := newMockBlockStore() + hashs := make([]types.Hash, 10) + latest := LatestBlockNumber + blockNum1 := BlockNumber(1) + blockNum2 := BlockNumber(2) + + for i := 0; i < 10; i++ { + hashs[i] = types.StringToHash(strconv.Itoa(i)) + block := newTestBlock(uint64(i), hashs[i]) + block.Header.GasUsed = uint64(i * 10) + store.add(block) + } + + eth := newTestEthEndpoint(store) + + txn := &txnArgs{ + From: &addr0, + To: &addr1, + Gas: argUintPtr(100000), + GasPrice: argBytesPtr([]byte{0x64}), + Value: argBytesPtr([]byte{0x64}), + Data: nil, + Nonce: argUintPtr(0), + } + + cases := []struct { + filter BlockNumberOrHash + err bool + }{ + { + // both fields are empty + BlockNumberOrHash{}, + true, + }, + { + // return the latest block number + BlockNumberOrHash{BlockNumber: &latest}, + true, + }, + { + // specific real block number + BlockNumberOrHash{BlockNumber: &blockNum1}, + true, + }, + { + // specific block number (not found) + BlockNumberOrHash{BlockNumber: &blockNum2}, + true, + }, + { + // specific block by hash (found). By default all blocks in the mock have hash zero + BlockNumberOrHash{BlockHash: &types.ZeroHash}, + false, + }, + { + // specific block by hash (not found) + BlockNumberOrHash{BlockHash: &hashs[8]}, + true, + }, + } + + for _, c := range cases { + res, err := eth.CreateAccessList(txn, c.filter) + if c.err { + assert.NoError(t, err) + assert.NotNil(t, res) + } else { + assert.NoError(t, err) + } + } +} + type testStore interface { ethStore } @@ -558,6 +750,24 @@ func (m *mockBlockStore) appendBlocksToStore(blocks []*types.Block) { } } +func (m *mockBlockStore) GetHeaderByNumber(num uint64) (*types.Header, bool) { + block, ok := m.GetBlockByNumber(num, true) + if !ok { + return nil, false + } + + return block.Header, block.Header != nil +} + +func (m *mockBlockStore) GetHeaderByHash(hash types.Hash) (*types.Header, bool) { + block, ok := m.GetBlockByHash(hash, true) + if !ok { + return nil, false + } + + return block.Header, block.Header != nil +} + func (m *mockBlockStore) setupLogs() { m.receipts = make(map[types.Hash][]*types.Receipt) @@ -700,6 +910,7 @@ func (m *mockBlockStore) ApplyTxn(_ *types.Header, _ *types.Transaction, _ types return &runtime.ExecutionResult{ Err: m.ethCallError, ReturnValue: m.returnValue, + AccessList: runtime.NewAccessList(), }, nil } diff --git a/jsonrpc/eth_endpoint.go b/jsonrpc/eth_endpoint.go index 8b2978aea9..c2b7e66f09 100644 --- a/jsonrpc/eth_endpoint.go +++ b/jsonrpc/eth_endpoint.go @@ -53,6 +53,9 @@ type ethBlockchainStore interface { // GetBlockByHash gets a block using the provided hash GetBlockByHash(hash types.Hash, full bool) (*types.Block, bool) + // GetHeaderByHash returns the header by his hash + GetHeaderByHash(hash types.Hash) (*types.Header, bool) + // GetBlockByNumber returns a block using the provided number GetBlockByNumber(num uint64, full bool) (*types.Block, bool) @@ -155,23 +158,106 @@ func (e *Eth) GetBlockByHash(hash types.Hash, fullTx bool) (interface{}, error) return toBlock(block, fullTx), nil } -func (e *Eth) filterExtra(block *types.Block) error { +// GetHeaderByNumber returns the requested canonical block header. +func (e *Eth) GetHeaderByNumber(number BlockNumber) (interface{}, error) { + num, err := GetNumericBlockNumber(number, e.store) + if err != nil { + return nil, err + } + + header, ok := e.store.GetHeaderByNumber(num) + if !ok { + return nil, nil + } + + headerCopy, err := e.headerFilterExtra(header) + if err != nil { + return nil, err + } + + return toHeader(headerCopy), nil +} + +// GetHeaderByHash returns the requested header by hash. +func (e *Eth) GetHeaderByHash(hash types.Hash) (interface{}, error) { + header, ok := e.store.GetHeaderByHash(hash) + if !ok { + return nil, nil + } + + headerCopy, err := e.headerFilterExtra(header) + if err != nil { + return nil, err + } + + return toHeader(headerCopy), nil +} + +func (e *Eth) headerFilterExtra(header *types.Header) (*types.Header, error) { // we need to copy it because the store returns header from storage directly // and not a copy, so changing it, actually changes it in storage as well - headerCopy := block.Header.Copy() + headerCopy := header.Copy() filteredExtra, err := e.store.FilterExtra(headerCopy.ExtraData) if err != nil { - return err + return nil, err } headerCopy.ExtraData = filteredExtra + + return headerCopy, err +} + +func (e *Eth) filterExtra(block *types.Block) error { + headerCopy, err := e.headerFilterExtra(block.Header) + if err != nil { + return err + } + // no need to recompute hash (filtered out data is not in the hash in the first place) block.Header = headerCopy return nil } +// CreateAccessList creates a EIP-2930 type AccessList for the given transaction. +// Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. +func (e *Eth) CreateAccessList(arg *txnArgs, filter BlockNumberOrHash) (interface{}, error) { + header, err := GetHeaderFromBlockNumberOrHash(filter, e.store) + if err != nil { + return nil, err + } + + transaction, err := DecodeTxn(arg, header.Number, e.store, true) + if err != nil { + return nil, err + } + + // If the caller didn't supply the gas limit in the message, then we set it to maximum possible => block gas limit + if transaction.Gas() == 0 { + transaction.SetGas(header.GasLimit) + } + + // Force transaction gas price if empty + if err = e.fillTransactionGasPrice(transaction); err != nil { + return nil, err + } + + // The return value of the execution is saved in the transition (returnValue field) + result, err := e.store.ApplyTxn(header, transaction, nil, true) + if err != nil { + return nil, err + } + + res := &accessListResult{ + Accesslist: result.AccessList.ToTxAccessList(), + Error: result.Err, + GasUsed: argUint64(result.GasUsed), + } + + return res, nil +} + // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. func (e *Eth) GetBlockTransactionCountByHash(blockHash types.Hash) (interface{}, error) { block, ok := e.store.GetBlockByHash(blockHash, true) @@ -226,7 +312,7 @@ func (e *Eth) GetTransactionByBlockHashAndIndex(blockHash types.Hash, index argU func (e *Eth) BlockNumber() (interface{}, error) { h := e.store.Header() if h == nil { - return nil, fmt.Errorf("header has a nil value") + return nil, ErrHeaderNotFound } return argUintPtr(h.Number), nil @@ -375,6 +461,47 @@ func (e *Eth) GetTransactionReceipt(hash types.Hash) (interface{}, error) { return toReceipt(raw, txn, uint64(txIndex), block.Header, logs), nil } +// GetBlockReceipts returns all transaction receipts for a given block. +func (e *Eth) GetBlockReceipts(number BlockNumber) (interface{}, error) { + num, err := GetNumericBlockNumber(number, e.store) + if err != nil { + return nil, err + } + + block, ok := e.store.GetBlockByNumber(num, true) + if !ok { + return nil, ErrBlockNotFound + } + + if len(block.Transactions) == 0 { + return nil, nil + } + + receipts, err := e.store.GetReceiptsByHash(block.Hash()) + if err != nil { + return nil, err + } + + receiptsNum := len(receipts) + if receiptsNum == 0 { + return nil, nil + } + + resReceipts := make([]*receipt, receiptsNum) + logIndex := 0 + + for i, transaction := range block.Transactions { + raw := receipts[i] + // accumulate receipt logs indices from block transactions + // that are before the desired transaction + logs := toLogs(raw.Logs, uint64(logIndex), uint64(i), block.Header, raw.TxHash) + resReceipts[i] = toReceipt(raw, transaction, uint64(i), block.Header, logs) + logIndex += len(raw.Logs) + } + + return resReceipts, nil +} + // GetStorageAt returns the contract storage at the index position func (e *Eth) GetStorageAt( address types.Address, diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index f931294145..858681a562 100644 --- a/jsonrpc/eth_state_test.go +++ b/jsonrpc/eth_state_test.go @@ -131,6 +131,7 @@ func TestEth_State_GetBalance(t *testing.T) { assert.Equal(t, nil, balance) } else { assert.NoError(t, err) + if tt.expectedBalance == 0 { uintBalance, ok := balance.(*argUint64) if !ok { @@ -383,6 +384,7 @@ func TestEth_State_GetCode(t *testing.T) { assert.Error(t, err) } else { assert.NoError(t, err) + if tt.target.String() == uninitializedAddress.String() { assert.Equal(t, "0x", code) } else { @@ -553,6 +555,7 @@ func TestEth_State_GetStorageAt(t *testing.T) { storage: make(map[types.Hash][]byte), } account := store.account + for index, data := range storage { account.Storage(index, data.Bytes()) } diff --git a/jsonrpc/filter_manager.go b/jsonrpc/filter_manager.go index 03bacde8ff..b33c293177 100644 --- a/jsonrpc/filter_manager.go +++ b/jsonrpc/filter_manager.go @@ -973,6 +973,7 @@ func (h *headElem) getUpdates() ([]*block, *headElem) { if nextElem.header != nil { res = append(res, nextElem.header) } + cur = nextElem } } diff --git a/jsonrpc/filter_manager_fuzz_test.go b/jsonrpc/filter_manager_fuzz_test.go index d9e7d68da9..45b44d32e3 100644 --- a/jsonrpc/filter_manager_fuzz_test.go +++ b/jsonrpc/filter_manager_fuzz_test.go @@ -90,6 +90,7 @@ func FuzzGetLogsForQuery(f *testing.F) { if len(hash) != types.HashLength { t.Skip() } + blockHash := types.BytesToHash(hash) logQuery := LogQuery{ @@ -145,6 +146,7 @@ func FuzzGetLogFilterFromID(f *testing.F) { if len(address) != types.AddressLength { t.Skip() } + logFilter := &LogQuery{ Addresses: []types.Address{types.BytesToAddress(address)}, toBlock: BlockNumber(toBlock), @@ -153,6 +155,7 @@ func FuzzGetLogFilterFromID(f *testing.F) { retrivedLogFilter, err := m.GetLogFilterFromID( m.NewLogFilter(logFilter, &MockClosedWSConnection{}), ) + if err != nil { assert.Equal(t, logFilter, retrivedLogFilter.query) } diff --git a/jsonrpc/filter_manager_test.go b/jsonrpc/filter_manager_test.go index 48e43aca9c..e22dd9cfc8 100644 --- a/jsonrpc/filter_manager_test.go +++ b/jsonrpc/filter_manager_test.go @@ -661,13 +661,13 @@ func newMockWsConnWithMsgCh() (*mockWsConn, <-chan []byte) { func TestHeadStream_Basic(t *testing.T) { t.Parallel() - b := newBlockStream(&block{Hash: types.StringToHash("1")}) - b.push(&block{Hash: types.StringToHash("2")}) + b := newBlockStream(&block{header: header{Hash: types.StringToHash("1")}}) + b.push(&block{header: header{Hash: types.StringToHash("2")}}) cur := b.getHead() - b.push(&block{Hash: types.StringToHash("3")}) - b.push(&block{Hash: types.StringToHash("4")}) + b.push(&block{header: header{Hash: types.StringToHash("3")}}) + b.push(&block{header: header{Hash: types.StringToHash("4")}}) // get the updates, there are two new entries updates, next := cur.getUpdates() @@ -686,7 +686,7 @@ func TestHeadStream_Concurrent(t *testing.T) { nReaders := 20 nMessages := 10 - b := newBlockStream(&block{Number: 0}) + b := newBlockStream(&block{header: header{Number: 0}}) // Write co-routine with jitter go func() { @@ -696,7 +696,7 @@ func TestHeadStream_Concurrent(t *testing.T) { z := rand.NewZipf(rand.New(rand.NewSource(seed)), 1.5, 1.5, 50) for i := 0; i < nMessages; i++ { - b.push(&block{Number: argUint64(i)}) + b.push(&block{header: header{Number: argUint64(i)}}) wait := time.Duration(z.Uint64()) * time.Millisecond time.Sleep(wait) @@ -723,6 +723,7 @@ func TestHeadStream_Concurrent(t *testing.T) { return } + expect++ if expect == uint64(nMessages) { diff --git a/jsonrpc/helper.go b/jsonrpc/helper.go index 2b67fb43a3..5db6f5cdbf 100644 --- a/jsonrpc/helper.go +++ b/jsonrpc/helper.go @@ -195,6 +195,7 @@ func DecodeTxn(arg *txnArgs, blockNumber uint64, store nonceGetter, forceSetNonc if err != nil { return nil, err } + arg.Nonce = argUintPtr(nonce) } diff --git a/jsonrpc/jsonrpc.go b/jsonrpc/jsonrpc.go index c478eab397..aa238e0696 100644 --- a/jsonrpc/jsonrpc.go +++ b/jsonrpc/jsonrpc.go @@ -129,6 +129,7 @@ func (j *JSONRPC) setupHTTP() error { } j.logger.Info("http server started", "addr", j.config.Addr.String()) + return nil } @@ -151,6 +152,7 @@ func middlewareFactory(config *Config) func(http.Handler) http.Handler { break } } + next.ServeHTTP(w, r) }) } diff --git a/jsonrpc/txpool_endpoint.go b/jsonrpc/txpool_endpoint.go index 5c2bb5e69f..c2ecc6aac1 100644 --- a/jsonrpc/txpool_endpoint.go +++ b/jsonrpc/txpool_endpoint.go @@ -29,6 +29,11 @@ type ContentResponse struct { Queued map[types.Address]map[uint64]*transaction `json:"queued"` } +type ContentAddressResponse struct { + Pending map[uint64]*transaction `json:"pending"` + Queued map[uint64]*transaction `json:"queued"` +} + type InspectResponse struct { Pending map[string]map[string]string `json:"pending"` Queued map[string]map[string]string `json:"queued"` @@ -41,6 +46,26 @@ type StatusResponse struct { Queued uint64 `json:"queued"` } +// ContentFrom returns the transactions contained within the transaction pool. +func (t *TxPool) ContentFrom(addr types.Address) (interface{}, error) { + convertTxMap := func(txs []*types.Transaction) map[uint64]*transaction { + result := make(map[uint64]*transaction, len(txs)) + for _, tx := range txs { + result[tx.Nonce()] = toTransaction(tx, nil, &types.ZeroHash, nil) + } + + return result + } + + pendingTxs, queuedTxs := t.store.GetTxs(true) + resp := ContentAddressResponse{ + Pending: convertTxMap(pendingTxs[addr]), + Queued: convertTxMap(queuedTxs[addr]), + } + + return resp, nil +} + // Create response for txpool_content request. // See https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content. func (t *TxPool) Content() (interface{}, error) { diff --git a/jsonrpc/txpool_endpoint_test.go b/jsonrpc/txpool_endpoint_test.go index a46dae8e17..430f38f93e 100644 --- a/jsonrpc/txpool_endpoint_test.go +++ b/jsonrpc/txpool_endpoint_test.go @@ -152,6 +152,132 @@ func TestContentEndpoint(t *testing.T) { }) } +func TestContentFrom(t *testing.T) { + t.Parallel() + + t.Run("returns empty ContentAddressResponse if tx pool has no transactions", func(t *testing.T) { + t.Parallel() + + mockStore := newMockTxPoolStore() + txPoolEndpoint := &TxPool{mockStore} + address := types.Address{0x0} + result, _ := txPoolEndpoint.ContentFrom(address) + + response := result.(ContentAddressResponse) + + assert.True(t, mockStore.includeQueued) + assert.Equal(t, 0, len(response.Pending)) + assert.Equal(t, 0, len(response.Queued)) + }) + + t.Run("returns the correct data for the correct address", func(t *testing.T) { + t.Parallel() + + mockStore := newMockTxPoolStore() + address1 := types.Address{0x1} + testTx1 := newTestTransaction(2, address1) + testTx2 := newTestDynamicFeeTransaction(3, address1) + mockStore.pending[address1] = []*types.Transaction{testTx1, testTx2} + txPoolEndpoint := &TxPool{mockStore} + + result, _ := txPoolEndpoint.ContentFrom(address1) + response := result.(ContentAddressResponse) + + assert.Equal(t, 0, len(response.Queued)) + assert.Equal(t, 2, len(response.Pending)) + + txData := response.Pending[testTx1.Nonce()] + assert.NotNil(t, txData) + assert.Equal(t, testTx1.Gas(), uint64(txData.Gas)) + assert.Equal(t, *(testTx1.GasPrice()), big.Int(*txData.GasPrice)) + assert.Equal(t, *(testTx1.GasFeeCap()), big.Int(*txData.GasPrice)) + assert.Equal(t, *(testTx1.GasTipCap()), big.Int(*txData.GasPrice)) + assert.Equal(t, testTx1.To(), txData.To) + assert.Equal(t, testTx1.From(), txData.From) + assert.Equal(t, *(testTx1.Value()), big.Int(txData.Value)) + assert.Equal(t, testTx1.Input(), []byte(txData.Input)) + assert.Equal(t, (*argUint64)(nil), txData.BlockNumber) + assert.Equal(t, (*argUint64)(nil), txData.TxIndex) + + txData = response.Pending[testTx2.Nonce()] + assert.NotNil(t, txData) + assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) + assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) + assert.Nil(t, testTx2.GasPrice()) + assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) + assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) + assert.Equal(t, testTx2.To(), txData.To) + assert.Equal(t, testTx2.From(), txData.From) + assert.Equal(t, *(testTx2.ChainID()), big.Int(*txData.ChainID)) + assert.Equal(t, *(testTx2.Value()), big.Int(txData.Value)) + assert.Equal(t, testTx2.Input(), []byte(txData.Input)) + assert.Equal(t, (*argUint64)(nil), txData.BlockNumber) + assert.Equal(t, (*argUint64)(nil), txData.TxIndex) + }) + + t.Run("returns correct data for queued transaction", func(t *testing.T) { + t.Parallel() + + mockStore := newMockTxPoolStore() + address1, address2 := types.Address{0x1}, types.Address{0x2} + testTx1 := newTestTransaction(2, address1) + testTx2 := newTestDynamicFeeTransaction(1, address2) + mockStore.queued[address1] = []*types.Transaction{testTx1} + mockStore.queued[address2] = []*types.Transaction{testTx2} + txPoolEndpoint := &TxPool{mockStore} + + result, err := txPoolEndpoint.ContentFrom(address2) + assert.NoError(t, err) + + response := result.(ContentAddressResponse) + assert.Equal(t, 1, len(response.Queued)) + + txData := response.Queued[testTx2.Nonce()] + assert.NotNil(t, txData) + assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) + assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) + assert.Nil(t, testTx2.GasPrice()) + assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) + assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) + assert.Equal(t, testTx2.To(), txData.To) + assert.Equal(t, testTx2.From(), txData.From) + assert.Equal(t, *(testTx2.ChainID()), big.Int(*txData.ChainID)) + assert.Equal(t, *(testTx2.Value()), big.Int(txData.Value)) + assert.Equal(t, testTx2.Input(), []byte(txData.Input)) + assert.Equal(t, (*argUint64)(nil), txData.BlockNumber) + assert.Equal(t, (*argUint64)(nil), txData.TxIndex) + }) + + t.Run("returns correct ContentAddressResponse data for multiple transactions", func(t *testing.T) { + t.Parallel() + + mockStore := newMockTxPoolStore() + address1 := types.Address{0x1} + testTx1 := newTestTransaction(2, address1) + testTx2 := newTestTransaction(4, address1) + testTx3 := newTestTransaction(11, address1) + address2 := types.Address{0x2} + testTx4 := newTestTransaction(7, address2) + testTx5 := newTestTransaction(8, address2) + mockStore.pending[address1] = []*types.Transaction{testTx1, testTx2} + mockStore.pending[address2] = []*types.Transaction{testTx4} + mockStore.queued[address1] = []*types.Transaction{testTx3} + mockStore.queued[address2] = []*types.Transaction{testTx5} + txPoolEndpoint := &TxPool{mockStore} + + result, err := txPoolEndpoint.ContentFrom(address2) + assert.NoError(t, err) + + response := result.(ContentAddressResponse) + + assert.True(t, mockStore.includeQueued) + assert.Equal(t, 1, len(response.Pending)) + assert.Equal(t, testTx4.Hash(), response.Pending[testTx4.Nonce()].Hash) + assert.Equal(t, 1, len(response.Queued)) + assert.Equal(t, testTx5.Hash(), response.Queued[testTx5.Nonce()].Hash) + }) +} + func TestInspectEndpoint(t *testing.T) { t.Parallel() diff --git a/jsonrpc/types.go b/jsonrpc/types.go index 46b98b7cfd..a8055ae791 100644 --- a/jsonrpc/types.go +++ b/jsonrpc/types.go @@ -112,28 +112,38 @@ func toTransaction( return res } +type header struct { + ParentHash types.Hash `json:"parentHash"` + Sha3Uncles types.Hash `json:"sha3Uncles"` + Miner argBytes `json:"miner"` + StateRoot types.Hash `json:"stateRoot"` + TxRoot types.Hash `json:"transactionsRoot"` + ReceiptsRoot types.Hash `json:"receiptsRoot"` + LogsBloom types.Bloom `json:"logsBloom"` + Difficulty argUint64 `json:"difficulty"` + TotalDifficulty argUint64 `json:"totalDifficulty"` + Number argUint64 `json:"number"` + GasLimit argUint64 `json:"gasLimit"` + GasUsed argUint64 `json:"gasUsed"` + Timestamp argUint64 `json:"timestamp"` + ExtraData argBytes `json:"extraData"` + MixHash types.Hash `json:"mixHash"` + Nonce types.Nonce `json:"nonce"` + Hash types.Hash `json:"hash"` + BaseFee argUint64 `json:"baseFeePerGas,omitempty"` +} + +type accessListResult struct { + Accesslist types.TxAccessList `json:"accessList"` + Error error `json:"error,omitempty"` + GasUsed argUint64 `json:"gasUsed"` +} + type block struct { - ParentHash types.Hash `json:"parentHash"` - Sha3Uncles types.Hash `json:"sha3Uncles"` - Miner argBytes `json:"miner"` - StateRoot types.Hash `json:"stateRoot"` - TxRoot types.Hash `json:"transactionsRoot"` - ReceiptsRoot types.Hash `json:"receiptsRoot"` - LogsBloom types.Bloom `json:"logsBloom"` - Difficulty argUint64 `json:"difficulty"` - TotalDifficulty argUint64 `json:"totalDifficulty"` - Size argUint64 `json:"size"` - Number argUint64 `json:"number"` - GasLimit argUint64 `json:"gasLimit"` - GasUsed argUint64 `json:"gasUsed"` - Timestamp argUint64 `json:"timestamp"` - ExtraData argBytes `json:"extraData"` - MixHash types.Hash `json:"mixHash"` - Nonce types.Nonce `json:"nonce"` - Hash types.Hash `json:"hash"` - Transactions []transactionOrHash `json:"transactions"` - Uncles []types.Hash `json:"uncles"` - BaseFee argUint64 `json:"baseFeePerGas,omitempty"` + header + Size argUint64 `json:"size"` + Transactions []transactionOrHash `json:"transactions"` + Uncles []types.Hash `json:"uncles"` } func (b *block) Copy() *block { @@ -151,7 +161,7 @@ func (b *block) Copy() *block { func toBlock(b *types.Block, fullTx bool) *block { h := b.Header - res := &block{ + resHeader := header{ ParentHash: h.ParentHash, Sha3Uncles: h.Sha3Uncles, Miner: argBytes(h.Miner), @@ -161,7 +171,6 @@ func toBlock(b *types.Block, fullTx bool) *block { LogsBloom: h.LogsBloom, Difficulty: argUint64(h.Difficulty), TotalDifficulty: argUint64(h.Difficulty), // not needed for POS - Size: argUint64(b.Size()), Number: argUint64(h.Number), GasLimit: argUint64(h.GasLimit), GasUsed: argUint64(h.GasUsed), @@ -170,11 +179,16 @@ func toBlock(b *types.Block, fullTx bool) *block { MixHash: h.MixHash, Nonce: h.Nonce, Hash: h.Hash, - Transactions: []transactionOrHash{}, - Uncles: []types.Hash{}, BaseFee: argUint64(h.BaseFee), } + res := &block{ + header: resHeader, + Size: argUint64(b.Size()), + Transactions: []transactionOrHash{}, + Uncles: []types.Hash{}, + } + for idx, txn := range b.Transactions { if fullTx { txn.SetGasPrice(txn.GetGasPrice(b.Header.BaseFee)) @@ -202,6 +216,31 @@ func toBlock(b *types.Block, fullTx bool) *block { return res } +func toHeader(h *types.Header) *header { + res := &header{ + ParentHash: h.ParentHash, + Sha3Uncles: h.Sha3Uncles, + Miner: argBytes(h.Miner), + StateRoot: h.StateRoot, + TxRoot: h.TxRoot, + ReceiptsRoot: h.ReceiptsRoot, + LogsBloom: h.LogsBloom, + Difficulty: argUint64(h.Difficulty), + TotalDifficulty: argUint64(h.Difficulty), // not needed for POS + Number: argUint64(h.Number), + GasLimit: argUint64(h.GasLimit), + GasUsed: argUint64(h.GasUsed), + Timestamp: argUint64(h.Timestamp), + ExtraData: argBytes(h.ExtraData), + MixHash: h.MixHash, + Nonce: h.Nonce, + Hash: h.Hash, + BaseFee: argUint64(h.BaseFee), + } + + return res +} + type receipt struct { Root types.Hash `json:"root"` CumulativeGasUsed argUint64 `json:"cumulativeGasUsed"` diff --git a/jsonrpc/types_test.go b/jsonrpc/types_test.go index 3b6da3a0ba..286b4cbf3c 100644 --- a/jsonrpc/types_test.go +++ b/jsonrpc/types_test.go @@ -156,9 +156,12 @@ func TestToTransaction_EIP1559(t *testing.T) { func TestBlock_Copy(t *testing.T) { b := &block{ - ExtraData: []byte{0x1}, - Miner: []byte{0x2}, - Uncles: []types.Hash{{0x0, 0x1}}, + header: header{ + ExtraData: []byte{0x1}, + Miner: []byte{0x2}, + }, + + Uncles: []types.Hash{{0x0, 0x1}}, } bb := b.Copy() @@ -170,7 +173,7 @@ var testsuite embed.FS func TestBlock_Encoding(t *testing.T) { getBlock := func() block { - return block{ + return block{header: header{ ParentHash: types.Hash{0x1}, Sha3Uncles: types.Hash{0x2}, Miner: types.Address{0x1}.Bytes(), @@ -188,7 +191,7 @@ func TestBlock_Encoding(t *testing.T) { Nonce: types.Nonce{10}, Hash: types.Hash{0x8}, BaseFee: 15, - } + }} } testBlock := func(name string, b block) { diff --git a/network/identity_e2e_test.go b/network/identity_e2e_test.go index 6d6f7c3ed2..7d493b050a 100644 --- a/network/identity_e2e_test.go +++ b/network/identity_e2e_test.go @@ -45,6 +45,7 @@ func TestIdentityHandshake(t *testing.T) { }, } servers, createErr := createServers(2, params) + if createErr != nil { t.Fatalf("Unable to create servers, %v", createErr) } diff --git a/network/server_test.go b/network/server_test.go index 43f06582a6..c458b5f3b4 100644 --- a/network/server_test.go +++ b/network/server_test.go @@ -654,6 +654,7 @@ func TestRunDial(t *testing.T) { t.Fatalf("Unable to join peer, %v", joinErr) } } + closeServers(servers...) }) @@ -674,6 +675,7 @@ func TestRunDial(t *testing.T) { assert.Error(t, joinErr) } } + closeServers(servers...) }) @@ -766,6 +768,7 @@ func TestSubscribe(t *testing.T) { server := setupServer(t, true) ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(func() { cancel() }) @@ -801,6 +804,7 @@ func TestSubscribe(t *testing.T) { server := setupServer(t, false) ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(func() { cancel() }) diff --git a/state/executor.go b/state/executor.go index 4f094c0c86..5274549368 100644 --- a/state/executor.go +++ b/state/executor.go @@ -667,6 +667,8 @@ func (t *Transition) apply(msg *types.Transaction) (*runtime.ExecutionResult, er result = t.Call2(msg.From(), *(msg.To()), msg.Input(), value, gasLeft) } + result.AccessList = t.accessList + refundQuotient := LegacyRefundQuotient if t.config.London { refundQuotient = LondonRefundQuotient @@ -882,7 +884,6 @@ func (t *Transition) applyCreate(c *runtime.Contract, host runtime.Host) *runtim } } - //Berlin: check // we add this to the access-list before taking a snapshot. Even if the creation fails, // the access-list change should not be rolled back according to EIP2929 specs if t.config.Berlin { diff --git a/state/immutable-trie/copy_trie_test.go b/state/immutable-trie/copy_trie_test.go index 4d678f5eed..7faa764d8f 100644 --- a/state/immutable-trie/copy_trie_test.go +++ b/state/immutable-trie/copy_trie_test.go @@ -14,9 +14,11 @@ func TestCompareModelOfTrieCopy(t *testing.T) { ldbStorageOld := ldbstorage.NewMemStorage() ldbStorageNew := ldbstorage.NewMemStorage() ldb, err := leveldb.Open(ldbStorageOld, nil) + if err != nil { t.Fatal(err) } + defer ldb.Close() ldbNew, err := leveldb.Open(ldbStorageNew, nil) @@ -39,11 +41,14 @@ func TestCompareModelOfTrieCopy(t *testing.T) { } tx.Commit() + stateRoot := trie.Hash() result, err := HashChecker(stateRoot.Bytes(), kv) + if err != nil { t.Fatal(err) } + if stateRoot != result { t.Fatal("Hashes are not equal", stateRoot, result) } @@ -57,6 +62,7 @@ func TestCompareModelOfTrieCopy(t *testing.T) { if err != nil { t.Error(err) } + if stateRoot != result { t.Error("Hashes are not equal", stateRoot, result) } diff --git a/state/immutable-trie/hasher.go b/state/immutable-trie/hasher.go index 38ea53350c..aa5b80a8e3 100644 --- a/state/immutable-trie/hasher.go +++ b/state/immutable-trie/hasher.go @@ -117,6 +117,7 @@ func (t *Txn) Hash() ([]byte, error) { } } else { tmp := val.MarshalTo(nil) + h.hash.Reset() h.hash.Write(tmp) diff --git a/state/runtime/access_list.go b/state/runtime/access_list.go index 8b806931a5..7471829932 100644 --- a/state/runtime/access_list.go +++ b/state/runtime/access_list.go @@ -113,3 +113,28 @@ func (al *AccessList) DeleteSlot(address types.Address, slot types.Hash) { delete(slotMap, slot) } } + +// ToTxAccessList converts access list from internal representation to the types.TxAccessList +func (al *AccessList) ToTxAccessList() types.TxAccessList { + convertToKeysSlice := func(m map[types.Hash]struct{}) []types.Hash { + storageKeys := make([]types.Hash, 0, len(m)) + for key := range m { + storageKeys = append(storageKeys, key) + } + + return storageKeys + } + + result := make(types.TxAccessList, 0, len(*al)) + for address, storageKeys := range *al { + result = append( + result, + types.AccessTuple{ + Address: address, + StorageKeys: convertToKeysSlice(storageKeys), + }, + ) + } + + return result +} diff --git a/state/runtime/evm/bitmap.go b/state/runtime/evm/bitmap.go index ae6929ea57..7a830bc806 100644 --- a/state/runtime/evm/bitmap.go +++ b/state/runtime/evm/bitmap.go @@ -39,6 +39,7 @@ func (b *bitmap) setCode(code []byte) { // jumpdest b.set(uint64(i)) } + i++ } } diff --git a/state/runtime/evm/bitmap_test.go b/state/runtime/evm/bitmap_test.go index 932fc69a39..b4f6809fb6 100644 --- a/state/runtime/evm/bitmap_test.go +++ b/state/runtime/evm/bitmap_test.go @@ -13,6 +13,7 @@ func TestIsPush(t *testing.T) { if !strings.HasPrefix(OpCode(i).String(), "PUSH") { t.Fatal("err") } + num++ } } diff --git a/state/runtime/evm/dispatch_table.go b/state/runtime/evm/dispatch_table.go index ec7b44b4c5..e7b45264b1 100644 --- a/state/runtime/evm/dispatch_table.go +++ b/state/runtime/evm/dispatch_table.go @@ -22,6 +22,7 @@ func registerRange(from, to OpCode, factory func(n int) instruction, gas uint64) c := 1 for i := from; i <= to; i++ { register(i, handler{factory(c), 0, gas}) + c++ } } diff --git a/state/runtime/evm/dispatch_table_test.go b/state/runtime/evm/dispatch_table_test.go index a3dfe906a6..9c296660aa 100644 --- a/state/runtime/evm/dispatch_table_test.go +++ b/state/runtime/evm/dispatch_table_test.go @@ -29,6 +29,7 @@ func TestPushOpcodes(t *testing.T) { assert.Len(t, res, c) assert.True(t, bytes.HasPrefix(code[1:], res)) + c++ } } diff --git a/state/runtime/evm/evm_test.go b/state/runtime/evm/evm_test.go index 6b20b48e29..f690305fcb 100644 --- a/state/runtime/evm/evm_test.go +++ b/state/runtime/evm/evm_test.go @@ -237,9 +237,11 @@ func TestRun(t *testing.T) { contract := newMockContract(tt.value, tt.gas, tt.code) host := &mockHost{} config := tt.config + if config == nil { config = &chain.ForksInTime{} } + res := evm.Run(contract, host, config) assert.Equal(t, tt.expected, res) }) @@ -408,6 +410,7 @@ func TestRunWithTracer(t *testing.T) { host := &mockHost{ tracer: tracer, } + config := tt.config if config == nil { config = &chain.ForksInTime{} diff --git a/state/runtime/evm/instructions.go b/state/runtime/evm/instructions.go index 8fc6d3bb19..b7d369b648 100644 --- a/state/runtime/evm/instructions.go +++ b/state/runtime/evm/instructions.go @@ -88,9 +88,11 @@ func opSDiv(c *state) { } else { neg := a.Sign() != b.Sign() b.Div(a.Abs(a), b.Abs(b)) + if neg { b.Neg(b) } + toU256(b) } } @@ -118,9 +120,11 @@ func opSMod(c *state) { } else { neg := a.Sign() < 0 b.Mod(a.Abs(a), b.Abs(b)) + if neg { b.Neg(b) } + toU256(b) } } @@ -1347,6 +1351,7 @@ func (c *state) buildCallContract(op OpCode) (*runtime.Contract, uint64, uint64, return nil, 0, 0, nil } + gas = initialGas.Uint64() } diff --git a/state/runtime/evm/instructions_test.go b/state/runtime/evm/instructions_test.go index 143921b989..74fa195204 100644 --- a/state/runtime/evm/instructions_test.go +++ b/state/runtime/evm/instructions_test.go @@ -639,6 +639,7 @@ func TestSStore(t *testing.T) { mockHost := &mockHost{} mockHost.On("SetStorage", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(runtime.StorageUnchanged).Once() + s.host = mockHost s.push(one) @@ -659,6 +660,7 @@ func TestSStore(t *testing.T) { mockHost := &mockHost{} mockHost.On("SetStorage", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(runtime.StorageModified).Once() + s.host = mockHost s.push(one) @@ -676,6 +678,7 @@ func TestSStore(t *testing.T) { mockHost := &mockHost{} mockHost.On("SetStorage", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(runtime.StorageAdded).Once() + s.host = mockHost s.push(one) @@ -696,6 +699,7 @@ func TestSStore(t *testing.T) { mockHost := &mockHost{} mockHost.On("SetStorage", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(runtime.StorageDeleted).Once() + s.host = mockHost s.push(one) @@ -1093,6 +1097,7 @@ func TestExtCodeCopy(t *testing.T) { t.Run("NonEIP150Fork", func(t *testing.T) { leftGas := uint64(974) + s, cancelFn := getState(&chain.ForksInTime{}) defer cancelFn() diff --git a/state/runtime/evm/state.go b/state/runtime/evm/state.go index 8f6fa2ebd0..52aba2b9f9 100644 --- a/state/runtime/evm/state.go +++ b/state/runtime/evm/state.go @@ -104,6 +104,7 @@ func (c *state) reset() { return x.SetInt64(0) }, c.stack[i]) } + c.stack = c.stack[:0] c.tmp = c.tmp[:0] c.ret = c.ret[:0] diff --git a/state/runtime/runtime.go b/state/runtime/runtime.go index c180c7c777..809b9564d9 100644 --- a/state/runtime/runtime.go +++ b/state/runtime/runtime.go @@ -119,6 +119,7 @@ type ExecutionResult struct { GasUsed uint64 // Total gas used as result of execution Err error // Any error encountered during the execution, listed below Address types.Address // Contract address + AccessList *AccessList // Access list } func (r *ExecutionResult) Succeeded() bool { return r.Err == nil } diff --git a/state/transition_test.go b/state/transition_test.go index c225652b87..692f39b187 100644 --- a/state/transition_test.go +++ b/state/transition_test.go @@ -151,6 +151,7 @@ func TestTransfer(t *testing.T) { err := transition.Transfer(tt.from, tt.to, amount) assert.Equal(t, tt.expectedErr, err) + if err == nil { // should move balance oldBalanceOfFrom := big.NewInt(int64(tt.preState[tt.from].Balance)) diff --git a/state/txn.go b/state/txn.go index 0eeb618ff7..168481d22c 100644 --- a/state/txn.go +++ b/state/txn.go @@ -150,7 +150,7 @@ func (txn *Txn) upsertAccount(addr types.Address, create bool, f func(object *St func (txn *Txn) AddSealingReward(addr types.Address, balance *big.Int) { txn.upsertAccount(addr, true, func(object *StateObject) { if object.Suicide { - *object = *newStateObject(txn) + *object = *newStateObject() object.Account.Balance.SetBytes(balance.Bytes()) } else { object.Account.Balance.Add(object.Account.Balance, balance) @@ -366,6 +366,7 @@ func (txn *Txn) IncrNonce(addr types.Address) error { return } + object.Account.Nonce++ }) @@ -447,6 +448,7 @@ func (txn *Txn) Suicide(addr types.Address) bool { suicided = true object.Suicide = true } + if object != nil { object.Account.Balance = new(big.Int) } @@ -536,7 +538,7 @@ func (txn *Txn) Empty(addr types.Address) bool { return obj.Empty() } -func newStateObject(txn *Txn) *StateObject { +func newStateObject() *StateObject { return &StateObject{ Account: &Account{ Balance: big.NewInt(0), @@ -571,6 +573,7 @@ func (txn *Txn) CleanDeleteObjects(deleteEmptyObjects bool) error { if !ok { return false } + if a.Suicide || a.Empty() && deleteEmptyObjects { remove = append(remove, k) } @@ -637,6 +640,7 @@ func (txn *Txn) Commit(deleteEmptyObjects bool) ([]*Object, error) { } else { store.Val = v.([]byte) //nolint:forcetypeassert } + obj.Storage = append(obj.Storage, store) return false diff --git a/txpool/event_subscription_test.go b/txpool/event_subscription_test.go index e7c6412927..d003a71141 100644 --- a/txpool/event_subscription_test.go +++ b/txpool/event_subscription_test.go @@ -123,6 +123,7 @@ func TestEventSubscription_ProcessedEvents(t *testing.T) { // Set the event listener processed := int64(0) + go func() { for range subscription.outputCh { atomic.AddInt64(&processed, 1) @@ -133,6 +134,7 @@ func TestEventSubscription_ProcessedEvents(t *testing.T) { var wg sync.WaitGroup for _, event := range testCase.events { wg.Add(1) + go func(event *proto.TxPoolEvent) { defer wg.Done() @@ -141,8 +143,11 @@ func TestEventSubscription_ProcessedEvents(t *testing.T) { } wg.Wait() + eventWaitCtx, eventWaitFn := context.WithTimeout(context.Background(), 30*time.Second) + defer eventWaitFn() + if _, err := tests.RetryUntilTimeout(eventWaitCtx, func() (interface{}, bool) { return nil, atomic.LoadInt64(&processed) != int64(testCase.expectedProcessed) }); err != nil { diff --git a/txpool/txpool_test.go b/txpool/txpool_test.go index 0f4cfa3ed3..22c01dbad6 100644 --- a/txpool/txpool_test.go +++ b/txpool/txpool_test.go @@ -152,6 +152,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrInvalidTxType", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.StateTxType) @@ -170,7 +171,9 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrTxTypeNotSupported London hardfork not enabled", func(t *testing.T) { t.Parallel() + pool := setupPool() + pool.forks.RemoveFork(chain.London) tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) @@ -188,6 +191,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrNegativeValue", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -201,6 +205,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrBlockLimitExceeded", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -217,6 +222,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrExtractSignature", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -231,6 +237,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrInvalidSender", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(addr1, 0, 1, types.LegacyTxType) @@ -247,7 +254,9 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrUnderpriced", func(t *testing.T) { t.Parallel() + pool := setupPool() + pool.priceLimit = 1000000 tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) // gasPrice == 1 @@ -261,7 +270,9 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrInvalidAccountState", func(t *testing.T) { t.Parallel() + pool := setupPool() + pool.store = faultyMockStore{} // nonce is 1000000 so ErrNonceTooLow @@ -277,6 +288,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrTxPoolOverflow", func(t *testing.T) { t.Parallel() + pool := setupPool() // fill the pool @@ -293,6 +305,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("FillTxPoolToTheLimit", func(t *testing.T) { t.Parallel() + pool := setupPool() // fill the pool leaving only 1 slot @@ -309,6 +322,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrIntrinsicGas", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -323,6 +337,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrAlreadyKnown", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -340,6 +355,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrAlreadyKnown", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -362,6 +378,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrOversizedData", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -382,6 +399,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrNonceTooLow", func(t *testing.T) { t.Parallel() + pool := setupPool() // faultyMockStore.GetNonce() == 99999 @@ -397,6 +415,7 @@ func TestAddTxErrors(t *testing.T) { t.Run("ErrInsufficientFunds", func(t *testing.T) { t.Parallel() + pool := setupPool() tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) @@ -543,6 +562,7 @@ func TestAddTxHighPressure(t *testing.T) { pool.SetSigner(&mockSigner{}) pool.getOrCreateAccount(addr1) + pool.accounts.get(addr1).nextNonce = 5 // mock high pressure @@ -570,6 +590,7 @@ func TestAddTxHighPressure(t *testing.T) { pool.SetSigner(&mockSigner{}) pool.getOrCreateAccount(addr1) + pool.accounts.get(addr1).nextNonce = 5 // mock high pressure @@ -602,6 +623,7 @@ func TestAddGossipTx(t *testing.T) { pool, err := newTestPool() pool.localPeerID = peer.ID("test") + assert.NoError(t, err) pool.SetSigner(signer) @@ -2191,7 +2213,9 @@ func Test_TxPool_validateTx(t *testing.T) { t.Run("tx input larger than the TxPoolMaxInitCodeSize", func(t *testing.T) { t.Parallel() + pool := setupPool() + pool.forks = chain.AllForksEnabled.Copy() input := make([]byte, state.TxPoolMaxInitCodeSize+1) @@ -2210,7 +2234,9 @@ func Test_TxPool_validateTx(t *testing.T) { t.Run("tx input the same as TxPoolMaxInitCodeSize", func(t *testing.T) { t.Parallel() + pool := setupPool() + pool.forks = chain.AllForksEnabled.Copy() input := make([]byte, state.TxPoolMaxInitCodeSize) @@ -2330,7 +2356,9 @@ func Test_TxPool_validateTx(t *testing.T) { t.Run("eip-1559 tx placed without eip-1559 fork enabled", func(t *testing.T) { t.Parallel() + pool := setupPool() + pool.forks = chain.AllForksEnabled.Copy() pool.forks.RemoveFork(chain.London) @@ -2619,10 +2647,13 @@ func TestResetAccounts_Enqueued(t *testing.T) { // setup prestate totalTx := 0 expectedPromoted := uint64(0) + for addr, txs := range allTxs { expectedPromoted += expected.accounts[addr].promoted + for _, tx := range txs { totalTx++ + assert.NoError(t, pool.addTx(local, tx)) } } @@ -2714,10 +2745,13 @@ func TestResetAccounts_Enqueued(t *testing.T) { // setup prestate expectedEnqueuedTx := 0 expectedPromotedTx := uint64(0) + for addr, txs := range allTxs { expectedPromotedTx += expected.accounts[addr].promoted + for _, tx := range txs { expectedEnqueuedTx++ + assert.NoError(t, pool.addTx(local, tx)) } } @@ -2903,6 +2937,7 @@ func TestExecutablesOrder(t *testing.T) { ) expectedPromotedTx := 0 + for _, txs := range test.allTxs { for _, tx := range txs { expectedPromotedTx++ @@ -2921,8 +2956,10 @@ func TestExecutablesOrder(t *testing.T) { pool.Prepare() var successful []*types.Transaction + for { tx := pool.Peek() + if tx == nil { break } @@ -3102,6 +3139,7 @@ func TestRecovery(t *testing.T) { // setup prestate totalTx := 0 expectedEnqueued := uint64(0) + for addr, txs := range test.allTxs { // preset nonce so promotions can happen acc := pool.getOrCreateAccount(addr) @@ -3112,6 +3150,7 @@ func TestRecovery(t *testing.T) { // send txs for _, sTx := range txs { totalTx++ + assert.NoError(t, pool.addTx(local, sTx.tx)) } } @@ -3124,8 +3163,10 @@ func TestRecovery(t *testing.T) { func() { pool.Prepare() + for { tx := pool.Peek() + if tx == nil { break } @@ -3322,9 +3363,11 @@ func TestGetTxs(t *testing.T) { // send txs expectedPromotedTx := 0 + for _, txs := range test.allTxs { nonce := uint64(0) promotable := uint64(0) + for _, tx := range txs { // send all txs if tx.Nonce() == nonce+promotable { @@ -3419,6 +3462,7 @@ func TestSetSealing(t *testing.T) { // Set initial value pool.sealing.Store(false) + if test.initialValue { pool.sealing.Store(true) } @@ -3700,6 +3744,7 @@ func TestAddTx_TxReplacement(t *testing.T) { pool, err := newTestPool() pool.chainID = big.NewInt(100) + require.NoError(t, err) pool.baseFee = 100 diff --git a/types/rlp_marshal_storage.go b/types/rlp_marshal_storage.go index 6d11d009ab..1c8f5055a0 100644 --- a/types/rlp_marshal_storage.go +++ b/types/rlp_marshal_storage.go @@ -21,6 +21,7 @@ func (b *Body) marshalRLPWith(ar *fastrlp.Arena) *fastrlp.Value { for _, tx := range b.Transactions { v0.Set(tx.marshalStoreRLPWith(ar)) } + vv.Set(v0) } @@ -31,6 +32,7 @@ func (b *Body) marshalRLPWith(ar *fastrlp.Arena) *fastrlp.Value { for _, uncle := range b.Uncles { v1.Set(uncle.MarshalRLPWith(ar)) } + vv.Set(v1) } From c37f113abe7794adce5f700dbe117fa56cf2d922 Mon Sep 17 00:00:00 2001 From: Branislav Kojic Date: Wed, 27 Mar 2024 09:54:56 +0100 Subject: [PATCH 45/48] Release fixes (#167) --- .goreleaser.yml | 2 +- Dockerfile.release | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index cfcdcf844a..7f40e1a7ca 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -34,7 +34,7 @@ builds: - CC=oa64-clang - CXX=oa64-clang++ ldflags: - -s-w + -s -w -X 'github.com/0xPolygon/polygon-edge/versioning.Version=v{{ .Version }}' -X 'github.com/0xPolygon/polygon-edge/versioning.Commit={{ .Commit }}' -X 'github.com/0xPolygon/polygon-edge/versioning.Branch={{ .Branch }}' diff --git a/Dockerfile.release b/Dockerfile.release index 9100d7eb4a..217268c613 100644 --- a/Dockerfile.release +++ b/Dockerfile.release @@ -9,7 +9,7 @@ COPY blade /usr/local/bin/ EXPOSE 8545 9632 1478 RUN addgroup -S blade-group \ - && adduser -S blade -G blade-group + && adduser -S -u 1001 blade -G blade-group USER blade From c756706d9d31d3843d458f080039038b0be4f8ce Mon Sep 17 00:00:00 2001 From: Branislav Kojic Date: Wed, 27 Mar 2024 11:12:22 +0100 Subject: [PATCH 46/48] [BLADE-113] GitHub workflow changes (#146) * GitHub workflow and Slack notifications changes * Small fixes * Deploy notification fixes * Small fixes * Small fixes * Small fixes * Destroy notification fixes * Destroy notification fixes * Fixed Restore data Ansible command --- .github/workflows/benchmark-test.yml | 10 +- .github/workflows/ci.yml | 2 +- .github/workflows/deploy-network.yml | 33 ++- .github/workflows/destroy-network.yml | 2 +- .github/workflows/load-test.yml | 9 +- .github/workflows/nightly.yml | 26 +- .../workflows/notification-deploy-network.yml | 167 +++++++---- .../notification-destroy-network.yml | 76 +++-- .github/workflows/notification-load-test.yml | 192 ++++++++----- .github/workflows/notification-nightly.yml | 259 ++++++++++++------ 10 files changed, 517 insertions(+), 259 deletions(-) diff --git a/.github/workflows/benchmark-test.yml b/.github/workflows/benchmark-test.yml index 7187054b88..9f7c385ef8 100644 --- a/.github/workflows/benchmark-test.yml +++ b/.github/workflows/benchmark-test.yml @@ -1,11 +1,11 @@ --- name: Benchmark Tests on: # yamllint disable-line rule:truthy - workflow_call: - outputs: - workflow_output: - description: "Benchmark Tests output" - value: ${{ jobs.benchmark_test.outputs.test_output_failure }} + workflow_call: + outputs: + workflow_output: + description: "Benchmark Tests output" + value: ${{ jobs.benchmark_test.outputs.test_output_failure }} jobs: benchmark_test: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71d06339fe..1408456592 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,7 @@ on: # yamllint disable-line rule:truthy benchmark-test: description: Benchmark Tests type: boolean - default: true + required: true outputs: build-blade: description: Build Blade output diff --git a/.github/workflows/deploy-network.yml b/.github/workflows/deploy-network.yml index 118c0b653a..462ef0e691 100644 --- a/.github/workflows/deploy-network.yml +++ b/.github/workflows/deploy-network.yml @@ -18,6 +18,16 @@ on: # yamllint disable-line rule:truthy type: string default: "2" required: true + max_slots: + description: Max Slots + type: string + default: "276480" + required: true + max_enqueued: + description: Max Enqueued + type: string + default: "276480" + required: true is_london_fork_active: description: EIP-1559 type: boolean @@ -44,6 +54,14 @@ on: # yamllint disable-line rule:truthy description: Block Time type: string required: true + max_slots: + description: Max Slots + type: string + required: true + max_enqueued: + description: Max Enqueued + type: string + required: true is_london_fork_active: description: EIP-1559 type: boolean @@ -80,7 +98,6 @@ jobs: check_network: name: Check if the network is already deployed runs-on: ubuntu-latest - environment: ${{ inputs.environment }} outputs: check_output: ${{ steps.check_state_file.outputs.resources }} rpc_url: ${{ steps.rpc_url.outputs.url }} @@ -163,6 +180,8 @@ jobs: echo "${{ secrets.VAULT_PASSWORD }}" > password.txt sed 's/devnet/${{ inputs.environment }}/g' inventory/aws_ec2.yml > inventory/aws_ec2.yml.tmp && mv inventory/aws_ec2.yml.tmp inventory/aws_ec2.yml sed 's/blade_tag: .*/blade_tag: ${{ github.sha }}/g' group_vars/all.yml > group_vars/all.yml.tmp && mv group_vars/all.yml.tmp group_vars/all.yml + sed 's/is_bridge_active: .*/is_bridge_active: ${{ inputs.is_bridge_active }}/g' group_vars/all.yml > group_vars/all.yml.tmp && mv group_vars/all.yml.tmp group_vars/all.yml + sed 's/is_london_fork_active: .*/is_london_fork_active: ${{ inputs.is_london_fork_active }}/g' group_vars/all.yml > group_vars/all.yml.tmp && mv group_vars/all.yml.tmp group_vars/all.yml sed 's/INFO/${{ vars.LOG_LEVEL }}/g' roles/blade/templates/blade.service > roles/blade/templates/blade.service.tmp && mv roles/blade/templates/blade.service.tmp roles/blade/templates/blade.service - name: Setup Ansible working-directory: ansible @@ -175,11 +194,11 @@ jobs: - name: Run Ansible (Bootstrap blade) if: (steps.previous_data.outputs.previous_data_output == '' || contains(steps.previous_data.outputs.previous_data_output, 'error')) working-directory: ansible - run: ansible-playbook site.yml --extra-vars "clean_deploy_title=${{ inputs.environment }} blade_repository=${{ github.repository }} block_gas_limit=${{ inputs.block_gas_limit }} block_time=${{ inputs.block_time }} is_london_fork_active=${{ inputs.is_london_fork_active }} is_bridge_active=${{ inputs.is_bridge_active }}" + run: ansible-playbook site.yml --extra-vars "clean_deploy_title=${{ inputs.environment }} blade_repository=${{ github.repository }} block_gas_limit=${{ inputs.block_gas_limit }} block_time=${{ inputs.block_time }} max_slots=${{ inputs.max_slots }} max_enqueued=${{ inputs.max_enqueued }}" - name: Run Ansible (Restore data) if: contains(steps.previous_data.outputs.previous_data_output, 'download') working-directory: ansible - run: ansible-playbook site.yml --extra-vars "clean_deploy_title=${{ inputs.environment }} blade_repository=${{ github.repository }} block_gas_limit=${{ inputs.block_gas_limit }} block_time=${{ inputs.block_time }} s3_bucket=${{ secrets.AWS_S3_BLADE_BUCKET }} restore_data=true" + run: ansible-playbook site.yml --extra-vars "clean_deploy_title=${{ inputs.environment }} blade_repository=${{ github.repository }} s3_bucket=${{ secrets.AWS_S3_BLADE_BUCKET }} restore_data=true" - name: Ansible Failed if: failure() id: ansible_failure @@ -191,9 +210,15 @@ jobs: name: Deploy Notification needs: [check_network, deploy_network] uses: ./.github/workflows/notification-deploy-network.yml - if: (always() && inputs.notification) + if: ((success() || failure()) && inputs.notification) with: environment: ${{ inputs.environment }} + block_gas_limit: ${{ inputs.block_gas_limit }} + block_time: ${{ inputs.block_time }} + max_slots: ${{ inputs.max_slots }} + max_enqueued: ${{ inputs.max_enqueued }} + is_london_fork_active: ${{ inputs.is_london_fork_active }} + is_bridge_active: ${{ inputs.is_bridge_active }} deploy_network_terraform_output: ${{ needs.deploy_network.outputs.terraform_output }} deploy_network_ansible_output: ${{ needs.deploy_network.outputs.ansible_output }} rpc_url: ${{ needs.check_network.outputs.rpc_url || needs.deploy_network.outputs.rpc_url }} diff --git a/.github/workflows/destroy-network.yml b/.github/workflows/destroy-network.yml index b280103051..5ee456b903 100644 --- a/.github/workflows/destroy-network.yml +++ b/.github/workflows/destroy-network.yml @@ -11,7 +11,7 @@ on: # yamllint disable-line rule:truthy logs: description: Upload Logs type: boolean - default: false + default: true notification: description: Notification type: boolean diff --git a/.github/workflows/load-test.yml b/.github/workflows/load-test.yml index 6fa0c7938d..b082959156 100644 --- a/.github/workflows/load-test.yml +++ b/.github/workflows/load-test.yml @@ -15,7 +15,7 @@ on: # yamllint disable-line rule:truthy timeout: description: Time Out type: string - default: "220s" + default: "1800s" required: true rate: description: Rate @@ -136,7 +136,6 @@ jobs: check_network: name: Check if the network is already deployed runs-on: ubuntu-latest - environment: ${{ inputs.environment }} outputs: rpc_url: ${{ steps.rpc_url.outputs.url }} steps: @@ -228,6 +227,12 @@ jobs: with: environment: ${{ inputs.environment }} scenario: ${{ inputs.scenario }} + timeout: ${{ inputs.timeout }} + rate: ${{ inputs.rate }} + timeUnit: ${{ inputs.timeUnit }} + duration: ${{ inputs.duration }} + preAllocatedVUs: ${{ inputs.preAllocatedVUs }} + maxVUs: ${{ inputs.maxVUs }} tps_avg: ${{ needs.load_test_scenario.outputs.tps_avg }} tps_max: ${{ needs.load_test_scenario.outputs.tps_max }} iterations: ${{ needs.load_test_scenario.outputs.iterations }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 93b311bfda..4f21ac2d65 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -4,6 +4,12 @@ on: # yamllint disable-line rule:truthy schedule: # * is a special character in YAML so you have to quote this string - cron: '0 0 * * *' + workflow_dispatch: + inputs: + force-run: + description: Force Run + type: boolean + default: false jobs: check: @@ -21,7 +27,7 @@ jobs: name: CI uses: ./.github/workflows/ci.yml needs: check - if: needs.check.outputs.new_commit_count > 0 + if: (needs.check.outputs.new_commit_count > 0 || inputs.force-run) with: build-blade: true lint: true @@ -35,12 +41,14 @@ jobs: name: Deploy Network uses: ./.github/workflows/deploy-network.yml needs: check - if: needs.check.outputs.new_commit_count > 0 + if: (needs.check.outputs.new_commit_count > 0 || inputs.force-run) with: environment: nightly block_gas_limit: "200000000" block_time: "2" - is_london_fork_active: true + max_slots: "276480" + max_enqueued: "276480" + is_london_fork_active: false is_bridge_active: true notification: false secrets: @@ -96,8 +104,8 @@ jobs: destroy_network: name: Destroy Network uses: ./.github/workflows/destroy-network.yml - needs: [deploy_network, load_test_multiple_eoa, load_test_multiple_erc20] - if: always() + needs: [check, deploy_network, load_test_multiple_eoa, load_test_multiple_erc20] + if: (always() && (needs.check.outputs.new_commit_count > 0 || inputs.force-run)) with: environment: nightly logs: true @@ -113,6 +121,12 @@ jobs: if: success() || failure() with: environment: nightly + block_gas_limit: "200000000" + block_time: "2" + max_slots: "276480" + max_enqueued: "276480" + is_london_fork_active: false + is_bridge_active: true logs: true build_blade_output: ${{ needs.ci.outputs.build-blade }} lint_output: ${{ needs.ci.outputs.lint }} @@ -151,7 +165,7 @@ jobs: notification_load_test_multiple_erc20: name: Load Test ERC20 Notification uses: ./.github/workflows/notification-load-test.yml - needs: [load_test_multiple_erc20, notification_nightly] + needs: [load_test_multiple_erc20, notification_nightly, notification_load_test_multiple_eoa] if: (always() && needs.load_test_multiple_erc20.outputs.load_test_output == 'true') with: environment: nightly diff --git a/.github/workflows/notification-deploy-network.yml b/.github/workflows/notification-deploy-network.yml index bbae04c529..1a41f109cc 100644 --- a/.github/workflows/notification-deploy-network.yml +++ b/.github/workflows/notification-deploy-network.yml @@ -7,6 +7,30 @@ on: # yamllint disable-line rule:truthy description: The environment to run against type: string required: true + block_gas_limit: + description: Block Gas Limit + type: string + required: true + block_time: + description: Block Time (sec) + type: string + required: true + max_slots: + description: Max Slots + type: string + required: true + max_enqueued: + description: Max Enqueued + type: string + required: true + is_london_fork_active: + description: EIP-1559 + type: boolean + required: true + is_bridge_active: + description: With Bridge + type: boolean + required: true deploy_network_terraform_output: description: Deploy Network - Terraform output type: string @@ -27,6 +51,7 @@ jobs: notification: name: Notification runs-on: ubuntu-latest + environment: ${{ inputs.environment }} steps: - name: Short SHA id: short_sha @@ -36,71 +61,117 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - green_color: '#03C03C' - red_color: '#E60012' succeed_bnt: 'primary' failed_bnt: 'danger' with: payload: | { - "attachments": [ + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "Deploy ${{ inputs.environment }}net" + } + }, { - "color": "${{ inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && env.green_color || env.red_color }}", - "blocks": [ + "type": "actions", + "elements": [ { - "type": "header", + "type": "button", "text": { "type": "plain_text", - "text": "Deploy ${{ inputs.environment }}net" - } + "text": "Workflow Run" + }, + "style": "${{ inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && env.succeed_bnt || env.failed_bnt }}", + "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "JSON-RPC" + }, + "url": "http://${{ inputs.rpc_url }}" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Triggered by: *${{ github.triggering_actor }}*" + }, + { + "type": "mrkdwn", + "text": "Commit: **" + } + ] + }, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Environment: *${{ inputs.environment }}*" + }, + { + "type": "mrkdwn", + "text": "Instances Type: *${{ vars.AWS_INSTANCE_TYPE }}*" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Validators: *${{ vars.VALIDATOR_COUNT }}*" + }, + { + "type": "mrkdwn", + "text": "Full Nodes: *${{ vars.FULLNODE_COUNT }}*" + }, + { + "type": "mrkdwn", + "text": "Rootchain servers: *${{ vars.GETH_COUNT }}*" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Block Gas Limit: *${{ inputs.block_gas_limit }}*" + }, + { + "type": "mrkdwn", + "text": "Block Time: *${{ inputs.block_time }}s*" + }, + { + "type": "mrkdwn", + "text": "Max Slots: *${{ inputs.max_slots }}*" }, { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Environment: *${{ inputs.environment }}*" - } - ] + "type": "mrkdwn", + "text": "Max Enqueued: *${{ inputs.max_enqueued }}*" }, { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Commit: **" - } - ] + "type": "mrkdwn", + "text": "Bridge: *${{ inputs.is_bridge_active }}*" }, { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Triggered by: *${{ github.triggering_actor }}*" - } - ] + "type": "mrkdwn", + "text": "London: *${{ inputs.is_london_fork_active }}*" }, { - "type": "actions", - "elements": [ - { - "type": "button", - "text": { - "type": "plain_text", - "text": "Workflow Run" - }, - "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - }, - { - "type": "button", - "text": { - "type": "plain_text", - "text": "JSON-RPC" - }, - "url": "http://${{ inputs.rpc_url }}" - } - ] + "type": "mrkdwn", + "text": "Log Level: *${{ vars.LOG_LEVEL }}*" } ] } diff --git a/.github/workflows/notification-destroy-network.yml b/.github/workflows/notification-destroy-network.yml index 1f53823765..b9b06b54e9 100644 --- a/.github/workflows/notification-destroy-network.yml +++ b/.github/workflows/notification-destroy-network.yml @@ -35,64 +35,52 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - green_color: '#03C03C' - red_color: '#E60012' succeed_bnt: 'primary' failed_bnt: 'danger' - url: https://s3.console.aws.amazon.com/s3/buckets/${{ secrets.AWS_S3_BLADE_BUCKET }}?region=${{ vars.AWS_REGION }}&prefix=logs/${{ github.run_id }}/ with: payload: | { - "attachments": [ + "blocks": [ { - "color": "${{ inputs.destroy_network_upload_logs == '' && inputs.destroy_network_terraform_logs == '' && env.green_color || env.red_color }}", - "blocks": [ + "type": "header", + "text": { + "type": "plain_text", + "text": "Destroy ${{ inputs.environment }}net" + } + }, + { + "type": "actions", + "elements": [ { - "type": "header", + "type": "button", "text": { "type": "plain_text", - "text": "Destroy ${{ inputs.environment }}net" - } + "text": "Workflow Run" + }, + "style": "${{ inputs.destroy_network_upload_logs == '' && inputs.destroy_network_terraform_logs == '' && env.succeed_bnt || env.failed_bnt }}", + "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" }, { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Environment: *${{ inputs.environment }}*" - } - ] - }, + "type": "button", + "text": { + "type": "plain_text", + "text": "${{ inputs.logs && inputs.destroy_network_upload_logs == '' && 'Logs' || 'No Logs' }}" + }, + "style": "${{ inputs.logs && inputs.destroy_network_upload_logs == '' && env.succeed_bnt || env.failed_bnt }}", + "url": "https://s3.console.aws.amazon.com/s3/buckets/${{ secrets.AWS_S3_BLADE_BUCKET }}?region=${{ vars.AWS_REGION }}&prefix=logs/${{ github.run_id }}/" + } + ] + }, + { + "type": "context", + "elements": [ { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Triggered by: *${{ github.triggering_actor }}*" - } - ] + "type": "mrkdwn", + "text": "Triggered by: *${{ github.triggering_actor }}*" }, { - "type": "actions", - "elements": [ - { - "type": "button", - "text": { - "type": "plain_text", - "text": "Workflow Run" - }, - "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - }, - { - "type": "button", - "text": { - "type": "plain_text", - "text": "${{ inputs.logs && inputs.destroy_network_upload_logs == '' && 'Logs' || 'No Logs' }}" - }, - "style": "${{ inputs.logs && inputs.destroy_network_upload_logs == '' && env.succeed_bnt || env.failed_bnt }}", - "url": "https://s3.console.aws.amazon.com/s3/buckets/${{ secrets.AWS_S3_BLADE_BUCKET }}?region=${{ vars.AWS_REGION }}&prefix=logs/${{ github.run_id }}/" - } - ] + "type": "mrkdwn", + "text": "Environment: *${{ inputs.environment }}*" } ] } diff --git a/.github/workflows/notification-load-test.yml b/.github/workflows/notification-load-test.yml index 519cc151af..984f37f3d7 100644 --- a/.github/workflows/notification-load-test.yml +++ b/.github/workflows/notification-load-test.yml @@ -11,6 +11,30 @@ on: # yamllint disable-line rule:truthy description: The scenario to run type: string required: true + timeout: + description: Time Out + type: string + required: true + rate: + description: Rate + type: string + required: true + timeUnit: + description: Time Unit + type: string + required: true + duration: + description: Duration + type: string + required: true + preAllocatedVUs: + description: Preallocated VUs + type: string + required: true + maxVUs: + description: Max VUs + type: string + required: true tps_avg: description: "Average Transactions Per Second" type: string @@ -47,91 +71,133 @@ jobs: notification: name: Notification runs-on: ubuntu-latest + environment: ${{ inputs.environment }} steps: + - name: Short SHA + id: short_sha + run: echo "value=`echo ${{ github.sha }} | cut -c1-7`" >> $GITHUB_OUTPUT - name: Notify Slack uses: slackapi/slack-github-action@v1.25.0 env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - green_color: '#03C03C' succeed_bnt: 'primary' with: payload: | { - "attachments": [ + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "Load Test: ${{ inputs.scenario }}" + } + }, { - "color": "${{ env.green_color }}", - "blocks": [ + "type": "actions", + "elements": [ { - "type": "header", + "type": "button", "text": { "type": "plain_text", - "text": "Load Test: ${{ inputs.scenario }}" - } + "text": "Workflow Run" + }, + "style": "${{ env.succeed_bnt }}", + "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Triggered by: *${{ github.triggering_actor }}*" + }, + { + "type": "mrkdwn", + "text": "Commit: **" + } + ] + }, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Environment: *${{ inputs.environment }}*" + }, + { + "type": "mrkdwn", + "text": "Instance Type: *${{ vars.AWS_INSTANCE_TYPE }}*" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Time Out: *${{ inputs.timeout }}*" + }, + { + "type": "mrkdwn", + "text": "Rate: *${{ inputs.rate }}*" + }, + { + "type": "mrkdwn", + "text": "Time Unit: *${{ inputs.timeUnit }}*" + }, + { + "type": "mrkdwn", + "text": "Duration: *${{ inputs.duration }}*" + }, + { + "type": "mrkdwn", + "text": "Preallocated VUs: *${{ inputs.preAllocatedVUs }}*" + }, + { + "type": "mrkdwn", + "text": "Max VUs: *${{ inputs.maxVUs }}*" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Average TPS*\n${{ inputs.tps_avg }}" + }, + { + "type": "mrkdwn", + "text": "*Max TPS*\n${{ inputs.tps_max }}" + }, + { + "type": "mrkdwn", + "text": "*Average Gas Used*\n${{ inputs.gas_avg }}" }, { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Environment: *${{ inputs.environment }}*" - } - ] + "type": "mrkdwn", + "text": "*Max Gas Used*\n${{ inputs.gas_max }}" }, { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Triggered by: *${{ github.triggering_actor }}*" - } - ] + "type": "mrkdwn", + "text": "*Transactions*\n${{ inputs.iterations }}" }, { - "type": "actions", - "elements": [ - { - "type": "button", - "text": { - "type": "plain_text", - "text": "Workflow Run" - }, - "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - } - ] + "type": "mrkdwn", + "text": "*Block Number*\n${{ inputs.block }}" }, { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Average TPS*\n${{ inputs.tps_avg }}" - }, - { - "type": "mrkdwn", - "text": "*Max TPS*\n${{ inputs.tps_max }}" - }, - { - "type": "mrkdwn", - "text": "*Average Gas Used*\n${{ inputs.gas_avg }}" - }, - { - "type": "mrkdwn", - "text": "*Max Gas Used*\n${{ inputs.gas_max }}" - }, - { - "type": "mrkdwn", - "text": "*Transactions*\n${{ inputs.iterations }}" - }, - { - "type": "mrkdwn", - "text": "*Block Number*\n${{ inputs.block }}" - }, - { - "type": "mrkdwn", - "text": "*Time to Mine*\n${{ inputs.ttm }}" - } - ] + "type": "mrkdwn", + "text": "*Time to Mine (ms)*\n${{ inputs.ttm }}" } ] } diff --git a/.github/workflows/notification-nightly.yml b/.github/workflows/notification-nightly.yml index 8bdf8967be..2b20508b0e 100644 --- a/.github/workflows/notification-nightly.yml +++ b/.github/workflows/notification-nightly.yml @@ -7,6 +7,30 @@ on: # yamllint disable-line rule:truthy description: The environment to run against type: string required: true + block_gas_limit: + description: Block Gas Limit + type: string + required: true + block_time: + description: Block Time (sec) + type: string + required: true + max_slots: + description: Max Slots + type: string + required: true + max_enqueued: + description: Max Enqueued + type: string + required: true + is_london_fork_active: + description: EIP-1559 + type: boolean + required: true + is_bridge_active: + description: With Bridge + type: boolean + required: true logs: description: Upload Logs type: string @@ -77,6 +101,7 @@ jobs: notification: name: Notification runs-on: ubuntu-latest + environment: ${{ inputs.environment }} steps: - name: Short SHA id: short_sha @@ -86,120 +111,184 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - green_color: '#03C03C' - red_color: '#E60012' succeed_bnt: 'primary' failed_bnt: 'danger' + succeed_job: ':green:' + failed_job: ':red:' with: payload: | { - "attachments": [ + "blocks": [ { - "color": "${{ inputs.build_blade_output == '' && inputs.lint_output == '' && inputs.unit_test_output == '' && inputs.e2e_polybft_test_output == '' && inputs.e2e_legacy_test_output == '' && inputs.property_polybft_test_output == '' && inputs.fuzz_test_output == '' && inputs.benchmark_test_output == '' && inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && inputs.load_test_multiple_eoa_output == 'true' && inputs.load_test_multiple_erc20_output == 'true' && inputs.destroy_network_logs_output == '' && inputs.destroy_network_terraform_output == '' && env.green_color || env.red_color }}", - "blocks": [ + "type": "header", + "text": { + "type": "plain_text", + "text": "Nightly build" + } + }, + { + "type": "actions", + "elements": [ { - "type": "header", + "type": "button", "text": { "type": "plain_text", - "text": "Nightly build" - } - }, - { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Environment: *${{ inputs.environment }}*" - } - ] - }, - { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Commit: **" - } - ] - }, - { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Triggered by: *${{ github.triggering_actor }}*" - } - ] - }, - { - "type": "actions", - "elements": [ - { - "type": "button", - "text": { - "type": "plain_text", - "text": "Workflow Run" - }, - "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - }, - { - "type": "button", - "text": { - "type": "plain_text", - "text": "${{ inputs.logs == 'true' && inputs.destroy_network_logs_output == '' && 'Logs' || 'No Logs' }}" - }, - "style": "${{ inputs.logs == 'true' && inputs.destroy_network_logs_output == '' && env.succeed_bnt || env.failed_bnt }}", - "url": "https://s3.console.aws.amazon.com/s3/buckets/${{ secrets.AWS_S3_BLADE_BUCKET }}?region=${{ vars.AWS_REGION }}&prefix=logs/${{ github.run_id }}/" - } - ] + "text": "Workflow Run" + }, + "style": "${{ inputs.build_blade_output == '' && inputs.lint_output == '' && inputs.unit_test_output == '' && inputs.e2e_polybft_test_output == '' && inputs.e2e_legacy_test_output == '' && inputs.property_polybft_test_output == '' && inputs.fuzz_test_output == '' && inputs.benchmark_test_output == '' && inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && inputs.load_test_multiple_eoa_output == 'true' && inputs.load_test_multiple_erc20_output == 'true' && inputs.destroy_network_logs_output == '' && inputs.destroy_network_terraform_output == '' && env.succeed_bnt || env.failed_bnt }}", + "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "${{ inputs.logs == 'true' && inputs.destroy_network_logs_output == '' && 'Logs' || 'No Logs' }}" + }, + "style": "${{ inputs.logs == 'true' && inputs.destroy_network_logs_output == '' && env.succeed_bnt || env.failed_bnt }}", + "url": "https://s3.console.aws.amazon.com/s3/buckets/${{ secrets.AWS_S3_BLADE_BUCKET }}?region=${{ vars.AWS_REGION }}&prefix=logs/${{ github.run_id }}/" } ] }, { - "color": "${{ inputs.build_blade_output == '' && inputs.lint_output == '' && inputs.unit_test_output == '' && inputs.fuzz_test_output == '' && inputs.benchmark_test_output == '' && inputs.e2e_legacy_test_output == '' && inputs.e2e_polybft_test_output == '' && inputs.property_polybft_test_output == '' && env.green_color || env.red_color }}", - "blocks": [ + "type": "context", + "elements": [ { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "*CI*\n${{ inputs.build_blade_output == '' && 'Build' || '~Build~' }}, ${{ inputs.lint_output == '' && 'Lint' || '~Lint~' }}, ${{ inputs.unit_test_output == '' && 'Unit Tests' || '~Unit Tests~' }},\n${{ inputs.fuzz_test_output == '' && 'Fuzz Tests' || '~Fuzz Tests~' }}, ${{ inputs.e2e_legacy_test_output == '' && 'E2E Legacy Tests' || '~E2E Legacy Tests~' }},\n${{ inputs.e2e_polybft_test_output == '' && 'E2E PolyBFT Tests' || '~E2E PolyBFT Tests~' }}, ${{ inputs.property_polybft_test_output == '' && 'Property PolyBFT Tests' || '~Property PolyBFT Tests~' }},\n${{ inputs.benchmark_test_output == '' && 'Benchmark Tests' || '~Benchmark Tests~' }}" - } + "type": "mrkdwn", + "text": "Triggered by: *${{ github.triggering_actor }}*" + }, + { + "type": "mrkdwn", + "text": "Commit: **" } ] }, { - "color": "${{ inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && env.green_color || env.red_color }}", - "blocks": [ + "type": "divider" + }, + { + "type": "context", + "elements": [ { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "*Deploy Network*" - } + "type": "mrkdwn", + "text": "Environment: *${{ inputs.environment }}*" + }, + { + "type": "mrkdwn", + "text": "Instances Type: *${{ vars.AWS_INSTANCE_TYPE }}*" } ] }, { - "color": "${{ inputs.load_test_multiple_eoa_output == 'true' && inputs.load_test_multiple_erc20_output == 'true' && env.green_color || env.red_color }}", - "blocks": [ + "type": "context", + "elements": [ { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "*Load Tests*\n${{ inputs.load_test_multiple_eoa_output == 'true' && 'EOA' || '~EOA~' }},\n${{ inputs.load_test_multiple_erc20_output == 'true' && 'ERC20' || '~ERC20~' }}" - } + "type": "mrkdwn", + "text": "Validators: *${{ vars.VALIDATOR_COUNT }}*" + }, + { + "type": "mrkdwn", + "text": "Full Nodes: *${{ vars.FULLNODE_COUNT }}*" + }, + { + "type": "mrkdwn", + "text": "Rootchain servers: *${{ vars.GETH_COUNT }}*" } ] }, { - "color": "${{ inputs.destroy_network_logs_output == '' && inputs.destroy_network_terraform_output == '' && env.green_color || env.red_color }}", - "blocks": [ + "type": "context", + "elements": [ { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "*Destroy Network*" - } + "type": "mrkdwn", + "text": "Block Gas Limit: *${{ inputs.block_gas_limit }}*" + }, + { + "type": "mrkdwn", + "text": "Block Time: *${{ inputs.block_time }}s*" + }, + { + "type": "mrkdwn", + "text": "Max Slots: *${{ inputs.max_slots }}*" + }, + { + "type": "mrkdwn", + "text": "Max Enqueued: *${{ inputs.max_enqueued }}*" + }, + { + "type": "mrkdwn", + "text": "Bridge: *${{ inputs.is_bridge_active }}*" + }, + { + "type": "mrkdwn", + "text": "London: *${{ inputs.is_london_fork_active }}*" + }, + { + "type": "mrkdwn", + "text": "Log Level: *${{ vars.LOG_LEVEL }}*" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "${{ inputs.build_blade_output == '' && env.succeed_job || env.failed_job }} *Build*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.lint_output == '' && env.succeed_job || env.failed_job }} *Lint*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.unit_test_output == '' && env.succeed_job || env.failed_job }} *Unit Tests*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.fuzz_test_output == '' && env.succeed_job || env.failed_job }} *Fuzz Tests*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.e2e_legacy_test_output == '' && env.succeed_job || env.failed_job }} *E2E Legacy Tests*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.e2e_polybft_test_output == '' && env.succeed_job || env.failed_job }} *E2E PolyBFT Tests*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.property_polybft_test_output == '' && env.succeed_job || env.failed_job }} *Property PolyBFT Tests*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.benchmark_test_output == '' && env.succeed_job || env.failed_job }} *Benchmark Tests*" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "${{ inputs.deploy_network_terraform_output == '' && inputs.deploy_network_ansible_output == '' && env.succeed_job || env.failed_job }} *Deploy Network*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.benchmark_test_output == '' && env.succeed_job || env.failed_job }} *Destroy Network*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.load_test_multiple_eoa_output == 'true' && env.succeed_job || env.failed_job }} *Load Test EOA*" + }, + { + "type": "mrkdwn", + "text": "${{ inputs.load_test_multiple_erc20_output == 'true' && env.succeed_job || env.failed_job }} *Load Test ERC20*" } ] } From 51dea59badbcd6a27d53fd7c6d28395331b5b001 Mon Sep 17 00:00:00 2001 From: Oliver Bundalo Date: Wed, 27 Mar 2024 11:25:03 +0100 Subject: [PATCH 47/48] 2nd database instance eliminated --- blockchain/storagev2/leveldb/leveldb.go | 38 +++++++------------------ blockchain/storagev2/storage.go | 7 ++++- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/blockchain/storagev2/leveldb/leveldb.go b/blockchain/storagev2/leveldb/leveldb.go index 73f1e05784..ff56ebd2f0 100644 --- a/blockchain/storagev2/leveldb/leveldb.go +++ b/blockchain/storagev2/leveldb/leveldb.go @@ -13,19 +13,16 @@ type levelDB struct { } var tableMapper = map[uint8][]byte{ - // Main DB - storagev2.BODY: []byte("b"), // DB key = block number + block hash + mapper, value = block body - storagev2.DIFFICULTY: []byte("d"), // DB key = block number + block hash + mapper, value = block total diffculty - storagev2.HEADER: []byte("h"), // DB key = block number + block hash + mapper, value = block header - storagev2.RECEIPTS: []byte("r"), // DB key = block number + block hash + mapper, value = block receipts - storagev2.CANONICAL: {}, // DB key = block number + mapper, value = block hash - - // Lookup DB - storagev2.FORK: {}, // DB key = FORK_KEY + mapper, value = fork hashes - storagev2.HEAD_HASH: {}, // DB key = HEAD_HASH_KEY + mapper, value = head hash - storagev2.HEAD_NUMBER: {}, // DB key = HEAD_NUMBER_KEY + mapper, value = head number - storagev2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number - storagev2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number + storagev2.BODY: []byte("b"), // DB key = block number + block hash + mapper, value = block body + storagev2.DIFFICULTY: []byte("d"), // DB key = block number + block hash + mapper, value = block total diffculty + storagev2.HEADER: []byte("h"), // DB key = block number + block hash + mapper, value = block header + storagev2.RECEIPTS: []byte("r"), // DB key = block number + block hash + mapper, value = block receipts + storagev2.CANONICAL: {}, // DB key = block number + mapper, value = block hash + storagev2.FORK: {}, // DB key = FORK_KEY + mapper, value = fork hashes + storagev2.HEAD_HASH: {}, // DB key = HEAD_HASH_KEY + mapper, value = head hash + storagev2.HEAD_NUMBER: {}, // DB key = HEAD_NUMBER_KEY + mapper, value = head number + storagev2.BLOCK_LOOKUP: {}, // DB key = block hash + mapper, value = block number + storagev2.TX_LOOKUP: {}, // DB key = tx hash + mapper, value = block number } // NewLevelDBStorage creates the new storage reference with leveldb default options @@ -44,21 +41,8 @@ func NewLevelDBStorage(path string, logger hclog.Logger) (*storagev2.Storage, er return nil, err } - // Open Lookup - // Set default options - options = &opt.Options{ - BlockCacheCapacity: 64 * opt.MiB, - WriteBuffer: opt.DefaultWriteBuffer, - } - path += "/lookup" - - lookup, err := openLevelDBStorage(path, options) - if err != nil { - return nil, err - } - ldbs[0] = &levelDB{maindb} - ldbs[1] = &levelDB{lookup} + ldbs[1] = nil return storagev2.Open(logger.Named("leveldb"), ldbs) } diff --git a/blockchain/storagev2/storage.go b/blockchain/storagev2/storage.go index eff6aada80..7a60ddf7fe 100644 --- a/blockchain/storagev2/storage.go +++ b/blockchain/storagev2/storage.go @@ -1,4 +1,3 @@ -//nolint:stylecheck package storagev2 import ( @@ -39,6 +38,8 @@ const ( ) // Lookup tables +// +//nolint:stylecheck // needed because linter considers _ in name as an error const ( FORK = uint8(0) | LOOKUP_INDEX HEAD_HASH = uint8(2) | LOOKUP_INDEX @@ -47,14 +48,18 @@ const ( TX_LOOKUP = uint8(8) | LOOKUP_INDEX ) +//nolint:stylecheck // needed because linter considers _ in name as an error const MAX_TABLES = uint8(20) // Database indexes +// +//nolint:stylecheck // needed because linter considers _ in name as an error const ( MAINDB_INDEX = uint8(0) LOOKUP_INDEX = uint8(1) ) +//nolint:stylecheck // needed because linter considers _ in name as an error var ( FORK_KEY = []byte("0000000f") HEAD_HASH_KEY = []byte("0000000h") From 307c7bb95be1025974c9899da62f147889e0da2a Mon Sep 17 00:00:00 2001 From: Goran Rojovic <100121253+goran-ethernal@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:58:15 +0100 Subject: [PATCH 48/48] Usage of new `EthClient` (#165) --- command/bridge/deploy/deploy.go | 16 +- command/bridge/deploy/deploy_test.go | 4 +- command/bridge/exit/exit.go | 8 +- command/regenesis/get_root.go | 14 +- .../registration/register_validator.go | 2 +- consensus/polybft/checkpoint_manager_test.go | 4 +- consensus/polybft/stake_manager_test.go | 4 +- e2e-polybft/e2e/acls_test.go | 17 +- e2e-polybft/e2e/bridge_test.go | 91 ++-- e2e-polybft/e2e/burn_contract_test.go | 6 +- e2e-polybft/e2e/consensus_test.go | 67 +-- e2e-polybft/e2e/governance_test.go | 22 +- e2e-polybft/e2e/helpers_test.go | 12 +- e2e-polybft/e2e/jsonrpc_test.go | 454 +----------------- e2e-polybft/e2e/migration_test.go | 39 +- e2e-polybft/e2e/storage_test.go | 59 +-- e2e-polybft/e2e/txpool_test.go | 28 +- e2e-polybft/framework/test-cluster.go | 46 +- e2e-polybft/framework/test-server.go | 14 +- e2e-polybft/property/property_test.go | 6 +- e2e/framework/helper.go | 19 +- e2e/framework/testserver.go | 207 +------- e2e/transaction_test.go | 23 +- e2e/txpool_test.go | 30 +- gasprice/feehistory_test.go | 6 +- gasprice/gasprice_test.go | 13 +- helper/common/common.go | 25 + helper/tests/testing.go | 38 +- jsonrpc/client.go | 50 +- jsonrpc/jsonrpc_test.go | 4 +- jsonrpc/types.go | 106 +++- network/e2e_testing.go | 2 +- txrelayer/txrelayer.go | 154 +++--- types/access_list_tx.go | 25 +- types/base_tx.go | 57 ++- types/dynamic_fee_tx.go | 33 +- types/json_marshal.go | 20 + types/json_marshalling_util.go | 138 ++++++ types/json_unmarshal.go | 231 ++------- types/legacy_tx.go | 15 +- types/state_tx.go | 15 +- types/transaction.go | 1 + 42 files changed, 864 insertions(+), 1261 deletions(-) create mode 100644 types/json_marshal.go create mode 100644 types/json_marshalling_util.go diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index d0b2090785..b837c7db1c 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -6,9 +6,9 @@ import ( "math/big" "sync" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/spf13/cobra" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" "golang.org/x/sync/errgroup" "github.com/0xPolygon/polygon-edge/chain" @@ -368,7 +368,7 @@ func runCommand(cmd *cobra.Command, _ []string) { return } - client, err := jsonrpc.NewClient(params.jsonRPCAddress) + client, err := jsonrpc.NewEthClient(params.jsonRPCAddress) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize JSON RPC client for provided IP address: %s: %w", params.jsonRPCAddress, err)) @@ -377,7 +377,7 @@ func runCommand(cmd *cobra.Command, _ []string) { } if consensusCfg.Bridge != nil { - code, err := client.Eth().GetCode(ethgo.Address(consensusCfg.Bridge.StateSenderAddr), ethgo.Latest) + code, err := client.GetCode(consensusCfg.Bridge.StateSenderAddr, jsonrpc.LatestBlockNumberOrHash) if err != nil { outputter.SetError(fmt.Errorf("failed to check if rootchain contracts are deployed: %w", err)) @@ -394,7 +394,7 @@ func runCommand(cmd *cobra.Command, _ []string) { // set event tracker start blocks for rootchain contract(s) of interest // the block number should be queried before deploying contracts so that no events during deployment // and initialization are missed - blockNum, err := client.Eth().BlockNumber() + blockNum, err := client.BlockNumber() if err != nil { outputter.SetError(fmt.Errorf("failed to query rootchain latest block number: %w", err)) @@ -434,7 +434,7 @@ func runCommand(cmd *cobra.Command, _ []string) { } // deployContracts deploys and initializes rootchain smart contracts -func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, chainID int64, +func deployContracts(outputter command.OutputFormatter, client *jsonrpc.EthClient, chainID int64, initialValidators []*validator.GenesisValidator, cmdCtx context.Context) (deploymentResultInfo, error) { txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(client), txrelayer.WithWriter(outputter), txrelayer.WithReceiptsTimeout(params.txTimeout)) @@ -474,7 +474,7 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, if !consensusCfg.NativeTokenConfig.IsMintable { if params.rootERC20TokenAddr != "" { // use existing root chain ERC20 token - if err := populateExistingTokenAddr(client.Eth(), + if err := populateExistingTokenAddr(client, params.rootERC20TokenAddr, rootERC20Name, rootchainConfig); err != nil { return deploymentResultInfo{RootchainCfg: nil, CommandResults: nil}, err } @@ -697,11 +697,11 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, // populateExistingTokenAddr checks whether given token is deployed on the provided address. // If it is, then its address is set to the rootchain config, otherwise an error is returned -func populateExistingTokenAddr(eth *jsonrpc.Eth, tokenAddr, tokenName string, +func populateExistingTokenAddr(eth *jsonrpc.EthClient, tokenAddr, tokenName string, rootchainCfg *polybft.RootchainConfig) error { addr := types.StringToAddress(tokenAddr) - code, err := eth.GetCode(ethgo.Address(addr), ethgo.Latest) + code, err := eth.GetCode(addr, jsonrpc.LatestBlockNumberOrHash) if err != nil { return fmt.Errorf("failed to check is %s token deployed: %w", tokenName, err) } else if code == "0x" { diff --git a/command/bridge/deploy/deploy_test.go b/command/bridge/deploy/deploy_test.go index 12d2d6bce4..d575baae8c 100644 --- a/command/bridge/deploy/deploy_test.go +++ b/command/bridge/deploy/deploy_test.go @@ -5,9 +5,9 @@ import ( "os" "testing" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" "github.com/umbracle/ethgo/testutil" "github.com/0xPolygon/polygon-edge/command" @@ -27,7 +27,7 @@ func TestDeployContracts_NoPanics(t *testing.T) { } }) - client, err := jsonrpc.NewClient(server.HTTPAddr()) + client, err := jsonrpc.NewEthClient(server.HTTPAddr()) require.NoError(t, err) testKey, err := helper.DecodePrivateKey("") diff --git a/command/bridge/exit/exit.go b/command/bridge/exit/exit.go index 0563d45bef..1182444561 100644 --- a/command/bridge/exit/exit.go +++ b/command/bridge/exit/exit.go @@ -7,7 +7,6 @@ import ( "time" "github.com/spf13/cobra" - "github.com/umbracle/ethgo/jsonrpc" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/common" @@ -15,6 +14,7 @@ import ( cmdHelper "github.com/0xPolygon/polygon-edge/command/helper" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" ) @@ -118,7 +118,7 @@ func run(cmd *cobra.Command, _ []string) { return } - childClient, err := jsonrpc.NewClient(ep.childJSONRPCAddr) + childClient, err := jsonrpc.NewEthClient(ep.childJSONRPCAddr) if err != nil { outputter.SetError(fmt.Errorf("could not create child chain JSON RPC client: %w", err)) @@ -127,9 +127,7 @@ func run(cmd *cobra.Command, _ []string) { // acquire proof for given exit event var proof types.Proof - - err = childClient.Call(generateExitProofFn, &proof, fmt.Sprintf("0x%x", ep.exitID)) - if err != nil { + if err = childClient.EndpointCall(generateExitProofFn, &proof, fmt.Sprintf("0x%x", ep.exitID)); err != nil { outputter.SetError(fmt.Errorf("failed to get exit proof (exit id=%d): %w", ep.exitID, err)) return diff --git a/command/regenesis/get_root.go b/command/regenesis/get_root.go index facec0f0cc..2033a58f62 100644 --- a/command/regenesis/get_root.go +++ b/command/regenesis/get_root.go @@ -3,10 +3,11 @@ package regenesis import ( "fmt" - "github.com/0xPolygon/polygon-edge/command" "github.com/spf13/cobra" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" + + "github.com/0xPolygon/polygon-edge/command" + "github.com/0xPolygon/polygon-edge/jsonrpc" ) var ( @@ -14,9 +15,6 @@ var ( blockNumber int64 ) -/* -./polygon-edge regenesis getroot --rpc "http://localhost:10002" -*/ func GetRootCMD() *cobra.Command { getRootCmd := &cobra.Command{ Use: "getroot", @@ -26,21 +24,21 @@ func GetRootCMD() *cobra.Command { outputter := command.InitializeOutputter(getRootCmd) defer outputter.WriteOutput() - rpcClient, err := jsonrpc.NewClient(jsonRPCAddress) + rpcClient, err := jsonrpc.NewEthClient(jsonRPCAddress) if err != nil { outputter.SetError(fmt.Errorf("connect to client error:%w", err)) return } - block, err := rpcClient.Eth().GetBlockByNumber(ethgo.BlockNumber(blockNumber), false) + block, err := rpcClient.GetBlockByNumber(jsonrpc.BlockNumber(blockNumber), false) if err != nil { outputter.SetError(fmt.Errorf("get block error:%w", err)) return } - _, err = outputter.Write([]byte(fmt.Sprintf("state root %s for block %d\n", block.StateRoot, block.Number))) + _, err = outputter.Write([]byte(fmt.Sprintf("state root %s for block %d\n", block.Header.StateRoot, block.Number()))) if err != nil { outputter.SetError(fmt.Errorf("get block error:%w", err)) diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 8428f79386..8fb7908cf5 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -98,7 +98,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { return err } - rootChainID, err := txRelayer.Client().Eth().ChainID() + rootChainID, err := txRelayer.Client().ChainID() if err != nil { return err } diff --git a/consensus/polybft/checkpoint_manager_test.go b/consensus/polybft/checkpoint_manager_test.go index c3a2a03da8..2cb1411f05 100644 --- a/consensus/polybft/checkpoint_manager_test.go +++ b/consensus/polybft/checkpoint_manager_test.go @@ -7,7 +7,7 @@ import ( "strconv" "testing" - "github.com/umbracle/ethgo/jsonrpc" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/signer" @@ -495,7 +495,7 @@ func (d *dummyTxRelayer) SendTransactionLocal(txn *types.Transaction) (*ethgo.Re return args.Get(0).(*ethgo.Receipt), args.Error(1) } -func (d *dummyTxRelayer) Client() *jsonrpc.Client { +func (d *dummyTxRelayer) Client() *jsonrpc.EthClient { return nil } diff --git a/consensus/polybft/stake_manager_test.go b/consensus/polybft/stake_manager_test.go index c6b5cf4993..ab0fce6a4e 100644 --- a/consensus/polybft/stake_manager_test.go +++ b/consensus/polybft/stake_manager_test.go @@ -8,6 +8,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/hex" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" @@ -15,7 +16,6 @@ import ( "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/abi" - "github.com/umbracle/ethgo/jsonrpc" ) func TestStakeManager_PostBlock(t *testing.T) { @@ -534,6 +534,6 @@ func (d *dummyStakeTxRelayer) SendTransactionLocal(txn *types.Transaction) (*eth return args.Get(0).(*ethgo.Receipt), args.Error(1) } -func (d *dummyStakeTxRelayer) Client() *jsonrpc.Client { +func (d *dummyStakeTxRelayer) Client() *jsonrpc.EthClient { return nil } diff --git a/e2e-polybft/e2e/acls_test.go b/e2e-polybft/e2e/acls_test.go index 154a0717f6..d71b3fad9e 100644 --- a/e2e-polybft/e2e/acls_test.go +++ b/e2e-polybft/e2e/acls_test.go @@ -77,17 +77,18 @@ func TestE2E_AllowList_ContractDeployment(t *testing.T) { deployTxn := cluster.Deploy(t, target, bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Reverted()) - require.False(t, cluster.ExistsCode(t, deployTxn.Receipt().ContractAddress)) + require.False(t, cluster.ExistsCode(t, types.Address(deployTxn.Receipt().ContractAddress))) } { // Step 3. 'adminAddr' can create contracts deployTxn := cluster.Deploy(t, admin, bytecode) require.NoError(t, deployTxn.Wait()) - require.True(t, deployTxn.Succeed()) - require.True(t, cluster.ExistsCode(t, deployTxn.Receipt().ContractAddress)) proxyContract = types.Address(deployTxn.Receipt().ContractAddress) + + require.True(t, deployTxn.Succeed()) + require.True(t, cluster.ExistsCode(t, proxyContract)) } { @@ -104,7 +105,7 @@ func TestE2E_AllowList_ContractDeployment(t *testing.T) { deployTxn := cluster.Deploy(t, target, bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) - require.True(t, cluster.ExistsCode(t, deployTxn.Receipt().ContractAddress)) + require.True(t, cluster.ExistsCode(t, types.Address(deployTxn.Receipt().ContractAddress))) } { @@ -168,7 +169,7 @@ func TestE2E_BlockList_ContractDeployment(t *testing.T) { deployTxn := cluster.Deploy(t, target, bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) - require.True(t, cluster.ExistsCode(t, deployTxn.Receipt().ContractAddress)) + require.True(t, cluster.ExistsCode(t, types.Address(deployTxn.Receipt().ContractAddress))) } { @@ -176,7 +177,7 @@ func TestE2E_BlockList_ContractDeployment(t *testing.T) { deployTxn := cluster.Deploy(t, admin, bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) - require.True(t, cluster.ExistsCode(t, deployTxn.Receipt().ContractAddress)) + require.True(t, cluster.ExistsCode(t, types.Address(deployTxn.Receipt().ContractAddress))) } { @@ -193,7 +194,7 @@ func TestE2E_BlockList_ContractDeployment(t *testing.T) { deployTxn := cluster.Deploy(t, target, bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Reverted()) - require.False(t, cluster.ExistsCode(t, deployTxn.Receipt().ContractAddress)) + require.False(t, cluster.ExistsCode(t, types.Address(deployTxn.Receipt().ContractAddress))) } { @@ -256,7 +257,7 @@ func TestE2E_AllowList_Transactions(t *testing.T) { deployTxn := cluster.Deploy(t, target, bytecode) require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Reverted()) - require.False(t, cluster.ExistsCode(t, deployTxn.Receipt().ContractAddress)) + require.False(t, cluster.ExistsCode(t, types.Address(deployTxn.Receipt().ContractAddress))) } { diff --git a/e2e-polybft/e2e/bridge_test.go b/e2e-polybft/e2e/bridge_test.go index 16964972c7..0769ece3f2 100644 --- a/e2e-polybft/e2e/bridge_test.go +++ b/e2e-polybft/e2e/bridge_test.go @@ -22,6 +22,7 @@ import ( "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" helperCommon "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/state/runtime/addresslist" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -90,12 +91,12 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { validatorSrv := cluster.Servers[0] - childEthEndpoint := validatorSrv.JSONRPC().Eth() + childEthEndpoint := validatorSrv.JSONRPC() rootchainTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Bridge.JSONRPCAddr())) require.NoError(t, err) - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(validatorSrv.JSONRPC())) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(childEthEndpoint)) require.NoError(t, err) deployerKey, err := bridgeHelper.DecodePrivateKey("") @@ -199,7 +200,7 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) { depositsSubset = 1 ) - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(validatorSrv.JSONRPC())) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(childEthEndpoint)) require.NoError(t, err) lastCommittedIDMethod := contractsapi.StateReceiver.Abi.GetMethod("lastCommittedId") @@ -347,7 +348,7 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { receipt, err := rootchainTxRelayer.SendTransaction(deployTx, rootchainDeployer) require.NoError(t, err) - rootERC721Addr := receipt.ContractAddress + rootERC721Addr := types.Address(receipt.ContractAddress) // DEPOSIT ERC721 TOKENS // send a few transactions to the bridge @@ -355,7 +356,7 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { t, cluster.Bridge.Deposit( common.ERC721, - types.Address(rootERC721Addr), + rootERC721Addr, polybftCfg.Bridge.RootERC721PredicateAddr, bridgeHelper.TestAccountPrivKey, strings.Join(receivers[:], ","), @@ -370,7 +371,7 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { require.NoError(t, cluster.WaitForBlock(50, 4*time.Minute)) validatorSrv := cluster.Servers[0] - childEthEndpoint := validatorSrv.JSONRPC().Eth() + childEthEndpoint := validatorSrv.JSONRPC() // the transactions are processed and there should be a success events var stateSyncedResult contractsapi.StateSyncResultEvent @@ -391,14 +392,14 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { require.NoError(t, cluster.WaitForBlock(uint64(50+(i+1)*epochSize), 1*time.Minute)) } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(validatorSrv.JSONRPC())) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(childEthEndpoint)) require.NoError(t, err) // retrieve child token address (from both chains, and assert they are the same) l1ChildTokenAddr := getChildToken(t, contractsapi.RootERC721Predicate.Abi, polybftCfg.Bridge.RootERC721PredicateAddr, - types.Address(rootERC721Addr), rootchainTxRelayer) + rootERC721Addr, rootchainTxRelayer) l2ChildTokenAddr := getChildToken(t, contractsapi.ChildERC721Predicate.Abi, contracts.ChildERC721PredicateContract, - types.Address(rootERC721Addr), txRelayer) + rootERC721Addr, txRelayer) t.Log("L1 child token", l1ChildTokenAddr) t.Log("L2 child token", l2ChildTokenAddr) @@ -427,13 +428,13 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { require.NoError(t, err) } - currentBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) + currentBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) - currentExtra, err := polybft.GetIbftExtra(currentBlock.ExtraData) + currentExtra, err := polybft.GetIbftExtra(currentBlock.Header.ExtraData) require.NoError(t, err) - t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number, currentExtra.Checkpoint.EpochNumber) + t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number(), currentExtra.Checkpoint.EpochNumber) currentEpoch := currentExtra.Checkpoint.EpochNumber require.NoError(t, waitForRootchainEpoch(currentEpoch, 3*time.Minute, rootchainTxRelayer, polybftCfg.Bridge.CheckpointManagerAddr)) @@ -450,7 +451,7 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) { // assert that owners of given token ids are the accounts on the root chain ERC 721 token for i, receiver := range receiversAddrs { - owner := erc721OwnerOf(t, big.NewInt(int64(i)), types.Address(rootERC721Addr), rootchainTxRelayer) + owner := erc721OwnerOf(t, big.NewInt(int64(i)), rootERC721Addr, rootchainTxRelayer) require.Equal(t, receiver, owner) } } @@ -529,7 +530,7 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { t, cluster.Bridge.Deposit( common.ERC1155, - types.Address(rootERC1155Addr), + rootERC1155Addr, polybftCfg.Bridge.RootERC1155PredicateAddr, bridgeHelper.TestAccountPrivKey, strings.Join(receivers[:], ","), @@ -544,7 +545,7 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { require.NoError(t, cluster.WaitForBlock(50, 4*time.Minute)) validatorSrv := cluster.Servers[0] - childEthEndpoint := validatorSrv.JSONRPC().Eth() + childEthEndpoint := validatorSrv.JSONRPC() // the transactions are processed and there should be a success events var stateSyncedResult contractsapi.StateSyncResultEvent @@ -565,14 +566,14 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { require.NoError(t, cluster.WaitForBlock(uint64(50+(i+1)*epochSize), 1*time.Minute)) } - txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(validatorSrv.JSONRPC())) + txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(childEthEndpoint)) require.NoError(t, err) // retrieve child token address l1ChildTokenAddr := getChildToken(t, contractsapi.RootERC1155Predicate.Abi, polybftCfg.Bridge.RootERC1155PredicateAddr, - types.Address(rootERC1155Addr), rootchainTxRelayer) + rootERC1155Addr, rootchainTxRelayer) l2ChildTokenAddr := getChildToken(t, contractsapi.ChildERC1155Predicate.Abi, contracts.ChildERC1155PredicateContract, - types.Address(rootERC1155Addr), txRelayer) + rootERC1155Addr, txRelayer) t.Log("L1 child token", l1ChildTokenAddr) t.Log("L2 child token", l2ChildTokenAddr) @@ -619,14 +620,14 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) { require.NoError(t, err) } - currentBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) + currentBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) - currentExtra, err := polybft.GetIbftExtra(currentBlock.ExtraData) + currentExtra, err := polybft.GetIbftExtra(currentBlock.Header.ExtraData) require.NoError(t, err) currentEpoch := currentExtra.Checkpoint.EpochNumber - t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number, currentExtra.Checkpoint.EpochNumber) + t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number(), currentExtra.Checkpoint.EpochNumber) require.NoError(t, waitForRootchainEpoch(currentEpoch, 3*time.Minute, rootchainTxRelayer, polybftCfg.Bridge.CheckpointManagerAddr)) @@ -710,7 +711,7 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { require.NoError(t, err) validatorSrv := cluster.Servers[0] - childEthEndpoint := validatorSrv.JSONRPC().Eth() + childEthEndpoint := validatorSrv.JSONRPC() // fund accounts on rootchain require.NoError(t, validatorSrv.RootchainFundFor(depositors, funds)) @@ -720,7 +721,7 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { rootchainTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Bridge.JSONRPCAddr())) require.NoError(t, err) - childchainTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(validatorSrv.JSONRPC())) + childchainTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(childEthEndpoint)) require.NoError(t, err) t.Run("bridge native tokens", func(t *testing.T) { @@ -765,10 +766,10 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { require.NoError(t, err) } - latestBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) + latestBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) - extra, err := polybft.GetIbftExtra(latestBlock.ExtraData) + extra, err := polybft.GetIbftExtra(latestBlock.Header.ExtraData) require.NoError(t, err) // wait for checkpoint to get submitted before invoking exit transactions @@ -804,7 +805,7 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { balancesBefore := make([]*big.Int, transfersCount) for i := uint64(0); i < transfersCount; i++ { - balancesBefore[i], err = childEthEndpoint.GetBalance(ethgo.Address(depositors[i]), ethgo.Latest) + balancesBefore[i], err = childEthEndpoint.GetBalance(depositors[i], jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) } @@ -857,7 +858,7 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { erc721DeployTxn := cluster.Deploy(t, admin, contractsapi.RootERC721.Bytecode) require.NoError(t, erc721DeployTxn.Wait()) require.True(t, erc721DeployTxn.Succeed()) - rootERC721Token := erc721DeployTxn.Receipt().ContractAddress + rootERC721Token := types.Address(erc721DeployTxn.Receipt().ContractAddress) for _, depositor := range depositors { // mint all the depositors in advance @@ -865,7 +866,7 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { mintInput, err := mintFn.EncodeAbi() require.NoError(t, err) - mintTxn := cluster.MethodTxn(t, admin, types.Address(rootERC721Token), mintInput) + mintTxn := cluster.MethodTxn(t, admin, rootERC721Token, mintInput) require.NoError(t, mintTxn.Wait()) require.True(t, mintTxn.Succeed()) @@ -876,7 +877,7 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { // deposit should fail because depositors are in bridge block list err = cluster.Bridge.Deposit( common.ERC721, - types.Address(rootERC721Token), + rootERC721Token, contracts.RootMintableERC721PredicateContract, depositorKeys[0], depositors[0].String(), @@ -906,10 +907,10 @@ func TestE2E_Bridge_ChildchainTokensTransfer(t *testing.T) { require.NoError(t, err) } - childChainBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) + childChainBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) - childChainBlockExtra, err := polybft.GetIbftExtra(childChainBlock.ExtraData) + childChainBlockExtra, err := polybft.GetIbftExtra(childChainBlock.Header.ExtraData) require.NoError(t, err) // wait for checkpoint to be submitted @@ -1089,8 +1090,8 @@ func TestE2E_Bridge_Transfers_AccessLists(t *testing.T) { require.NoError(t, err) validatorSrv := cluster.Servers[0] - childEthEndpoint := validatorSrv.JSONRPC().Eth() - relayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(validatorSrv.JSONRPC())) + childEthEndpoint := validatorSrv.JSONRPC() + relayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(childEthEndpoint)) require.NoError(t, err) senderAccount, err := validatorHelper.GetAccountFromDir(validatorSrv.DataDir()) @@ -1210,13 +1211,13 @@ func TestE2E_Bridge_Transfers_AccessLists(t *testing.T) { false) require.ErrorContains(t, err, "failed to send withdraw transaction") - currentBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) + currentBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) - currentExtra, err := polybft.GetIbftExtra(currentBlock.ExtraData) + currentExtra, err := polybft.GetIbftExtra(currentBlock.Header.ExtraData) require.NoError(t, err) - t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number, currentExtra.Checkpoint.EpochNumber) + t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number(), currentExtra.Checkpoint.EpochNumber) currentEpoch := currentExtra.Checkpoint.EpochNumber @@ -1307,7 +1308,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { rootchainTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Bridge.JSONRPCAddr())) require.NoError(t, err) - childEthEndpoint := cluster.Servers[0].JSONRPC().Eth() + childEthEndpoint := cluster.Servers[0].JSONRPC() defer cluster.Stop() @@ -1328,7 +1329,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { t.Log("Balance of native ERC20 token on root", balance, "Address", address) require.Equal(t, rootExpected, balance) - balance, err = childEthEndpoint.GetBalance(ethgo.Address(address), ethgo.Latest) + balance, err = childEthEndpoint.GetBalance(address, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Log("Balance of native ERC20 token on child", balance, "Address", address) @@ -1377,7 +1378,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { require.NoError(t, err) validatorBalanceAfterWithdraw, err := childEthEndpoint.GetBalance( - ethgo.Address(validatorAcc.Address()), ethgo.Latest) + validatorAcc.Address(), jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) err = cluster.Bridge.Withdraw( @@ -1393,16 +1394,16 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { require.NoError(t, err) nonValidatorBalanceAfterWithdraw, err := childEthEndpoint.GetBalance( - ethgo.Address(nonValidatorKey.Address()), ethgo.Latest) + nonValidatorKey.Address(), jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) - currentBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) + currentBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) - currentExtra, err := polybft.GetIbftExtra(currentBlock.ExtraData) + currentExtra, err := polybft.GetIbftExtra(currentBlock.Header.ExtraData) require.NoError(t, err) - t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number, currentExtra.Checkpoint.EpochNumber) + t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number(), currentExtra.Checkpoint.EpochNumber) currentEpoch := currentExtra.Checkpoint.EpochNumber @@ -1442,11 +1443,11 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) { false), ) - currentBlock, err := childEthEndpoint.GetBlockByNumber(ethgo.Latest, false) + currentBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) // wait for a couple of sprints - finalBlockNum := currentBlock.Number + 5*sprintSize + finalBlockNum := currentBlock.Header.Number + 5*sprintSize // the transaction is processed and there should be a success event var stateSyncedResult contractsapi.StateSyncResultEvent diff --git a/e2e-polybft/e2e/burn_contract_test.go b/e2e-polybft/e2e/burn_contract_test.go index 057eb8e718..f7224c64fe 100644 --- a/e2e-polybft/e2e/burn_contract_test.go +++ b/e2e-polybft/e2e/burn_contract_test.go @@ -6,9 +6,9 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/require" - "github.com/umbracle/ethgo" ) func TestE2E_BurnContract_Deployed(t *testing.T) { @@ -30,10 +30,10 @@ func TestE2E_BurnContract_Deployed(t *testing.T) { defer cluster.Stop() cluster.WaitForReady(t) - client := cluster.Servers[0].JSONRPC().Eth() + client := cluster.Servers[0].JSONRPC() // Get the code for the default deployed burn contract - code, err := client.GetCode(ethgo.Address(contractAddr), ethgo.Latest) + code, err := client.GetCode(contractAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) require.NotEqual(t, code, "0x") } diff --git a/e2e-polybft/e2e/consensus_test.go b/e2e-polybft/e2e/consensus_test.go index dfd8d50561..f03d2d1af1 100644 --- a/e2e-polybft/e2e/consensus_test.go +++ b/e2e-polybft/e2e/consensus_test.go @@ -23,6 +23,7 @@ import ( "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" ) @@ -60,7 +61,7 @@ func TestE2E_Consensus_Basic(t *testing.T) { t.Run("sync protocol, drop single validator node", func(t *testing.T) { // query the current block number, as it is a starting point for the test - currentBlockNum, err := cluster.Servers[0].JSONRPC().Eth().BlockNumber() + currentBlockNum, err := cluster.Servers[0].JSONRPC().BlockNumber() require.NoError(t, err) // stop one node @@ -79,7 +80,7 @@ func TestE2E_Consensus_Basic(t *testing.T) { t.Run("sync protocol, drop single non-validator node", func(t *testing.T) { // query the current block number, as it is a starting point for the test - currentBlockNum, err := cluster.Servers[0].JSONRPC().Eth().BlockNumber() + currentBlockNum, err := cluster.Servers[0].JSONRPC().BlockNumber() require.NoError(t, err) // stop one non-validator node @@ -192,10 +193,10 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { require.NoError(t, err) require.Equal(t, validatorSetSize+2, len(validatorSecrets)) - genesisBlock, err := owner.JSONRPC().Eth().GetBlockByNumber(0, false) + genesisBlock, err := owner.JSONRPC().GetBlockByNumber(0, false) require.NoError(t, err) - _, err = polybft.GetIbftExtra(genesisBlock.ExtraData) + _, err = polybft.GetIbftExtra(genesisBlock.Header.ExtraData) require.NoError(t, err) // owner whitelists both new validators @@ -212,12 +213,12 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { []*big.Int{initialBalance, initialBalance}, polybftConfig.StakeTokenAddr)) // first validator's balance to be received - firstBalance, err := relayer.Client().Eth().GetBalance(ethgo.Address(firstValidatorAddr), ethgo.Latest) + firstBalance, err := relayer.Client().GetBalance(firstValidatorAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Logf("First validator balance=%d\n", firstBalance) // second validator's balance to be received - secondBalance, err := relayer.Client().Eth().GetBalance(ethgo.Address(secondValidatorAddr), ethgo.Latest) + secondBalance, err := relayer.Client().GetBalance(secondValidatorAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Logf("Second validator balance=%d\n", secondBalance) @@ -251,11 +252,11 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { require.True(t, secondValidatorInfo.IsActive) require.True(t, secondValidatorInfo.Stake.Cmp(stakeAmount) == 0) - currentBlock, err := owner.JSONRPC().Eth().GetBlockByNumber(ethgo.Latest, false) + currentBlock, err := owner.JSONRPC().GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) // wait for couple of epochs to have some rewards accumulated - require.NoError(t, cluster.WaitForBlock(currentBlock.Number+(polybftConfig.EpochSize*2), time.Minute)) + require.NoError(t, cluster.WaitForBlock(currentBlock.Header.Number+(polybftConfig.EpochSize*2), time.Minute)) bigZero := big.NewInt(0) @@ -271,10 +272,10 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { // wait until one of the validators mine one block to check if they joined consensus require.NoError(t, cluster.WaitUntil(3*time.Minute, 2*time.Second, func() bool { - latestBlock, err := cluster.Servers[0].JSONRPC().Eth().GetBlockByNumber(ethgo.Latest, false) + latestBlock, err := cluster.Servers[0].JSONRPC().GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) - blockMiner := latestBlock.Miner.Bytes() + blockMiner := latestBlock.Header.Miner return bytes.Equal(firstValidatorAddr.Bytes(), blockMiner) || bytes.Equal(secondValidatorAddr.Bytes(), blockMiner) @@ -309,9 +310,9 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { cluster.WaitForReady(t) - validatorAddr := ethgo.Address(validatorAcc.Ecdsa.Address()) + validatorAddr := validatorAcc.Ecdsa.Address() - initialValidatorBalance, err := srv.JSONRPC().Eth().GetBalance(validatorAddr, ethgo.Latest) + initialValidatorBalance, err := srv.JSONRPC().GetBalance(validatorAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Logf("Balance (before unstake)=%d\n", initialValidatorBalance) @@ -332,11 +333,11 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { // unstake entire balance (which should remove validator from the validator set in next epoch) require.NoError(t, srv.Unstake(initialStake)) - currentBlock, err := srv.JSONRPC().Eth().GetBlockByNumber(ethgo.Latest, false) + currentBlock, err := srv.JSONRPC().GetBlockByNumber(jsonrpc.LatestBlockNumber, false) require.NoError(t, err) // wait for couple of epochs to withdraw stake - require.NoError(t, cluster.WaitForBlock(currentBlock.Number+(polybftCfg.EpochSize*2), time.Minute)) + require.NoError(t, cluster.WaitForBlock(currentBlock.Header.Number+(polybftCfg.EpochSize*2), time.Minute)) require.NoError(t, srv.WitdhrawStake()) // check that validator is no longer active (out of validator set) @@ -347,14 +348,14 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { t.Logf("Stake (after unstake and withdraw)=%d\n", validatorInfo.Stake) - balanceBeforeRewardsWithdraw, err := srv.JSONRPC().Eth().GetBalance(validatorAddr, ethgo.Latest) + balanceBeforeRewardsWithdraw, err := srv.JSONRPC().GetBalance(validatorAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Logf("Balance (before withdraw rewards)=%d\n", balanceBeforeRewardsWithdraw) // withdraw pending rewards require.NoError(t, srv.WithdrawRewards()) - newValidatorBalance, err := srv.JSONRPC().Eth().GetBalance(validatorAddr, ethgo.Latest) + newValidatorBalance, err := srv.JSONRPC().GetBalance(validatorAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Logf("Balance (after withdrawal of rewards)=%s\n", newValidatorBalance) require.True(t, newValidatorBalance.Cmp(balanceBeforeRewardsWithdraw) > 0) @@ -433,7 +434,7 @@ func TestE2E_Consensus_MintableERC20NativeToken(t *testing.T) { mintAmount := ethgo.Ether(1) // make sure minter account can mint tokens - balanceBefore, err := targetJSONRPC.Eth().GetBalance(ethgo.Address(receiver.Address()), ethgo.Latest) + balanceBefore, err := targetJSONRPC.GetBalance(receiver.Address(), jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Logf("Pre-mint balance: %v=%d\n", receiver.Address(), balanceBefore) @@ -456,7 +457,7 @@ func TestE2E_Consensus_MintableERC20NativeToken(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) - balanceAfter, err := targetJSONRPC.Eth().GetBalance(ethgo.Address(receiver.Address()), ethgo.Latest) + balanceAfter, err := targetJSONRPC.GetBalance(receiver.Address(), jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) t.Logf("Post-mint balance: %v=%d\n", receiver.Address(), balanceAfter) @@ -535,11 +536,11 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { cluster.WaitForReady(t) - client := cluster.Servers[0].JSONRPC().Eth() + client := cluster.Servers[0].JSONRPC() waitUntilBalancesChanged := func(acct types.Address, initialBalance *big.Int) error { err := cluster.WaitUntil(30*time.Second, 1*time.Second, func() bool { - balance, err := client.GetBalance(ethgo.Address(acct), ethgo.Latest) + balance, err := client.GetBalance(acct, jsonrpc.LatestBlockNumberOrHash) if err != nil { return true } @@ -575,12 +576,12 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { initialMinerBalance := big.NewInt(0) - prevMiner := ethgo.ZeroAddress + prevMiner := types.ZeroAddress.Bytes() for i, txn := range txns { - senderInitialBalance, _ := client.GetBalance(ethgo.Address(sender.Address()), ethgo.Latest) - receiverInitialBalance, _ := client.GetBalance(ethgo.Address(recipient), ethgo.Latest) - burnContractInitialBalance, _ := client.GetBalance(ethgo.Address(types.ZeroAddress), ethgo.Latest) + senderInitialBalance, _ := client.GetBalance(sender.Address(), jsonrpc.LatestBlockNumberOrHash) + receiverInitialBalance, _ := client.GetBalance(recipient, jsonrpc.LatestBlockNumberOrHash) + burnContractInitialBalance, _ := client.GetBalance(types.ZeroAddress, jsonrpc.LatestBlockNumberOrHash) receipt, err := relayer.SendTransaction(txn, sender) require.NoError(t, err) @@ -590,21 +591,21 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { err = waitUntilBalancesChanged(recipient, receiverInitialBalance) require.NoError(t, err) - block, _ := client.GetBlockByHash(receipt.BlockHash, true) - finalMinerFinalBalance, _ := client.GetBalance(block.Miner, ethgo.Latest) + block, _ := client.GetBlockByHash(types.Hash(receipt.BlockHash), true) + finalMinerFinalBalance, _ := client.GetBalance(types.BytesToAddress(block.Header.Miner), jsonrpc.LatestBlockNumberOrHash) if i == 0 { - prevMiner = block.Miner + prevMiner = block.Header.Miner } - senderFinalBalance, _ := client.GetBalance(ethgo.Address(sender.Address()), ethgo.Latest) - receiverFinalBalance, _ := client.GetBalance(ethgo.Address(recipient), ethgo.Latest) - burnContractFinalBalance, _ := client.GetBalance(ethgo.Address(types.ZeroAddress), ethgo.Latest) + senderFinalBalance, _ := client.GetBalance(sender.Address(), jsonrpc.LatestBlockNumberOrHash) + receiverFinalBalance, _ := client.GetBalance(recipient, jsonrpc.LatestBlockNumberOrHash) + burnContractFinalBalance, _ := client.GetBalance(types.ZeroAddress, jsonrpc.LatestBlockNumberOrHash) diffReceiverBalance := new(big.Int).Sub(receiverFinalBalance, receiverInitialBalance) require.Equal(t, sendAmount, diffReceiverBalance, "Receiver balance should be increased by send amount") - if i == 1 && prevMiner != block.Miner { + if i == 1 && bytes.Equal(prevMiner, block.Header.Miner) { initialMinerBalance = big.NewInt(0) } @@ -718,12 +719,12 @@ func TestE2E_Consensus_ChangeVotingPowerByStakingPendingRewards(t *testing.T) { for i := 0; i < numOfEpochsToCheckChange; i++ { require.NoError(t, cluster.WaitForBlock(epochEndingBlock, time.Minute)) - latestBlock, err := cluster.Servers[0].JSONRPC().Eth().GetBlockByNumber(ethgo.BlockNumber(epochEndingBlock), false) + latestBlock, err := cluster.Servers[0].JSONRPC().GetBlockByNumber(jsonrpc.BlockNumber(epochEndingBlock), false) require.NoError(t, err) epochEndingBlock += epochSize - currentExtra, err := polybft.GetIbftExtra(latestBlock.ExtraData) + currentExtra, err := polybft.GetIbftExtra(latestBlock.Header.ExtraData) require.NoError(t, err) if currentExtra.Validators == nil || currentExtra.Validators.IsEmpty() { diff --git a/e2e-polybft/e2e/governance_test.go b/e2e-polybft/e2e/governance_test.go index edcbef1653..e9b47da7ce 100644 --- a/e2e-polybft/e2e/governance_test.go +++ b/e2e-polybft/e2e/governance_test.go @@ -13,10 +13,10 @@ import ( "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/require" - "github.com/umbracle/ethgo" ) type VoteType uint8 @@ -119,7 +119,7 @@ func TestE2E_Governance_ProposeAndExecuteSimpleProposal(t *testing.T) { return proposalState == Queued })) - currentBlockNumber, err := relayer.Client().Eth().BlockNumber() + currentBlockNumber, err := relayer.Client().BlockNumber() require.NoError(t, err) // wait for couple of more blocks because of execution delay @@ -131,7 +131,7 @@ func TestE2E_Governance_ProposeAndExecuteSimpleProposal(t *testing.T) { polybftCfg.GovernanceConfig.NetworkParamsAddr, proposalInput, proposalDescription) - currentBlockNumber, err = relayer.Client().Eth().BlockNumber() + currentBlockNumber, err = relayer.Client().BlockNumber() require.NoError(t, err) // check if epoch size changed on NetworkParams @@ -149,20 +149,20 @@ func TestE2E_Governance_ProposeAndExecuteSimpleProposal(t *testing.T) { // wait until the new epoch (with new size finishes) require.NoError(t, cluster.WaitForBlock(endOfNewEpoch, 3*time.Minute)) - block, err := relayer.Client().Eth().GetBlockByNumber( - ethgo.BlockNumber(endOfPreviousEpoch), false) + block, err := relayer.Client().GetBlockByNumber( + jsonrpc.BlockNumber(endOfPreviousEpoch), false) require.NoError(t, err) - extra, err := polybft.GetIbftExtra(block.ExtraData) + extra, err := polybft.GetIbftExtra(block.Header.ExtraData) require.NoError(t, err) oldEpoch := extra.Checkpoint.EpochNumber - block, err = relayer.Client().Eth().GetBlockByNumber( - ethgo.BlockNumber(endOfNewEpoch), false) + block, err = relayer.Client().GetBlockByNumber( + jsonrpc.BlockNumber(endOfNewEpoch), false) require.NoError(t, err) - extra, err = polybft.GetIbftExtra(block.ExtraData) + extra, err = polybft.GetIbftExtra(block.Header.ExtraData) require.NoError(t, err) newEpoch := extra.Checkpoint.EpochNumber @@ -209,7 +209,7 @@ func TestE2E_Governance_ProposeAndExecuteSimpleProposal(t *testing.T) { relayer, voterAcc.Ecdsa) } - currentBlockNumber, err := relayer.Client().Eth().BlockNumber() + currentBlockNumber, err := relayer.Client().BlockNumber() require.NoError(t, err) // wait for voting period to end @@ -277,7 +277,7 @@ func TestE2E_Governance_ProposeAndExecuteSimpleProposal(t *testing.T) { return proposalState == Queued })) - currentBlockNumber, err := relayer.Client().Eth().BlockNumber() + currentBlockNumber, err := relayer.Client().BlockNumber() require.NoError(t, err) // wait for couple of more blocks because of execution delay diff --git a/e2e-polybft/e2e/helpers_test.go b/e2e-polybft/e2e/helpers_test.go index 3290eeef6d..b623d5a6c8 100644 --- a/e2e-polybft/e2e/helpers_test.go +++ b/e2e-polybft/e2e/helpers_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/abi" - "github.com/umbracle/ethgo/jsonrpc" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/contracts" @@ -33,7 +33,13 @@ func ABICall(relayer txrelayer.TxRelayer, artifact *contracts.Artifact, contract return relayer.Call(senderAddr, contractAddress, input) } -func ABITransaction(relayer txrelayer.TxRelayer, key crypto.Key, artifact *contracts.Artifact, contractAddress types.Address, method string, params ...interface{}) (*ethgo.Receipt, error) { +func ABITransaction( + relayer txrelayer.TxRelayer, + key crypto.Key, + artifact *contracts.Artifact, + contractAddress types.Address, + method string, + params ...interface{}) (*ethgo.Receipt, error) { input, err := artifact.Abi.GetMethod(method).Encode(params) if err != nil { return nil, err @@ -157,7 +163,7 @@ func expectRole(t *testing.T, cluster *framework.TestCluster, contract types.Add // getFilteredLogs retrieves Ethereum logs, described by event signature within the block range func getFilteredLogs(eventSig ethgo.Hash, startBlock, endBlock uint64, - ethEndpoint *jsonrpc.Eth) ([]*ethgo.Log, error) { + ethEndpoint *jsonrpc.EthClient) ([]*ethgo.Log, error) { filter := ðgo.LogFilter{Topics: [][]*ethgo.Hash{{&eventSig}}} filter.SetFromUint64(startBlock) diff --git a/e2e-polybft/e2e/jsonrpc_test.go b/e2e-polybft/e2e/jsonrpc_test.go index 8741c7715d..ff46c54622 100644 --- a/e2e-polybft/e2e/jsonrpc_test.go +++ b/e2e-polybft/e2e/jsonrpc_test.go @@ -7,16 +7,13 @@ import ( "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" - "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/helper/tests" bladeRPC "github.com/0xPolygon/polygon-edge/jsonrpc" - "github.com/0xPolygon/polygon-edge/state" "github.com/0xPolygon/polygon-edge/types" ) @@ -25,447 +22,6 @@ var ( ) func TestE2E_JsonRPC(t *testing.T) { - senderKey, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - cluster := framework.NewTestCluster(t, 4, - framework.WithPremine(senderKey.Address()), - framework.WithHTTPS("/etc/ssl/certs/localhost.pem", "/etc/ssl/private/localhost.key"), - ) - defer cluster.Stop() - - cluster.WaitForReady(t) - - jsonRPC := cluster.Servers[0].JSONRPC() - client := jsonRPC.Eth() - debug := jsonRPC.Debug() - - // Test eth_call with override in state diff - t.Run("eth_call state override", func(t *testing.T) { - deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) - require.NoError(t, deployTxn.Wait()) - require.True(t, deployTxn.Succeed()) - - target := deployTxn.Receipt().ContractAddress - - input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() - - resp, err := client.Call(ðgo.CallMsg{To: &target, Data: input}, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resp) - - override := ðgo.StateOverride{ - target: ethgo.OverrideAccount{ - StateDiff: &map[ethgo.Hash]ethgo.Hash{ - // storage slot 0 stores the 'val' uint256 value - {0x0}: {0x3}, - }, - }, - } - - resp, err = client.Call(ðgo.CallMsg{To: &target, Data: input}, ethgo.Latest, override) - require.NoError(t, err) - - require.Equal(t, "0x0300000000000000000000000000000000000000000000000000000000000000", resp) - }) - - // Test eth_call with zero account balance - t.Run("eth_call with zero-balance account", func(t *testing.T) { - deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) - require.NoError(t, deployTxn.Wait()) - require.True(t, deployTxn.Succeed()) - - target := deployTxn.Receipt().ContractAddress - - input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() - - acctZeroBalance, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - resp, err := client.Call(ðgo.CallMsg{ - From: ethgo.Address(acctZeroBalance.Address()), - To: &target, - Data: input, - }, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resp) - }) - - t.Run("eth_estimateGas", func(t *testing.T) { - deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) - require.NoError(t, deployTxn.Wait()) - require.True(t, deployTxn.Succeed()) - - target := deployTxn.Receipt().ContractAddress - - input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() - - estimatedGas, err := client.EstimateGas(ðgo.CallMsg{ - From: ethgo.Address(senderKey.Address()), - To: &target, - Data: input, - }) - require.NoError(t, err) - require.Equal(t, uint64(0x5bb7), estimatedGas) - }) - - t.Run("eth_estimateGas by zero-balance account", func(t *testing.T) { - deployTxn := cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) - require.NoError(t, deployTxn.Wait()) - require.True(t, deployTxn.Succeed()) - - target := deployTxn.Receipt().ContractAddress - input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() - - acctZeroBalance, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - resp, err := client.EstimateGas(ðgo.CallMsg{ - From: ethgo.Address(acctZeroBalance.Address()), - To: &target, - Data: input, - }) - require.NoError(t, err) - require.Equal(t, uint64(0x5bb7), resp) - }) - - t.Run("eth_estimateGas by zero-balance account - simple value transfer", func(t *testing.T) { - acctZeroBalance, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - fundedAccountAddress := senderKey.Address() - nonFundedAccountAddress := acctZeroBalance.Address() - - estimateGasFn := func(value *big.Int) { - resp, err := client.EstimateGas(ðgo.CallMsg{ - From: ethgo.Address(nonFundedAccountAddress), - To: (*ethgo.Address)(&fundedAccountAddress), - Value: value, - }) - - require.NoError(t, err) - require.Equal(t, state.TxGas, resp) - } - - estimateGasFn(ethgo.Gwei(1)) - - // transfer some funds to zero balance account - valueTransferTxn := cluster.SendTxn(t, senderKey, - types.NewTx(types.NewLegacyTx( - types.WithFrom(fundedAccountAddress), - types.WithTo(&nonFundedAccountAddress), - types.WithValue(ethgo.Gwei(10)), - ))) - - require.NoError(t, valueTransferTxn.Wait()) - require.True(t, valueTransferTxn.Succeed()) - - // now call estimate gas again for the now funded account - estimateGasFn(ethgo.Gwei(1)) - }) - - t.Run("eth_getBalance", func(t *testing.T) { - recipientKey, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - recipientAddr := ethgo.Address(recipientKey.Address()) - - // Test. return zero if the account does not exist - balance1, err := client.GetBalance(recipientAddr, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, balance1, big.NewInt(0)) - - // Test. return the balance of an account - newBalance := ethgo.Ether(1) - txn := cluster.Transfer(t, senderKey, recipientKey.Address(), newBalance) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - balance1, err = client.GetBalance(recipientAddr, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, balance1, newBalance) - - // Test. return 0 if the balance of an existing account is empty - gasPrice, err := client.GasPrice() - require.NoError(t, err) - - estimatedGas, err := client.EstimateGas(ðgo.CallMsg{ - From: ethgo.Address(senderKey.Address()), - To: &recipientAddr, - Value: newBalance, - }) - require.NoError(t, err) - - txPrice := gasPrice * estimatedGas - // subtract gasPrice * estimatedGas from the balance and transfer the rest to the other account - // in order to leave no funds on the account - amountToSend := new(big.Int).Sub(newBalance, big.NewInt(int64(txPrice))) - targetAddr := senderKey.Address() - txn = cluster.SendTxn(t, recipientKey, - types.NewTx(types.NewLegacyTx( - types.WithTo(&targetAddr), - types.WithValue(amountToSend), - types.WithGas(estimatedGas), - ))) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - balance1, err = client.GetBalance(ethgo.Address(recipientKey.Address()), ethgo.Latest) - require.NoError(t, err) - require.Equal(t, big.NewInt(0), balance1) - }) - - t.Run("eth_getTransactionCount", func(t *testing.T) { - recipientKey, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - recipient := ethgo.Address(recipientKey.Address()) - - nonce, err := client.GetNonce(recipient, ethgo.Latest) - require.Equal(t, uint64(0), nonce) - require.NoError(t, err) - - txn := cluster.Transfer(t, senderKey, types.Address(recipient), big.NewInt(10000000000000000)) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - // Test. increase the nonce with new transactions - txn = cluster.Transfer(t, recipientKey, types.ZeroAddress, big.NewInt(0)) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - nonce1, err := client.GetNonce(recipient, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, nonce1, uint64(1)) - - // Test. you can query the nonce at any block number in time - nonce1, err = client.GetNonce(recipient, ethgo.BlockNumber(txn.Receipt().BlockNumber-1)) - require.NoError(t, err) - require.Equal(t, nonce1, uint64(0)) - - block, err := client.GetBlockByNumber(ethgo.BlockNumber(txn.Receipt().BlockNumber)-1, false) - require.NoError(t, err) - - _, err = client.GetNonce(recipient, ethgo.BlockNumber(block.Number)) - require.NoError(t, err) - }) - - t.Run("eth_getStorageAt", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - txn = cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - target := txn.Receipt().ContractAddress - - resp, err := client.GetStorageAt(target, ethgo.Hash{}, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", resp.String()) - - setValueFn := contractsapi.TestSimple.Abi.GetMethod("setValue") - - newVal := big.NewInt(1) - - input, err := setValueFn.Encode([]interface{}{newVal}) - require.NoError(t, err) - - txn = cluster.SendTxn(t, senderKey, - types.NewTx( - types.NewLegacyTx(types.WithInput(input), types.WithTo((*types.Address)(&target))), - )) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - resp, err = client.GetStorageAt(target, ethgo.Hash{}, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000001", resp.String()) - }) - - t.Run("eth_getCode", func(t *testing.T) { - // we use a predefined private key so that the deployed contract address is deterministic. - // Note that in order to work, this private key should only be used for this test. - priv, err := hex.DecodeString("2c15bd0dc992a47ca660983ae4b611f4ffb6178e14e04e2b34d153f3a74ce741") - require.NoError(t, err) - key1, err := crypto.NewECDSAKeyFromRawPrivECDSA(priv) - require.NoError(t, err) - - // fund the account so that it can deploy a contract - txn := cluster.Transfer(t, senderKey, key1.Address(), ethgo.Ether(1)) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - codeAddr := ethgo.HexToAddress("0xDBfca0c43cA12759256a7Dd587Dc4c6EEC1D89A5") - - // Test. We get empty code from an empty contract - code, err := client.GetCode(codeAddr, ethgo.Latest) - require.NoError(t, err) - require.Equal(t, code, "0x") - - txn = cluster.Deploy(t, key1, contractsapi.TestSimple.Bytecode) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - receipt := txn.Receipt() - - // Test. The deployed address is the one expected - require.Equal(t, codeAddr, receipt.ContractAddress) - - // Test. We can retrieve the code by address on latest, block number and block hash - cases := []ethgo.BlockNumberOrHash{ - ethgo.Latest, - ethgo.BlockNumber(receipt.BlockNumber), - } - for _, c := range cases { - code, err = client.GetCode(codeAddr, c) - require.NoError(t, err) - require.NotEqual(t, code, "0x") - } - - // Test. We can query in past state (when the code was empty) - code, err = client.GetCode(codeAddr, ethgo.BlockNumber(receipt.BlockNumber-1)) - require.NoError(t, err) - require.Equal(t, code, "0x") - - // Test. Query by pending should default to latest - code, err = client.GetCode(codeAddr, ethgo.Pending) - require.NoError(t, err) - require.NotEqual(t, code, "0x") - }) - - t.Run("eth_getBlockByHash", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - txReceipt := txn.Receipt() - - block, err := client.GetBlockByHash(txReceipt.BlockHash, false) - require.NoError(t, err) - require.Equal(t, txReceipt.BlockNumber, block.Number) - require.Equal(t, txReceipt.BlockHash, block.Hash) - }) - - t.Run("eth_getBlockByNumber", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - txReceipt := txn.Receipt() - - block, err := client.GetBlockByNumber(ethgo.BlockNumber(txReceipt.BlockNumber), false) - require.NoError(t, err) - require.Equal(t, txReceipt.BlockNumber, block.Number) - require.Equal(t, txReceipt.BlockHash, block.Hash) - }) - - t.Run("eth_getTransactionReceipt", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - // Test. We cannot retrieve a receipt of an empty hash - emptyReceipt, err := client.GetTransactionReceipt(ethgo.ZeroHash) - require.NoError(t, err) // Note that ethgo does not return an error when the item does not exists - require.Nil(t, emptyReceipt) - - // Test. We can retrieve the receipt by the hash - receipt, err := client.GetTransactionReceipt(txn.Receipt().TransactionHash) - require.NoError(t, err) - - // Test. The populated fields match with the block - block, err := client.GetBlockByHash(receipt.BlockHash, false) - require.NoError(t, err) - - require.Equal(t, receipt.TransactionHash, txn.Receipt().TransactionHash) - require.Equal(t, receipt.BlockNumber, block.Number) - require.Equal(t, receipt.BlockHash, block.Hash) - - // Test. The receipt of a deployed contract has the 'ContractAddress' field. - txn = cluster.Deploy(t, senderKey, contractsapi.TestSimple.Bytecode) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - require.NotEqual(t, txn.Receipt().ContractAddress, ethgo.ZeroAddress) - }) - - t.Run("eth_getTransactionByHash", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - // Test. We should be able to query the transaction by its hash - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - ethTxn, err := client.GetTransactionByHash(txn.Receipt().TransactionHash) - require.NoError(t, err) - - // Test. The dynamic 'from' field is populated - require.NotEqual(t, ethTxn.From, ethgo.ZeroAddress) - }) - - t.Run("eth_getHeaderByNumber", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - txReceipt := txn.Receipt() - - var header types.Header - err = jsonRPC.Call("eth_getHeaderByNumber", &header, ethgo.BlockNumber(txReceipt.BlockNumber)) - require.NoError(t, err) - - require.Equal(t, txReceipt.BlockNumber, header.Number) - require.Equal(t, txReceipt.BlockHash, ethgo.Hash(header.Hash)) - }) - - t.Run("eth_getHeaderByHash", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - txReceipt := txn.Receipt() - - var header types.Header - err = jsonRPC.Call("eth_getHeaderByHash", &header, txReceipt.BlockHash) - require.NoError(t, err) - - require.Equal(t, txReceipt.BlockNumber, header.Number) - require.Equal(t, txReceipt.BlockHash, ethgo.Hash(header.Hash)) - }) - - t.Run("debug_traceTransaction", func(t *testing.T) { - key1, err := crypto.GenerateECDSAKey() - require.NoError(t, err) - - txn := cluster.Transfer(t, senderKey, key1.Address(), one) - require.NoError(t, txn.Wait()) - require.True(t, txn.Succeed()) - - txReceipt := txn.Receipt() - - // Use a wrapper function from "jsonrpc" package when the config is introduced. - trace, err := debug.TraceTransaction(txReceipt.TransactionHash, jsonrpc.TraceTransactionOptions{}) - require.NoError(t, err) - require.Equal(t, txReceipt.GasUsed, trace.Gas) - }) -} - -func TestE2E_JsonRPC_NewEthClient(t *testing.T) { const epochSize = uint64(5) preminedAcct, err := crypto.GenerateECDSAKey() @@ -546,9 +102,9 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { require.NoError(t, deployTxn.Wait()) require.True(t, deployTxn.Succeed()) - target := deployTxn.Receipt().ContractAddress + target := types.Address(deployTxn.Receipt().ContractAddress) - code, err := newEthClient.GetCode(types.Address(target), bladeRPC.LatestBlockNumberOrHash) + code, err := newEthClient.GetCode(target, bladeRPC.LatestBlockNumberOrHash) require.NoError(t, err) require.NotEmpty(t, code) }) @@ -582,7 +138,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { require.NoError(t, txn.Wait()) require.True(t, txn.Succeed()) - resp, err = newEthClient.GetStorageAt(types.Address(target), types.Hash{}, bladeRPC.LatestBlockNumberOrHash) + resp, err = newEthClient.GetStorageAt(target, types.Hash{}, bladeRPC.LatestBlockNumberOrHash) require.NoError(t, err) require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000001", resp.String()) }) @@ -600,7 +156,7 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { receipt, err := newEthClient.GetTransactionReceipt(ethTxn.Hash()) require.NoError(t, err) require.NotNil(t, receipt) - require.Equal(t, ethTxn.Hash(), receipt.TxHash) + require.Equal(t, ethTxn.Hash(), types.Hash(receipt.TransactionHash)) }) t.Run("eth_getTransactionCount", func(t *testing.T) { @@ -641,7 +197,6 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { require.True(t, deployTxn.Succeed()) target := types.Address(deployTxn.Receipt().ContractAddress) - input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() estimatedGas, err := newEthClient.EstimateGas(&bladeRPC.CallMsg{ @@ -665,7 +220,6 @@ func TestE2E_JsonRPC_NewEthClient(t *testing.T) { require.True(t, deployTxn.Succeed()) target := types.Address(deployTxn.Receipt().ContractAddress) - input := contractsapi.TestSimple.Abi.GetMethod("getValue").ID() acctZeroBalance, err := crypto.GenerateECDSAKey() diff --git a/e2e-polybft/e2e/migration_test.go b/e2e-polybft/e2e/migration_test.go index c86cd23a55..2d33a164bc 100644 --- a/e2e-polybft/e2e/migration_test.go +++ b/e2e-polybft/e2e/migration_test.go @@ -17,6 +17,7 @@ import ( frameworkpolybft "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/e2e/framework" "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/jsonrpc" itrie "github.com/0xPolygon/polygon-edge/state/immutable-trie" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -24,9 +25,9 @@ import ( func TestE2E_Migration(t *testing.T) { userKey, _ := crypto.GenerateECDSAKey() - userAddr := ethgo.Address(userKey.Address()) + userAddr := userKey.Address() userKey2, _ := crypto.GenerateECDSAKey() - userAddr2 := ethgo.Address(userKey2.Address()) + userAddr2 := userKey2.Address() initialBalance := ethgo.Ether(10) srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { @@ -41,17 +42,11 @@ func TestE2E_Migration(t *testing.T) { rpcClient := srv.JSONRPC() // Fetch the balances before sending - balanceSender, err := rpcClient.Eth().GetBalance( - userAddr, - ethgo.Latest, - ) + balanceSender, err := rpcClient.GetBalance(userAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) require.Equal(t, balanceSender.Cmp(initialBalance), 0) - balanceReceiver, err := rpcClient.Eth().GetBalance( - userAddr2, - ethgo.Latest, - ) + balanceReceiver, err := rpcClient.GetBalance(userAddr2, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) if balanceReceiver.Uint64() != 0 { @@ -101,25 +96,19 @@ func TestE2E_Migration(t *testing.T) { require.Equal(t, uint64(types.ReceiptSuccess), initReceipt.Status) // Fetch the balances after sending - balanceSender, err = rpcClient.Eth().GetBalance( - userAddr, - ethgo.Latest, - ) + balanceSender, err = rpcClient.GetBalance(userAddr, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) - balanceReceiver, err = rpcClient.Eth().GetBalance( - userAddr2, - ethgo.Latest, - ) + balanceReceiver, err = rpcClient.GetBalance(userAddr2, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) require.Equal(t, sendAmount, balanceReceiver) - block, err := rpcClient.Eth().GetBlockByNumber(ethgo.Latest, true) + block, err := rpcClient.GetBlockByNumber(jsonrpc.LatestBlockNumber, true) if err != nil { t.Fatal(err) } - stateRoot := block.StateRoot + stateRoot := block.Header.StateRoot path := filepath.Join(srvs[0].Config.RootDir, "trie") srvs[0].Stop() @@ -131,7 +120,7 @@ func TestE2E_Migration(t *testing.T) { err = frameworkpolybft.RunEdgeCommand([]string{ "regenesis", - "--stateRoot", block.StateRoot.String(), + "--stateRoot", block.Header.StateRoot.String(), "--source-path", path, "--target-path", tmpDir, }, os.Stdout) @@ -146,7 +135,7 @@ func TestE2E_Migration(t *testing.T) { stateStorageNew := itrie.NewKV(db) - copiedStateRoot, err := itrie.HashChecker(block.StateRoot.Bytes(), stateStorageNew) + copiedStateRoot, err := itrie.HashChecker(block.Header.StateRoot.Bytes(), stateStorageNew) if err != nil { t.Fatal(err) } @@ -168,12 +157,12 @@ func TestE2E_Migration(t *testing.T) { cluster.WaitForReady(t) - senderBalanceAfterMigration, err := cluster.Servers[0].JSONRPC().Eth().GetBalance(userAddr, ethgo.Latest) + senderBalanceAfterMigration, err := cluster.Servers[0].JSONRPC().GetBalance(userAddr, jsonrpc.LatestBlockNumberOrHash) if err != nil { t.Fatal(err) } - receiverBalanceAfterMigration, err := cluster.Servers[0].JSONRPC().Eth().GetBalance(userAddr2, ethgo.Latest) + receiverBalanceAfterMigration, err := cluster.Servers[0].JSONRPC().GetBalance(userAddr2, jsonrpc.LatestBlockNumberOrHash) if err != nil { t.Fatal(err) } @@ -181,7 +170,7 @@ func TestE2E_Migration(t *testing.T) { require.Equal(t, balanceSender, senderBalanceAfterMigration) require.Equal(t, balanceReceiver, receiverBalanceAfterMigration) - deployedCode, err := cluster.Servers[0].JSONRPC().Eth().GetCode(deployedContractBalance, ethgo.Latest) + deployedCode, err := cluster.Servers[0].JSONRPC().GetCode(types.Address(deployedContractBalance), jsonrpc.LatestBlockNumberOrHash) if err != nil { t.Fatal(err) } diff --git a/e2e-polybft/e2e/storage_test.go b/e2e-polybft/e2e/storage_test.go index 8ac1daf8e8..b9ff7424c9 100644 --- a/e2e-polybft/e2e/storage_test.go +++ b/e2e-polybft/e2e/storage_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" "github.com/umbracle/ethgo/wallet" "github.com/0xPolygon/polygon-edge/consensus/polybft" @@ -30,23 +30,23 @@ func TestE2E_Storage(t *testing.T) { cluster.WaitForReady(t) - client := cluster.Servers[0].JSONRPC().Eth() + client := cluster.Servers[0].JSONRPC() num := 20 - receivers := []ethgo.Address{} + receivers := []types.Address{} for i := 0; i < num; i++ { key, err := wallet.GenerateKey() require.NoError(t, err) - receivers = append(receivers, key.Address()) + receivers = append(receivers, types.Address(key.Address())) } txs := []*framework.TestTxn{} for i := 0; i < num; i++ { - func(i int, to ethgo.Address) { + func(i int, to types.Address) { // Send every second transaction as a dynamic fees one var txn *types.Transaction @@ -81,7 +81,7 @@ func TestE2E_Storage(t *testing.T) { err = cluster.WaitUntil(2*time.Minute, 2*time.Second, func() bool { for i, receiver := range receivers { - balance, err := client.GetBalance(receiver, ethgo.Latest) + balance, err := client.GetBalance(receiver, jsonrpc.LatestBlockNumberOrHash) if err != nil { return true } @@ -100,15 +100,15 @@ func TestE2E_Storage(t *testing.T) { checkStorage(t, txs, client) } -func checkStorage(t *testing.T, txs []*framework.TestTxn, client *jsonrpc.Eth) { +func checkStorage(t *testing.T, txs []*framework.TestTxn, client *jsonrpc.EthClient) { t.Helper() for i, tx := range txs { - bn, err := client.GetBlockByNumber(ethgo.BlockNumber(tx.Receipt().BlockNumber), true) + bn, err := client.GetBlockByNumber(jsonrpc.BlockNumber(tx.Receipt().BlockNumber), true) require.NoError(t, err) assert.NotNil(t, bn) - bh, err := client.GetBlockByHash(bn.Hash, true) + bh, err := client.GetBlockByHash(bn.Header.Hash, true) require.NoError(t, err) assert.NotNil(t, bh) @@ -116,36 +116,37 @@ func checkStorage(t *testing.T, txs []*framework.TestTxn, client *jsonrpc.Eth) { t.Fatal("blocks dont match") } - bt, err := client.GetTransactionByHash(tx.Receipt().TransactionHash) + bt, err := client.GetTransactionByHash(types.Hash(tx.Receipt().TransactionHash)) require.NoError(t, err) assert.NotNil(t, bt) - assert.Equal(t, tx.Txn().Value(), bt.Value) - assert.Equal(t, tx.Txn().Gas(), bt.Gas) - assert.Equal(t, tx.Txn().Nonce(), bt.Nonce) + assert.Equal(t, tx.Txn().Value(), bt.Value()) + assert.Equal(t, tx.Txn().Gas(), bt.Gas()) + assert.Equal(t, tx.Txn().Nonce(), bt.Nonce()) assert.Equal(t, tx.Receipt().TransactionIndex, bt.TxnIndex) - assert.NotEmpty(t, bt.V) - assert.NotEmpty(t, bt.R) - assert.NotEmpty(t, bt.S) - assert.Equal(t, tx.Txn().From().Bytes(), bt.From.Bytes()) - assert.Equal(t, tx.Txn().To().Bytes(), bt.To.Bytes()) + v, r, s := bt.RawSignatureValues() + assert.NotEmpty(t, v) + assert.NotEmpty(t, r) + assert.NotEmpty(t, s) + assert.Equal(t, tx.Txn().From().Bytes(), bt.From().Bytes()) + assert.Equal(t, tx.Txn().To().Bytes(), bt.To().Bytes()) if i%2 == 10 { // Intentionally disable it since dynamic fee tx not working - assert.Equal(t, ethgo.TransactionDynamicFee, bt.Type) - assert.Equal(t, uint64(0), bt.GasPrice) - assert.NotNil(t, bt.ChainID) + assert.Equal(t, ethgo.TransactionDynamicFee, bt.Type()) + assert.Equal(t, uint64(0), bt.GasPrice().Uint64()) + assert.NotNil(t, bt.ChainID()) } else { // assert.Equal(t, ethgo.TransactionLegacy, bt.Type) - assert.Equal(t, ethgo.Gwei(2).Uint64(), bt.GasPrice) + assert.Equal(t, ethgo.Gwei(2).Uint64(), bt.GasPrice().Uint64()) } - r, err := client.GetTransactionReceipt(tx.Receipt().TransactionHash) + receipt, err := client.GetTransactionReceipt(types.Hash(tx.Receipt().TransactionHash)) require.NoError(t, err) assert.NotNil(t, r) - assert.Equal(t, bt.TxnIndex, r.TransactionIndex) - assert.Equal(t, bt.Hash, r.TransactionHash) - assert.Equal(t, bt.BlockHash, r.BlockHash) - assert.Equal(t, bt.BlockNumber, r.BlockNumber) - assert.NotEmpty(t, r.LogsBloom) - assert.Equal(t, bt.To, r.To) + assert.Equal(t, bt.TxnIndex, receipt.TransactionIndex) + assert.Equal(t, bt.Hash(), types.Hash(receipt.TransactionHash)) + assert.Equal(t, bt.BlockHash, types.Hash(receipt.BlockHash)) + assert.Equal(t, bt.BlockNumber, receipt.BlockNumber) + assert.NotEmpty(t, receipt.LogsBloom) + assert.Equal(t, bt.To(), (*types.Address)(receipt.To)) } } diff --git a/e2e-polybft/e2e/txpool_test.go b/e2e-polybft/e2e/txpool_test.go index d76d322820..c1d007cd91 100644 --- a/e2e-polybft/e2e/txpool_test.go +++ b/e2e-polybft/e2e/txpool_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" @@ -32,25 +32,25 @@ func TestE2E_TxPool_Transfer(t *testing.T) { cluster.WaitForReady(t) - client := cluster.Servers[0].JSONRPC().Eth() + client := cluster.Servers[0].JSONRPC() sendAmount := 1 num := 20 - receivers := []ethgo.Address{} + receivers := []types.Address{} for i := 0; i < num; i++ { key, err := crypto.GenerateECDSAKey() require.NoError(t, err) - receivers = append(receivers, ethgo.Address(key.Address())) + receivers = append(receivers, key.Address()) } var wg sync.WaitGroup for i := 0; i < num; i++ { wg.Add(1) - go func(i int, to ethgo.Address) { + go func(i int, to types.Address) { defer wg.Done() var txData types.TxData @@ -87,7 +87,7 @@ func TestE2E_TxPool_Transfer(t *testing.T) { err = cluster.WaitUntil(2*time.Minute, 2*time.Second, func() bool { for _, receiver := range receivers { - balance, err := client.GetBalance(receiver, ethgo.Latest) + balance, err := client.GetBalance(receiver, jsonrpc.LatestBlockNumberOrHash) if err != nil { return true } @@ -118,11 +118,11 @@ func TestE2E_TxPool_Transfer_Linear(t *testing.T) { cluster.WaitForReady(t) - client := cluster.Servers[0].JSONRPC().Eth() + client := cluster.Servers[0].JSONRPC() - waitUntilBalancesChanged := func(acct ethgo.Address) error { + waitUntilBalancesChanged := func(acct types.Address) error { err := cluster.WaitUntil(30*time.Second, 2*time.Second, func() bool { - balance, err := client.GetBalance(acct, ethgo.Latest) + balance, err := client.GetBalance(acct, jsonrpc.LatestBlockNumberOrHash) if err != nil { return true } @@ -185,12 +185,12 @@ func TestE2E_TxPool_Transfer_Linear(t *testing.T) { sendTransaction(t, client, receivers[i-1], txn) - err := waitUntilBalancesChanged(ethgo.Address(receivers[i].Address())) + err := waitUntilBalancesChanged(receivers[i].Address()) require.NoError(t, err) } for i := 1; i < num; i++ { - balance, err := client.GetBalance(ethgo.Address(receivers[i].Address()), ethgo.Latest) + balance, err := client.GetBalance(receivers[i].Address(), jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) require.Equal(t, uint64(sendAmount), balance.Uint64()) } @@ -258,7 +258,7 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { // Wait until the cluster is up and running cluster.WaitForReady(t) - client := cluster.Servers[0].JSONRPC().Eth() + client := cluster.Servers[0].JSONRPC() sentAmount := new(big.Int) nonce := uint64(0) @@ -295,7 +295,7 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { // Wait until the balance has changed on all nodes in the cluster err = cluster.WaitUntil(time.Minute, time.Second*3, func() bool { for _, srv := range cluster.Servers { - balance, err := srv.WaitForNonZeroBalance(ethgo.Address(recipient), time.Second*10) + balance, err := srv.WaitForNonZeroBalance(recipient, time.Second*10) assert.NoError(t, err) if balance != nil && balance.BitLen() > 0 { @@ -311,7 +311,7 @@ func TestE2E_TxPool_BroadcastTransactions(t *testing.T) { } // sendTransaction is a helper function which signs transaction with provided private key and sends it -func sendTransaction(t *testing.T, client *jsonrpc.Eth, sender crypto.Key, txn *types.Transaction) { +func sendTransaction(t *testing.T, client *jsonrpc.EthClient, sender crypto.Key, txn *types.Transaction) { t.Helper() chainID, err := client.ChainID() diff --git a/e2e-polybft/framework/test-cluster.go b/e2e-polybft/framework/test-cluster.go index c64cd08edb..7a4916a615 100644 --- a/e2e-polybft/framework/test-cluster.go +++ b/e2e-polybft/framework/test-cluster.go @@ -23,12 +23,12 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/abi" - "github.com/umbracle/ethgo/jsonrpc" ) const ( @@ -863,7 +863,7 @@ func (c *TestCluster) Stats(t *testing.T) { continue } - num, err := i.JSONRPC().Eth().BlockNumber() + num, err := i.JSONRPC().BlockNumber() t.Log("Stats node", index, "err", err, "block", num, "validator", i.config.Validator) } } @@ -911,7 +911,7 @@ func (c *TestCluster) WaitForBlock(n uint64, timeout time.Duration) error { continue } - num, err := i.JSONRPC().Eth().BlockNumber() + num, err := i.JSONRPC().BlockNumber() if err != nil || num < n { ok = false @@ -1000,13 +1000,13 @@ func (c *TestCluster) InitSecrets(prefix string, count int) ([]types.Address, er return result, nil } -func (c *TestCluster) ExistsCode(t *testing.T, addr ethgo.Address) bool { +func (c *TestCluster) ExistsCode(t *testing.T, addr types.Address) bool { t.Helper() - client, err := jsonrpc.NewClient(c.Servers[0].JSONRPCAddr()) + client, err := jsonrpc.NewEthClient(c.Servers[0].JSONRPCAddr()) require.NoError(t, err) - code, err := client.Eth().GetCode(addr, ethgo.Latest) + code, err := client.GetCode(addr, jsonrpc.LatestBlockNumberOrHash) if err != nil { return false } @@ -1018,19 +1018,17 @@ func (c *TestCluster) Call(t *testing.T, to types.Address, method *abi.Method, args ...interface{}) map[string]interface{} { t.Helper() - client, err := jsonrpc.NewClient(c.Servers[0].JSONRPCAddr()) + client, err := jsonrpc.NewEthClient(c.Servers[0].JSONRPCAddr()) require.NoError(t, err) input, err := method.Encode(args) require.NoError(t, err) - toAddr := ethgo.Address(to) - - msg := ðgo.CallMsg{ - To: &toAddr, + msg := &jsonrpc.CallMsg{ + To: &to, Data: input, } - resp, err := client.Eth().Call(msg, ethgo.Latest) + resp, err := client.Call(msg, jsonrpc.LatestBlockNumber, nil) require.NoError(t, err) data, err := hex.DecodeString(resp[2:]) @@ -1090,19 +1088,19 @@ func (c *TestCluster) SendTxn(t *testing.T, sender *crypto.ECDSAKey, txn *types. c.sendTxnLock.Lock() defer c.sendTxnLock.Unlock() - client, err := jsonrpc.NewClient(c.Servers[0].JSONRPCAddr()) + client, err := jsonrpc.NewEthClient(c.Servers[0].JSONRPCAddr()) require.NoError(t, err) // initialize transaction values if not set if txn.Nonce() == 0 { - nonce, err := client.Eth().GetNonce(ethgo.Address(sender.Address()), ethgo.Latest) + nonce, err := client.GetNonce(sender.Address(), jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) txn.SetNonce(nonce) } if txn.GasPrice() == nil || txn.GasPrice() == big.NewInt(0) { - gasPrice, err := client.Eth().GasPrice() + gasPrice, err := client.GasPrice() require.NoError(t, err) txn.SetGasPrice(new(big.Int).SetUint64(gasPrice)) @@ -1111,7 +1109,7 @@ func (c *TestCluster) SendTxn(t *testing.T, sender *crypto.ECDSAKey, txn *types. if txn.Gas() == 0 { callMsg := txrelayer.ConvertTxnToCallMsg(txn) - gasLimit, err := client.Eth().EstimateGas(callMsg) + gasLimit, err := client.EstimateGas(callMsg) if err != nil { // gas estimation can fail in case an account is not allow-listed // (fallback it to default gas limit in that case) @@ -1121,7 +1119,7 @@ func (c *TestCluster) SendTxn(t *testing.T, sender *crypto.ECDSAKey, txn *types. } } - chainID, err := client.Eth().ChainID() + chainID, err := client.ChainID() require.NoError(t, err) signer := crypto.NewLondonSigner(chainID.Uint64()) @@ -1133,19 +1131,19 @@ func (c *TestCluster) SendTxn(t *testing.T, sender *crypto.ECDSAKey, txn *types. rlpTxn := signedTxn.MarshalRLPTo(nil) - hash, err := client.Eth().SendRawTransaction(rlpTxn) + hash, err := client.SendRawTransaction(rlpTxn) require.NoError(t, err) return &TestTxn{ - client: client.Eth(), + client: client, txn: txn, hash: hash, } } type TestTxn struct { - client *jsonrpc.Eth - hash ethgo.Hash + client *jsonrpc.EthClient + hash types.Hash txn *types.Transaction receipt *ethgo.Receipt } @@ -1162,18 +1160,18 @@ func (t *TestTxn) Receipt() *ethgo.Receipt { // Succeed returns whether the transaction succeed and it was not reverted func (t *TestTxn) Succeed() bool { - return t.receipt.Status == uint64(types.ReceiptSuccess) + return t.receipt != nil && t.receipt.Status == uint64(types.ReceiptSuccess) } // Failed returns whether the transaction failed func (t *TestTxn) Failed() bool { - return t.receipt.Status == uint64(types.ReceiptFailed) + return t.receipt == nil || t.receipt.Status == uint64(types.ReceiptFailed) } // Reverted returns whether the transaction failed and was reverted consuming // all the gas from the call func (t *TestTxn) Reverted() bool { - return t.receipt.Status == uint64(types.ReceiptFailed) && t.txn.Gas() == t.receipt.GasUsed + return t.Failed() && t.txn.Gas() == t.receipt.GasUsed } // Wait waits for the transaction to be executed diff --git a/e2e-polybft/framework/test-server.go b/e2e-polybft/framework/test-server.go index 8f283b35d2..0934628d64 100644 --- a/e2e-polybft/framework/test-server.go +++ b/e2e-polybft/framework/test-server.go @@ -17,13 +17,13 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" "github.com/0xPolygon/polygon-edge/consensus/polybft/wallet" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/server/proto" txpoolProto "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/0xPolygon/polygon-edge/types" "github.com/google/uuid" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" "google.golang.org/grpc" ) @@ -78,8 +78,8 @@ func (t *TestServer) BridgeJSONRPCAddr() string { return t.config.BridgeJSONRPC } -func (t *TestServer) JSONRPC() *jsonrpc.Client { - clt, err := jsonrpc.NewClient(t.JSONRPCAddr()) +func (t *TestServer) JSONRPC() *jsonrpc.EthClient { + clt, err := jsonrpc.NewEthClient(t.JSONRPCAddr()) if err != nil { t.t.Fatal(err) } @@ -357,12 +357,12 @@ func (t *TestServer) HasValidatorSealed(firstBlock, lastBlock uint64, validators validatorAddr ethgo.Address) (bool, error) { rpcClient := t.JSONRPC() for i := firstBlock + 1; i <= lastBlock; i++ { - block, err := rpcClient.Eth().GetBlockByNumber(ethgo.BlockNumber(i), false) + block, err := rpcClient.GetBlockByNumber(jsonrpc.BlockNumber(i), false) if err != nil { return false, err } - extra, err := polybft.GetIbftExtra(block.ExtraData) + extra, err := polybft.GetIbftExtra(block.Header.ExtraData) if err != nil { return false, err } @@ -380,7 +380,7 @@ func (t *TestServer) HasValidatorSealed(firstBlock, lastBlock uint64, validators return false, nil } -func (t *TestServer) WaitForNonZeroBalance(address ethgo.Address, dur time.Duration) (*big.Int, error) { +func (t *TestServer) WaitForNonZeroBalance(address types.Address, dur time.Duration) (*big.Int, error) { timer := time.NewTimer(dur) defer timer.Stop() @@ -394,7 +394,7 @@ func (t *TestServer) WaitForNonZeroBalance(address ethgo.Address, dur time.Durat case <-timer.C: return nil, fmt.Errorf("timeout occurred while waiting for balance ") case <-ticker.C: - balance, err := rpcClient.Eth().GetBalance(address, ethgo.Latest) + balance, err := rpcClient.GetBalance(address, jsonrpc.LatestBlockNumberOrHash) if err != nil { return nil, fmt.Errorf("error getting balance") } diff --git a/e2e-polybft/property/property_test.go b/e2e-polybft/property/property_test.go index 55d7bcdc71..58e9af55ff 100644 --- a/e2e-polybft/property/property_test.go +++ b/e2e-polybft/property/property_test.go @@ -84,7 +84,7 @@ func TestProperty_DropValidators(t *testing.T) { // stop first validator, block production should continue cluster.Servers[0].Stop() activeValidator := cluster.Servers[numNodes-1] - currentBlock, err := activeValidator.JSONRPC().Eth().BlockNumber() + currentBlock, err := activeValidator.JSONRPC().BlockNumber() require.NoError(t, err) require.NoError(t, cluster.WaitForBlock(currentBlock+1, 2*blockTime)) @@ -107,14 +107,14 @@ func TestProperty_DropValidators(t *testing.T) { wg.Wait() // check that block production is stoped - currentBlock, err = activeValidator.JSONRPC().Eth().BlockNumber() + currentBlock, err = activeValidator.JSONRPC().BlockNumber() require.NoError(t, err) oldBlockNumber := currentBlock time.Sleep(2 * blockTime) - currentBlock, err = activeValidator.JSONRPC().Eth().BlockNumber() + currentBlock, err = activeValidator.JSONRPC().BlockNumber() require.NoError(t, err) require.Equal(t, oldBlockNumber, currentBlock) diff --git a/e2e/framework/helper.go b/e2e/framework/helper.go index d55a33a79c..ac8dde882c 100644 --- a/e2e/framework/helper.go +++ b/e2e/framework/helper.go @@ -13,16 +13,16 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "golang.org/x/crypto/sha3" + empty "google.golang.org/protobuf/types/known/emptypb" + "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/helper/tests" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/server/proto" txpoolProto "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/0xPolygon/polygon-edge/types" - "github.com/stretchr/testify/assert" - "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" - "golang.org/x/crypto/sha3" - empty "google.golang.org/protobuf/types/known/emptypb" ) var ( @@ -65,13 +65,10 @@ func EthToWeiPrecise(ethValue int64, decimals int64) *big.Int { } // GetAccountBalance is a helper method for fetching the Balance field of an account -func GetAccountBalance(t *testing.T, address types.Address, rpcClient *jsonrpc.Client) *big.Int { +func GetAccountBalance(t *testing.T, address types.Address, rpcClient *jsonrpc.EthClient) *big.Int { t.Helper() - accountBalance, err := rpcClient.Eth().GetBalance( - ethgo.Address(address), - ethgo.Latest, - ) + accountBalance, err := rpcClient.GetBalance(address, jsonrpc.LatestBlockNumberOrHash) assert.NoError(t, err) @@ -211,7 +208,7 @@ func WaitUntilTxPoolFilled( // WaitUntilBlockMined waits until server mined block with bigger height than given height // otherwise returns timeout func WaitUntilBlockMined(ctx context.Context, srv *TestServer, desiredHeight uint64) (uint64, error) { - clt := srv.JSONRPC().Eth() + clt := srv.JSONRPC() res, err := tests.RetryUntilTimeout(ctx, func() (interface{}, bool) { height, err := clt.BlockNumber() if err == nil && height >= desiredHeight { diff --git a/e2e/framework/testserver.go b/e2e/framework/testserver.go index 450ce6a6b0..1e884c8cae 100644 --- a/e2e/framework/testserver.go +++ b/e2e/framework/testserver.go @@ -20,9 +20,8 @@ import ( "testing" "time" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" - "github.com/umbracle/ethgo/wallet" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" empty "google.golang.org/protobuf/types/known/emptypb" @@ -104,8 +103,8 @@ func (t *TestServer) WSJSONRPCURL() string { return fmt.Sprintf("ws://%s/ws", t.JSONRPCAddr()) } -func (t *TestServer) JSONRPC() *jsonrpc.Client { - clt, err := jsonrpc.NewClient(t.HTTPJSONRPCURL()) +func (t *TestServer) JSONRPC() *jsonrpc.EthClient { + clt, err := jsonrpc.NewEthClient(t.HTTPJSONRPCURL()) if err != nil { t.t.Fatal(err) } @@ -156,7 +155,7 @@ func (t *TestServer) Stop() { } func (t *TestServer) GetLatestBlockHeight() (uint64, error) { - return t.JSONRPC().Eth().BlockNumber() + return t.JSONRPC().BlockNumber() } type InitIBFTResult struct { @@ -276,7 +275,7 @@ func (t *TestServer) Start(ctx context.Context) error { } // query the chain id - chainID, err := t.JSONRPC().Eth().ChainID() + chainID, err := t.JSONRPC().ChainID() if err != nil { return err } @@ -299,15 +298,15 @@ func (t *TestServer) DeployContract( ctx context.Context, binary string, privateKey *ecdsa.PrivateKey, -) (ethgo.Address, error) { +) (types.Address, error) { buf, err := hex.DecodeString(binary) if err != nil { - return ethgo.Address{}, err + return types.ZeroAddress, err } sender, err := crypto.GetAddressFromKey(privateKey) if err != nil { - return ethgo.ZeroAddress, fmt.Errorf("unable to extract key, %w", err) + return types.ZeroAddress, fmt.Errorf("unable to extract key, %w", err) } receipt, err := t.SendRawTx(ctx, &PreparedTransaction{ @@ -317,10 +316,10 @@ func (t *TestServer) DeployContract( Input: buf, }, privateKey) if err != nil { - return ethgo.Address{}, err + return types.ZeroAddress, err } - return receipt.ContractAddress, nil + return types.Address(receipt.ContractAddress), nil } const ( @@ -337,176 +336,6 @@ type PreparedTransaction struct { Input []byte } -type Txn struct { - key *wallet.Key - client *jsonrpc.Eth - hash *ethgo.Hash - receipt *ethgo.Receipt - raw *ethgo.Transaction - chainID *big.Int - - sendErr error - waitErr error -} - -func (t *Txn) Deploy(input []byte) *Txn { - t.raw.Input = input - - return t -} - -func (t *Txn) Transfer(to ethgo.Address, value *big.Int) *Txn { - t.raw.To = &to - t.raw.Value = value - t.raw.GasPrice = ethgo.Gwei(2).Uint64() - - return t -} - -func (t *Txn) Value(value *big.Int) *Txn { - t.raw.Value = value - - return t -} - -func (t *Txn) To(to ethgo.Address) *Txn { - t.raw.To = &to - - return t -} - -func (t *Txn) GasLimit(gas uint64) *Txn { - t.raw.Gas = gas - - return t -} - -func (t *Txn) Nonce(nonce uint64) *Txn { - t.raw.Nonce = nonce - - return t -} - -func (t *Txn) sendImpl() error { - // populate default values - if t.raw.Gas == 0 { - t.raw.Gas = 1048576 - } - - if t.raw.GasPrice == 0 { - gasPrice, err := t.client.GasPrice() - if err != nil { - return fmt.Errorf("failed to get gas price: %w", err) - } - - t.raw.GasPrice = gasPrice - } - - if t.raw.Nonce == 0 { - nextNonce, err := t.client.GetNonce(t.key.Address(), ethgo.Latest) - if err != nil { - return fmt.Errorf("failed to get nonce: %w", err) - } - - t.raw.Nonce = nextNonce - } - - signer := wallet.NewEIP155Signer(t.chainID.Uint64()) - - signedTxn, err := signer.SignTx(t.raw, t.key) - if err != nil { - return err - } - - data, _ := signedTxn.MarshalRLPTo(nil) - - txHash, err := t.client.SendRawTransaction(data) - if err != nil { - return fmt.Errorf("failed to send transaction: %w", err) - } - - t.hash = &txHash - - return nil -} - -func (t *Txn) Send() (*Txn, error) { - if t.hash != nil { - return nil, errors.New("txn already sent") - } - - t.sendErr = t.sendImpl() - - return t, nil -} - -func (t *Txn) Receipt() *ethgo.Receipt { - return t.receipt -} - -//nolint:thelper -func (t *Txn) NoFail(tt *testing.T) { - t.Wait() - - if t.sendErr != nil { - tt.Fatal(t.sendErr) - } - - if t.waitErr != nil { - tt.Fatal(t.waitErr) - } - - if t.receipt.Status != 1 { - tt.Fatal("txn failed with status 0") - } -} - -func (t *Txn) Complete() bool { - if t.sendErr != nil { - // txn failed during sending - return true - } - - if t.waitErr != nil { - // txn failed during waiting - return true - } - - if t.receipt != nil { - // txn was mined - return true - } - - return false -} - -func (t *Txn) Wait() { - if t.Complete() { - return - } - - ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout) - defer cancelFn() - - receipt, err := tests.WaitForReceipt(ctx, t.client, *t.hash) - if err != nil { - t.waitErr = err - } else { - t.receipt = receipt - } -} - -func (t *TestServer) Txn(key *wallet.Key) *Txn { - tt := &Txn{ - key: key, - client: t.JSONRPC().Eth(), - chainID: t.chainID, - raw: ðgo.Transaction{}, - } - - return tt -} - // SendRawTx signs the transaction with the provided private key, executes it, and returns the receipt func (t *TestServer) SendRawTx( ctx context.Context, @@ -515,7 +344,7 @@ func (t *TestServer) SendRawTx( ) (*ethgo.Receipt, error) { client := t.JSONRPC() - nextNonce, err := client.Eth().GetNonce(ethgo.Address(tx.From), ethgo.Latest) + nextNonce, err := client.GetNonce(tx.From, jsonrpc.LatestBlockNumberOrHash) if err != nil { return nil, err } @@ -533,15 +362,15 @@ func (t *TestServer) SendRawTx( return nil, err } - txHash, err := client.Eth().SendRawTransaction(signedTx.MarshalRLP()) + txHash, err := client.SendRawTransaction(signedTx.MarshalRLP()) if err != nil { return nil, err } - return tests.WaitForReceipt(ctx, t.JSONRPC().Eth(), txHash) + return tests.WaitForReceipt(ctx, t.JSONRPC(), txHash) } -func (t *TestServer) WaitForReceipt(ctx context.Context, hash ethgo.Hash) (*ethgo.Receipt, error) { +func (t *TestServer) WaitForReceipt(ctx context.Context, hash types.Hash) (*ethgo.Receipt, error) { client := t.JSONRPC() type result struct { @@ -550,7 +379,7 @@ func (t *TestServer) WaitForReceipt(ctx context.Context, hash ethgo.Hash) (*ethg } res, err := tests.RetryUntilTimeout(ctx, func() (interface{}, bool) { - receipt, err := client.Eth().GetTransactionReceipt(hash) + receipt, err := client.GetTransactionReceipt(hash) if err != nil && err.Error() != "not found" { return result{receipt, err}, false @@ -576,7 +405,7 @@ func (t *TestServer) WaitForReceipt(ctx context.Context, hash ethgo.Hash) (*ethg // GetGasTotal waits for the total gas used sum for the passed in // transactions -func (t *TestServer) GetGasTotal(txHashes []ethgo.Hash) uint64 { +func (t *TestServer) GetGasTotal(txHashes []types.Hash) uint64 { t.t.Helper() var ( @@ -596,13 +425,13 @@ func (t *TestServer) GetGasTotal(txHashes []ethgo.Hash) uint64 { for _, txHash := range txHashes { wg.Add(1) - go func(txHash ethgo.Hash) { + go func(txHash types.Hash) { defer wg.Done() ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout) defer cancelFn() - receipt, receiptErr := tests.WaitForReceipt(ctx, t.JSONRPC().Eth(), txHash) + receipt, receiptErr := tests.WaitForReceipt(ctx, t.JSONRPC(), txHash) if receiptErr != nil { appendReceiptErr(fmt.Errorf("unable to wait for receipt, %w", receiptErr)) diff --git a/e2e/transaction_test.go b/e2e/transaction_test.go index aec654d677..5d82a5415f 100644 --- a/e2e/transaction_test.go +++ b/e2e/transaction_test.go @@ -11,6 +11,7 @@ import ( "github.com/0xPolygon/polygon-edge/e2e/framework" "github.com/0xPolygon/polygon-edge/helper/tests" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/types" ) @@ -59,7 +60,7 @@ func TestPreminedBalance(t *testing.T) { for _, testCase := range testTable { t.Run(testCase.name, func(t *testing.T) { - balance, err := rpcClient.Eth().GetBalance(ethgo.Address(testCase.address), ethgo.Latest) + balance, err := rpcClient.GetBalance(testCase.address, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) require.Equal(t, testCase.balance, balance) }) @@ -137,16 +138,10 @@ func TestEthTransfer(t *testing.T) { for _, testCase := range testTable { t.Run(testCase.name, func(t *testing.T) { // Fetch the balances before sending - balanceSender, err := rpcClient.Eth().GetBalance( - ethgo.Address(testCase.sender), - ethgo.Latest, - ) + balanceSender, err := rpcClient.GetBalance(testCase.sender, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) - balanceReceiver, err := rpcClient.Eth().GetBalance( - ethgo.Address(testCase.recipient), - ethgo.Latest, - ) + balanceReceiver, err := rpcClient.GetBalance(testCase.recipient, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) // Set the preSend balances @@ -176,16 +171,10 @@ func TestEthTransfer(t *testing.T) { } // Fetch the balances after sending - balanceSender, err = rpcClient.Eth().GetBalance( - ethgo.Address(testCase.sender), - ethgo.Latest, - ) + balanceSender, err = rpcClient.GetBalance(testCase.sender, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) - balanceReceiver, err = rpcClient.Eth().GetBalance( - ethgo.Address(testCase.recipient), - ethgo.Latest, - ) + balanceReceiver, err = rpcClient.GetBalance(testCase.recipient, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err) expectedSenderBalance := previousSenderBalance diff --git a/e2e/txpool_test.go b/e2e/txpool_test.go index 1c744011bd..86ca9e6ca8 100644 --- a/e2e/txpool_test.go +++ b/e2e/txpool_test.go @@ -9,11 +9,11 @@ import ( "time" "github.com/0xPolygon/polygon-edge/chain" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/stretchr/testify/require" "github.com/0xPolygon/polygon-edge/txpool" - "github.com/umbracle/ethgo" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e/framework" @@ -190,7 +190,7 @@ func TestTxPool_ErrorCodes(t *testing.T) { defer waitCancelFn() convertedHash := types.StringToHash(addResponse.TxHash) - _, receiptErr := tests.WaitForReceipt(receiptCtx, srv.JSONRPC().Eth(), ethgo.Hash(convertedHash)) + _, receiptErr := tests.WaitForReceipt(receiptCtx, srv.JSONRPC(), convertedHash) if receiptErr != nil { t.Fatalf("Unable to get receipt, %v", receiptErr) @@ -280,7 +280,7 @@ func TestTxPool_RecoverableError(t *testing.T) { client := server.JSONRPC() operator := server.TxnPoolOperator() - hashes := make([]ethgo.Hash, 3) + hashes := make([]types.Hash, 3) for i, tx := range transactions { signedTx, err := signer.SignTx(tx, senderKey) @@ -294,31 +294,29 @@ func TestTxPool_RecoverableError(t *testing.T) { }) require.NoError(t, err, "Unable to send transaction, %v", err) - txHash := ethgo.Hash(types.StringToHash(response.TxHash)) - // save for later querying - hashes[i] = txHash + hashes[i] = types.StringToHash(response.TxHash) } ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second) defer cancel() // wait for the last tx to be included in a block - receipt, err := tests.WaitForReceipt(ctx, client.Eth(), hashes[2]) + receipt, err := tests.WaitForReceipt(ctx, client, hashes[2]) require.NoError(t, err) require.NotNil(t, receipt) // assert balance moved - balance, err := client.Eth().GetBalance(ethgo.Address(receiverAddress), ethgo.Latest) + balance, err := client.GetBalance(receiverAddress, jsonrpc.LatestBlockNumberOrHash) require.NoError(t, err, "failed to retrieve receiver account balance") require.Equal(t, framework.EthToWei(3).String(), balance.String()) // Query 1st and 2nd txs - firstTx, err := client.Eth().GetTransactionByHash(hashes[0]) + firstTx, err := client.GetTransactionByHash(hashes[0]) require.NoError(t, err) require.NotNil(t, firstTx) - secondTx, err := client.Eth().GetTransactionByHash(hashes[1]) + secondTx, err := client.GetTransactionByHash(hashes[1]) require.NoError(t, err) require.NotNil(t, secondTx) @@ -370,34 +368,34 @@ func TestTxPool_GetPendingTx(t *testing.T) { }) assert.NoError(t, err, "Unable to send transaction, %v", err) - txHash := ethgo.Hash(types.StringToHash(response.TxHash)) + txHash := types.StringToHash(response.TxHash) // Grab the pending transaction from the pool - tx, err := client.Eth().GetTransactionByHash(txHash) + tx, err := client.GetTransactionByHash(txHash) assert.NoError(t, err, "Unable to get transaction by hash, %v", err) assert.NotNil(t, tx) // Make sure the specific fields are not filled yet assert.Equal(t, uint64(0), tx.TxnIndex) assert.Equal(t, uint64(0), tx.BlockNumber) - assert.Equal(t, ethgo.ZeroHash, tx.BlockHash) + assert.Equal(t, types.ZeroHash, tx.BlockHash) // Wait for the transaction to be included into a block ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - receipt, err := tests.WaitForReceipt(ctx, client.Eth(), txHash) + receipt, err := tests.WaitForReceipt(ctx, client, txHash) assert.NoError(t, err) assert.NotNil(t, receipt) assert.Equal(t, tx.TxnIndex, receipt.TransactionIndex) // fields should be updated - tx, err = client.Eth().GetTransactionByHash(txHash) + tx, err = client.GetTransactionByHash(txHash) assert.NoError(t, err, "Unable to get transaction by hash, %v", err) assert.NotNil(t, tx) assert.Equal(t, uint64(0), tx.TxnIndex) assert.Equal(t, receipt.BlockNumber, tx.BlockNumber) - assert.Equal(t, receipt.BlockHash, tx.BlockHash) + assert.Equal(t, types.Hash(receipt.BlockHash), tx.BlockHash) } diff --git a/gasprice/feehistory_test.go b/gasprice/feehistory_test.go index 68f2115168..2fc2005746 100644 --- a/gasprice/feehistory_test.go +++ b/gasprice/feehistory_test.go @@ -7,7 +7,6 @@ import ( "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/crypto" - "github.com/0xPolygon/polygon-edge/helper/tests" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -184,7 +183,10 @@ func TestGasHelper_FeeHistory(t *testing.T) { backend := createTestBlocks(t, 10) rand.Seed(time.Now().UTC().UnixNano()) - senderKey, sender := tests.GenerateKeyAndAddr(t) + senderKey, err := crypto.GenerateECDSAPrivateKey() + require.NoError(t, err) + + sender := crypto.PubKeyToAddress(&senderKey.PublicKey) for _, b := range backend.blocksByNumber { signer := crypto.NewSigner(backend.Config().Forks.At(b.Number()), diff --git a/gasprice/gasprice_test.go b/gasprice/gasprice_test.go index aba8a0c274..2abd7c1be5 100644 --- a/gasprice/gasprice_test.go +++ b/gasprice/gasprice_test.go @@ -9,7 +9,6 @@ import ( "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/crypto" - "github.com/0xPolygon/polygon-edge/helper/tests" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -74,7 +73,10 @@ func TestGasHelper_MaxPriorityFeePerGas(t *testing.T) { backend := createTestBlocks(t, 10) rand.Seed(time.Now().UTC().UnixNano()) - senderKey, sender := tests.GenerateKeyAndAddr(t) + senderKey, err := crypto.GenerateECDSAPrivateKey() + require.NoError(t, err) + + sender := crypto.PubKeyToAddress(&senderKey.PublicKey) for _, b := range backend.blocks { signer := crypto.NewSigner(backend.Config().Forks.At(b.Number()), @@ -217,7 +219,10 @@ func createTestTxs(t *testing.T, backend *backendMock, numOfTxsPerBlock, txCap i b.Transactions = make([]*types.Transaction, numOfTxsPerBlock) for i := 0; i < numOfTxsPerBlock; i++ { - senderKey, sender := tests.GenerateKeyAndAddr(t) + senderKey, err := crypto.GenerateECDSAPrivateKey() + require.NoError(t, err) + + sender := crypto.PubKeyToAddress(&senderKey.PublicKey) tx := types.NewTx(types.NewDynamicFeeTx( types.WithGasTipCap(ethgo.Gwei(uint64(rand.Intn(txCap)))), @@ -228,7 +233,7 @@ func createTestTxs(t *testing.T, backend *backendMock, numOfTxsPerBlock, txCap i types.WithTo(&types.ZeroAddress), )) - tx, err := signer.SignTx(tx, senderKey) + tx, err = signer.SignTx(tx, senderKey) require.NoError(t, err) b.Transactions[i] = tx diff --git a/helper/common/common.go b/helper/common/common.go index bd58bdaced..4400ac6e57 100644 --- a/helper/common/common.go +++ b/helper/common/common.go @@ -9,6 +9,7 @@ import ( "io/fs" "math" "math/big" + "net" "os" "os/signal" "os/user" @@ -415,3 +416,27 @@ func (f *UnsafePool[T]) Put(resetFunc func(T) T, obj T) { f.stack = append(f.stack, obj) } + +// GetFreePort asks the kernel for a free open port that is ready to use +func GetFreePort() (port int, err error) { + var addr *net.TCPAddr + + if addr, err = net.ResolveTCPAddr("tcp", "localhost:0"); err == nil { + var l *net.TCPListener + + if l, err = net.ListenTCP("tcp", addr); err == nil { + defer func(l *net.TCPListener) { + _ = l.Close() + }(l) + + netAddr, ok := l.Addr().(*net.TCPAddr) + if !ok { + return 0, errors.New("invalid type assert to TCPAddr") + } + + return netAddr.Port, nil + } + } + + return +} diff --git a/helper/tests/testing.go b/helper/tests/testing.go index 442e39c7c5..d9d1967770 100644 --- a/helper/tests/testing.go +++ b/helper/tests/testing.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "math/big" - "net" "testing" "time" @@ -17,10 +16,11 @@ import ( "github.com/umbracle/ethgo" "github.com/0xPolygon/polygon-edge/crypto" + "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/jsonrpc" txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/assert" - "github.com/umbracle/ethgo/jsonrpc" empty "google.golang.org/protobuf/types/known/emptypb" ) @@ -51,7 +51,7 @@ func GenerateTestMultiAddr(t *testing.T) multiaddr.Multiaddr { nodeID, err := peer.IDFromPrivateKey(priv) assert.NoError(t, err) - port, portErr := GetFreePort() + port, portErr := common.GetFreePort() if portErr != nil { t.Fatalf("Unable to fetch free port, %v", portErr) } @@ -130,8 +130,8 @@ func WaitUntilTxPoolEmpty( func WaitForNonce( ctx context.Context, - ethClient *jsonrpc.Eth, - addr ethgo.Address, + ethClient *jsonrpc.EthClient, + addr types.Address, expectedNonce uint64, ) ( interface{}, @@ -143,7 +143,7 @@ func WaitForNonce( } resObj, err := RetryUntilTimeout(ctx, func() (interface{}, bool) { - nonce, err := ethClient.GetNonce(addr, ethgo.Latest) + nonce, err := ethClient.GetNonce(addr, jsonrpc.LatestBlockNumberOrHash) if err != nil { // error -> stop retrying return result{nonce, err}, false @@ -171,7 +171,7 @@ func WaitForNonce( } // WaitForReceipt waits transaction receipt -func WaitForReceipt(ctx context.Context, client *jsonrpc.Eth, hash ethgo.Hash) (*ethgo.Receipt, error) { +func WaitForReceipt(ctx context.Context, client *jsonrpc.EthClient, hash types.Hash) (*ethgo.Receipt, error) { type result struct { receipt *ethgo.Receipt err error @@ -201,30 +201,6 @@ func WaitForReceipt(ctx context.Context, client *jsonrpc.Eth, hash ethgo.Hash) ( return data.receipt, data.err } -// GetFreePort asks the kernel for a free open port that is ready to use -func GetFreePort() (port int, err error) { - var addr *net.TCPAddr - - if addr, err = net.ResolveTCPAddr("tcp", "localhost:0"); err == nil { - var l *net.TCPListener - - if l, err = net.ListenTCP("tcp", addr); err == nil { - defer func(l *net.TCPListener) { - _ = l.Close() - }(l) - - netAddr, ok := l.Addr().(*net.TCPAddr) - if !ok { - return 0, errors.New("invalid type assert to TCPAddr") - } - - return netAddr.Port, nil - } - } - - return -} - type GenerateTxReqParams struct { Nonce uint64 ReferenceAddr types.Address diff --git a/jsonrpc/client.go b/jsonrpc/client.go index 6349745093..254b93aba9 100644 --- a/jsonrpc/client.go +++ b/jsonrpc/client.go @@ -6,6 +6,7 @@ import ( "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/types" + "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/jsonrpc" ) @@ -24,6 +25,12 @@ func NewEthClient(url string) (*EthClient, error) { return &EthClient{client}, nil } +// EndpointCall calls a specified method on the json rpc client with given params +// and returns the result in the out parameter +func (e *EthClient) EndpointCall(method string, out interface{}, params ...interface{}) error { + return e.client.Call(method, out, params...) +} + // GetCode returns the code of a contract func (e *EthClient) GetCode(addr types.Address, block BlockNumberOrHash) (string, error) { var res string @@ -73,8 +80,8 @@ func (e *EthClient) GetBlockByHash(hash types.Hash, full bool) (*types.Block, er } // GetTransactionByHash returns a transaction by hash -func (e *EthClient) GetTransactionByHash(hash types.Hash) (*types.Transaction, error) { - var txn *types.Transaction +func (e *EthClient) GetTransactionByHash(hash types.Hash) (*Transaction, error) { + var txn *Transaction err := e.client.Call("eth_getTransactionByHash", &txn, hash) return txn, err @@ -99,8 +106,8 @@ func (e *EthClient) SendTransaction(txn *types.Transaction) (types.Hash, error) } // GetTransactionReceipt returns the receipt of a transaction by transaction hash -func (e *EthClient) GetTransactionReceipt(hash types.Hash) (*types.Receipt, error) { - var receipt *types.Receipt +func (e *EthClient) GetTransactionReceipt(hash types.Hash) (*ethgo.Receipt, error) { + var receipt *ethgo.Receipt err := e.client.Call("eth_getTransactionReceipt", &receipt, hash) return receipt, err @@ -176,3 +183,38 @@ func (e *EthClient) MaxPriorityFeePerGas() (*big.Int, error) { return common.ParseUint256orHex(&out) } + +// FeeHistory returns base fee per gas and transaction effective priority fee +func (e *EthClient) FeeHistory( + blockCount uint64, + newestBlock BlockNumber, + rewardPercentiles []float64, +) (*FeeHistory, error) { + var out *FeeHistory + if err := e.client.Call("eth_feeHistory", &out, blockCount, + newestBlock.String(), rewardPercentiles); err != nil { + return nil, err + } + + return out, nil +} + +// Accounts returns a list of addresses owned by client +func (e *EthClient) Accounts() ([]types.Address, error) { + var out []types.Address + if err := e.client.Call("eth_accounts", &out); err != nil { + return nil, err + } + + return out, nil +} + +// GetLogs returns an array of all logs matching a given filter object +func (e *EthClient) GetLogs(filter *ethgo.LogFilter) ([]*ethgo.Log, error) { + var out []*ethgo.Log + if err := e.client.Call("eth_getLogs", &out, filter); err != nil { + return nil, err + } + + return out, nil +} diff --git a/jsonrpc/jsonrpc_test.go b/jsonrpc/jsonrpc_test.go index 32399ab84c..e941278978 100644 --- a/jsonrpc/jsonrpc_test.go +++ b/jsonrpc/jsonrpc_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/require" - "github.com/0xPolygon/polygon-edge/helper/tests" + "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/versioning" ) @@ -103,7 +103,7 @@ func newTestJSONRPC(t *testing.T) (*JSONRPC, error) { store := newMockStore() - port, err := tests.GetFreePort() + port, err := common.GetFreePort() require.NoError(t, err, "Unable to fetch free port, %v", err) config := &Config{ diff --git a/jsonrpc/types.go b/jsonrpc/types.go index a8055ae791..212a2a2aea 100644 --- a/jsonrpc/types.go +++ b/jsonrpc/types.go @@ -1,6 +1,7 @@ package jsonrpc import ( + "encoding/json" "fmt" "math/big" "strconv" @@ -12,7 +13,10 @@ import ( "github.com/valyala/fastjson" ) -var defaultArena fastjson.ArenaPool +var ( + defaultArena fastjson.ArenaPool + defaultPool fastjson.ParserPool +) const jsonRPCMetric = "json_rpc" @@ -579,7 +583,10 @@ func (c *CallMsg) MarshalJSON() ([]byte, error) { o := a.NewObject() o.Set("from", a.NewString(c.From.String())) - o.Set("gas", a.NewString(fmt.Sprintf("0x%x", c.Gas))) + + if c.Gas != 0 { + o.Set("gas", a.NewString(fmt.Sprintf("0x%x", c.Gas))) + } if c.To != nil { o.Set("to", a.NewString(c.To.String())) @@ -615,3 +622,98 @@ func (c *CallMsg) MarshalJSON() ([]byte, error) { return res, nil } + +// FeeHistory represents the fee history data returned by an rpc node +type FeeHistory struct { + OldestBlock uint64 `json:"oldestBlock"` + Reward [][]uint64 `json:"reward,omitempty"` + BaseFee []uint64 `json:"baseFeePerGas,omitempty"` + GasUsedRatio []float64 `json:"gasUsedRatio"` +} + +// UnmarshalJSON unmarshals the FeeHistory object from JSON +func (f *FeeHistory) UnmarshalJSON(data []byte) error { + var raw feeHistoryResult + + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + f.OldestBlock = uint64(raw.OldestBlock) + + if raw.Reward != nil { + f.Reward = make([][]uint64, 0, len(raw.Reward)) + + for _, r := range raw.Reward { + elem := make([]uint64, 0, len(r)) + for _, i := range r { + elem = append(elem, uint64(i)) + } + + f.Reward = append(f.Reward, elem) + } + } + + f.BaseFee = make([]uint64, 0, len(raw.BaseFeePerGas)) + for _, i := range raw.BaseFeePerGas { + f.BaseFee = append(f.BaseFee, uint64(i)) + } + + f.GasUsedRatio = raw.GasUsedRatio + + return nil +} + +// Transaction is the json rpc transaction object +// (types.Transaction object, expanded with block number, hash and index) +type Transaction struct { + *types.Transaction + + // BlockNumber is the number of the block in which the transaction was included. + BlockNumber uint64 `json:"blockNumber"` + + // BlockHash is the hash of the block in which the transaction was included. + BlockHash types.Hash `json:"blockHash"` + + // TxnIndex is the index of the transaction within the block. + TxnIndex uint64 `json:"transactionIndex"` +} + +// UnmarshalJSON unmarshals the transaction object from JSON +func (t *Transaction) UnmarshalJSON(data []byte) error { + p := defaultPool.Get() + defer defaultPool.Put(p) + + v, err := p.Parse(string(data)) + if err != nil { + return err + } + + t.Transaction = new(types.Transaction) + if err := t.Transaction.UnmarshalJSONWith(v); err != nil { + return err + } + + if types.HasJSONKey(v, "blockNumber") { + t.BlockNumber, err = types.UnmarshalJSONUint64(v, "blockNumber") + if err != nil { + return err + } + } + + if types.HasJSONKey(v, "blockHash") { + t.BlockHash, err = types.UnmarshalJSONHash(v, "blockHash") + if err != nil { + return err + } + } + + if types.HasJSONKey(v, "transactionIndex") { + t.TxnIndex, err = types.UnmarshalJSONUint64(v, "transactionIndex") + if err != nil { + return err + } + } + + return nil +} diff --git a/network/e2e_testing.go b/network/e2e_testing.go index b94edf6b84..0f19dcabfe 100644 --- a/network/e2e_testing.go +++ b/network/e2e_testing.go @@ -262,7 +262,7 @@ func initBootnodes(server *Server, bootnodes ...string) { func CreateServer(params *CreateServerParams) (*Server, error) { cfg := DefaultConfig() - port, portErr := tests.GetFreePort() + port, portErr := common.GetFreePort() if portErr != nil { return nil, fmt.Errorf("unable to fetch free port, %w", portErr) diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 8f9cb6dcea..27fec88889 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -9,8 +9,8 @@ import ( "sync" "time" + "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/jsonrpc" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/types" @@ -45,14 +45,14 @@ type TxRelayer interface { // (this function is meant only for testing purposes and is about to be removed at some point) SendTransactionLocal(txn *types.Transaction) (*ethgo.Receipt, error) // Client returns jsonrpc client - Client() *jsonrpc.Client + Client() *jsonrpc.EthClient } var _ TxRelayer = (*TxRelayerImpl)(nil) type TxRelayerImpl struct { ipAddress string - client *jsonrpc.Client + client *jsonrpc.EthClient receiptsPollFreq time.Duration receiptsTimeout time.Duration noWaitReceipt bool @@ -84,7 +84,7 @@ func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { } if t.client == nil { - client, err := jsonrpc.NewClient(t.ipAddress) + client, err := jsonrpc.NewEthClient(t.ipAddress) if err != nil { return nil, err } @@ -97,13 +97,13 @@ func NewTxRelayer(opts ...TxRelayerOption) (TxRelayer, error) { // Call executes a message call immediately without creating a transaction on the blockchain func (t *TxRelayerImpl) Call(from types.Address, to types.Address, input []byte) (string, error) { - callMsg := ðgo.CallMsg{ - From: ethgo.Address(from), - To: (*ethgo.Address)(&to), + callMsg := &jsonrpc.CallMsg{ + From: from, + To: &to, Data: input, } - return t.client.Eth().Call(callMsg, ethgo.Pending) + return t.client.Call(callMsg, jsonrpc.PendingBlockNumber, nil) } // SendTransaction signs given transaction by provided key and sends it to the blockchain @@ -137,22 +137,22 @@ func (t *TxRelayerImpl) SendTransaction(txn *types.Transaction, key crypto.Key) } // Client returns jsonrpc client -func (t *TxRelayerImpl) Client() *jsonrpc.Client { +func (t *TxRelayerImpl) Client() *jsonrpc.EthClient { return t.client } -func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto.Key) (ethgo.Hash, error) { +func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto.Key) (types.Hash, error) { t.lock.Lock() defer t.lock.Unlock() - nonce, err := t.client.Eth().GetNonce(ethgo.Address(key.Address()), ethgo.Pending) + nonce, err := t.client.GetNonce(key.Address(), jsonrpc.PendingBlockNumberOrHash) if err != nil { - return ethgo.ZeroHash, fmt.Errorf("failed to get nonce: %w", err) + return types.ZeroHash, fmt.Errorf("failed to get nonce: %w", err) } - chainID, err := t.client.Eth().ChainID() + chainID, err := t.client.ChainID() if err != nil { - return ethgo.ZeroHash, err + return types.ZeroHash, err } txn.SetChainID(chainID) @@ -166,8 +166,8 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto maxPriorityFee := txn.GetGasTipCap() if maxPriorityFee == nil { // retrieve the max priority fee per gas - if maxPriorityFee, err = t.Client().Eth().MaxPriorityFeePerGas(); err != nil { - return ethgo.ZeroHash, fmt.Errorf("failed to get max priority fee per gas: %w", err) + if maxPriorityFee, err = t.Client().MaxPriorityFeePerGas(); err != nil { + return types.ZeroHash, fmt.Errorf("failed to get max priority fee per gas: %w", err) } // set retrieved max priority fee per gas increased by certain percentage @@ -178,12 +178,17 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto if txn.GetGasFeeCap() == nil { // retrieve the latest base fee - feeHist, err := t.Client().Eth().FeeHistory(1, ethgo.Latest, nil) + feeHist, err := t.Client().FeeHistory(1, jsonrpc.LatestBlockNumber, nil) if err != nil { - return ethgo.ZeroHash, fmt.Errorf("failed to get fee history: %w", err) + return types.ZeroHash, fmt.Errorf("failed to get fee history: %w", err) + } + + baseFee := big.NewInt(0) + + if len(feeHist.BaseFee) != 0 { + baseFee = baseFee.SetUint64(feeHist.BaseFee[len(feeHist.BaseFee)-1]) } - baseFee := feeHist.BaseFee[len(feeHist.BaseFee)-1] // set max fee per gas as sum of base fee and max priority fee // (increased by certain percentage) maxFeePerGas := new(big.Int).Add(baseFee, maxPriorityFee) @@ -192,9 +197,9 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto txn.SetGasFeeCap(new(big.Int).Add(maxFeePerGas, compMaxFeePerGas)) } } else if txn.GasPrice() == nil || txn.GasPrice().Uint64() == 0 { - gasPrice, err := t.Client().Eth().GasPrice() + gasPrice, err := t.Client().GasPrice() if err != nil { - return ethgo.ZeroHash, fmt.Errorf("failed to get gas price: %w", err) + return types.ZeroHash, fmt.Errorf("failed to get gas price: %w", err) } gasPriceBigInt := new(big.Int).SetUint64(gasPrice + (gasPrice * feeIncreasePercentage / 100)) @@ -202,9 +207,9 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto } if txn.Gas() == 0 { - gasLimit, err := t.client.Eth().EstimateGas(ConvertTxnToCallMsg(txn)) + gasLimit, err := t.client.EstimateGas(ConvertTxnToCallMsg(txn)) if err != nil { - return ethgo.ZeroHash, fmt.Errorf("failed to estimate gas: %w", err) + return types.ZeroHash, fmt.Errorf("failed to estimate gas: %w", err) } txn.SetGas(gasLimit + (gasLimit * gasLimitIncreasePercentage / 100)) @@ -217,7 +222,7 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto return key.Sign(hash.Bytes()) }) if err != nil { - return ethgo.ZeroHash, err + return types.ZeroHash, err } if t.writer != nil { @@ -237,7 +242,7 @@ func (t *TxRelayerImpl) sendTransactionLocked(txn *types.Transaction, key crypto rlpTxn := signedTxn.MarshalRLP() - return t.client.Eth().SendRawTransaction(rlpTxn) + return t.client.SendRawTransaction(rlpTxn) } // SendTransactionLocal sends non-signed transaction @@ -251,33 +256,41 @@ func (t *TxRelayerImpl) SendTransactionLocal(txn *types.Transaction) (*ethgo.Rec return t.waitForReceipt(txnHash) } -func (t *TxRelayerImpl) sendTransactionLocalLocked(txn *types.Transaction) (ethgo.Hash, error) { +func (t *TxRelayerImpl) sendTransactionLocalLocked(txn *types.Transaction) (types.Hash, error) { t.lock.Lock() defer t.lock.Unlock() - accounts, err := t.client.Eth().Accounts() + accounts, err := t.client.Accounts() if err != nil { - return ethgo.ZeroHash, err + return types.ZeroHash, err } if len(accounts) == 0 { - return ethgo.ZeroHash, errNoAccounts + return types.ZeroHash, errNoAccounts + } + + sender := accounts[0] + txn.SetFrom(sender) + + nonce, err := t.client.GetNonce(sender, jsonrpc.PendingBlockNumberOrHash) + if err != nil { + return types.ZeroHash, fmt.Errorf("failed to get nonce: %w", err) } - txn.SetFrom(types.Address(accounts[0])) + txn.SetNonce(nonce) - gasLimit, err := t.client.Eth().EstimateGas(ConvertTxnToCallMsg(txn)) + gasLimit, err := t.client.EstimateGas(ConvertTxnToCallMsg(txn)) if err != nil { - return ethgo.ZeroHash, err + return types.ZeroHash, err } txn.SetGas(gasLimit) txn.SetGasPrice(new(big.Int).SetUint64(defaultGasPrice)) - return t.client.Eth().SendTransaction(convertTxn(txn)) + return t.client.SendTransaction(txn) } -func (t *TxRelayerImpl) waitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { +func (t *TxRelayerImpl) waitForReceipt(hash types.Hash) (*ethgo.Receipt, error) { if t.noWaitReceipt { return nil, nil } @@ -291,7 +304,7 @@ func (t *TxRelayerImpl) waitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) for { select { case <-ticker.C: - receipt, err := t.client.Eth().GetTransactionReceipt(hash) + receipt, err := t.client.GetTransactionReceipt(hash) if err != nil { if err.Error() != "not found" { return nil, err @@ -308,80 +321,25 @@ func (t *TxRelayerImpl) waitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) } // ConvertTxnToCallMsg converts txn instance to call message -func ConvertTxnToCallMsg(txn *types.Transaction) *ethgo.CallMsg { - gasPrice := uint64(0) +func ConvertTxnToCallMsg(txn *types.Transaction) *jsonrpc.CallMsg { + gasPrice := big.NewInt(0) if txn.GasPrice() != nil { - gasPrice = txn.GasPrice().Uint64() + gasPrice = gasPrice.Set(txn.GasPrice()) } - return ðgo.CallMsg{ - From: ethgo.Address(txn.From()), - To: (*ethgo.Address)(txn.To()), + return &jsonrpc.CallMsg{ + From: txn.From(), + To: txn.To(), Data: txn.Input(), GasPrice: gasPrice, Value: txn.Value(), - Gas: new(big.Int).SetUint64(txn.Gas()), + Gas: txn.Gas(), } } -// convertTxn converts transaction from types.Transaction to ethgo.Transaction -func convertTxn(tx *types.Transaction) *ethgo.Transaction { - getAccessList := func() ethgo.AccessList { - accessList := make(ethgo.AccessList, 0, len(tx.AccessList())) - - for _, e := range tx.AccessList() { - storageKeys := make([]ethgo.Hash, 0) - - for _, sk := range e.StorageKeys { - storageKeys = append(storageKeys, ethgo.Hash(sk)) - } - - accessList = append(accessList, - ethgo.AccessEntry{ - Address: ethgo.Address(e.Address), - Storage: storageKeys, - }) - } - - return accessList - } - - convertedTx := ðgo.Transaction{ - From: ethgo.Address(tx.From()), - To: (*ethgo.Address)(tx.To()), - Input: tx.Input(), - Value: tx.Value(), - Gas: tx.Gas(), - } - - switch tx.Type() { - case types.DynamicFeeTxType: - convertedTx.Type = ethgo.TransactionDynamicFee - convertedTx.AccessList = getAccessList() - convertedTx.MaxFeePerGas = tx.GetGasFeeCap() - convertedTx.MaxPriorityFeePerGas = tx.GetGasTipCap() - - break - - case types.AccessListTxType: - convertedTx.Type = ethgo.TransactionAccessList - convertedTx.AccessList = getAccessList() - - break - - default: - convertedTx.Type = ethgo.TransactionLegacy - convertedTx.GasPrice = tx.GetGasPrice(0).Uint64() - - break - } - - return convertedTx -} - type TxRelayerOption func(*TxRelayerImpl) -func WithClient(client *jsonrpc.Client) TxRelayerOption { +func WithClient(client *jsonrpc.EthClient) TxRelayerOption { return func(t *TxRelayerImpl) { t.client = client } diff --git a/types/access_list_tx.go b/types/access_list_tx.go index 2c601704f3..257001cde7 100644 --- a/types/access_list_tx.go +++ b/types/access_list_tx.go @@ -134,7 +134,7 @@ func (t *TxAccessList) unmarshalJSON(v *fastjson.Value) error { for _, elem := range elems { accessTuple := AccessTuple{} - addr, err := unmarshalJSONAddr(elem, "address") + addr, err := UnmarshalJSONAddr(elem, "address") if err != nil { return err } @@ -390,26 +390,43 @@ func (tx *AccessListTxn) copy() TxData { return cpy } +func (tx *AccessListTxn) marshalJSON(a *fastjson.Arena) *fastjson.Value { + v := a.NewObject() + + tx.BaseTx.marshalJSON(a, v) + v.Set("type", a.NewString(fmt.Sprintf("0x%x", tx.transactionType()))) + + if tx.ChainID != nil { + v.Set("chainId", a.NewString(fmt.Sprintf("0x%x", tx.ChainID))) + } + + if len(tx.AccessList) > 0 { + v.Set("accessList", tx.AccessList.MarshalJSONWith(a)) + } + + return v +} + func (tx *AccessListTxn) unmarshalJSON(v *fastjson.Value) error { if err := tx.BaseTx.unmarshalJSON(v); err != nil { return err } - gasPrice, err := unmarshalJSONBigInt(v, "gasPrice") + gasPrice, err := UnmarshalJSONBigInt(v, "gasPrice") if err != nil { return err } tx.setGasPrice(gasPrice) - chainID, err := unmarshalJSONBigInt(v, "chainId") + chainID, err := UnmarshalJSONBigInt(v, "chainId") if err != nil { return err } tx.setChainID(chainID) - if hasKey(v, "accessList") { + if HasJSONKey(v, "accessList") { if err := tx.AccessList.unmarshalJSON(v.Get("accessList")); err != nil { return err } diff --git a/types/base_tx.go b/types/base_tx.go index 982c68e4c6..74a18adb2d 100644 --- a/types/base_tx.go +++ b/types/base_tx.go @@ -1,8 +1,10 @@ package types import ( + "fmt" "math/big" + "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/valyala/fastjson" ) @@ -108,15 +110,48 @@ func (tx *BaseTx) copy() *BaseTx { return cpy } +func (tx *BaseTx) marshalJSON(a *fastjson.Arena, v *fastjson.Value) { + v.Set("hash", a.NewString(tx.Hash.String())) + v.Set("from", a.NewString(tx.From.String())) + v.Set("gas", a.NewString(fmt.Sprintf("0x%x", tx.Gas))) + v.Set("nonce", a.NewString(fmt.Sprintf("0x%x", tx.Nonce))) + + if tx.V != nil { + v.Set("v", a.NewString(hex.EncodeToHex(tx.V.Bytes()))) + } + + if tx.R != nil { + v.Set("r", a.NewString(hex.EncodeToHex(tx.R.Bytes()))) + } + + if tx.S != nil { + v.Set("s", a.NewString(hex.EncodeToHex(tx.S.Bytes()))) + } + + if len(tx.Input) != 0 { + v.Set("input", a.NewString(hex.EncodeToHex(tx.Input))) + } + + if tx.Value != nil { + v.Set("value", a.NewString(fmt.Sprintf("0x%x", tx.Value))) + } + + if tx.To == nil { + v.Set("to", a.NewNull()) + } else { + v.Set("to", a.NewString(tx.To.String())) + } +} + func (tx *BaseTx) unmarshalJSON(v *fastjson.Value) error { - hash, err := unmarshalJSONHash(v, "hash") + hash, err := UnmarshalJSONHash(v, "hash") if err != nil { return err } tx.setHash(hash) - from, err := unmarshalJSONAddr(v, "from") + from, err := UnmarshalJSONAddr(v, "from") if err != nil { return err } @@ -124,11 +159,11 @@ func (tx *BaseTx) unmarshalJSON(v *fastjson.Value) error { tx.setFrom(from) // Do not decode 'to' if it doesn't exist. - if hasKey(v, "to") { + if HasJSONKey(v, "to") { if v.Get("to").String() != "null" { var to Address - if to, err = unmarshalJSONAddr(v, "to"); err != nil { + if to, err = UnmarshalJSONAddr(v, "to"); err != nil { return err } @@ -136,45 +171,45 @@ func (tx *BaseTx) unmarshalJSON(v *fastjson.Value) error { } } - input, err := unmarshalJSONBytes(v, "input") + input, err := UnmarshalJSONBytes(v, "input") if err != nil { return err } tx.setInput(input) - value, err := unmarshalJSONBigInt(v, "value") + value, err := UnmarshalJSONBigInt(v, "value") if err != nil { return err } tx.setValue(value) - nonce, err := unmarshalJSONUint64(v, "nonce") + nonce, err := UnmarshalJSONUint64(v, "nonce") if err != nil { return err } tx.setNonce(nonce) - vParity, err := unmarshalJSONBigInt(v, "v") + vParity, err := UnmarshalJSONBigInt(v, "v") if err != nil { return err } - r, err := unmarshalJSONBigInt(v, "r") + r, err := UnmarshalJSONBigInt(v, "r") if err != nil { return err } - s, err := unmarshalJSONBigInt(v, "s") + s, err := UnmarshalJSONBigInt(v, "s") if err != nil { return err } tx.setSignatureValues(vParity, r, s) - gas, err := unmarshalJSONUint64(v, "gas") + gas, err := UnmarshalJSONUint64(v, "gas") if err != nil { return err } diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index a90c650fd2..c221206b6c 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -248,33 +248,58 @@ func (tx *DynamicFeeTx) copy() TxData { return cpy } +func (tx *DynamicFeeTx) marshalJSON(a *fastjson.Arena) *fastjson.Value { + v := a.NewObject() + + tx.BaseTx.marshalJSON(a, v) + v.Set("type", a.NewString(fmt.Sprintf("0x%x", tx.transactionType()))) + + if tx.GasTipCap != nil { + v.Set("maxPriorityFeePerGas", a.NewString(fmt.Sprintf("0x%x", tx.GasTipCap))) + } + + if tx.GasFeeCap != nil { + v.Set("maxFeePerGas", a.NewString(fmt.Sprintf("0x%x", tx.GasFeeCap))) + } + + if tx.ChainID != nil { + v.Set("chainId", a.NewString(fmt.Sprintf("0x%x", tx.ChainID))) + } + + if len(tx.AccessList) > 0 { + v.Set("accessList", tx.AccessList.MarshalJSONWith(a)) + } + + return v +} + func (tx *DynamicFeeTx) unmarshalJSON(v *fastjson.Value) error { if err := tx.BaseTx.unmarshalJSON(v); err != nil { return err } - gasTipCap, err := unmarshalJSONBigInt(v, "maxPriorityFeePerGas") + gasTipCap, err := UnmarshalJSONBigInt(v, "maxPriorityFeePerGas") if err != nil { return err } tx.setGasTipCap(gasTipCap) - gasFeeCap, err := unmarshalJSONBigInt(v, "maxFeePerGas") + gasFeeCap, err := UnmarshalJSONBigInt(v, "maxFeePerGas") if err != nil { return err } tx.setGasFeeCap(gasFeeCap) - chainID, err := unmarshalJSONBigInt(v, "chainId") + chainID, err := UnmarshalJSONBigInt(v, "chainId") if err != nil { return err } tx.setChainID(chainID) - if hasKey(v, "accessList") { + if HasJSONKey(v, "accessList") { if err := tx.AccessList.unmarshalJSON(v.Get("accessList")); err != nil { return err } diff --git a/types/json_marshal.go b/types/json_marshal.go new file mode 100644 index 0000000000..7ca2f335e1 --- /dev/null +++ b/types/json_marshal.go @@ -0,0 +1,20 @@ +package types + +import "github.com/valyala/fastjson" + +// MarshalJSON implements the Marshal interface. +func (t *Transaction) MarshalJSON() ([]byte, error) { + a := DefaultArena.Get() + defer a.Reset() + + v := t.marshalJSON(a) + res := v.MarshalTo(nil) + + DefaultArena.Put(a) + + return res, nil +} + +func (t *Transaction) marshalJSON(a *fastjson.Arena) *fastjson.Value { + return t.Inner.marshalJSON(a) +} diff --git a/types/json_marshalling_util.go b/types/json_marshalling_util.go new file mode 100644 index 0000000000..b7c71ddd8c --- /dev/null +++ b/types/json_marshalling_util.go @@ -0,0 +1,138 @@ +package types + +import ( + "fmt" + "math/big" + "strings" + + "github.com/0xPolygon/polygon-edge/helper/common" + "github.com/0xPolygon/polygon-edge/helper/hex" + "github.com/valyala/fastjson" +) + +var ( + DefaultArena fastjson.ArenaPool + DefaultPool fastjson.ParserPool +) + +func UnmarshalJSONHash(v *fastjson.Value, key string) (Hash, error) { + hash := Hash{} + + b := v.GetStringBytes(key) + if len(b) == 0 { + return ZeroHash, fmt.Errorf("field '%s' not found", key) + } + + err := hash.UnmarshalText(b) + + return hash, err +} + +func UnmarshalJSONAddr(v *fastjson.Value, key string) (Address, error) { + b := v.GetStringBytes(key) + if len(b) == 0 { + return ZeroAddress, fmt.Errorf("field '%s' not found", key) + } + + a := Address{} + err := a.UnmarshalText(b) + + return a, err +} + +func UnmarshalJSONBytes(v *fastjson.Value, key string, bits ...int) ([]byte, error) { + vv := v.Get(key) + if vv == nil { + return nil, fmt.Errorf("field '%s' not found", key) + } + + str := vv.String() + str = strings.Trim(str, "\"") + + if !strings.HasPrefix(str, "0x") { + return nil, fmt.Errorf("field '%s' does not have 0x prefix: '%s'", key, str) + } + + str = str[2:] + if len(str)%2 != 0 { + str = "0" + str + } + + buf, err := hex.DecodeString(str) + if err != nil { + return nil, err + } + + if len(bits) > 0 && bits[0] != len(buf) { + return nil, fmt.Errorf("field '%s' invalid length, expected %d but found %d: %s", key, bits[0], len(buf), str) + } + + return buf, nil +} + +func UnmarshalJSONUint64(v *fastjson.Value, key string) (uint64, error) { + vv := v.Get(key) + if vv == nil { + return 0, fmt.Errorf("field '%s' not found", key) + } + + str := vv.String() + str = strings.Trim(str, "\"") + + return common.ParseUint64orHex(&str) +} + +func UnmarshalJSONBigInt(v *fastjson.Value, key string) (*big.Int, error) { + vv := v.Get(key) + if vv == nil { + return nil, fmt.Errorf("field '%s' not found", key) + } + + str := vv.String() + str = strings.Trim(str, "\"") + + return common.ParseUint256orHex(&str) +} + +func UnmarshalJSONNonce(n *Nonce, v *fastjson.Value, key string) error { + b := v.GetStringBytes(key) + if len(b) == 0 { + return fmt.Errorf("field '%s' not found", key) + } + + return UnmarshalTextByte(n[:], b, 8) +} + +func UnmarshalJSONBloom(bloom *Bloom, v *fastjson.Value, key string) error { + b := v.GetStringBytes(key) + if len(b) == 0 { + return fmt.Errorf("field '%s' not found", key) + } + + return UnmarshalTextByte(bloom[:], b, BloomByteLength) +} + +func UnmarshalTextByte(dst, src []byte, size int) error { + str := string(src) + str = strings.Trim(str, "\"") + + b, err := hex.DecodeHex(str) + if err != nil { + return err + } + + if len(b) != size { + return fmt.Errorf("length %d is not correct, expected %d", len(b), size) + } + + copy(dst, b) + + return nil +} + +// HasJSONKey is a helper function for checking if given key exists in json +func HasJSONKey(v *fastjson.Value, key string) bool { + value := v.Get(key) + + return value != nil && value.Type() != fastjson.TypeNull +} diff --git a/types/json_unmarshal.go b/types/json_unmarshal.go index 3d57b89df9..dbee1e5360 100644 --- a/types/json_unmarshal.go +++ b/types/json_unmarshal.go @@ -1,21 +1,13 @@ package types import ( - "fmt" - "math/big" - "strings" - - "github.com/0xPolygon/polygon-edge/helper/common" - "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/valyala/fastjson" ) -var defaultPool fastjson.ParserPool - // UnmarshalJSON implements the unmarshal interface func (b *Block) UnmarshalJSON(buf []byte) error { - p := defaultPool.Get() - defer defaultPool.Put(p) + p := DefaultPool.Get() + defer DefaultPool.Put(p) v, err := p.Parse(string(buf)) if err != nil { @@ -23,7 +15,8 @@ func (b *Block) UnmarshalJSON(buf []byte) error { } // header - b.Header = &Header{} + b.Header = new(Header) + if err := b.Header.unmarshalJSON(v); err != nil { return err } @@ -35,7 +28,7 @@ func (b *Block) UnmarshalJSON(buf []byte) error { if len(elems) != 0 && elems[0].Type() != fastjson.TypeString { for _, elem := range elems { txn := new(Transaction) - if err := txn.unmarshalJSON(elem); err != nil { + if err := txn.UnmarshalJSONWith(elem); err != nil { return err } @@ -62,8 +55,8 @@ func (b *Block) UnmarshalJSON(buf []byte) error { } func (h *Header) UnmarshalJSON(buf []byte) error { - p := defaultPool.Get() - defer defaultPool.Put(p) + p := DefaultPool.Get() + defer DefaultPool.Put(p) v, err := p.Parse(string(buf)) if err != nil { @@ -76,67 +69,67 @@ func (h *Header) UnmarshalJSON(buf []byte) error { func (h *Header) unmarshalJSON(v *fastjson.Value) error { var err error - if h.Hash, err = unmarshalJSONHash(v, "hash"); err != nil { + if h.Hash, err = UnmarshalJSONHash(v, "hash"); err != nil { return err } - if h.ParentHash, err = unmarshalJSONHash(v, "parentHash"); err != nil { + if h.ParentHash, err = UnmarshalJSONHash(v, "parentHash"); err != nil { return err } - if h.Sha3Uncles, err = unmarshalJSONHash(v, "sha3Uncles"); err != nil { + if h.Sha3Uncles, err = UnmarshalJSONHash(v, "sha3Uncles"); err != nil { return err } - if h.TxRoot, err = unmarshalJSONHash(v, "transactionsRoot"); err != nil { + if h.TxRoot, err = UnmarshalJSONHash(v, "transactionsRoot"); err != nil { return err } - if h.StateRoot, err = unmarshalJSONHash(v, "stateRoot"); err != nil { + if h.StateRoot, err = UnmarshalJSONHash(v, "stateRoot"); err != nil { return err } - if h.ReceiptsRoot, err = unmarshalJSONHash(v, "receiptsRoot"); err != nil { + if h.ReceiptsRoot, err = UnmarshalJSONHash(v, "receiptsRoot"); err != nil { return err } - if h.Miner, err = unmarshalJSONBytes(v, "miner"); err != nil { + if h.Miner, err = UnmarshalJSONBytes(v, "miner"); err != nil { return err } - if h.Number, err = unmarshalJSONUint64(v, "number"); err != nil { + if h.Number, err = UnmarshalJSONUint64(v, "number"); err != nil { return err } - if h.GasLimit, err = unmarshalJSONUint64(v, "gasLimit"); err != nil { + if h.GasLimit, err = UnmarshalJSONUint64(v, "gasLimit"); err != nil { return err } - if h.GasUsed, err = unmarshalJSONUint64(v, "gasUsed"); err != nil { + if h.GasUsed, err = UnmarshalJSONUint64(v, "gasUsed"); err != nil { return err } - if h.MixHash, err = unmarshalJSONHash(v, "mixHash"); err != nil { + if h.MixHash, err = UnmarshalJSONHash(v, "mixHash"); err != nil { return err } - if err = unmarshalJSONNonce(&h.Nonce, v, "nonce"); err != nil { + if err = UnmarshalJSONNonce(&h.Nonce, v, "nonce"); err != nil { return err } - if h.Timestamp, err = unmarshalJSONUint64(v, "timestamp"); err != nil { + if h.Timestamp, err = UnmarshalJSONUint64(v, "timestamp"); err != nil { return err } - if h.Difficulty, err = unmarshalJSONUint64(v, "difficulty"); err != nil { + if h.Difficulty, err = UnmarshalJSONUint64(v, "difficulty"); err != nil { return err } - if h.ExtraData, err = unmarshalJSONBytes(v, "extraData"); err != nil { + if h.ExtraData, err = UnmarshalJSONBytes(v, "extraData"); err != nil { return err } - if h.BaseFee, err = unmarshalJSONUint64(v, "baseFee"); err != nil { + if h.BaseFee, err = UnmarshalJSONUint64(v, "baseFee"); err != nil { if err.Error() != "field 'baseFee' not found" { return err } @@ -147,28 +140,28 @@ func (h *Header) unmarshalJSON(v *fastjson.Value) error { // UnmarshalJSON implements the unmarshal interface func (t *Transaction) UnmarshalJSON(buf []byte) error { - p := defaultPool.Get() - defer defaultPool.Put(p) + p := DefaultPool.Get() + defer DefaultPool.Put(p) v, err := p.Parse(string(buf)) if err != nil { return err } - return t.unmarshalJSON(v) + return t.UnmarshalJSONWith(v) } -func (t *Transaction) unmarshalJSON(v *fastjson.Value) error { - if hasKey(v, "type") { - txnType, err := unmarshalJSONUint64(v, "type") +func (t *Transaction) UnmarshalJSONWith(v *fastjson.Value) error { + if HasJSONKey(v, "type") { + txnType, err := UnmarshalJSONUint64(v, "type") if err != nil { return err } t.InitInnerData(TxType(txnType)) } else { - if hasKey(v, "chainId") { - if hasKey(v, "maxFeePerGas") { + if HasJSONKey(v, "chainId") { + if HasJSONKey(v, "maxFeePerGas") { t.InitInnerData(DynamicFeeTxType) } else { t.InitInnerData(AccessListTxType) @@ -183,16 +176,16 @@ func (t *Transaction) unmarshalJSON(v *fastjson.Value) error { // UnmarshalJSON implements the unmarshal interface func (r *Receipt) UnmarshalJSON(buf []byte) error { - p := defaultPool.Get() - defer defaultPool.Put(p) + p := DefaultPool.Get() + defer DefaultPool.Put(p) v, err := p.Parse(string(buf)) if err != nil { return nil } - if hasKey(v, "contractAddress") { - contractAddr, err := unmarshalJSONAddr(v, "contractAddress") + if HasJSONKey(v, "contractAddress") { + contractAddr, err := UnmarshalJSONAddr(v, "contractAddress") if err != nil { return err } @@ -200,29 +193,29 @@ func (r *Receipt) UnmarshalJSON(buf []byte) error { r.ContractAddress = &contractAddr } - if r.TxHash, err = unmarshalJSONHash(v, "transactionHash"); err != nil { + if r.TxHash, err = UnmarshalJSONHash(v, "transactionHash"); err != nil { return err } - if r.GasUsed, err = unmarshalJSONUint64(v, "gasUsed"); err != nil { + if r.GasUsed, err = UnmarshalJSONUint64(v, "gasUsed"); err != nil { return err } - if r.CumulativeGasUsed, err = unmarshalJSONUint64(v, "cumulativeGasUsed"); err != nil { + if r.CumulativeGasUsed, err = UnmarshalJSONUint64(v, "cumulativeGasUsed"); err != nil { return err } - if err = unmarshalJSONBloom(&r.LogsBloom, v, "logsBloom"); err != nil { + if err = UnmarshalJSONBloom(&r.LogsBloom, v, "logsBloom"); err != nil { return err } - if r.Root, err = unmarshalJSONHash(v, "root"); err != nil { + if r.Root, err = UnmarshalJSONHash(v, "root"); err != nil { return err } - if hasKey(v, "status") { + if HasJSONKey(v, "status") { // post-byzantium fork - status, err := unmarshalJSONUint64(v, "status") + status, err := UnmarshalJSONUint64(v, "status") if err != nil { return err } @@ -246,30 +239,30 @@ func (r *Receipt) UnmarshalJSON(buf []byte) error { } // UnmarshalJSON implements the unmarshal interface -func (r *Log) UnmarshalJSON(buf []byte) error { - p := defaultPool.Get() - defer defaultPool.Put(p) +func (l *Log) UnmarshalJSON(buf []byte) error { + p := DefaultPool.Get() + defer DefaultPool.Put(p) v, err := p.Parse(string(buf)) if err != nil { return nil } - return r.unmarshalJSON(v) + return l.unmarshalJSON(v) } -func (r *Log) unmarshalJSON(v *fastjson.Value) error { +func (l *Log) unmarshalJSON(v *fastjson.Value) error { var err error - if r.Address, err = unmarshalJSONAddr(v, "address"); err != nil { + if l.Address, err = UnmarshalJSONAddr(v, "address"); err != nil { return err } - if r.Data, err = unmarshalJSONBytes(v, "data"); err != nil { + if l.Data, err = UnmarshalJSONBytes(v, "data"); err != nil { return err } - r.Topics = r.Topics[:0] + l.Topics = l.Topics[:0] for _, topic := range v.GetArray("topics") { b, err := topic.StringBytes() @@ -282,130 +275,8 @@ func (r *Log) unmarshalJSON(v *fastjson.Value) error { return err } - r.Topics = append(r.Topics, t) - } - - return nil -} - -func unmarshalJSONHash(v *fastjson.Value, key string) (Hash, error) { - hash := Hash{} - - b := v.GetStringBytes(key) - if len(b) == 0 { - return ZeroHash, fmt.Errorf("field '%s' not found", key) - } - - err := hash.UnmarshalText(b) - - return hash, err -} - -func unmarshalJSONAddr(v *fastjson.Value, key string) (Address, error) { - b := v.GetStringBytes(key) - if len(b) == 0 { - return ZeroAddress, fmt.Errorf("field '%s' not found", key) - } - - a := Address{} - err := a.UnmarshalText(b) - - return a, err -} - -func unmarshalJSONBytes(v *fastjson.Value, key string, bits ...int) ([]byte, error) { - vv := v.Get(key) - if vv == nil { - return nil, fmt.Errorf("field '%s' not found", key) - } - - str := vv.String() - str = strings.Trim(str, "\"") - - if !strings.HasPrefix(str, "0x") { - return nil, fmt.Errorf("field '%s' does not have 0x prefix: '%s'", key, str) - } - - str = str[2:] - if len(str)%2 != 0 { - str = "0" + str - } - - buf, err := hex.DecodeString(str) - if err != nil { - return nil, err - } - - if len(bits) > 0 && bits[0] != len(buf) { - return nil, fmt.Errorf("field '%s' invalid length, expected %d but found %d: %s", key, bits[0], len(buf), str) - } - - return buf, nil -} - -func unmarshalJSONUint64(v *fastjson.Value, key string) (uint64, error) { - vv := v.Get(key) - if vv == nil { - return 0, fmt.Errorf("field '%s' not found", key) - } - - str := vv.String() - str = strings.Trim(str, "\"") - - return common.ParseUint64orHex(&str) -} - -func unmarshalJSONBigInt(v *fastjson.Value, key string) (*big.Int, error) { - vv := v.Get(key) - if vv == nil { - return nil, fmt.Errorf("field '%s' not found", key) - } - - str := vv.String() - str = strings.Trim(str, "\"") - - return common.ParseUint256orHex(&str) -} - -func unmarshalJSONNonce(n *Nonce, v *fastjson.Value, key string) error { - b := v.GetStringBytes(key) - if len(b) == 0 { - return fmt.Errorf("field '%s' not found", key) - } - - return unmarshalTextByte(n[:], b, 8) -} - -func unmarshalJSONBloom(bloom *Bloom, v *fastjson.Value, key string) error { - b := v.GetStringBytes(key) - if len(b) == 0 { - return fmt.Errorf("field '%s' not found", key) + l.Topics = append(l.Topics, t) } - return unmarshalTextByte(bloom[:], b, BloomByteLength) -} - -func unmarshalTextByte(dst, src []byte, size int) error { - str := string(src) - str = strings.Trim(str, "\"") - - b, err := hex.DecodeHex(str) - if err != nil { - return err - } - - if len(b) != size { - return fmt.Errorf("length %d is not correct, expected %d", len(b), size) - } - - copy(dst, b) - return nil } - -// hasKey is a helper function for checking if given key exists in json -func hasKey(v *fastjson.Value, key string) bool { - value := v.Get(key) - - return value != nil && value.Type() != fastjson.TypeNull -} diff --git a/types/legacy_tx.go b/types/legacy_tx.go index f78aca36ee..fd514fa35c 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -200,12 +200,25 @@ func deriveChainID(v *big.Int) *big.Int { return v.Div(v, big.NewInt(2)) } +func (tx *LegacyTx) marshalJSON(a *fastjson.Arena) *fastjson.Value { + v := a.NewObject() + + tx.BaseTx.marshalJSON(a, v) + v.Set("type", a.NewString(fmt.Sprintf("0x%x", tx.transactionType()))) + + if tx.GasPrice != nil { + v.Set("gasPrice", a.NewString(fmt.Sprintf("0x%x", tx.GasPrice))) + } + + return v +} + func (tx *LegacyTx) unmarshalJSON(v *fastjson.Value) error { if err := tx.BaseTx.unmarshalJSON(v); err != nil { return err } - gasPrice, err := unmarshalJSONBigInt(v, "gasPrice") + gasPrice, err := UnmarshalJSONBigInt(v, "gasPrice") if err != nil { return err } diff --git a/types/state_tx.go b/types/state_tx.go index ff62671a49..38546414ad 100644 --- a/types/state_tx.go +++ b/types/state_tx.go @@ -200,12 +200,25 @@ func (tx *StateTx) copy() TxData { //nolint:dupl return cpy } +func (tx *StateTx) marshalJSON(a *fastjson.Arena) *fastjson.Value { + v := a.NewObject() + + tx.BaseTx.marshalJSON(a, v) + v.Set("type", a.NewString(fmt.Sprintf("0x%x", tx.transactionType()))) + + if tx.GasPrice != nil { + v.Set("gasPrice", a.NewString(fmt.Sprintf("0x%x", tx.GasPrice))) + } + + return v +} + func (tx *StateTx) unmarshalJSON(v *fastjson.Value) error { if err := tx.BaseTx.unmarshalJSON(v); err != nil { return err } - gasPrice, err := unmarshalJSONBigInt(v, "gasPrice") + gasPrice, err := UnmarshalJSONBigInt(v, "gasPrice") if err != nil { return err } diff --git a/types/transaction.go b/types/transaction.go index 73804406cb..a37e83f1be 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -118,6 +118,7 @@ type TxData interface { setSignatureValues(v, r, s *big.Int) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value + marshalJSON(a *fastjson.Arena) *fastjson.Value unmarshalJSON(v *fastjson.Value) error copy() TxData }