From 69fd672ded5e6e9565b9fcff6e1b498de7781993 Mon Sep 17 00:00:00 2001 From: NathanBSC <122502194+NathanBSC@users.noreply.github.com> Date: Sun, 25 Jun 2023 14:11:17 +0800 Subject: [PATCH 1/4] feat: support password flag when handling bls keys (#1726) --- cmd/geth/blsaccountcmd.go | 50 +++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/cmd/geth/blsaccountcmd.go b/cmd/geth/blsaccountcmd.go index 99c4453e07..cb95c1332a 100644 --- a/cmd/geth/blsaccountcmd.go +++ b/cmd/geth/blsaccountcmd.go @@ -46,6 +46,10 @@ var ( Name: "show-private-key", Usage: "Show the BLS12-381 private key you will encrypt into a keystore file", } + BLSAccountPasswordFileFlag = cli.StringFlag{ + Name: "blsaccountpassword", + Usage: "File path for the BLS account password, which contains the password to encrypt private key into keystore file for managing votes in fast_finality feature", + } ) var ( @@ -87,6 +91,7 @@ or import a BLS account. The BLS wallet dir should be "/bls/wallet".`, Category: "BLS ACCOUNT COMMANDS", Flags: []cli.Flag{ utils.DataDirFlag, + utils.BLSPasswordFileFlag, }, Description: ` geth bls wallet create @@ -128,6 +133,8 @@ Make sure you backup your BLS keys regularly.`, utils.DataDirFlag, privateKeyFlag, showPrivateKeyFlag, + utils.BLSPasswordFileFlag, + BLSAccountPasswordFileFlag, }, Description: ` geth bls account new @@ -147,6 +154,8 @@ You must remember this password to unlock your account in the future.`, Category: "BLS ACCOUNT COMMANDS", Flags: []cli.Flag{ utils.DataDirFlag, + utils.BLSPasswordFileFlag, + BLSAccountPasswordFileFlag, }, Description: ` geth bls account import @@ -163,6 +172,7 @@ If the BLS wallet not created yet, it will try to create BLS wallet first.`, Category: "BLS ACCOUNT COMMANDS", Flags: []cli.Flag{ utils.DataDirFlag, + utils.BLSPasswordFileFlag, }, Description: ` geth bls account list @@ -177,6 +187,7 @@ Print summary of existing BLS accounts in the current BLS wallet.`, Category: "BLS ACCOUNT COMMANDS", Flags: []cli.Flag{ utils.DataDirFlag, + utils.BLSPasswordFileFlag, }, Description: ` geth bls account delete @@ -209,7 +220,7 @@ func blsWalletCreate(ctx *cli.Context) error { utils.Fatalf("BLS wallet already exists in /bls/wallet.") } - password := utils.GetPassPhrase("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true) + password := utils.GetPassPhraseWithList("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true, 0, GetBLSPassword(ctx)) opts := []accounts.Option{} opts = append(opts, accounts.WithWalletDir(dir)) @@ -239,7 +250,7 @@ func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, e } if !dirExists { fmt.Println("BLS wallet not exists, creating BLS wallet...") - password := utils.GetPassPhrase("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true) + password := utils.GetPassPhraseWithList("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true, 0, GetBLSPassword(ctx)) opts := []accounts.Option{} opts = append(opts, accounts.WithWalletDir(walletDir)) @@ -259,7 +270,7 @@ func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, e return w, nil } - walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, GetBLSPassword(ctx)) w, err = wallet.OpenWallet(context.Background(), &wallet.Config{ WalletDir: walletDir, WalletPassword: walletPassword, @@ -299,7 +310,7 @@ func blsAccountCreate(ctx *cli.Context) error { if err := os.MkdirAll(keystoreDir, 0755); err != nil { utils.Fatalf("Could not access keystore dir: %v.", err) } - accountPassword := utils.GetPassPhrase("Your new BLS account will be encrypted with a password. Please give a password. Do not forget this password.", true) + accountPassword := utils.GetPassPhraseWithList("Your new BLS account will be encrypted with a password. Please give a password. Do not forget this password.", true, 0, GetBLSAccountPassword(ctx)) if err := core.ValidatePasswordFormat(accountPassword); err != nil { utils.Fatalf("Password invalid: %v.", err) } @@ -411,7 +422,8 @@ func blsAccountImport(ctx *cli.Context) error { utils.Fatalf("The BLS keymanager cannot import keystores") } - password := utils.GetPassPhrase("Enter the password for your imported account.", false) + password := utils.GetPassPhraseWithList("Enter the password for your imported account.", false, 0, GetBLSAccountPassword(ctx)) + fmt.Println("Importing BLS account, this may take a while...") statuses, err := accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{ Importer: k, @@ -447,7 +459,7 @@ func blsAccountList(ctx *cli.Context) error { utils.Fatalf("BLS wallet not exists.") } - walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, GetBLSPassword(ctx)) w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ WalletDir: walletDir, WalletPassword: walletPassword, @@ -526,7 +538,7 @@ func blsAccountDelete(ctx *cli.Context) error { utils.Fatalf("BLS wallet not exists.") } - walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + walletPassword := utils.GetPassPhraseWithList("Enter the password for your BLS wallet.", false, 0, GetBLSPassword(ctx)) w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ WalletDir: walletDir, WalletPassword: walletPassword, @@ -587,3 +599,27 @@ func blsAccountDelete(ctx *cli.Context) error { return nil } + +func GetBLSPassword(ctx *cli.Context) []string { + path := ctx.GlobalString(utils.BLSPasswordFileFlag.Name) + if path == "" { + return nil + } + text, err := ioutil.ReadFile(path) + if err != nil { + utils.Fatalf("Failed to read wallet password file: %v", err) + } + return []string{string(text)} +} + +func GetBLSAccountPassword(ctx *cli.Context) []string { + path := ctx.String(BLSAccountPasswordFileFlag.Name) + if path == "" { + return nil + } + text, err := ioutil.ReadFile(path) + if err != nil { + utils.Fatalf("Failed to read account password file: %v", err) + } + return []string{string(text)} +} From 598c36bcea53b0b9bf05ba64143488dbddc682a7 Mon Sep 17 00:00:00 2001 From: NathanBSC <122502194+NathanBSC@users.noreply.github.com> Date: Tue, 27 Jun 2023 08:59:08 +0800 Subject: [PATCH 2/4] fix: avoid to block the chain when failed to send votes (#1734) --- eth/protocols/bsc/peer.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/eth/protocols/bsc/peer.go b/eth/protocols/bsc/peer.go index e66ab2a6b3..202502a4b8 100644 --- a/eth/protocols/bsc/peer.go +++ b/eth/protocols/bsc/peer.go @@ -13,6 +13,9 @@ const ( // maxKnownVotes is the maximum vote hashes to keep in the known list // before starting to randomly evict them. maxKnownVotes = 5376 + + // voteBufferSize is the maximum number of batch votes can be hold before sending + voteBufferSize = 21 * 2 ) // max is a helper function which returns the larger of the two given integers. @@ -43,7 +46,7 @@ func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) *Peer { peer := &Peer{ id: id, knownVotes: newKnownCache(maxKnownVotes), - voteBroadcast: make(chan []*types.VoteEnvelope), + voteBroadcast: make(chan []*types.VoteEnvelope, voteBufferSize), Peer: p, rw: rw, version: version, @@ -105,7 +108,9 @@ func (p *Peer) AsyncSendVotes(votes []*types.VoteEnvelope) { select { case p.voteBroadcast <- votes: case <-p.term: - p.Log().Debug("Dropping vote propagation", "count", len(votes)) + p.Log().Debug("Dropping vote propagation for closed peer", "count", len(votes)) + default: + p.Log().Debug("Dropping vote propagation for abnormal peer", "count", len(votes)) } } From 291cb8ab51bf93d9bcbf6b89bff7b604e85a4516 Mon Sep 17 00:00:00 2001 From: lmittmann <3458786+lmittmann@users.noreply.github.com> Date: Tue, 27 Jun 2023 05:52:31 +0200 Subject: [PATCH 3/4] eth/filters, ethclient/gethclient: add fullTx option to pending tx filter (#25186) (#1626) This PR adds a way to subscribe to the _full_ pending transactions, as opposed to just being notified about hashes. In use cases where client subscribes to newPendingTransactions and gets txhashes only to then request the actual transaction, the caller can now shortcut that flow and obtain the transactions directly. Co-authored-by: lx <92799281+brilliant-lx@users.noreply.github.com> Co-authored-by: lmittmann Co-authored-by: Felix Lange --- eth/filters/api.go | 38 +++++++++++++++--------- eth/filters/filter_system.go | 32 +++++++++----------- eth/filters/filter_system_test.go | 22 +++++++------- ethclient/gethclient/gethclient.go | 7 ++++- ethclient/gethclient/gethclient_test.go | 39 ++++++++++++++++++++++++- 5 files changed, 93 insertions(+), 45 deletions(-) diff --git a/eth/filters/api.go b/eth/filters/api.go index a7a1c16d9b..31de091838 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -39,6 +39,7 @@ type filter struct { typ Type deadline *time.Timer // filter is inactiv when deadline triggers hashes []common.Hash + txs []*types.Transaction crit FilterCriteria logs []*types.Log s *Subscription // associated subscription in event system @@ -99,7 +100,7 @@ func (api *PublicFilterAPI) timeoutLoop(timeout time.Duration) { } } -// NewPendingTransactionFilter creates a filter that fetches pending transaction hashes +// NewPendingTransactionFilter creates a filter that fetches pending transactions // as transactions enter the pending state. // // It is part of the filter package because this filter can be used through the @@ -108,20 +109,20 @@ func (api *PublicFilterAPI) timeoutLoop(timeout time.Duration) { // https://eth.wiki/json-rpc/API#eth_newpendingtransactionfilter func (api *PublicFilterAPI) NewPendingTransactionFilter() rpc.ID { var ( - pendingTxs = make(chan []common.Hash) + pendingTxs = make(chan []*types.Transaction) pendingTxSub = api.events.SubscribePendingTxs(pendingTxs) ) api.filtersMu.Lock() - api.filters[pendingTxSub.ID] = &filter{typ: PendingTransactionsSubscription, deadline: time.NewTimer(api.timeout), hashes: make([]common.Hash, 0), s: pendingTxSub} + api.filters[pendingTxSub.ID] = &filter{typ: PendingTransactionsSubscription, deadline: time.NewTimer(api.timeout), txs: make([]*types.Transaction, 0), s: pendingTxSub} api.filtersMu.Unlock() gopool.Submit(func() { for { select { - case ph := <-pendingTxs: + case pTx := <-pendingTxs: api.filtersMu.Lock() if f, found := api.filters[pendingTxSub.ID]; found { - f.hashes = append(f.hashes, ph...) + f.txs = append(f.txs, pTx...) } api.filtersMu.Unlock() case <-pendingTxSub.Err(): @@ -136,9 +137,10 @@ func (api *PublicFilterAPI) NewPendingTransactionFilter() rpc.ID { return pendingTxSub.ID } -// NewPendingTransactions creates a subscription that is triggered each time a transaction -// enters the transaction pool and was signed from one of the transactions this nodes manages. -func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Subscription, error) { +// NewPendingTransactions creates a subscription that is triggered each time a +// transaction enters the transaction pool. If fullTx is true the full tx is +// sent to the client, otherwise the hash is sent. +func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context, fullTx *bool) (*rpc.Subscription, error) { notifier, supported := rpc.NotifierFromContext(ctx) if !supported { return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported @@ -147,16 +149,20 @@ func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Su rpcSub := notifier.CreateSubscription() gopool.Submit(func() { - txHashes := make(chan []common.Hash, 128) - pendingTxSub := api.events.SubscribePendingTxs(txHashes) + txs := make(chan []*types.Transaction, 128) + pendingTxSub := api.events.SubscribePendingTxs(txs) for { select { - case hashes := <-txHashes: + case txs := <-txs: // To keep the original behaviour, send a single tx hash in one notification. // TODO(rjl493456442) Send a batch of tx hashes in one notification - for _, h := range hashes { - notifier.Notify(rpcSub.ID, h) + for _, tx := range txs { + if fullTx != nil && *fullTx { + notifier.Notify(rpcSub.ID, tx) + } else { + notifier.Notify(rpcSub.ID, tx.Hash()) + } } case <-rpcSub.Err(): pendingTxSub.Unsubscribe() @@ -551,10 +557,14 @@ func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { f.deadline.Reset(api.timeout) switch f.typ { - case PendingTransactionsSubscription, BlocksSubscription, FinalizedHeadersSubscription, VotesSubscription: + case BlocksSubscription, FinalizedHeadersSubscription, VotesSubscription: hashes := f.hashes f.hashes = nil return returnHashes(hashes), nil + case PendingTransactionsSubscription: + txs := f.txs + f.txs = nil + return txs, nil case LogsSubscription, MinedAndPendingLogsSubscription: logs := f.logs f.logs = nil diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index bf461a1c5c..7186e7f7d7 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -47,8 +47,8 @@ const ( PendingLogsSubscription // MinedAndPendingLogsSubscription queries for logs in mined and pending blocks. MinedAndPendingLogsSubscription - // PendingTransactionsSubscription queries tx hashes for pending - // transactions entering the pending state + // PendingTransactionsSubscription queries for pending transactions entering + // the pending state PendingTransactionsSubscription // BlocksSubscription queries hashes for blocks that are imported BlocksSubscription @@ -83,7 +83,7 @@ type subscription struct { created time.Time logsCrit ethereum.FilterQuery logs chan []*types.Log - hashes chan []common.Hash + txs chan []*types.Transaction headers chan *types.Header finalizedHeaders chan *types.Header votes chan *types.VoteEnvelope @@ -187,7 +187,7 @@ func (sub *Subscription) Unsubscribe() { case sub.es.uninstall <- sub.f: break uninstallLoop case <-sub.f.logs: - case <-sub.f.hashes: + case <-sub.f.txs: case <-sub.f.headers: case <-sub.f.votes: } @@ -255,7 +255,7 @@ func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs logsCrit: crit, created: time.Now(), logs: logs, - hashes: make(chan []common.Hash), + txs: make(chan []*types.Transaction), headers: make(chan *types.Header), votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), @@ -273,7 +273,7 @@ func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*typ logsCrit: crit, created: time.Now(), logs: logs, - hashes: make(chan []common.Hash), + txs: make(chan []*types.Transaction), headers: make(chan *types.Header), votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), @@ -291,7 +291,7 @@ func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan logsCrit: crit, created: time.Now(), logs: logs, - hashes: make(chan []common.Hash), + txs: make(chan []*types.Transaction), headers: make(chan *types.Header), votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), @@ -308,7 +308,7 @@ func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscripti typ: BlocksSubscription, created: time.Now(), logs: make(chan []*types.Log), - hashes: make(chan []common.Hash), + txs: make(chan []*types.Transaction), headers: headers, votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), @@ -325,7 +325,7 @@ func (es *EventSystem) SubscribeNewFinalizedHeaders(headers chan *types.Header) typ: FinalizedHeadersSubscription, created: time.Now(), logs: make(chan []*types.Log), - hashes: make(chan []common.Hash), + txs: make(chan []*types.Transaction), headers: headers, votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), @@ -334,15 +334,15 @@ func (es *EventSystem) SubscribeNewFinalizedHeaders(headers chan *types.Header) return es.subscribe(sub) } -// SubscribePendingTxs creates a subscription that writes transaction hashes for +// SubscribePendingTxs creates a subscription that writes transactions for // transactions that enter the transaction pool. -func (es *EventSystem) SubscribePendingTxs(hashes chan []common.Hash) *Subscription { +func (es *EventSystem) SubscribePendingTxs(txs chan []*types.Transaction) *Subscription { sub := &subscription{ id: rpc.NewID(), typ: PendingTransactionsSubscription, created: time.Now(), logs: make(chan []*types.Log), - hashes: hashes, + txs: txs, headers: make(chan *types.Header), votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), @@ -359,7 +359,7 @@ func (es *EventSystem) SubscribeNewVotes(votes chan *types.VoteEnvelope) *Subscr typ: VotesSubscription, created: time.Now(), logs: make(chan []*types.Log), - hashes: make(chan []common.Hash), + txs: make(chan []*types.Transaction), headers: make(chan *types.Header), votes: votes, installed: make(chan struct{}), @@ -404,12 +404,8 @@ func (es *EventSystem) handleRemovedLogs(filters filterIndex, ev core.RemovedLog } func (es *EventSystem) handleTxsEvent(filters filterIndex, ev core.NewTxsEvent) { - hashes := make([]common.Hash, 0, len(ev.Txs)) - for _, tx := range ev.Txs { - hashes = append(hashes, tx.Hash()) - } for _, f := range filters[PendingTransactionsSubscription] { - f.hashes <- hashes + f.txs <- ev.Txs } } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 737eaa17c7..3acc0b6da9 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -250,7 +250,7 @@ func TestPendingTxFilter(t *testing.T) { types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), } - hashes []common.Hash + txs []*types.Transaction ) fid0 := api.NewPendingTransactionFilter() @@ -265,9 +265,9 @@ func TestPendingTxFilter(t *testing.T) { t.Fatalf("Unable to retrieve logs: %v", err) } - h := results.([]common.Hash) - hashes = append(hashes, h...) - if len(hashes) >= len(transactions) { + tx := results.([]*types.Transaction) + txs = append(txs, tx...) + if len(txs) >= len(transactions) { break } // check timeout @@ -278,13 +278,13 @@ func TestPendingTxFilter(t *testing.T) { time.Sleep(100 * time.Millisecond) } - if len(hashes) != len(transactions) { - t.Errorf("invalid number of transactions, want %d transactions(s), got %d", len(transactions), len(hashes)) + if len(txs) != len(transactions) { + t.Errorf("invalid number of transactions, want %d transactions(s), got %d", len(transactions), len(txs)) return } - for i := range hashes { - if hashes[i] != transactions[i].Hash() { - t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), hashes[i]) + for i := range txs { + if txs[i].Hash() != transactions[i].Hash() { + t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), txs[i].Hash()) } } } @@ -715,11 +715,11 @@ func TestPendingTxFilterDeadlock(t *testing.T) { fids[i] = fid // Wait for at least one tx to arrive in filter for { - hashes, err := api.GetFilterChanges(fid) + txs, err := api.GetFilterChanges(fid) if err != nil { t.Fatalf("Filter should exist: %v\n", err) } - if len(hashes.([]common.Hash)) > 0 { + if len(txs.([]*types.Transaction)) > 0 { break } runtime.Gosched() diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index 3795b182e1..72dc14d7c1 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -175,7 +175,12 @@ func (ec *Client) GetNodeInfo(ctx context.Context) (*p2p.NodeInfo, error) { return &result, err } -// SubscribePendingTransactions subscribes to new pending transactions. +// SubscribeFullPendingTransactions subscribes to new pending transactions. +func (ec *Client) SubscribeFullPendingTransactions(ctx context.Context, ch chan<- *types.Transaction) (*rpc.ClientSubscription, error) { + return ec.c.EthSubscribe(ctx, ch, "newPendingTransactions", true) +} + +// SubscribePendingTransactions subscribes to new pending transaction hashes. func (ec *Client) SubscribePendingTransactions(ctx context.Context, ch chan<- common.Hash) (*rpc.ClientSubscription, error) { return ec.c.EthSubscribe(ctx, ch, "newPendingTransactions") } diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go index d8f9385690..1fb2683e30 100644 --- a/ethclient/gethclient/gethclient_test.go +++ b/ethclient/gethclient/gethclient_test.go @@ -123,8 +123,11 @@ func TestGethClient(t *testing.T) { "TestSetHead", func(t *testing.T) { testSetHead(t, client) }, }, { - "TestSubscribePendingTxs", + "TestSubscribePendingTxHashes", func(t *testing.T) { testSubscribePendingTransactions(t, client) }, + }, { + "TestSubscribePendingTxs", + func(t *testing.T) { testSubscribeFullPendingTransactions(t, client) }, }, { "TestCallContract", func(t *testing.T) { testCallContract(t, client) }, @@ -298,6 +301,40 @@ func testSubscribePendingTransactions(t *testing.T, client *rpc.Client) { } } +func testSubscribeFullPendingTransactions(t *testing.T, client *rpc.Client) { + ec := New(client) + ethcl := ethclient.NewClient(client) + // Subscribe to Transactions + ch := make(chan *types.Transaction) + ec.SubscribeFullPendingTransactions(context.Background(), ch) + // Send a transaction + chainID, err := ethcl.ChainID(context.Background()) + if err != nil { + t.Fatal(err) + } + // Create transaction + tx := types.NewTransaction(1, common.Address{1}, big.NewInt(1), 22000, big.NewInt(1), nil) + signer := types.LatestSignerForChainID(chainID) + signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey) + if err != nil { + t.Fatal(err) + } + signedTx, err := tx.WithSignature(signer, signature) + if err != nil { + t.Fatal(err) + } + // Send transaction + err = ethcl.SendTransaction(context.Background(), signedTx) + if err != nil { + t.Fatal(err) + } + // Check that the transaction was send over the channel + tx = <-ch + if tx.Hash() != signedTx.Hash() { + t.Fatalf("Invalid tx hash received, got %v, want %v", tx.Hash(), signedTx.Hash()) + } +} + func testCallContract(t *testing.T, client *rpc.Client) { ec := New(client) msg := ethereum.CallMsg{ From dda8e8da6a8662ef42688945fe32bb91054ba95b Mon Sep 17 00:00:00 2001 From: lx <92799281+brilliant-lx@users.noreply.github.com> Date: Tue, 27 Jun 2023 13:01:58 +0800 Subject: [PATCH 4/4] release: prepare for release v1.2.8 (#1736) --- CHANGELOG.md | 8 ++++++++ params/version.go | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3438279146..68af7939be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ # Changelog +## v1.2.8 +FEATURE +* [\#1626](https://github.com/bnb-chain/bsc/pull/1626) eth/filters, ethclient/gethclient: add fullTx option to pending tx filter +* [\#1726](https://github.com/bnb-chain/bsc/pull/1726) feat: support password flag when handling bls keys + +BUGFIX +* [\#1734](https://github.com/bnb-chain/bsc/pull/1734) fix: avoid to block the chain when failed to send votes + ## v1.2.7 FEATURE * [\#1645](https://github.com/bnb-chain/bsc/pull/1645) lightclient: fix validator set change diff --git a/params/version.go b/params/version.go index 2104c7ef14..b551bcdc2f 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 1 // Major version component of the current release VersionMinor = 2 // Minor version component of the current release - VersionPatch = 7 // Patch version component of the current release + VersionPatch = 8 // Patch version component of the current release VersionMeta = "" // Version metadata to append to the version string )