From 70a3e886cc2a9ef21c64eaf9801ecbdba29cf729 Mon Sep 17 00:00:00 2001 From: wgr523 Date: Tue, 19 Nov 2024 15:59:46 +0800 Subject: [PATCH 001/121] fix: reduce mine period reset (waiting) time (#735) * fix: reduce mine period reset (waiting) time * fix: reset time negative problem * fix: too many time reset=0, and change log level * update log format --------- Co-authored-by: liam.lai --- miner/worker.go | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 0e341636d243..c96379210cc6 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/binary" "errors" + "fmt" "math/big" "sync" "sync/atomic" @@ -290,6 +291,7 @@ func (self *worker) update() { } }() for { + prevReset0TimeMillisec := int64(0) // A real event arrived, process interesting content select { case v := <-MinePeriodCh: @@ -301,12 +303,14 @@ func (self *worker) update() { if atomic.LoadInt32(&self.mining) == 1 { self.commitNewWork() } - timeout.Reset(time.Duration(minePeriod) * time.Second) + resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec) + timeout.Reset(resetTime) // Handle ChainHeadEvent case <-self.chainHeadCh: self.commitNewWork() - timeout.Reset(time.Duration(minePeriod) * time.Second) + resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec) + timeout.Reset(resetTime) // Handle ChainSideEvent case <-self.chainSideCh: @@ -353,6 +357,31 @@ func (self *worker) update() { } } +func getResetTime(chain *core.BlockChain, minePeriod int, prevReset0TimeMillisec *int64) time.Duration { + minePeriodDuration := time.Duration(minePeriod) * time.Second + currentBlockTime := chain.CurrentBlock().Time().Int64() + nowTime := time.Now().UnixMilli() + resetTime := time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond + // in case the current block time is not very accurate + if resetTime > minePeriodDuration { + resetTime = minePeriodDuration + } + // in case the current block is too far in the past, the block time already is huge, we wait for mine period + if resetTime < 0 { + resetTime = minePeriodDuration + } + if resetTime == 0 { + if nowTime == *prevReset0TimeMillisec { + // in case it resets to 0 in one millisecond too many times, we wait for mine period + resetTime = minePeriodDuration + } else { + *prevReset0TimeMillisec = nowTime + } + } + log.Debug("[update] Miner worker timer reset", "resetMilliseconds", resetTime.Milliseconds(), "minePeriodSec", minePeriod, "currentBlockTimeSec", fmt.Sprintf("%d", currentBlockTime), "currentSystemTimeSec", fmt.Sprintf("%d.%03d", nowTime/1000, nowTime%1000)) + return resetTime +} + func (self *worker) wait() { for { mustCommitNewWork := true From 572660612d5852e7840ed5dd1b633a0643b2b920 Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Tue, 19 Nov 2024 00:56:38 -0800 Subject: [PATCH 002/121] update version --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 0162660a4c65..49c269f5c132 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 2 // Major version component of the current release - VersionMinor = 3 // Minor version component of the current release - VersionPatch = 0 // Patch version component of the current release - VersionMeta = "stable" // Version metadata to append to the version string + VersionMajor = 2 // Major version component of the current release + VersionMinor = 4 // Minor version component of the current release + VersionPatch = 1 // Patch version component of the current release + VersionMeta = "beta1" // Version metadata to append to the version string ) // Version holds the textual version string. From 100ce5cbe5109f4376274bcb30d8c4e3addcd5ca Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Fri, 22 Nov 2024 00:01:22 -0800 Subject: [PATCH 003/121] bug fix for count vote threshold --- consensus/XDPoS/engines/engine_v2/vote.go | 4 ++-- params/version.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/consensus/XDPoS/engines/engine_v2/vote.go b/consensus/XDPoS/engines/engine_v2/vote.go index de79585297af..6e458c67a05b 100644 --- a/consensus/XDPoS/engines/engine_v2/vote.go +++ b/consensus/XDPoS/engines/engine_v2/vote.go @@ -76,7 +76,7 @@ func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *types.Vote) go x.ForensicsProcessor.DetectEquivocationInVotePool(voteMsg, x.votePool) go x.ForensicsProcessor.ProcessVoteEquivocation(chain, x, voteMsg) - epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash()) + epochInfo, err := x.getEpochSwitchInfo(chain, nil, voteMsg.ProposedBlockInfo.Hash) if err != nil { log.Error("[voteHandler] Error when getting epoch switch Info", "error", err) return errors.New("Fail on voteHandler due to failure in getting epoch switch info") @@ -175,7 +175,7 @@ func (x *XDPoS_v2) onVotePoolThresholdReached(chain consensus.ChainReader, poole } } - epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash()) + epochInfo, err := x.getEpochSwitchInfo(chain, nil, currentVoteMsg.(*types.Vote).ProposedBlockInfo.Hash) if err != nil { log.Error("[voteHandler] Error when getting epoch switch Info", "error", err) return errors.New("Fail on voteHandler due to failure in getting epoch switch info") diff --git a/params/version.go b/params/version.go index 49c269f5c132..4cc36519ec57 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 2 // Major version component of the current release VersionMinor = 4 // Minor version component of the current release - VersionPatch = 1 // Patch version component of the current release + VersionPatch = 2 // Patch version component of the current release VersionMeta = "beta1" // Version metadata to append to the version string ) From 21729181f7056dc23c753c25e459c5d8f618a77d Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Fri, 22 Nov 2024 18:36:53 -0800 Subject: [PATCH 004/121] increate timeout to 1 min for testnet --- params/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/config.go b/params/config.go index a7ac5ff3a4dc..73e54dd6c0f3 100644 --- a/params/config.go +++ b/params/config.go @@ -88,7 +88,7 @@ var ( SwitchRound: 0, CertThreshold: 0.45, TimeoutSyncThreshold: 3, - TimeoutPeriod: 20, + TimeoutPeriod: 60, MinePeriod: 2, }, 900000: { @@ -96,7 +96,7 @@ var ( SwitchRound: 900000, CertThreshold: 0.667, TimeoutSyncThreshold: 3, - TimeoutPeriod: 30, + TimeoutPeriod: 60, MinePeriod: 2, }, } From 8556473e69bda4367c9a8ced4bd6e424a3f073d9 Mon Sep 17 00:00:00 2001 From: Wang Gerui Date: Tue, 3 Dec 2024 23:05:03 +0800 Subject: [PATCH 005/121] feat: reduce wait time when block time already large --- miner/worker.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index c96379210cc6..599a4e935ec0 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -366,9 +366,9 @@ func getResetTime(chain *core.BlockChain, minePeriod int, prevReset0TimeMillisec if resetTime > minePeriodDuration { resetTime = minePeriodDuration } - // in case the current block is too far in the past, the block time already is huge, we wait for mine period + // in case the current block is too far in the past, the block time already is huge, we wait for 0 time (which will be handled in the next if statement) if resetTime < 0 { - resetTime = minePeriodDuration + resetTime = 0 } if resetTime == 0 { if nowTime == *prevReset0TimeMillisec { From 1b89654663479d0186ab804342831acfa4034407 Mon Sep 17 00:00:00 2001 From: Wang Gerui Date: Wed, 4 Dec 2024 22:42:45 +0800 Subject: [PATCH 006/121] feat: add a new round chan between consensus and miner --- consensus/XDPoS/XDPoS.go | 11 +++++++++-- consensus/XDPoS/engines/engine_v2/engine.go | 11 ++++++++++- miner/worker.go | 7 +++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index eb976ca60370..36ad2b3a6afa 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -41,6 +41,7 @@ import ( const ( ExtraFieldCheck = true SkipExtraFieldCheck = false + newRoundChanSize = 1 ) func (x *XDPoS) SigHash(header *types.Header) (hash common.Hash) { @@ -64,6 +65,8 @@ type XDPoS struct { // Share Channel MinePeriodCh chan int // Miner wait Period Channel + NewRoundCh chan types.Round // Miner use this channel to trigger worker to commitNewWork + // Trading and lending service GetXDCXService func() utils.TradingService GetLendingService func() utils.LendingService @@ -104,6 +107,7 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS { log.Info("xdc config loading", "v2 config", config.V2) minePeriodCh := make(chan int) + newRoundCh := make(chan types.Round, newRoundChanSize) // Allocate the snapshot caches and create the engine signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) @@ -113,10 +117,11 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS { db: db, MinePeriodCh: minePeriodCh, + NewRoundCh: newRoundCh, signingTxsCache: signingTxsCache, EngineV1: engine_v1.New(chainConfig, db), - EngineV2: engine_v2.New(chainConfig, db, minePeriodCh), + EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh), } } @@ -131,6 +136,7 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS { } minePeriodCh := make(chan int) + newRoundCh := make(chan types.Round, newRoundChanSize) // Allocate the snapshot caches and create the engine signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) @@ -140,13 +146,14 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS { db: db, MinePeriodCh: minePeriodCh, + NewRoundCh: newRoundCh, GetXDCXService: func() utils.TradingService { return nil }, GetLendingService: func() utils.LendingService { return nil }, signingTxsCache: signingTxsCache, EngineV1: engine_v1.NewFaker(db, chainConfig), - EngineV2: engine_v2.New(chainConfig, db, minePeriodCh), + EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh), } return fakeEngine } diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index 6d7331025ecb..20558e860a8a 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -48,6 +48,7 @@ type XDPoS_v2 struct { BroadcastCh chan interface{} minePeriodCh chan int + newRoundCh chan types.Round timeoutWorker *countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached timeoutCount int // number of timeout being sent @@ -71,7 +72,7 @@ type XDPoS_v2 struct { votePoolCollectionTime time.Time } -func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan int) *XDPoS_v2 { +func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan int, newRoundCh chan types.Round) *XDPoS_v2 { config := chainConfig.XDPoS // Setup timeoutTimer duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second @@ -100,6 +101,7 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan i timeoutWorker: timeoutTimer, BroadcastCh: make(chan interface{}), minePeriodCh: minePeriodCh, + newRoundCh: newRoundCh, round2epochBlockInfo: round2epochBlockInfo, @@ -902,6 +904,7 @@ func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, incomingQuo 1. Set currentRound = QC round + 1 (or TC round +1) 2. Reset timer 3. Reset vote and timeout Pools +4. Send signal to miner */ func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round types.Round) { log.Info("[setNewRound] new round and reset pools and workers", "round", round) @@ -911,6 +914,12 @@ func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round typ x.timeoutPool.Clear() // don't need to clean vote pool, we have other process to clean and it's not good to clean here, some edge case may break // for example round gets bump during collecting vote, so we have to keep vote. + + // send signal to newRoundCh, but if full don't send + select { + case x.newRoundCh <- round: + default: + } } func (x *XDPoS_v2) broadcastToBftChannel(msg interface{}) { diff --git a/miner/worker.go b/miner/worker.go index 599a4e935ec0..f2e61d886529 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -273,6 +273,7 @@ func (self *worker) update() { minePeriod := 2 MinePeriodCh := self.engine.(*XDPoS.XDPoS).MinePeriodCh defer close(MinePeriodCh) + NewRoundCh := self.engine.(*XDPoS.XDPoS).NewRoundCh timeout := time.NewTimer(time.Duration(minePeriod) * time.Second) c := make(chan struct{}) @@ -312,6 +313,12 @@ func (self *worker) update() { resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec) timeout.Reset(resetTime) + // Handle new round + case <-NewRoundCh: + self.commitNewWork() + resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec) + timeout.Reset(resetTime) + // Handle ChainSideEvent case <-self.chainSideCh: From 89256cb2c25271191ba80507e42ce02e09dd5e54 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Mon, 9 Dec 2024 01:40:18 -0800 Subject: [PATCH 007/121] Use safe timer reset method (#757) * use saft timer reset method * use saft timer reset method --- miner/worker.go | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index f2e61d886529..df642c49bb5c 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -116,7 +116,9 @@ type worker struct { chainHeadSub event.Subscription chainSideCh chan core.ChainSideEvent chainSideSub event.Subscription - wg sync.WaitGroup + resetCh chan time.Duration // Channel to request timer resets + + wg sync.WaitGroup agents map[Agent]struct{} recv chan *Result @@ -158,6 +160,7 @@ func newWorker(config *params.ChainConfig, engine consensus.Engine, coinbase com txsCh: make(chan core.NewTxsEvent, txChanSize), chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize), + resetCh: make(chan time.Duration, 1), chainDb: eth.ChainDb(), recv: make(chan *Result, resultQueueSize), chain: eth.BlockChain(), @@ -284,6 +287,16 @@ func (self *worker) update() { for { // A real event arrived, process interesting content select { + case d := <-self.resetCh: + // Reset the timer to the new duration. + if !timeout.Stop() { + // Drain the timer channel if it had already expired. + select { + case <-timeout.C: + default: + } + } + timeout.Reset(d) case <-timeout.C: c <- struct{}{} case <-finish: @@ -292,32 +305,31 @@ func (self *worker) update() { } }() for { - prevReset0TimeMillisec := int64(0) // A real event arrived, process interesting content select { case v := <-MinePeriodCh: log.Info("[worker] update wait period", "period", v) minePeriod = v - timeout.Reset(time.Duration(minePeriod) * time.Second) + self.resetCh <- time.Duration(minePeriod) * time.Second case <-c: if atomic.LoadInt32(&self.mining) == 1 { self.commitNewWork() } - resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec) - timeout.Reset(resetTime) + resetTime := getResetTime(self.chain, minePeriod) + self.resetCh <- resetTime // Handle ChainHeadEvent case <-self.chainHeadCh: self.commitNewWork() - resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec) - timeout.Reset(resetTime) + resetTime := getResetTime(self.chain, minePeriod) + self.resetCh <- resetTime // Handle new round case <-NewRoundCh: self.commitNewWork() - resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec) - timeout.Reset(resetTime) + resetTime := getResetTime(self.chain, minePeriod) + self.resetCh <- resetTime // Handle ChainSideEvent case <-self.chainSideCh: @@ -364,27 +376,15 @@ func (self *worker) update() { } } -func getResetTime(chain *core.BlockChain, minePeriod int, prevReset0TimeMillisec *int64) time.Duration { +func getResetTime(chain *core.BlockChain, minePeriod int) time.Duration { minePeriodDuration := time.Duration(minePeriod) * time.Second currentBlockTime := chain.CurrentBlock().Time().Int64() nowTime := time.Now().UnixMilli() resetTime := time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond // in case the current block time is not very accurate - if resetTime > minePeriodDuration { + if resetTime > minePeriodDuration || resetTime <= 0 { resetTime = minePeriodDuration } - // in case the current block is too far in the past, the block time already is huge, we wait for 0 time (which will be handled in the next if statement) - if resetTime < 0 { - resetTime = 0 - } - if resetTime == 0 { - if nowTime == *prevReset0TimeMillisec { - // in case it resets to 0 in one millisecond too many times, we wait for mine period - resetTime = minePeriodDuration - } else { - *prevReset0TimeMillisec = nowTime - } - } log.Debug("[update] Miner worker timer reset", "resetMilliseconds", resetTime.Milliseconds(), "minePeriodSec", minePeriod, "currentBlockTimeSec", fmt.Sprintf("%d", currentBlockTime), "currentSystemTimeSec", fmt.Sprintf("%d.%03d", nowTime/1000, nowTime%1000)) return resetTime } From 92d239bf1dbd540a5d9710744bebafb52cb601e6 Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Fri, 13 Dec 2024 01:47:00 -0800 Subject: [PATCH 008/121] merge from master --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 4cc36519ec57..a2aea26f2c21 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 2 // Major version component of the current release VersionMinor = 4 // Minor version component of the current release - VersionPatch = 2 // Patch version component of the current release + VersionPatch = 3 // Patch version component of the current release VersionMeta = "beta1" // Version metadata to append to the version string ) From 78331172f325c5e843f0558ab147caa662055655 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Fri, 29 Nov 2024 03:14:25 -0800 Subject: [PATCH 009/121] cherry pick vote test fix --- consensus/XDPoS/engines/engine_v2/vote.go | 8 ++++++-- consensus/XDPoS/utils/errors.go | 13 +++++++++++++ consensus/tests/engine_v2_tests/vote_test.go | 11 +++++------ eth/bft/bft_handler.go | 4 ++++ eth/handler.go | 2 +- eth/hooks/engine_v2_hooks.go | 1 - 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/consensus/XDPoS/engines/engine_v2/vote.go b/consensus/XDPoS/engines/engine_v2/vote.go index 6e458c67a05b..4c1fb828d3c5 100644 --- a/consensus/XDPoS/engines/engine_v2/vote.go +++ b/consensus/XDPoS/engines/engine_v2/vote.go @@ -78,8 +78,12 @@ func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *types.Vote) epochInfo, err := x.getEpochSwitchInfo(chain, nil, voteMsg.ProposedBlockInfo.Hash) if err != nil { - log.Error("[voteHandler] Error when getting epoch switch Info", "error", err) - return errors.New("Fail on voteHandler due to failure in getting epoch switch info") + return &utils.ErrIncomingMessageBlockNotFound{ + Type: "vote", + IncomingBlockHash: voteMsg.ProposedBlockInfo.Hash, + IncomingBlockNumber: voteMsg.ProposedBlockInfo.Number, + Err: err, + } } certThreshold := x.config.V2.Config(uint64(voteMsg.ProposedBlockInfo.Round)).CertThreshold diff --git a/consensus/XDPoS/utils/errors.go b/consensus/XDPoS/utils/errors.go index 4a45d4157ab0..c6d0706ed853 100644 --- a/consensus/XDPoS/utils/errors.go +++ b/consensus/XDPoS/utils/errors.go @@ -3,7 +3,9 @@ package utils import ( "errors" "fmt" + "math/big" + "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" ) @@ -120,3 +122,14 @@ type ErrIncomingMessageRoundTooFarFromCurrentRound struct { func (e *ErrIncomingMessageRoundTooFarFromCurrentRound) Error() string { return fmt.Sprintf("%s message round number: %v is too far away from currentRound: %v", e.Type, e.IncomingRound, e.CurrentRound) } + +type ErrIncomingMessageBlockNotFound struct { + Type string + IncomingBlockHash common.Hash + IncomingBlockNumber *big.Int + Err error +} + +func (e *ErrIncomingMessageBlockNotFound) Error() string { + return fmt.Sprintf("%s proposed block is not found hash: %v, block number: %v, error: %s", e.Type, e.IncomingBlockHash.Hex(), e.IncomingBlockNumber, e.Err) +} diff --git a/consensus/tests/engine_v2_tests/vote_test.go b/consensus/tests/engine_v2_tests/vote_test.go index 53ac60eed1cd..35e9028f9c0c 100644 --- a/consensus/tests/engine_v2_tests/vote_test.go +++ b/consensus/tests/engine_v2_tests/vote_test.go @@ -10,7 +10,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" @@ -195,11 +194,11 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) { } func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testing.T) { - blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) + blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 blockInfo := &types.BlockInfo{ - Hash: common.HexToHash("0x1"), + Hash: currentBlock.Hash(), Round: types.Round(6), Number: big.NewInt(999), } @@ -397,7 +396,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) { } err := engineV2.VoteHandler(blockchain, voteMsg) - assert.Nil(t, err) + assert.Contains(t, err.Error(), "proposed block is not found") voteMsg = &types.Vote{ ProposedBlockInfo: blockInfo, @@ -405,7 +404,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) { GapNumber: 450, } err = engineV2.VoteHandler(blockchain, voteMsg) - assert.Nil(t, err) + assert.Contains(t, err.Error(), "proposed block is not found") // Create a vote message that should trigger vote pool hook, but it shall not produce any QC yet voteMsg = &types.Vote{ @@ -415,7 +414,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) { } err = engineV2.VoteHandler(blockchain, voteMsg) - assert.Nil(t, err) + assert.Contains(t, err.Error(), "proposed block is not found") currentRound, lockQuorumCert, highestQuorumCert, _, _, _ := engineV2.GetPropertiesFaker() // Still using the initlised value because we did not yet go to the next round assert.Nil(t, lockQuorumCert) diff --git a/eth/bft/bft_handler.go b/eth/bft/bft_handler.go index 44d7c9b42378..267153dfb55d 100644 --- a/eth/bft/bft_handler.go +++ b/eth/bft/bft_handler.go @@ -101,6 +101,10 @@ func (b *Bfter) Vote(peer string, vote *types.Vote) error { log.Debug("vote round not equal", "error", err, "vote", vote.Hash()) return err } + if _, ok := err.(*utils.ErrIncomingMessageBlockNotFound); ok { + log.Debug("vote proposed block not found", "error", err, "vote", vote.Hash()) + return err + } log.Error("handle BFT Vote", "error", err) return err } diff --git a/eth/handler.go b/eth/handler.go index 76733fb8d863..c6c47503e1c8 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -863,7 +863,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { if !exist { go pm.bft.Vote(p.id, &vote) } else { - log.Debug("Discarded vote, known vote", "vote hash", vote.Hash(), "voted block hash", vote.ProposedBlockInfo.Hash.Hex(), "number", vote.ProposedBlockInfo.Number, "round", vote.ProposedBlockInfo.Round) + log.Trace("Discarded vote, known vote", "vote hash", vote.Hash(), "voted block hash", vote.ProposedBlockInfo.Hash.Hex(), "number", vote.ProposedBlockInfo.Number, "round", vote.ProposedBlockInfo.Round) } case msg.Code == TimeoutMsg: diff --git a/eth/hooks/engine_v2_hooks.go b/eth/hooks/engine_v2_hooks.go index f356af27a74c..b725811b54ae 100644 --- a/eth/hooks/engine_v2_hooks.go +++ b/eth/hooks/engine_v2_hooks.go @@ -64,7 +64,6 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf parentNumber-- parentHash = parentHeader.ParentHash listBlockHash = append(listBlockHash, parentHash) - log.Debug("[HookPenalty] listBlockHash", "i", i, "len", len(listBlockHash), "parentHash", parentHash, "parentNumber", parentNumber) } // add list not miner to penalties From 21b05243b61acb92ee53a807fe4f68c34a50a3cf Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Thu, 19 Dec 2024 01:17:29 -0800 Subject: [PATCH 010/121] Merge from master mining time patch (#767) * merge from master * close channel * close channel --------- Co-authored-by: liam.lai --- consensus/XDPoS/XDPoS.go | 11 ++++- consensus/XDPoS/engines/engine_v2/engine.go | 11 ++++- miner/worker.go | 51 ++++++++++++++++++--- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index d6e532fc129e..5001abe4e8f1 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -41,6 +41,7 @@ import ( const ( ExtraFieldCheck = true SkipExtraFieldCheck = false + newRoundChanSize = 1 ) func (x *XDPoS) SigHash(header *types.Header) (hash common.Hash) { @@ -64,6 +65,8 @@ type XDPoS struct { // Share Channel MinePeriodCh chan int // Miner wait Period Channel + NewRoundCh chan types.Round // Miner use this channel to trigger worker to commitNewWork + // Trading and lending service GetXDCXService func() utils.TradingService GetLendingService func() utils.LendingService @@ -104,6 +107,7 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS { log.Info("xdc config loading", "v2 config", config.V2) minePeriodCh := make(chan int) + newRoundCh := make(chan types.Round, newRoundChanSize) // Allocate the snapshot caches and create the engine signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) @@ -113,10 +117,11 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS { db: db, MinePeriodCh: minePeriodCh, + NewRoundCh: newRoundCh, signingTxsCache: signingTxsCache, EngineV1: engine_v1.New(chainConfig, db), - EngineV2: engine_v2.New(chainConfig, db, minePeriodCh), + EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh), } } @@ -131,6 +136,7 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS { } minePeriodCh := make(chan int) + newRoundCh := make(chan types.Round, newRoundChanSize) // Allocate the snapshot caches and create the engine signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) @@ -140,13 +146,14 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS { db: db, MinePeriodCh: minePeriodCh, + NewRoundCh: newRoundCh, GetXDCXService: func() utils.TradingService { return nil }, GetLendingService: func() utils.LendingService { return nil }, signingTxsCache: signingTxsCache, EngineV1: engine_v1.NewFaker(db, chainConfig), - EngineV2: engine_v2.New(chainConfig, db, minePeriodCh), + EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh), } return fakeEngine } diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index b808a56236f1..25515c3f7acb 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -48,6 +48,7 @@ type XDPoS_v2 struct { BroadcastCh chan interface{} minePeriodCh chan int + newRoundCh chan types.Round timeoutWorker *countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached timeoutCount int // number of timeout being sent @@ -71,7 +72,7 @@ type XDPoS_v2 struct { votePoolCollectionTime time.Time } -func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan int) *XDPoS_v2 { +func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan int, newRoundCh chan types.Round) *XDPoS_v2 { config := chainConfig.XDPoS // Setup timeoutTimer duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second @@ -100,6 +101,7 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan i timeoutWorker: timeoutTimer, BroadcastCh: make(chan interface{}), minePeriodCh: minePeriodCh, + newRoundCh: newRoundCh, round2epochBlockInfo: round2epochBlockInfo, @@ -902,6 +904,7 @@ func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, incomingQuo 1. Set currentRound = QC round + 1 (or TC round +1) 2. Reset timer 3. Reset vote and timeout Pools +4. Send signal to miner */ func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round types.Round) { log.Info("[setNewRound] new round and reset pools and workers", "round", round) @@ -911,6 +914,12 @@ func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round typ x.timeoutPool.Clear() // don't need to clean vote pool, we have other process to clean and it's not good to clean here, some edge case may break // for example round gets bump during collecting vote, so we have to keep vote. + + // send signal to newRoundCh, but if full don't send + select { + case x.newRoundCh <- round: + default: + } } func (x *XDPoS_v2) broadcastToBftChannel(msg interface{}) { diff --git a/miner/worker.go b/miner/worker.go index 9aa9d4589eea..6514b48811fc 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/binary" "errors" + "fmt" "math/big" "sync" "sync/atomic" @@ -116,7 +117,9 @@ type worker struct { chainHeadSub event.Subscription chainSideCh chan core.ChainSideEvent chainSideSub event.Subscription - wg sync.WaitGroup + resetCh chan time.Duration // Channel to request timer resets + + wg sync.WaitGroup agents map[Agent]struct{} recv chan *Result @@ -158,6 +161,7 @@ func newWorker(config *params.ChainConfig, engine consensus.Engine, coinbase com txsCh: make(chan core.NewTxsEvent, txChanSize), chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize), + resetCh: make(chan time.Duration, 1), chainDb: eth.ChainDb(), recv: make(chan *Result, resultQueueSize), chain: eth.BlockChain(), @@ -273,16 +277,30 @@ func (w *worker) update() { minePeriod := 2 MinePeriodCh := w.engine.(*XDPoS.XDPoS).MinePeriodCh defer close(MinePeriodCh) + NewRoundCh := w.engine.(*XDPoS.XDPoS).NewRoundCh + defer close(NewRoundCh) timeout := time.NewTimer(time.Duration(minePeriod) * time.Second) - c := make(chan struct{}) + defer timeout.Stop() + c := make(chan struct{}, 1) + defer close(c) finish := make(chan struct{}) defer close(finish) - defer timeout.Stop() + go func() { for { // A real event arrived, process interesting content select { + case d := <-w.resetCh: + // Reset the timer to the new duration. + if !timeout.Stop() { + // Drain the timer channel if it had already expired. + select { + case <-timeout.C: + default: + } + } + timeout.Reset(d) case <-timeout.C: c <- struct{}{} case <-finish: @@ -296,18 +314,26 @@ func (w *worker) update() { case v := <-MinePeriodCh: log.Info("[worker] update wait period", "period", v) minePeriod = v - timeout.Reset(time.Duration(minePeriod) * time.Second) + w.resetCh <- time.Duration(minePeriod) * time.Second case <-c: if atomic.LoadInt32(&w.mining) == 1 { w.commitNewWork() } - timeout.Reset(time.Duration(minePeriod) * time.Second) + resetTime := getResetTime(w.chain, minePeriod) + w.resetCh <- resetTime // Handle ChainHeadEvent case <-w.chainHeadCh: w.commitNewWork() - timeout.Reset(time.Duration(minePeriod) * time.Second) + resetTime := getResetTime(w.chain, minePeriod) + w.resetCh <- resetTime + + // Handle new round + case <-NewRoundCh: + w.commitNewWork() + resetTime := getResetTime(w.chain, minePeriod) + w.resetCh <- resetTime // Handle ChainSideEvent case <-w.chainSideCh: @@ -354,6 +380,19 @@ func (w *worker) update() { } } +func getResetTime(chain *core.BlockChain, minePeriod int) time.Duration { + minePeriodDuration := time.Duration(minePeriod) * time.Second + currentBlockTime := chain.CurrentBlock().Time().Int64() + nowTime := time.Now().UnixMilli() + resetTime := time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond + // in case the current block time is not very accurate + if resetTime > minePeriodDuration || resetTime <= 0 { + resetTime = minePeriodDuration + } + log.Debug("[update] Miner worker timer reset", "resetMilliseconds", resetTime.Milliseconds(), "minePeriodSec", minePeriod, "currentBlockTimeSec", fmt.Sprintf("%d", currentBlockTime), "currentSystemTimeSec", fmt.Sprintf("%d.%03d", nowTime/1000, nowTime%1000)) + return resetTime +} + func (w *worker) wait() { for { mustCommitNewWork := true From e1ab3e03d1e3ea560955e22c68c57a5c10a18f67 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Thu, 19 Dec 2024 01:18:13 -0800 Subject: [PATCH 011/121] add buffer channel to unlock deadlock (#766) * add buffer channel to unlock deadlock * add buffer channel to unlock deadlock * close channel --------- Co-authored-by: liam.lai --- miner/worker.go | 7 +++++-- params/version.go | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index df642c49bb5c..31bb721744ac 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -277,12 +277,15 @@ func (self *worker) update() { MinePeriodCh := self.engine.(*XDPoS.XDPoS).MinePeriodCh defer close(MinePeriodCh) NewRoundCh := self.engine.(*XDPoS.XDPoS).NewRoundCh + defer close(NewRoundCh) timeout := time.NewTimer(time.Duration(minePeriod) * time.Second) - c := make(chan struct{}) + defer timeout.Stop() + c := make(chan struct{}, 1) + defer close(c) finish := make(chan struct{}) defer close(finish) - defer timeout.Stop() + go func() { for { // A real event arrived, process interesting content diff --git a/params/version.go b/params/version.go index a2aea26f2c21..45407ecbb3e9 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 2 // Major version component of the current release VersionMinor = 4 // Minor version component of the current release - VersionPatch = 3 // Patch version component of the current release + VersionPatch = 4 // Patch version component of the current release VersionMeta = "beta1" // Version metadata to append to the version string ) From 50f401305972e993b92973b9dc97a576f7c38ba8 Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Fri, 20 Dec 2024 14:11:32 -0800 Subject: [PATCH 012/121] remove normal log --- consensus/XDPoS/engines/engine_v2/epochSwitch.go | 1 - 1 file changed, 1 deletion(-) diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index e9d76daa620a..8f718de0bec8 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -41,7 +41,6 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types log.Debug("[getEpochSwitchInfo] header doesn't provide, get header by hash", "hash", hash.Hex()) h = chain.GetHeaderByHash(hash) if h == nil { - log.Warn("[getEpochSwitchInfo] can not find header from db", "hash", hash.Hex()) return nil, fmt.Errorf("[getEpochSwitchInfo] can not find header from db hash %v", hash.Hex()) } } From 7491a7ba7479de1db0358369abc4aea8e68733ff Mon Sep 17 00:00:00 2001 From: JukLee0ira Date: Fri, 20 Dec 2024 17:30:15 +0800 Subject: [PATCH 013/121] all: improve EstimateGas API (#20830) --- accounts/abi/abi_test.go | 32 ++++ accounts/abi/bind/backends/simulated.go | 74 +++++++-- accounts/abi/bind/backends/simulated_test.go | 154 +++++++++++++++++++ core/blockchain.go | 2 - core/error.go | 16 ++ core/state_processor.go | 12 +- core/state_transition.go | 92 ++++++----- core/token_validator.go | 4 +- core/vm/instructions.go | 2 +- eth/api_tracer.go | 10 +- eth/tracers/testing/calltrace_test.go | 4 +- eth/tracers/tracers_test.go | 6 +- internal/ethapi/api.go | 103 ++++++++----- les/odr_test.go | 8 +- light/odr_test.go | 4 +- tests/state_test_util.go | 2 +- 16 files changed, 404 insertions(+), 121 deletions(-) create mode 100644 accounts/abi/bind/backends/simulated_test.go diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 4cf5668ff641..790505b8c043 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -19,6 +19,7 @@ package abi import ( "bytes" "encoding/hex" + "errors" "fmt" "log" "math/big" @@ -713,3 +714,34 @@ func TestABI_MethodById(t *testing.T) { } } + +func TestUnpackRevert(t *testing.T) { + t.Parallel() + + var cases = []struct { + input string + expect string + expectErr error + }{ + {"", "", errors.New("invalid data for unpacking")}, + {"08c379a1", "", errors.New("invalid data for unpacking")}, + {"08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000", "revert reason", nil}, + } + for index, c := range cases { + t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) { + got, err := UnpackRevert(common.Hex2Bytes(c.input)) + if c.expectErr != nil { + if err == nil { + t.Fatalf("Expected non-nil error") + } + if err.Error() != c.expectErr.Error() { + t.Fatalf("Expected error mismatch, want %v, got %v", c.expectErr, err) + } + return + } + if c.expect != got { + t.Fatalf("Output mismatch, want %v, got %v", c.expect, got) + } + }) + } +} diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index f6b4a13da6fc..12005705c710 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/XDCxlending" "github.com/XinFinOrg/XDPoSChain/accounts" + "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/keystore" "github.com/XinFinOrg/XDPoSChain/common" @@ -54,7 +55,6 @@ import ( var _ bind.ContractBackend = (*SimulatedBackend)(nil) var errBlockNumberUnsupported = errors.New("SimulatedBackend cannot access blocks other than the latest block") -var errGasEstimationFailed = errors.New("gas required exceeds allowance or always failing transaction") // SimulatedBackend implements bind.ContractBackend, simulating a blockchain in // the background. Its main purpose is to allow easily testing contract bindings. @@ -161,6 +161,12 @@ func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend { return backend } +// Close terminates the underlying blockchain's update loop. +func (b *SimulatedBackend) Close() error { + b.blockchain.Stop() + return nil +} + // Commit imports all the pending transactions as a single block and starts a // fresh new state. func (b *SimulatedBackend) Commit() { @@ -290,8 +296,11 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call XDPoSChain.Cal if err != nil { return nil, err } - rval, _, _, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), state) - return rval, err + res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), state) + if err != nil { + return nil, err + } + return res.Return(), nil } // PendingCallContract executes a contract call on the pending state. @@ -300,8 +309,11 @@ func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call XDPoSCh defer b.mu.Unlock() defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot()) - rval, _, _, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) - return rval, err + res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) + if err != nil { + return nil, err + } + return res.Return(), nil } // PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving @@ -348,22 +360,33 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call cap = hi // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) bool { + executable := func(gas uint64) (bool, *core.ExecutionResult, error) { call.Gas = gas snapshot := b.pendingState.Snapshot() - _, _, failed, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) + res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) b.pendingState.RevertToSnapshot(snapshot) - if err != nil || failed { - return false + if err != nil { + if err == core.ErrIntrinsicGas { + return true, nil, nil // Special case, raise gas limit + } + return true, nil, err // Bail out } - return true + return res.Failed(), res, nil } // Execute the binary search and hone in on an executable gas limit for lo+1 < hi { mid := (hi + lo) / 2 - if !executable(mid) { + failed, _, err := executable(mid) + + // If the error is not nil(consensus error), it means the provided message + // call or transaction will never be accepted no matter how much gas it is + // assigned. Return the error directly, don't struggle any more + if err != nil { + return 0, err + } + if failed { lo = mid } else { hi = mid @@ -371,8 +394,25 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call } // Reject the transaction as invalid if it still fails at the highest allowance if hi == cap { - if !executable(hi) { - return 0, errGasEstimationFailed + failed, result, err := executable(hi) + if err != nil { + return 0, err + } + if failed { + if result != nil && result.Err != vm.ErrOutOfGas { + errMsg := fmt.Sprintf("always failing transaction (%v)", result.Err) + if len(result.Revert()) > 0 { + ret, err := abi.UnpackRevert(result.Revert()) + if err != nil { + errMsg += fmt.Sprintf(" (%#x)", result.Revert()) + } else { + errMsg += fmt.Sprintf(" (%s)", ret) + } + } + return 0, errors.New(errMsg) + } + // Otherwise, the specified gas cap is too low + return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) } } return hi, nil @@ -380,10 +420,10 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call // callContract implements common code between normal and pending contract calls. // state is modified during execution, make sure to copy it if necessary. -func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) (ret []byte, usedGas uint64, failed bool, err error) { +func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) (*core.ExecutionResult, error) { // Gas prices post 1559 need to be initialized if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) { - return nil, 0, false, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") + return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") } head := b.blockchain.CurrentHeader() if !b.blockchain.Config().IsEIP1559(head.Number) { @@ -438,8 +478,8 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.Cal vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, b.config, vm.Config{NoBaseFee: true}) gaspool := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - ret, usedGas, failed, err, _ = core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) - return + res, err, _ := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) + return res, err } // SendTransaction updates the pending block to include the given transaction. diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go new file mode 100644 index 000000000000..568189852310 --- /dev/null +++ b/accounts/abi/bind/backends/simulated_test.go @@ -0,0 +1,154 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backends + +import ( + "context" + "errors" + "math/big" + "strings" + "testing" + + "github.com/XinFinOrg/XDPoSChain" + "github.com/XinFinOrg/XDPoSChain/accounts/abi" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" +) + +func TestSimulatedBackend_EstimateGas(t *testing.T) { + /* + pragma solidity ^0.6.4; + contract GasEstimation { + function PureRevert() public { revert(); } + function Revert() public { revert("revert reason");} + function OOG() public { for (uint i = 0; ; i++) {}} + function Assert() public { assert(false);} + function Valid() public {} + }*/ + const contractAbi = "[{\"inputs\":[],\"name\":\"Assert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OOG\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PureRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Revert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Valid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + const contractBin = "0x60806040523480156100115760006000fd5b50610017565b61016e806100266000396000f3fe60806040523480156100115760006000fd5b506004361061005c5760003560e01c806350f6fe3414610062578063aa8b1d301461006c578063b9b046f914610076578063d8b9839114610080578063e09fface1461008a5761005c565b60006000fd5b61006a610094565b005b6100746100ad565b005b61007e6100b5565b005b6100886100c2565b005b610092610135565b005b6000600090505b5b808060010191505061009b565b505b565b60006000fd5b565b600015156100bf57fe5b5b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f72657665727420726561736f6e0000000000000000000000000000000000000081526020015060200191505060405180910390fd5b565b5b56fea2646970667358221220345bbcbb1a5ecf22b53a78eaebf95f8ee0eceff6d10d4b9643495084d2ec934a64736f6c63430006040033" + + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + opts := bind.NewKeyedTransactor(key) + + sim := NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000, ¶ms.ChainConfig{ + ConstantinopleBlock: big.NewInt(0), + XDPoS: ¶ms.XDPoSConfig{ + Epoch: 900, + SkipV1Validation: true, + V2: ¶ms.V2{ + SwitchBlock: big.NewInt(900), + CurrentConfig: params.UnitTestV2Configs[0], + }, + }, + }) + + defer sim.Close() + + parsed, _ := abi.JSON(strings.NewReader(contractAbi)) + contractAddr, _, _, _ := bind.DeployContract(opts, parsed, common.FromHex(contractBin), sim) + sim.Commit() + + var cases = []struct { + name string + message XDPoSChain.CallMsg + expect uint64 + expectError error + }{ + {"plain transfer(valid)", XDPoSChain.CallMsg{ + From: addr, + To: &addr, + Gas: 0, + GasPrice: big.NewInt(0), + Value: big.NewInt(1), + Data: nil, + }, params.TxGas, nil}, + + {"plain transfer(invalid)", XDPoSChain.CallMsg{ + From: addr, + To: &contractAddr, + Gas: 0, + GasPrice: big.NewInt(0), + Value: big.NewInt(1), + Data: nil, + }, 0, errors.New("always failing transaction (execution reverted)")}, + + {"Revert", XDPoSChain.CallMsg{ + From: addr, + To: &contractAddr, + Gas: 0, + GasPrice: big.NewInt(0), + Value: nil, + Data: common.Hex2Bytes("d8b98391"), + }, 0, errors.New("always failing transaction (execution reverted) (revert reason)")}, + + {"PureRevert", XDPoSChain.CallMsg{ + From: addr, + To: &contractAddr, + Gas: 0, + GasPrice: big.NewInt(0), + Value: nil, + Data: common.Hex2Bytes("aa8b1d30"), + }, 0, errors.New("always failing transaction (execution reverted)")}, + + {"OOG", XDPoSChain.CallMsg{ + From: addr, + To: &contractAddr, + Gas: 100000, + GasPrice: big.NewInt(0), + Value: nil, + Data: common.Hex2Bytes("50f6fe34"), + }, 0, errors.New("gas required exceeds allowance (100000)")}, + + {"Assert", XDPoSChain.CallMsg{ + From: addr, + To: &contractAddr, + Gas: 100000, + GasPrice: big.NewInt(0), + Value: nil, + Data: common.Hex2Bytes("b9b046f9"), + }, 0, errors.New("always failing transaction (invalid opcode: INVALID)")}, + + {"Valid", XDPoSChain.CallMsg{ + From: addr, + To: &contractAddr, + Gas: 100000, + GasPrice: big.NewInt(0), + Value: nil, + Data: common.Hex2Bytes("e09fface"), + }, 21483, nil}, + } + for _, c := range cases { + got, err := sim.EstimateGas(context.Background(), c.message) + if c.expectError != nil { + if err == nil { + t.Fatalf("Expect error, got nil") + } + if c.expectError.Error() != err.Error() { + t.Fatalf("Expect error, want %v, got %v", c.expectError, err) + } + continue + } + if got != c.expect { + t.Fatalf("Gas estimation mismatch, want %d, got %d", c.expect, got) + } + } +} diff --git a/core/blockchain.go b/core/blockchain.go index 7aebc61155bd..25ec81a7aa75 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -82,8 +82,6 @@ var ( blockReorgDropMeter = metrics.NewRegisteredMeter("chain/reorg/drop", nil) CheckpointCh = make(chan int) - - ErrNoGenesis = errors.New("Genesis not found in chain") ) const ( diff --git a/core/error.go b/core/error.go index 4eb7eebf0ec9..67bb75730e84 100644 --- a/core/error.go +++ b/core/error.go @@ -29,6 +29,18 @@ var ( // ErrBlacklistedHash is returned if a block to import is on the blacklist. ErrBlacklistedHash = errors.New("blacklisted hash") + // ErrNoGenesis is returned when there is no Genesis Block. + ErrNoGenesis = errors.New("genesis not found in chain") +) + +// List of evm-call-message pre-checking errors. All state transtion messages will +// be pre-checked before execution. If any invalidation detected, the corresponding +// error should be returned which is defined here. +// +// - If the pre-checking happens in the miner, then the transaction won't be packed. +// - If the pre-checking happens in the block processing procedure, then a "BAD BLOCk" +// error should be emitted. +var ( // ErrNonceTooLow is returned if the nonce of a transaction is lower than the // one present in the local chain. ErrNonceTooLow = errors.New("nonce too low") @@ -45,6 +57,10 @@ var ( // by a transaction is higher than what's left in the block. ErrGasLimitReached = errors.New("gas limit reached") + // ErrInsufficientFundsForTransfer is returned if the transaction sender doesn't + // have enough funds for transfer(topmost call only). + ErrInsufficientFundsForTransfer = errors.New("insufficient funds for transfer") + // ErrMaxInitCodeSizeExceeded is returned if creation transaction provides the init code bigger // than init code size limit. ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded") diff --git a/core/state_processor.go b/core/state_processor.go index 8234e36c8f7d..5fc975c7c72d 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -403,7 +403,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* // End Bypass blacklist address // Apply the transaction to the current state (included in the env) - _, gas, failed, err, _ := ApplyMessage(evm, msg, gp, coinbaseOwner) + result, err, _ := ApplyMessage(evm, msg, gp, coinbaseOwner) if err != nil { return nil, 0, err, false @@ -416,18 +416,18 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* } else { root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() } - *usedGas += gas + *usedGas += result.UsedGas // Create a new receipt for the transaction, storing the intermediate root and gas used // by the tx. receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: *usedGas} - if failed { + if result.Failed() { receipt.Status = types.ReceiptStatusFailed } else { receipt.Status = types.ReceiptStatusSuccessful } receipt.TxHash = tx.Hash() - receipt.GasUsed = gas + receipt.GasUsed = result.UsedGas // If the transaction created a contract, store the creation address in the receipt. if msg.To() == nil { @@ -440,10 +440,10 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* receipt.BlockHash = blockHash receipt.BlockNumber = blockNumber receipt.TransactionIndex = uint(statedb.TxIndex()) - if balanceFee != nil && failed { + if balanceFee != nil && result.Failed() { state.PayFeeWithTRC21TxFail(statedb, msg.From(), *to) } - return receipt, gas, err, balanceFee != nil + return receipt, result.UsedGas, err, balanceFee != nil } func getCoinbaseOwner(bc *BlockChain, statedb *state.StateDB, header *types.Header, author *common.Address) common.Address { diff --git a/core/state_transition.go b/core/state_transition.go index 05db0e7d9501..42e044a8de73 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -27,8 +27,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" + "github.com/holiman/uint256" ) var emptyCodeHash = crypto.Keccak256Hash(nil) @@ -73,7 +73,6 @@ type StateTransition struct { // Message represents a message sent to a contract. type Message interface { From() common.Address - //FromFrontier() (common.Address, error) To() *common.Address GasPrice() *big.Int @@ -89,6 +88,35 @@ type Message interface { AccessList() types.AccessList } +// ExecutionResult includes all output after executing given evm +// message no matter the execution itself is successful or not. +type ExecutionResult struct { + UsedGas uint64 // Total used gas but include the refunded gas + Err error // Any error encountered during the execution(listed in core/vm/errors.go) + ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode) +} + +// Failed returns the indicator whether the execution is successful or not +func (result *ExecutionResult) Failed() bool { return result.Err != nil } + +// Return is a helper function to help caller distinguish between revert reason +// and function return. Return returns the data after execution if no error occurs. +func (result *ExecutionResult) Return() []byte { + if result.Err != nil { + return nil + } + return common.CopyBytes(result.ReturnData) +} + +// Revert returns the concrete revert reason if the execution is aborted by `REVERT` +// opcode. Note the reason can be nil if no data supplied with revert opcode. +func (result *ExecutionResult) Revert() []byte { + if result.Err != vm.ErrExecutionReverted { + return nil + } + return common.CopyBytes(result.ReturnData) +} + // IntrinsicGas computes the 'intrinsic gas' for a message with the given data. func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation, isHomestead bool, isEIP3860 bool) (uint64, error) { // Set the starting gas for the raw transaction @@ -166,7 +194,7 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition // the gas used (which includes gas refunds) and an error if it failed. An error always // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. -func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) ([]byte, uint64, bool, error, error) { +func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) (*ExecutionResult, error, error) { return NewStateTransition(evm, msg, gp).TransitionDb(owner) } @@ -213,7 +241,7 @@ func (st *StateTransition) buyGas() error { return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want) } } else if balanceTokenFee.Cmp(mgval) < 0 { - return errInsufficientBalanceForGas + return ErrInsufficientFunds } if err := st.gp.SubGas(st.msg.Gas()); err != nil { return err @@ -289,7 +317,7 @@ func (st *StateTransition) preCheck() error { // // However if any consensus issue encountered, return the error directly with // nil evm execution result. -func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedGas uint64, failed bool, err error, vmErr error) { +func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, error, error) { // First check this message satisfies all consensus rules before // applying the message. The rules include these clauses // @@ -301,8 +329,8 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG // 6. caller has enough balance to cover asset transfer for **topmost** call // Check clauses 1-3, buy gas if everything is correct - if err = st.preCheck(); err != nil { - return nil, 0, false, err, nil + if err := st.preCheck(); err != nil { + return nil, err, nil } var ( @@ -317,16 +345,16 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG // Check clauses 4-5, subtract intrinsic gas if everything is correct gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, homestead, rules.IsEIP1559) if err != nil { - return nil, 0, false, err, nil + return nil, err, nil } if st.gas < gas { - return nil, 0, false, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas), nil + return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas), nil } st.gas -= gas // Check whether the init code size has been exceeded. if rules.IsEIP1559 && contractCreation && len(st.data) > params.MaxInitCodeSize { - return nil, 0, false, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(st.data), params.MaxInitCodeSize), nil + return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(st.data), params.MaxInitCodeSize), nil } // Execute the preparatory steps for state transition which includes: @@ -334,35 +362,25 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG // - reset transient storage(eip 1153) st.state.Prepare(rules, msg.From(), st.evm.Context.Coinbase, msg.To(), vm.ActivePrecompiles(rules), msg.AccessList()) + // Check clause 6 + value, overflow := uint256.FromBig(msg.Value()) + if overflow { + return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex()), nil + } + if !value.IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From(), value.ToBig()) { + return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex()), nil + } + var ( - evm = st.evm - // vm errors do not effect consensus and are therefor - // not assigned to err, except for insufficient balance - // error. - vmerr error + ret []byte + vmerr error // vm errors do not effect consensus and are therefore not assigned to err ) - // for debugging purpose - // TODO: clean it after fixing the issue https://github.com/XinFinOrg/XDPoSChain/issues/401 - var contractAction string - nonce := uint64(1) if contractCreation { - ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value) - contractAction = "contract creation" + ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value) } else { // Increment the nonce for the next transaction - nonce = st.state.GetNonce(sender.Address()) + 1 - st.state.SetNonce(sender.Address(), nonce) - ret, st.gas, vmerr = evm.Call(sender, st.to().Address(), st.data, st.gas, st.value) - contractAction = "contract call" - } - if vmerr != nil { - log.Debug("VM returned with error", "action", contractAction, "contract address", st.to().Address(), "gas", st.gas, "gasPrice", st.gasPrice, "nonce", nonce, "err", vmerr) - // The only possible consensus-error would be if there wasn't - // sufficient balance to make the transfer happen. The first - // balance transfer may never fail. - if vmerr == vm.ErrInsufficientBalance { - return nil, 0, false, vmerr, nil - } + st.state.SetNonce(sender.Address(), st.state.GetNonce(sender.Address())+1) + ret, st.gas, vmerr = st.evm.Call(sender, st.to().Address(), st.data, st.gas, st.value) } if !eip3529 { // Before EIP-3529: refunds were capped to gasUsed / 2 @@ -384,7 +402,11 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)) } - return ret, st.gasUsed(), vmerr != nil, nil, vmerr + return &ExecutionResult{ + UsedGas: st.gasUsed(), + Err: vmerr, + ReturnData: ret, + }, nil, vmerr } func (st *StateTransition) refundGas(refundQuotient uint64) { diff --git a/core/token_validator.go b/core/token_validator.go index 628db3c98a98..e888f37b102e 100644 --- a/core/token_validator.go +++ b/core/token_validator.go @@ -117,11 +117,11 @@ func CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext, vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, chain.Config(), vm.Config{}) gaspool := new(GasPool).AddGas(1000000) owner := common.Address{} - rval, _, _, err, _ := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) + result, err, _ := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) if err != nil { return nil, err } - return rval, err + return result.Return(), err } // make sure that balance of token is at slot 0 diff --git a/core/vm/instructions.go b/core/vm/instructions.go index b51bb870d79d..6a0ddea1b190 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -21,8 +21,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" "github.com/holiman/uint256" ) diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 88d2cf4881b4..35297da7f880 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -526,7 +526,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, vmenv := vm.NewEVM(blockCtx, txContext, statedb, XDCxState, api.config, vm.Config{}) owner := common.Address{} - if _, _, _, err, _ := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil { + if _, err, _ := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil { failed = err break } @@ -750,7 +750,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, t statedb.SetTxContext(txctx.TxHash, txctx.TxIndex) owner := common.Address{} - ret, gas, failed, err, _ := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner) + result, err, _ := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner) if err != nil { return nil, fmt.Errorf("tracing failed: %v", err) } @@ -758,9 +758,9 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, t switch tracer := tracer.(type) { case *vm.StructLogger: return ðapi.ExecutionResult{ - Gas: gas, - Failed: failed, - ReturnValue: fmt.Sprintf("%x", ret), + Gas: result.UsedGas, + Failed: result.Failed(), + ReturnValue: fmt.Sprintf("%x", result.Return()), StructLogs: ethapi.FormatLogs(tracer.StructLogs()), }, nil diff --git a/eth/tracers/testing/calltrace_test.go b/eth/tracers/testing/calltrace_test.go index aaea4f375d41..35d9407cd93a 100644 --- a/eth/tracers/testing/calltrace_test.go +++ b/eth/tracers/testing/calltrace_test.go @@ -120,7 +120,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err, _ = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon @@ -231,7 +231,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { evm := vm.NewEVM(context, txContext, statedb, nil, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) snap := statedb.Snapshot() st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err, _ = st.TransitionDb(common.Address{}); err != nil { b.Fatalf("failed to execute transaction: %v", err) } if _, err = tracer.GetResult(); err != nil { diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 9505387fce35..4b3198c95e0f 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -158,7 +158,7 @@ func TestZeroValueToNotExitCall(t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err, _ = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon @@ -244,7 +244,7 @@ func TestPrestateTracerCreate2(t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err, _ = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon @@ -346,7 +346,7 @@ func BenchmarkTransactionTrace(b *testing.B) { for i := 0; i < b.N; i++ { snap := statedb.Snapshot() st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - _, _, _, err, _ = st.TransitionDb(common.Address{}) + _, err, _ = st.TransitionDb(common.Address{}) if err != nil { b.Fatal(err) } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 273021e4f0a6..f8687bf626a3 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1322,18 +1322,18 @@ func (s *PublicBlockChainAPI) getCandidatesFromSmartContract() ([]utils.Masterno return candidatesWithStakeInfo, nil } -func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) ([]byte, uint64, bool, error, error) { +func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error, error) { defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) statedb, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if statedb == nil || err != nil { - return nil, 0, false, err, nil + return nil, err, nil } if header == nil { - return nil, 0, false, errors.New("nil header in DoCall"), nil + return nil, errors.New("nil header in DoCall"), nil } if err := overrides.Apply(statedb); err != nil { - return nil, 0, false, err, nil + return nil, err, nil } // Setup context so it may be cancelled the call has completed @@ -1350,32 +1350,32 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) if err != nil { - return nil, 0, false, err, nil + return nil, err, nil } if block == nil { - return nil, 0, false, fmt.Errorf("nil block in DoCall: number=%d, hash=%s", header.Number.Uint64(), header.Hash().Hex()), nil + return nil, fmt.Errorf("nil block in DoCall: number=%d, hash=%s", header.Number.Uint64(), header.Hash().Hex()), nil } author, err := b.GetEngine().Author(block.Header()) if err != nil { - return nil, 0, false, err, nil + return nil, err, nil } XDCxState, err := b.XDCxService().GetTradingState(block, author) if err != nil { - return nil, 0, false, err, nil + return nil, err, nil } // TODO: replace header.BaseFee with blockCtx.BaseFee // reference: https://github.com/ethereum/go-ethereum/pull/29051 msg, err := args.ToMessage(b, header.Number, globalGasCap, header.BaseFee) if err != nil { - return nil, 0, false, err, nil + return nil, err, nil } msg.SetBalanceTokenFeeForCall() // Get a new instance of the EVM. evm, vmError, err := b.GetEVM(ctx, msg, statedb, XDCxState, header, &vm.Config{NoBaseFee: true}) if err != nil { - return nil, 0, false, err, nil + return nil, err, nil } // Wait for the context to be done and cancel the evm. Even if the // EVM has finished, cancelling may be done (repeatedly) @@ -1387,19 +1387,19 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash // Execute the message. gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - res, gas, failed, err, vmErr := core.ApplyMessage(evm, msg, gp, owner) + result, err, vmErr := core.ApplyMessage(evm, msg, gp, owner) if err := vmError(); err != nil { - return nil, 0, false, err, nil + return nil, err, nil } // If the timer caused an abort, return an appropriate error message if evm.Cancelled() { - return nil, 0, false, fmt.Errorf("execution aborted (timeout = %v)", timeout), nil + return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout), nil } if err != nil { - return res, 0, false, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()), nil + return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()), nil } - return res, gas, failed, err, vmErr + return result, err, vmErr } func newRevertError(res []byte) *revertError { @@ -1443,16 +1443,32 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, bl if args.To != nil && *args.To == common.MasternodeVotingSMCBinary { timeout = 0 } - result, _, failed, err, vmErr := DoCall(ctx, s.b, args, *blockNrOrHash, overrides, timeout, s.b.RPCGasCap()) + result, err, vmErr := DoCall(ctx, s.b, args, *blockNrOrHash, overrides, timeout, s.b.RPCGasCap()) if err != nil { return nil, err } // If the result contains a revert reason, try to unpack and return it. - if failed && len(result) > 0 { - return nil, newRevertError(result) + if result.Failed() && len(result.Return()) > 0 { + return nil, newRevertError(result.Return()) } + return result.Return(), vmErr +} + +type estimateGasError struct { + error string // Concrete error type if it's failed to estimate gas usage + vmerr error // Additional field, it's non-nil if the given transaction is invalid + revert string // Additional field, it's non-empty if the transaction is reverted and reason is provided +} - return (hexutil.Bytes)(result), vmErr +func (e estimateGasError) Error() string { + errMsg := e.error + if e.vmerr != nil { + errMsg += fmt.Sprintf(" (%v)", e.vmerr) + } + if e.revert != "" { + errMsg += fmt.Sprintf(" (%s)", e.revert) + } + return errMsg } func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, gasCap uint64) (hexutil.Uint64, error) { @@ -1496,21 +1512,17 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr cap = hi // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) (bool, []byte, error, error) { + executable := func(gas uint64) (bool, *core.ExecutionResult, error) { args.Gas = (*hexutil.Uint64)(&gas) - res, _, failed, err, vmErr := DoCall(ctx, b, args, blockNrOrHash, nil, 0, gasCap) + result, err, _ := DoCall(ctx, b, args, blockNrOrHash, nil, 0, gasCap) if err != nil { if errors.Is(err, vm.ErrOutOfGas) || errors.Is(err, core.ErrIntrinsicGas) { - return false, nil, nil, nil // Special case, raise gas limit + return true, nil, nil // Special case, raise gas limit } - return false, nil, err, nil // Bail out - } - if failed { - return false, res, nil, vmErr + return true, nil, err // Bail out } - - return true, nil, nil, nil + return result.Failed(), result, nil } // If the transaction is a plain value transfer, short circuit estimation and @@ -1519,7 +1531,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr // unused access list items). Ever so slightly wasteful, but safer overall. if args.Data == nil || len(*args.Data) == 0 { if args.To != nil && state.GetCodeSize(*args.To) == 0 { - ok, _, err, _ := executable(params.TxGas) + ok, _, err := executable(params.TxGas) if ok && err == nil { return hexutil.Uint64(params.TxGas), nil } @@ -1529,7 +1541,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr // Execute the binary search and hone in on an executable gas limit for lo+1 < hi { mid := (hi + lo) / 2 - ok, _, err, _ := executable(mid) + failed, _, err := executable(mid) // If the error is not nil(consensus error), it means the provided message // call or transaction will never be accepted no matter how much gas it is @@ -1538,7 +1550,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr return 0, err } - if !ok { + if failed { lo = mid } else { hi = mid @@ -1547,21 +1559,30 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr // Reject the transaction as invalid if it still fails at the highest allowance if hi == cap { - ok, res, err, vmErr := executable(hi) + failed, result, err := executable(hi) if err != nil { return 0, err } - if !ok { - if vmErr != vm.ErrOutOfGas { - if len(res) > 0 { - return 0, newRevertError(res) + if failed { + if result != nil && result.Err != vm.ErrOutOfGas { + var revert string + if len(result.Revert()) > 0 { + ret, err := abi.UnpackRevert(result.Revert()) + if err != nil { + revert = hexutil.Encode(result.Revert()) + } else { + revert = ret + } + } + return 0, estimateGasError{ + error: "always failing transaction", + vmerr: result.Err, + revert: revert, } - return 0, vmErr } - // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) + return 0, estimateGasError{error: fmt.Sprintf("gas required exceeds allowance (%d)", cap)} } } return hexutil.Uint64(hi), nil @@ -2075,12 +2096,12 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH return nil, 0, nil, err } // TODO: determine the value of owner - _, UsedGas, _, err, vmErr := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner) + res, err, _ := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner) if err != nil { return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) } if tracer.Equal(prevTracer) { - return accessList, UsedGas, vmErr, nil + return accessList, res.UsedGas, res.Err, nil } prevTracer = tracer } diff --git a/les/odr_test.go b/les/odr_test.go index b4aa8cf21d0f..031a1df5dc1e 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -142,8 +142,8 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) - res = append(res, ret...) + result, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + res = append(res, result.Return()...) } } else { header := lc.GetHeaderByHash(bhash) @@ -160,9 +160,9 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai vmenv := vm.NewEVM(context, txContext, statedb, nil, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + result, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) if statedb.Error() == nil { - res = append(res, ret...) + res = append(res, result.Return()...) } } } diff --git a/light/odr_test.go b/light/odr_test.go index 94c1246065ad..1562f955d9fe 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -191,8 +191,8 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain vmenv := vm.NewEVM(context, txContext, st, nil, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) - res = append(res, ret...) + result, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + res = append(res, result.Return()...) if st.Error() != nil { return res, st.Error() } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 756eda3bf38f..1452ecd5d6a0 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -166,7 +166,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD gaspool.AddGas(block.GasLimit()) coinbase := &t.json.Env.Coinbase - if _, _, _, err, _ := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil { + if _, err, _ := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil { statedb.RevertToSnapshot(snapshot) } if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) { From 82ff8c19a05d71d22b7db46259dba4843c9d730f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 17:35:07 +0800 Subject: [PATCH 014/121] all: remove uses of untyped golang-lru --- XDCx/XDCx.go | 32 +++----- XDCx/token.go | 11 ++- XDCx/tradingstate/database.go | 15 +--- XDCxDAO/leveldb.go | 6 -- XDCxDAO/mongodb.go | 7 +- XDCxlending/XDCxlending.go | 39 ++++------ XDCxlending/lendingstate/database.go | 16 ++-- consensus/XDPoS/XDPoS.go | 44 ++++------- consensus/XDPoS/engines/engine_v1/engine.go | 44 ++++------- consensus/XDPoS/engines/engine_v1/snapshot.go | 7 +- consensus/XDPoS/engines/engine_v1/utils.go | 5 +- consensus/XDPoS/engines/engine_v2/engine.go | 28 +++---- .../XDPoS/engines/engine_v2/epochSwitch.go | 7 +- consensus/XDPoS/engines/engine_v2/snapshot.go | 3 +- consensus/XDPoS/engines/engine_v2/utils.go | 10 +-- .../XDPoS/engines/engine_v2/verifyHeader.go | 2 +- consensus/XDPoS/utils/types.go | 3 + consensus/clique/clique.go | 21 +++-- consensus/clique/snapshot.go | 10 ++- consensus/ethash/ethash.go | 72 +++++++++-------- contracts/utils.go | 9 +-- core/state/trc21_reader.go | 14 ++-- eth/fetcher/fetcher.go | 11 ++- eth/handler.go | 77 ++++++++----------- eth/hooks/engine_v1_hooks.go | 7 +- eth/hooks/engine_v2_hooks.go | 14 ++-- go.mod | 1 - go.sum | 2 - light/lightchain.go | 29 +++---- 29 files changed, 226 insertions(+), 320 deletions(-) diff --git a/XDCx/XDCx.go b/XDCx/XDCx.go index ac3f83d582f4..3fbaf0c783e2 100644 --- a/XDCx/XDCx.go +++ b/XDCx/XDCx.go @@ -10,6 +10,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCxDAO" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/common/prque" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/core/state" @@ -17,7 +18,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/p2p" "github.com/XinFinOrg/XDPoSChain/rpc" - lru "github.com/hashicorp/golang-lru" "golang.org/x/sync/syncmap" ) @@ -59,8 +59,8 @@ type XDCX struct { sdkNode bool settings syncmap.Map // holds configuration settings that can be dynamically changed - tokenDecimalCache *lru.Cache - orderCache *lru.Cache + tokenDecimalCache *lru.Cache[common.Address, *big.Int] + orderCache *lru.Cache[common.Hash, map[common.Hash]tradingstate.OrderHistoryItem] } func (XDCx *XDCX) Protocols() []p2p.Protocol { @@ -94,19 +94,11 @@ func NewMongoDBEngine(cfg *Config) *XDCxDAO.MongoDatabase { } func New(cfg *Config) *XDCX { - tokenDecimalCache, err := lru.New(defaultCacheLimit) - if err != nil { - log.Warn("[XDCx-New] fail to create new lru for token decimal", "error", err) - } - orderCache, err := lru.New(tradingstate.OrderCacheLimit) - if err != nil { - log.Warn("[XDCx-New] fail to create new lru for order", "error", err) - } XDCX := &XDCX{ orderNonce: make(map[common.Address]*big.Int), Triegc: prque.New(nil), - tokenDecimalCache: tokenDecimalCache, - orderCache: orderCache, + tokenDecimalCache: lru.NewCache[common.Address, *big.Int](defaultCacheLimit), + orderCache: lru.NewCache[common.Hash, map[common.Hash]tradingstate.OrderHistoryItem](tradingstate.OrderCacheLimit), } // default DBEngine: levelDB @@ -607,12 +599,9 @@ func (XDCx *XDCX) GetTradingStateRoot(block *types.Block, author common.Address) } func (XDCx *XDCX) UpdateOrderCache(baseToken, quoteToken common.Address, orderHash common.Hash, txhash common.Hash, lastState tradingstate.OrderHistoryItem) { - var orderCacheAtTxHash map[common.Hash]tradingstate.OrderHistoryItem - c, ok := XDCx.orderCache.Get(txhash) - if !ok || c == nil { + orderCacheAtTxHash, ok := XDCx.orderCache.Get(txhash) + if !ok || orderCacheAtTxHash == nil { orderCacheAtTxHash = make(map[common.Hash]tradingstate.OrderHistoryItem) - } else { - orderCacheAtTxHash = c.(map[common.Hash]tradingstate.OrderHistoryItem) } orderKey := tradingstate.GetOrderHistoryKey(baseToken, quoteToken, orderHash) _, ok = orderCacheAtTxHash[orderKey] @@ -629,16 +618,15 @@ func (XDCx *XDCX) RollbackReorgTxMatch(txhash common.Hash) error { items := db.GetListItemByTxHash(txhash, &tradingstate.OrderItem{}) if items != nil { for _, order := range items.([]*tradingstate.OrderItem) { - c, ok := XDCx.orderCache.Get(txhash) - log.Debug("XDCx reorg: rollback order", "txhash", txhash.Hex(), "order", tradingstate.ToJSON(order), "orderHistoryItem", c) - if !ok { + orderCacheAtTxHash, ok := XDCx.orderCache.Get(txhash) + log.Debug("XDCx reorg: rollback order", "txhash", txhash.Hex(), "order", tradingstate.ToJSON(order), "orderHistoryItem", orderCacheAtTxHash) + if !ok || orderCacheAtTxHash == nil { log.Debug("XDCx reorg: remove order due to no orderCache", "order", tradingstate.ToJSON(order)) if err := db.DeleteObject(order.Hash, &tradingstate.OrderItem{}); err != nil { log.Crit("SDKNode: failed to remove reorg order", "err", err.Error(), "order", tradingstate.ToJSON(order)) } continue } - orderCacheAtTxHash := c.(map[common.Hash]tradingstate.OrderHistoryItem) orderHistoryItem := orderCacheAtTxHash[tradingstate.GetOrderHistoryKey(order.BaseToken, order.QuoteToken, order.Hash)] if (orderHistoryItem == tradingstate.OrderHistoryItem{}) { log.Debug("XDCx reorg: remove order due to empty orderHistory", "order", tradingstate.ToJSON(order)) diff --git a/XDCx/token.go b/XDCx/token.go index 5aa8554cf9f5..c44dbe7e297f 100644 --- a/XDCx/token.go +++ b/XDCx/token.go @@ -4,15 +4,14 @@ import ( "math/big" "strings" - "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract" - "github.com/XinFinOrg/XDPoSChain/core" - "github.com/XinFinOrg/XDPoSChain/log" - "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus" + "github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract" + "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" + "github.com/XinFinOrg/XDPoSChain/log" ) // GetTokenAbi return token abi @@ -45,8 +44,8 @@ func RunContract(chain consensus.ChainContext, statedb *state.StateDB, contractA } func (XDCx *XDCX) GetTokenDecimal(chain consensus.ChainContext, statedb *state.StateDB, tokenAddr common.Address) (*big.Int, error) { - if tokenDecimal, ok := XDCx.tokenDecimalCache.Get(tokenAddr); ok { - return tokenDecimal.(*big.Int), nil + if tokenDecimal, ok := XDCx.tokenDecimalCache.Get(tokenAddr); ok && tokenDecimal != nil { + return tokenDecimal, nil } if tokenAddr == common.XDCNativeAddressBinary { XDCx.tokenDecimalCache.Add(tokenAddr, common.BasePrice) diff --git a/XDCx/tradingstate/database.go b/XDCx/tradingstate/database.go index b40f916a0f7f..2fe21932438e 100644 --- a/XDCx/tradingstate/database.go +++ b/XDCx/tradingstate/database.go @@ -23,7 +23,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/trie" - lru "github.com/hashicorp/golang-lru" ) // Trie cache generation limit after which to evic trie nodes from memory. @@ -33,9 +32,6 @@ const ( // Number of past tries to keep. This value is chosen such that // reasonable chain reorg depths will hit an existing trie. maxPastTries = 12 - - // Number of codehash->size associations to keep. - codeSizeCacheSize = 100000 ) // Database wraps access to tries and contract code. @@ -79,18 +75,15 @@ type Trie interface { // intermediate trie-node memory pool between the low level storage layer and the // high level trie abstraction. func NewDatabase(db ethdb.Database) Database { - csc, _ := lru.New(codeSizeCacheSize) return &cachingDB{ - db: trie.NewDatabase(db), - codeSizeCache: csc, + db: trie.NewDatabase(db), } } type cachingDB struct { - db *trie.Database - mu sync.Mutex - pastTries []*XDCXTrie - codeSizeCache *lru.Cache + db *trie.Database + mu sync.Mutex + pastTries []*XDCXTrie } // OpenTrie opens the main account trie. diff --git a/XDCxDAO/leveldb.go b/XDCxDAO/leveldb.go index 2a76162d4ca4..a6d90dd57a9f 100644 --- a/XDCxDAO/leveldb.go +++ b/XDCxDAO/leveldb.go @@ -8,10 +8,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" - lru "github.com/hashicorp/golang-lru" ) type BatchItem struct { @@ -21,7 +19,6 @@ type BatchItem struct { type BatchDatabase struct { db ethdb.Database emptyKey []byte - cacheItems *lru.Cache // Cache for reading lock sync.RWMutex cacheLimit int Debug bool @@ -44,11 +41,8 @@ func NewBatchDatabaseWithEncode(datadir string, cacheLimit int) *BatchDatabase { itemCacheLimit = cacheLimit } - cacheItems, _ := lru.New(itemCacheLimit) - batchDB := &BatchDatabase{ db: db, - cacheItems: cacheItems, emptyKey: EmptyKey(), // pre alloc for comparison cacheLimit: itemCacheLimit, } diff --git a/XDCxDAO/mongodb.go b/XDCxDAO/mongodb.go index 5c0352db7a59..8c8e45052ca7 100644 --- a/XDCxDAO/mongodb.go +++ b/XDCxDAO/mongodb.go @@ -10,11 +10,11 @@ import ( "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" "github.com/globalsign/mgo" "github.com/globalsign/mgo/bson" - lru "github.com/hashicorp/golang-lru" ) const ( @@ -32,7 +32,7 @@ type MongoDatabase struct { Session *mgo.Session dbName string emptyKey []byte - cacheItems *lru.Cache // Cache for reading + cacheItems *lru.Cache[string, interface{}] // Cache for reading orderBulk *mgo.Bulk tradeBulk *mgo.Bulk epochPriceBulk *mgo.Bulk @@ -64,12 +64,11 @@ func NewMongoDatabase(session *mgo.Session, dbName string, mongoURL string, repl if cacheLimit > 0 { itemCacheLimit = cacheLimit } - cacheItems, _ := lru.New(itemCacheLimit) db := &MongoDatabase{ Session: session, dbName: dbName, - cacheItems: cacheItems, + cacheItems: lru.NewCache[string, interface{}](itemCacheLimit), } if err := db.EnsureIndexes(); err != nil { return nil, err diff --git a/XDCxlending/XDCxlending.go b/XDCxlending/XDCxlending.go index 28e9321aff24..1bf2496ff237 100644 --- a/XDCxlending/XDCxlending.go +++ b/XDCxlending/XDCxlending.go @@ -13,6 +13,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/XDCxDAO" "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/common/prque" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/core/state" @@ -20,7 +21,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/p2p" "github.com/XinFinOrg/XDPoSChain/rpc" - lru "github.com/hashicorp/golang-lru" ) const ( @@ -42,8 +42,8 @@ type Lending struct { orderNonce map[common.Address]*big.Int XDCx *XDCx.XDCX - lendingItemHistory *lru.Cache - lendingTradeHistory *lru.Cache + lendingItemHistory *lru.Cache[common.Hash, map[common.Hash]lendingstate.LendingItemHistoryItem] + lendingTradeHistory *lru.Cache[common.Hash, map[common.Hash]lendingstate.LendingTradeHistoryItem] } func (l *Lending) Protocols() []p2p.Protocol { @@ -62,13 +62,11 @@ func (l *Lending) Stop() error { } func New(XDCx *XDCx.XDCX) *Lending { - itemCache, _ := lru.New(defaultCacheLimit) - lendingTradeCache, _ := lru.New(defaultCacheLimit) lending := &Lending{ orderNonce: make(map[common.Address]*big.Int), Triegc: prque.New(nil), - lendingItemHistory: itemCache, - lendingTradeHistory: lendingTradeCache, + lendingItemHistory: lru.NewCache[common.Hash, map[common.Hash]lendingstate.LendingItemHistoryItem](defaultCacheLimit), + lendingTradeHistory: lru.NewCache[common.Hash, map[common.Hash]lendingstate.LendingTradeHistoryItem](defaultCacheLimit), } lending.StateCache = lendingstate.NewDatabase(XDCx.GetLevelDB()) lending.XDCx = XDCx @@ -705,12 +703,9 @@ func (l *Lending) GetLendingStateRoot(block *types.Block, author common.Address) } func (l *Lending) UpdateLendingItemCache(LendingToken, CollateralToken common.Address, hash common.Hash, txhash common.Hash, lastState lendingstate.LendingItemHistoryItem) { - var lendingCacheAtTxHash map[common.Hash]lendingstate.LendingItemHistoryItem - c, ok := l.lendingItemHistory.Get(txhash) - if !ok || c == nil { + lendingCacheAtTxHash, ok := l.lendingItemHistory.Get(txhash) + if !ok || lendingCacheAtTxHash == nil { lendingCacheAtTxHash = make(map[common.Hash]lendingstate.LendingItemHistoryItem) - } else { - lendingCacheAtTxHash = c.(map[common.Hash]lendingstate.LendingItemHistoryItem) } orderKey := lendingstate.GetLendingItemHistoryKey(LendingToken, CollateralToken, hash) _, ok = lendingCacheAtTxHash[orderKey] @@ -722,11 +717,9 @@ func (l *Lending) UpdateLendingItemCache(LendingToken, CollateralToken common.Ad func (l *Lending) UpdateLendingTradeCache(hash common.Hash, txhash common.Hash, lastState lendingstate.LendingTradeHistoryItem) { var lendingCacheAtTxHash map[common.Hash]lendingstate.LendingTradeHistoryItem - c, ok := l.lendingTradeHistory.Get(txhash) - if !ok || c == nil { + lendingCacheAtTxHash, ok := l.lendingTradeHistory.Get(txhash) + if !ok || lendingCacheAtTxHash == nil { lendingCacheAtTxHash = make(map[common.Hash]lendingstate.LendingTradeHistoryItem) - } else { - lendingCacheAtTxHash = c.(map[common.Hash]lendingstate.LendingTradeHistoryItem) } _, ok = lendingCacheAtTxHash[hash] if !ok { @@ -743,16 +736,15 @@ func (l *Lending) RollbackLendingData(txhash common.Hash) error { items := db.GetListItemByTxHash(txhash, &lendingstate.LendingItem{}) if items != nil { for _, item := range items.([]*lendingstate.LendingItem) { - c, ok := l.lendingItemHistory.Get(txhash) - log.Debug("XDCxlending reorg: rollback lendingItem", "txhash", txhash.Hex(), "item", lendingstate.ToJSON(item), "lendingItemHistory", c) - if !ok { + cacheAtTxHash, ok := l.lendingItemHistory.Get(txhash) + log.Debug("XDCxlending reorg: rollback lendingItem", "txhash", txhash.Hex(), "item", lendingstate.ToJSON(item), "lendingItemHistory", cacheAtTxHash) + if !ok || cacheAtTxHash == nil { log.Debug("XDCxlending reorg: remove item due to no lendingItemHistory", "item", lendingstate.ToJSON(item)) if err := db.DeleteObject(item.Hash, &lendingstate.LendingItem{}); err != nil { return fmt.Errorf("failed to remove reorg LendingItem. Err: %v . Item: %s", err.Error(), lendingstate.ToJSON(item)) } continue } - cacheAtTxHash := c.(map[common.Hash]lendingstate.LendingItemHistoryItem) lendingItemHistory := cacheAtTxHash[lendingstate.GetLendingItemHistoryKey(item.LendingToken, item.CollateralToken, item.Hash)] if (lendingItemHistory == lendingstate.LendingItemHistoryItem{}) { log.Debug("XDCxlending reorg: remove item due to empty lendingItemHistory", "item", lendingstate.ToJSON(item)) @@ -776,16 +768,15 @@ func (l *Lending) RollbackLendingData(txhash common.Hash) error { items = db.GetListItemByTxHash(txhash, &lendingstate.LendingTrade{}) if items != nil { for _, trade := range items.([]*lendingstate.LendingTrade) { - c, ok := l.lendingTradeHistory.Get(txhash) - log.Debug("XDCxlending reorg: rollback LendingTrade", "txhash", txhash.Hex(), "trade", lendingstate.ToJSON(trade), "LendingTradeHistory", c) - if !ok { + cacheAtTxHash, ok := l.lendingTradeHistory.Get(txhash) + log.Debug("XDCxlending reorg: rollback LendingTrade", "txhash", txhash.Hex(), "trade", lendingstate.ToJSON(trade), "LendingTradeHistory", cacheAtTxHash) + if !ok || cacheAtTxHash == nil { log.Debug("XDCxlending reorg: remove trade due to no LendingTradeHistory", "trade", lendingstate.ToJSON(trade)) if err := db.DeleteObject(trade.Hash, &lendingstate.LendingTrade{}); err != nil { return fmt.Errorf("failed to remove reorg LendingTrade. Err: %v . Trade: %s", err.Error(), lendingstate.ToJSON(trade)) } continue } - cacheAtTxHash := c.(map[common.Hash]lendingstate.LendingTradeHistoryItem) lendingTradeHistoryItem := cacheAtTxHash[trade.Hash] if (lendingTradeHistoryItem == lendingstate.LendingTradeHistoryItem{}) { log.Debug("XDCxlending reorg: remove trade due to empty LendingTradeHistory", "trade", lendingstate.ToJSON(trade)) diff --git a/XDCxlending/lendingstate/database.go b/XDCxlending/lendingstate/database.go index d765a1eade76..7c4934bc7fec 100644 --- a/XDCxlending/lendingstate/database.go +++ b/XDCxlending/lendingstate/database.go @@ -23,7 +23,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/trie" - lru "github.com/hashicorp/golang-lru" ) // Trie cache generation limit after which to evic trie nodes from memory. @@ -33,9 +32,6 @@ const ( // Number of past tries to keep. This value is chosen such that // reasonable chain reorg depths will hit an existing trie. maxPastTries = 12 - - // Number of codehash->size associations to keep. - codeSizeCacheSize = 100000 ) // Database wraps access to tries and contract code. @@ -78,18 +74,16 @@ type Trie interface { // intermediate trie-node memory pool between the low level storage layer and the // high level trie abstraction. func NewDatabase(db ethdb.Database) Database { - csc, _ := lru.New(codeSizeCacheSize) return &cachingDB{ - db: trie.NewDatabase(db), - codeSizeCache: csc, + db: trie.NewDatabase(db), + // codeSizeCache: csc, } } type cachingDB struct { - db *trie.Database - mu sync.Mutex - pastTries []*XDCXTrie - codeSizeCache *lru.Cache + db *trie.Database + mu sync.Mutex + pastTries []*XDCXTrie } // OpenTrie opens the main account trie. diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index 5001abe4e8f1..411411d51857 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -22,20 +22,19 @@ import ( "math/big" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v1" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v2" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" - "github.com/XinFinOrg/XDPoSChain/event" - "github.com/XinFinOrg/XDPoSChain/consensus/clique" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/ethdb" + "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rpc" - lru "github.com/hashicorp/golang-lru" ) const ( @@ -60,7 +59,7 @@ type XDPoS struct { db ethdb.Database // Database to store and retrieve snapshot checkpoints // Transaction cache, only make sense for adaptor level - signingTxsCache *lru.Cache + signingTxsCache *lru.Cache[common.Hash, []*types.Transaction] // Share Channel MinePeriodCh chan int // Miner wait Period Channel @@ -109,17 +108,12 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS { minePeriodCh := make(chan int) newRoundCh := make(chan types.Round, newRoundChanSize) - // Allocate the snapshot caches and create the engine - signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) - return &XDPoS{ - config: config, - db: db, - - MinePeriodCh: minePeriodCh, - NewRoundCh: newRoundCh, - - signingTxsCache: signingTxsCache, + config: config, + db: db, + MinePeriodCh: minePeriodCh, + NewRoundCh: newRoundCh, + signingTxsCache: lru.NewCache[common.Hash, []*types.Transaction](utils.BlockSignersCacheLimit), EngineV1: engine_v1.New(chainConfig, db), EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh), } @@ -138,22 +132,16 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS { minePeriodCh := make(chan int) newRoundCh := make(chan types.Round, newRoundChanSize) - // Allocate the snapshot caches and create the engine - signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) - fakeEngine = &XDPoS{ - config: conf, - db: db, - - MinePeriodCh: minePeriodCh, - NewRoundCh: newRoundCh, - + config: conf, + db: db, + MinePeriodCh: minePeriodCh, + NewRoundCh: newRoundCh, GetXDCXService: func() utils.TradingService { return nil }, GetLendingService: func() utils.LendingService { return nil }, - - signingTxsCache: signingTxsCache, - EngineV1: engine_v1.NewFaker(db, chainConfig), - EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh), + signingTxsCache: lru.NewCache[common.Hash, []*types.Transaction](utils.BlockSignersCacheLimit), + EngineV1: engine_v1.NewFaker(db, chainConfig), + EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh), } return fakeEngine } @@ -554,7 +542,7 @@ func (x *XDPoS) CacheSigningTxs(hash common.Hash, txs []*types.Transaction) []*t return signTxs } -func (x *XDPoS) GetCachedSigningTxs(hash common.Hash) (interface{}, bool) { +func (x *XDPoS) GetCachedSigningTxs(hash common.Hash) ([]*types.Transaction, bool) { return x.signingTxsCache.Get(hash) } diff --git a/consensus/XDPoS/engines/engine_v1/engine.go b/consensus/XDPoS/engines/engine_v1/engine.go index b93a8729d6ef..54d4d48b876e 100644 --- a/consensus/XDPoS/engines/engine_v1/engine.go +++ b/consensus/XDPoS/engines/engine_v1/engine.go @@ -14,8 +14,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/consensus" - "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/consensus/clique" "github.com/XinFinOrg/XDPoSChain/consensus/misc" @@ -26,7 +26,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" - lru "github.com/hashicorp/golang-lru" ) const ( @@ -44,10 +43,10 @@ type XDPoS_v1 struct { config *params.XDPoSConfig // Consensus engine configuration parameters db ethdb.Database // Database to store and retrieve snapshot checkpoints - recents *lru.ARCCache // Snapshots for recent block to speed up reorgs - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining - validatorSignatures *lru.ARCCache // Signatures of recent blocks to speed up mining - verifiedHeaders *lru.ARCCache + recents *lru.Cache[common.Hash, *SnapshotV1] // Snapshots for recent block to speed up reorgs + signatures *utils.SigLRU // Signatures of recent blocks to speed up mining + validatorSignatures *utils.SigLRU // Signatures of recent blocks to speed up mining + verifiedHeaders *lru.Cache[common.Hash, struct{}] proposals map[common.Address]bool // Current list of proposals we are pushing signer common.Address // Ethereum address of the signing key @@ -92,20 +91,16 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS_v1 { conf.Epoch = utils.EpochLength } - recents, _ := lru.NewARC(utils.InmemorySnapshots) - signatures, _ := lru.NewARC(utils.InmemorySnapshots) - validatorSignatures, _ := lru.NewARC(utils.InmemorySnapshots) - verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots) return &XDPoS_v1{ chainConfig: chainConfig, config: &conf, db: db, - recents: recents, - signatures: signatures, - verifiedHeaders: verifiedHeaders, - validatorSignatures: validatorSignatures, + recents: lru.NewCache[common.Hash, *SnapshotV1](utils.InmemorySnapshots), + signatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots), + verifiedHeaders: lru.NewCache[common.Hash, struct{}](utils.InmemorySnapshots), + validatorSignatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots), proposals: make(map[common.Address]bool), } } @@ -145,7 +140,7 @@ func (x *XDPoS_v1) verifyHeaderWithCache(chain consensus.ChainReader, header *ty } err := x.verifyHeader(chain, header, parents, fullVerify) if err == nil { - x.verifiedHeaders.Add(header.Hash(), true) + x.verifiedHeaders.Add(header.Hash(), struct{}{}) } return err } @@ -483,8 +478,8 @@ func (x *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash com ) for { // If an in-memory SnapshotV1 was found, use that - if s, ok := x.recents.Get(hash); ok { - snap = s.(*SnapshotV1) + if s, ok := x.recents.Get(hash); ok && s != nil { + snap = s break } // If an on-disk checkpoint snapshot can be found, use that @@ -979,7 +974,7 @@ func (x *XDPoS_v1) RecoverValidator(header *types.Header) (common.Address, error // If the signature's already cached, return that hash := header.Hash() if address, known := x.validatorSignatures.Get(hash); known { - return address.(common.Address), nil + return address, nil } // Retrieve the signature from the header.Validator // len equals 65 bytes @@ -1044,20 +1039,15 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS_v1 { // Set any missing consensus parameters to their defaults conf := chainConfig.XDPoS - // Allocate the snapshot caches and create the engine - recents, _ := lru.NewARC(utils.InmemorySnapshots) - signatures, _ := lru.NewARC(utils.InmemorySnapshots) - validatorSignatures, _ := lru.NewARC(utils.InmemorySnapshots) - verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots) fakeEngine = &XDPoS_v1{ chainConfig: chainConfig, config: conf, db: db, - recents: recents, - signatures: signatures, - verifiedHeaders: verifiedHeaders, - validatorSignatures: validatorSignatures, + recents: lru.NewCache[common.Hash, *SnapshotV1](utils.InmemorySnapshots), + signatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots), + verifiedHeaders: lru.NewCache[common.Hash, struct{}](utils.InmemorySnapshots), + validatorSignatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots), proposals: make(map[common.Address]bool), } return fakeEngine diff --git a/consensus/XDPoS/engines/engine_v1/snapshot.go b/consensus/XDPoS/engines/engine_v1/snapshot.go index 3ad8b221894a..012b29aabea0 100644 --- a/consensus/XDPoS/engines/engine_v1/snapshot.go +++ b/consensus/XDPoS/engines/engine_v1/snapshot.go @@ -10,7 +10,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/params" - lru "github.com/hashicorp/golang-lru" ) // Vote represents a single vote that an authorized signer made to modify the @@ -32,7 +31,7 @@ import ( // Snapshot is the state of the authorization voting at a given point in time. type SnapshotV1 struct { config *params.XDPoSConfig // Consensus engine parameters to fine tune behavior - sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover + sigcache *utils.SigLRU // Cache of recent block signatures to speed up ecrecover Number uint64 `json:"number"` // Block number where the snapshot was created Hash common.Hash `json:"hash"` // Block hash where the snapshot was created @@ -45,7 +44,7 @@ type SnapshotV1 struct { // newSnapshot creates a new snapshot with the specified startup parameters. This // method does not initialize the set of recent signers, so only ever use if for // the genesis block. -func newSnapshot(config *params.XDPoSConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *SnapshotV1 { +func newSnapshot(config *params.XDPoSConfig, sigcache *utils.SigLRU, number uint64, hash common.Hash, signers []common.Address) *SnapshotV1 { snap := &SnapshotV1{ config: config, sigcache: sigcache, @@ -62,7 +61,7 @@ func newSnapshot(config *params.XDPoSConfig, sigcache *lru.ARCCache, number uint } // loadSnapshot loads an existing snapshot from the database. -func loadSnapshot(config *params.XDPoSConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*SnapshotV1, error) { +func loadSnapshot(config *params.XDPoSConfig, sigcache *utils.SigLRU, db ethdb.Database, hash common.Hash) (*SnapshotV1, error) { blob, err := db.Get(append([]byte("XDPoS-"), hash[:]...)) if err != nil { return nil, err diff --git a/consensus/XDPoS/engines/engine_v1/utils.go b/consensus/XDPoS/engines/engine_v1/utils.go index a0128331220c..fbd7814935d5 100644 --- a/consensus/XDPoS/engines/engine_v1/utils.go +++ b/consensus/XDPoS/engines/engine_v1/utils.go @@ -9,7 +9,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rlp" - lru "github.com/hashicorp/golang-lru" "golang.org/x/crypto/sha3" ) @@ -87,11 +86,11 @@ func sigHash(header *types.Header) (hash common.Hash) { } // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { +func ecrecover(header *types.Header, sigcache *utils.SigLRU) (common.Address, error) { // If the signature's already cached, return that hash := header.Hash() if address, known := sigcache.Get(hash); known { - return address.(common.Address), nil + return address, nil } // Retrieve the signature from the header extra-data if len(header.Extra) < utils.ExtraSeal { diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index 25515c3f7acb..bcbf4651cb9f 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -13,6 +13,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/countdown" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/consensus/clique" @@ -21,7 +22,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" - lru "github.com/hashicorp/golang-lru" ) type XDPoS_v2 struct { @@ -32,14 +32,14 @@ type XDPoS_v2 struct { isInitilised bool // status of v2 variables whosTurn common.Address // Record waiting for who to mine - snapshots *lru.ARCCache // Snapshots for gap block - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining - epochSwitches *lru.ARCCache // infos of epoch: master nodes, epoch switch block info, parent of that info - verifiedHeaders *lru.ARCCache + snapshots *lru.Cache[common.Hash, *SnapshotV2] // Snapshots for gap block + signatures *utils.SigLRU // Signatures of recent blocks to speed up mining + epochSwitches *lru.Cache[common.Hash, *types.EpochSwitchInfo] // infos of epoch: master nodes, epoch switch block info, parent of that info + verifiedHeaders *lru.Cache[common.Hash, struct{}] // only contains epoch switch block info // input: round, output: infos of epoch switch block and next epoch switch block info - round2epochBlockInfo *lru.ARCCache + round2epochBlockInfo *lru.Cache[types.Round, *types.BlockInfo] signer common.Address // Ethereum address of the signing key signFn clique.SignerFn // Signer function to authorize hashes with @@ -78,12 +78,6 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan i duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second timeoutTimer := countdown.NewCountDown(duration) - snapshots, _ := lru.NewARC(utils.InmemorySnapshots) - signatures, _ := lru.NewARC(utils.InmemorySnapshots) - epochSwitches, _ := lru.NewARC(int(utils.InmemoryEpochs)) - verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots) - round2epochBlockInfo, _ := lru.NewARC(utils.InmemoryRound2Epochs) - timeoutPool := utils.NewPool() votePool := utils.NewPool() engine := &XDPoS_v2{ @@ -93,17 +87,17 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan i db: db, isInitilised: false, - signatures: signatures, + signatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots), - verifiedHeaders: verifiedHeaders, - snapshots: snapshots, - epochSwitches: epochSwitches, + verifiedHeaders: lru.NewCache[common.Hash, struct{}](utils.InmemorySnapshots), + snapshots: lru.NewCache[common.Hash, *SnapshotV2](utils.InmemorySnapshots), + epochSwitches: lru.NewCache[common.Hash, *types.EpochSwitchInfo](int(utils.InmemoryEpochs)), timeoutWorker: timeoutTimer, BroadcastCh: make(chan interface{}), minePeriodCh: minePeriodCh, newRoundCh: newRoundCh, - round2epochBlockInfo: round2epochBlockInfo, + round2epochBlockInfo: lru.NewCache[types.Round, *types.BlockInfo](utils.InmemoryRound2Epochs), timeoutPool: timeoutPool, votePool: votePool, diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index e9d76daa620a..b6c4a0c16808 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -30,9 +30,8 @@ func (x *XDPoS_v2) getPreviousEpochSwitchInfoByHash(chain consensus.ChainReader, // Given header and its hash, get epoch switch info from the epoch switch block of that epoch, // header is allow to be nil. func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types.Header, hash common.Hash) (*types.EpochSwitchInfo, error) { - e, ok := x.epochSwitches.Get(hash) - if ok { - epochSwitchInfo := e.(*types.EpochSwitchInfo) + epochSwitchInfo, ok := x.epochSwitches.Get(hash) + if ok && epochSwitchInfo != nil { log.Debug("[getEpochSwitchInfo] cache hit", "number", epochSwitchInfo.EpochSwitchBlockInfo.Number, "hash", hash.Hex()) return epochSwitchInfo, nil } @@ -88,7 +87,7 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types x.epochSwitches.Add(hash, epochSwitchInfo) return epochSwitchInfo, nil } - epochSwitchInfo, err := x.getEpochSwitchInfo(chain, nil, h.ParentHash) + epochSwitchInfo, err = x.getEpochSwitchInfo(chain, nil, h.ParentHash) if err != nil { log.Error("[getEpochSwitchInfo] recursive error", "err", err, "hash", hash.Hex(), "number", h.Number.Uint64()) return nil, err diff --git a/consensus/XDPoS/engines/engine_v2/snapshot.go b/consensus/XDPoS/engines/engine_v2/snapshot.go index ccae59841278..de4fb76d82bf 100644 --- a/consensus/XDPoS/engines/engine_v2/snapshot.go +++ b/consensus/XDPoS/engines/engine_v2/snapshot.go @@ -84,8 +84,7 @@ func (x *XDPoS_v2) getSnapshot(chain consensus.ChainReader, number uint64, isGap log.Debug("get snapshot from gap block", "number", gapBlockNum, "hash", gapBlockHash.Hex()) // If an in-memory SnapshotV2 was found, use that - if s, ok := x.snapshots.Get(gapBlockHash); ok { - snap := s.(*SnapshotV2) + if snap, ok := x.snapshots.Get(gapBlockHash); ok && snap != nil { log.Trace("Loaded snapshot from memory", "number", gapBlockNum, "hash", gapBlockHash) return snap, nil } diff --git a/consensus/XDPoS/engines/engine_v2/utils.go b/consensus/XDPoS/engines/engine_v2/utils.go index b95d12c5f222..49d79177e8c1 100644 --- a/consensus/XDPoS/engines/engine_v2/utils.go +++ b/consensus/XDPoS/engines/engine_v2/utils.go @@ -13,7 +13,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/rlp" - lru "github.com/hashicorp/golang-lru" "golang.org/x/crypto/sha3" ) @@ -47,11 +46,11 @@ func sigHash(header *types.Header) (hash common.Hash) { return hash } -func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { +func ecrecover(header *types.Header, sigcache *utils.SigLRU) (common.Address, error) { // If the signature's already cached, return that hash := header.Hash() if address, known := sigcache.Get(hash); known { - return address.(common.Address), nil + return address, nil } // Recover the public key and the Ethereum address @@ -224,9 +223,8 @@ func (x *XDPoS_v2) CalculateMissingRounds(chain consensus.ChainReader, header *t func (x *XDPoS_v2) getBlockByEpochNumberInCache(chain consensus.ChainReader, estRound types.Round) *types.BlockInfo { epochSwitchInCache := make([]*types.BlockInfo, 0) for r := estRound; r < estRound+types.Round(x.config.Epoch); r++ { - info, ok := x.round2epochBlockInfo.Get(r) - if ok { - blockInfo := info.(*types.BlockInfo) + blockInfo, ok := x.round2epochBlockInfo.Get(r) + if ok && blockInfo != nil { epochSwitchInCache = append(epochSwitchInCache, blockInfo) } } diff --git a/consensus/XDPoS/engines/engine_v2/verifyHeader.go b/consensus/XDPoS/engines/engine_v2/verifyHeader.go index 4e18e2031e68..8341ae1c6be8 100644 --- a/consensus/XDPoS/engines/engine_v2/verifyHeader.go +++ b/consensus/XDPoS/engines/engine_v2/verifyHeader.go @@ -190,6 +190,6 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade return utils.ErrNotItsTurn } - x.verifiedHeaders.Add(header.Hash(), true) + x.verifiedHeaders.Add(header.Hash(), struct{}{}) return nil } diff --git a/consensus/XDPoS/utils/types.go b/consensus/XDPoS/utils/types.go index b5d116834110..fc4aaf0463aa 100644 --- a/consensus/XDPoS/utils/types.go +++ b/consensus/XDPoS/utils/types.go @@ -7,6 +7,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/common/prque" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/clique" @@ -79,3 +80,5 @@ type EpochNumInfo struct { EpochFirstBlockNumber *big.Int `json:"firstBlock"` EpochLastBlockNumber *big.Int `json:"lastBlock"` } + +type SigLRU = lru.Cache[common.Hash, common.Address] diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index bb1e8ef1189c..d6c7f42bde2a 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/misc" "github.com/XinFinOrg/XDPoSChain/core/state" @@ -39,7 +40,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rlp" "github.com/XinFinOrg/XDPoSChain/rpc" - lru "github.com/hashicorp/golang-lru" "golang.org/x/crypto/sha3" ) @@ -173,11 +173,11 @@ func sigHash(header *types.Header) (hash common.Hash) { } // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { +func ecrecover(header *types.Header, sigcache *sigLRU) (common.Address, error) { // If the signature's already cached, return that hash := header.Hash() if address, known := sigcache.Get(hash); known { - return address.(common.Address), nil + return address, nil } // Retrieve the signature from the header extra-data if len(header.Extra) < extraSeal { @@ -203,8 +203,8 @@ type Clique struct { config *params.CliqueConfig // Consensus engine configuration parameters db ethdb.Database // Database to store and retrieve snapshot checkpoints - recents *lru.ARCCache // Snapshots for recent block to speed up reorgs - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining + recents *lru.Cache[common.Hash, *Snapshot] // Snapshots for recent block to speed up reorgs + signatures *sigLRU // Signatures of recent blocks to speed up mining proposals map[common.Address]bool // Current list of proposals we are pushing @@ -221,15 +221,12 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique { if conf.Epoch == 0 { conf.Epoch = epochLength } - // Allocate the snapshot caches and create the engine - recents, _ := lru.NewARC(inmemorySnapshots) - signatures, _ := lru.NewARC(inmemorySignatures) return &Clique{ config: &conf, db: db, - recents: recents, - signatures: signatures, + recents: lru.NewCache[common.Hash, *Snapshot](inmemorySnapshots), + signatures: lru.NewCache[common.Hash, common.Address](inmemorySignatures), proposals: make(map[common.Address]bool), } } @@ -396,8 +393,8 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo ) for { // If an in-memory snapshot was found, use that - if s, ok := c.recents.Get(hash); ok { - snap = s.(*Snapshot) + if s, ok := c.recents.Get(hash); ok && s != nil { + snap = s break } // If an on-disk checkpoint snapshot can be found, use that diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index bc89168aff0f..ff7c5a4c8e9a 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -21,10 +21,10 @@ import ( "encoding/json" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/params" - lru "github.com/hashicorp/golang-lru" ) // Vote represents a single vote that an authorized signer made to modify the @@ -43,10 +43,12 @@ type Tally struct { Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal } +type sigLRU = lru.Cache[common.Hash, common.Address] + // Snapshot is the state of the authorization voting at a given point in time. type Snapshot struct { config *params.CliqueConfig // Consensus engine parameters to fine tune behavior - sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover + sigcache *sigLRU // Cache of recent block signatures to speed up ecrecover Number uint64 `json:"number"` // Block number where the snapshot was created Hash common.Hash `json:"hash"` // Block hash where the snapshot was created @@ -59,7 +61,7 @@ type Snapshot struct { // newSnapshot creates a new snapshot with the specified startup parameters. This // method does not initialize the set of recent signers, so only ever use if for // the genesis block. -func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *Snapshot { +func newSnapshot(config *params.CliqueConfig, sigcache *sigLRU, number uint64, hash common.Hash, signers []common.Address) *Snapshot { snap := &Snapshot{ config: config, sigcache: sigcache, @@ -76,7 +78,7 @@ func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uin } // loadSnapshot loads an existing snapshot from the database. -func loadSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) { +func loadSnapshot(config *params.CliqueConfig, sigcache *sigLRU, db ethdb.Database, hash common.Hash) (*Snapshot, error) { blob, err := db.Get(append([]byte("clique-"), hash[:]...)) if err != nil { return nil, err diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index 394d495a07e8..96dd5bb68d5d 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -32,12 +32,12 @@ import ( "time" "unsafe" + lrupkg "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/metrics" "github.com/XinFinOrg/XDPoSChain/rpc" mmap "github.com/edsrzf/mmap-go" - "github.com/hashicorp/golang-lru/simplelru" ) var ErrInvalidDumpMagic = errors.New("invalid dump magic") @@ -144,34 +144,45 @@ func memoryMapAndGenerate(path string, size uint64, generator func(buffer []uint return memoryMap(path) } +type cacheOrDataset interface { + *cache | *dataset +} + // lru tracks caches or datasets by their last use time, keeping at most N of them. -type lru struct { +type lru[T cacheOrDataset] struct { what string - new func(epoch uint64) interface{} + new func(epoch uint64) T mu sync.Mutex // Items are kept in a LRU cache, but there is a special case: // We always keep an item for (highest seen epoch) + 1 as the 'future item'. - cache *simplelru.LRU + cache lrupkg.BasicLRU[uint64, T] future uint64 - futureItem interface{} + futureItem T } -// newlru create a new least-recently-used cache for ither the verification caches +// newlru create a new least-recently-used cache for either the verification caches // or the mining datasets. -func newlru(what string, maxItems int, new func(epoch uint64) interface{}) *lru { - if maxItems <= 0 { - maxItems = 1 +func newlru[T cacheOrDataset](maxItems int, new func(epoch uint64) T) *lru[T] { + var what string + switch any(T(nil)).(type) { + case *cache: + what = "cache" + case *dataset: + what = "dataset" + default: + panic("unknown type") + } + return &lru[T]{ + what: what, + new: new, + cache: lrupkg.NewBasicLRU[uint64, T](maxItems), } - cache, _ := simplelru.NewLRU(maxItems, func(key, value interface{}) { - log.Trace("Evicted ethash "+what, "epoch", key) - }) - return &lru{what: what, new: new, cache: cache} } // get retrieves or creates an item for the given epoch. The first return value is always // non-nil. The second return value is non-nil if lru thinks that an item will be useful in // the near future. -func (lru *lru) get(epoch uint64) (item, future interface{}) { +func (lru *lru[T]) get(epoch uint64) (item, future T) { lru.mu.Lock() defer lru.mu.Unlock() @@ -205,9 +216,8 @@ type cache struct { once sync.Once // Ensures the cache is generated only once } -// newCache creates a new ethash verification cache and returns it as a plain Go -// interface to be usable in an LRU cache. -func newCache(epoch uint64) interface{} { +// newCache creates a new ethash verification cache. +func newCache(epoch uint64) *cache { return &cache{epoch: epoch} } @@ -283,7 +293,7 @@ type dataset struct { // newDataset creates a new ethash mining dataset and returns it as a plain Go // interface to be usable in an LRU cache. -func newDataset(epoch uint64) interface{} { +func newDataset(epoch uint64) *dataset { return &dataset{epoch: epoch} } @@ -394,13 +404,13 @@ type Config struct { type Ethash struct { config Config - caches *lru // In memory caches to avoid regenerating too often - datasets *lru // In memory datasets to avoid regenerating too often + caches *lru[*cache] // In memory caches to avoid regenerating too often + datasets *lru[*dataset] // In memory datasets to avoid regenerating too often // Mining related fields - rand *rand.Rand // Properly seeded random source for nonces - threads int // Number of threads to mine on if mining - update chan struct{} // Notification channel to update mining parameters + rand *rand.Rand // Properly seeded random source for nonces + threads int // Number of threads to mine on if mining + update chan struct{} // Notification channel to update mining parameters hashrate *metrics.Meter // Meter tracking the average hashrate // The fields below are hooks for testing @@ -425,8 +435,8 @@ func New(config Config) *Ethash { } return &Ethash{ config: config, - caches: newlru("cache", config.CachesInMem, newCache), - datasets: newlru("dataset", config.DatasetsInMem, newDataset), + caches: newlru(config.CachesInMem, newCache), + datasets: newlru(config.DatasetsInMem, newDataset), update: make(chan struct{}), hashrate: metrics.NewMeter(), } @@ -494,15 +504,13 @@ func NewShared() *Ethash { // stored on disk, and finally generating one if none can be found. func (ethash *Ethash) cache(block uint64) *cache { epoch := block / epochLength - currentI, futureI := ethash.caches.get(epoch) - current := currentI.(*cache) + current, future := ethash.caches.get(epoch) // Wait for generation finish. current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest) // If we need a new future cache, now's a good time to regenerate it. - if futureI != nil { - future := futureI.(*cache) + if future != nil { go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest) } return current @@ -513,15 +521,13 @@ func (ethash *Ethash) cache(block uint64) *cache { // stored on disk, and finally generating one if none can be found. func (ethash *Ethash) dataset(block uint64) *dataset { epoch := block / epochLength - currentI, futureI := ethash.datasets.get(epoch) - current := currentI.(*dataset) + current, future := ethash.datasets.get(epoch) // Wait for generation finish. current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest) // If we need a new future dataset, now's a good time to regenerate it. - if futureI != nil { - future := futureI.(*dataset) + if future != nil { go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest) } diff --git a/contracts/utils.go b/contracts/utils.go index 5e236743ea27..b309e5bdd24e 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -331,20 +331,19 @@ func GetRewardForCheckpoint(c *XDPoS.XDPoS, chain consensus.ChainReader, header for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- { header = chain.GetHeader(header.ParentHash, i) mapBlkHash[i] = header.Hash() - signData, ok := c.GetCachedSigningTxs(header.Hash()) + signingTxs, ok := c.GetCachedSigningTxs(header.Hash()) if !ok { log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i) block := chain.GetBlock(header.Hash(), i) txs := block.Transactions() if !chain.Config().IsTIPSigning(header.Number) { receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i) - signData = c.CacheNoneTIPSigningTxs(header, txs, receipts) + signingTxs = c.CacheNoneTIPSigningTxs(header, txs, receipts) } else { - signData = c.CacheSigningTxs(header.Hash(), txs) + signingTxs = c.CacheSigningTxs(header.Hash(), txs) } } - txs := signData.([]*types.Transaction) - for _, tx := range txs { + for _, tx := range signingTxs { blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:]) from := *tx.From() data[blkHash] = append(data[blkHash], from) diff --git a/core/state/trc21_reader.go b/core/state/trc21_reader.go index af5fd25b1390..561cebb5c766 100644 --- a/core/state/trc21_reader.go +++ b/core/state/trc21_reader.go @@ -5,8 +5,7 @@ import ( "math/big" "github.com/XinFinOrg/XDPoSChain/common" - lru "github.com/hashicorp/golang-lru" - + "github.com/XinFinOrg/XDPoSChain/common/lru" ) var ( @@ -22,21 +21,18 @@ var ( } transferFuncHex = common.Hex2Bytes("0xa9059cbb") transferFromFuncHex = common.Hex2Bytes("0x23b872dd") - cache, _ = lru.NewARC(128) + cache = lru.NewCache[common.Hash, map[common.Address]*big.Int](128) ) func GetTRC21FeeCapacityFromStateWithCache(trieRoot common.Hash, statedb *StateDB) map[common.Address]*big.Int { if statedb == nil { return map[common.Address]*big.Int{} } - data, _ := cache.Get(trieRoot) - var info map[common.Address]*big.Int - if data != nil { - info = data.(map[common.Address]*big.Int) - } else { + info, ok := cache.Get(trieRoot) + if !ok || info == nil { info = GetTRC21FeeCapacityFromState(statedb) + cache.Add(trieRoot, info) } - cache.Add(trieRoot, info) tokensFee := map[common.Address]*big.Int{} for key, value := range info { tokensFee[key] = big.NewInt(0).SetBytes(value.Bytes()) diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index ed362f027635..259781a6bb11 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -22,9 +22,8 @@ import ( "math/rand" "time" - lru "github.com/hashicorp/golang-lru" - "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/common/prque" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -135,7 +134,8 @@ type Fetcher struct { queue *prque.Prque // Queue containing the import operations (block number sorted) queues map[string]int // Per peer block counts to prevent memory exhaustion queued map[common.Hash]*inject // Set of already queued blocks (to dedup imports) - knowns *lru.ARCCache + knowns *lru.Cache[common.Hash, struct{}] + // Callbacks getBlock blockRetrievalFn // Retrieves a block from the local chain verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work @@ -157,7 +157,6 @@ type Fetcher struct { // New creates a block fetcher to retrieve blocks based on hash announcements. func New(getBlock blockRetrievalFn, verifyHeader headerVerifierFn, handleProposedBlock proposeBlockHandlerFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertBlock blockInsertFn, prepareBlock blockPrepareFn, dropPeer peerDropFn) *Fetcher { - knownBlocks, _ := lru.NewARC(blockLimit) return &Fetcher{ notify: make(chan *announce), inject: make(chan *inject), @@ -174,7 +173,7 @@ func New(getBlock blockRetrievalFn, verifyHeader headerVerifierFn, handlePropose queue: prque.New(nil), queues: make(map[string]int), queued: make(map[common.Hash]*inject), - knowns: knownBlocks, + knowns: lru.NewCache[common.Hash, struct{}](blockLimit), getBlock: getBlock, verifyHeader: verifyHeader, handleProposedBlock: handleProposedBlock, @@ -641,7 +640,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) { } f.queues[peer] = count f.queued[hash] = op - f.knowns.Add(hash, true) + f.knowns.Add(hash, struct{}{}) f.queue.Push(op, -int64(block.NumberU64())) if f.queueChangeHook != nil { f.queueChangeHook(op.block.Hash(), true) diff --git a/eth/handler.go b/eth/handler.go index 503671eb5280..7ac5c633f720 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -25,9 +25,8 @@ import ( "sync/atomic" "time" - lru "github.com/hashicorp/golang-lru" - "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/misc" @@ -104,14 +103,14 @@ type ProtocolManager struct { // wait group is used for graceful shutdowns during downloading // and processing wg sync.WaitGroup - knownTxs *lru.Cache - knowOrderTxs *lru.Cache - knowLendingTxs *lru.Cache + knownTxs *lru.Cache[common.Hash, struct{}] + knowOrderTxs *lru.Cache[common.Hash, struct{}] + knowLendingTxs *lru.Cache[common.Hash, struct{}] // V2 messages - knownVotes *lru.Cache - knownSyncInfos *lru.Cache - knownTimeouts *lru.Cache + knownVotes *lru.Cache[common.Hash, struct{}] + knownSyncInfos *lru.Cache[common.Hash, struct{}] + knownTimeouts *lru.Cache[common.Hash, struct{}] } // NewProtocolManagerEx add order pool to protocol @@ -128,14 +127,6 @@ func NewProtocolManagerEx(config *params.ChainConfig, mode downloader.SyncMode, // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // with the ethereum network. func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) { - knownTxs, _ := lru.New(maxKnownTxs) - knowOrderTxs, _ := lru.New(maxKnownOrderTxs) - knowLendingTxs, _ := lru.New(maxKnownLendingTxs) - - knownVotes, _ := lru.New(maxKnownVote) - knownSyncInfos, _ := lru.New(maxKnownSyncInfo) - knownTimeouts, _ := lru.New(maxKnownTimeout) - // Create the protocol manager with the base fields manager := &ProtocolManager{ networkId: networkID, @@ -148,12 +139,12 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne noMorePeers: make(chan struct{}), txsyncCh: make(chan *txsync), quitSync: make(chan struct{}), - knownTxs: knownTxs, - knowOrderTxs: knowOrderTxs, - knowLendingTxs: knowLendingTxs, - knownVotes: knownVotes, - knownSyncInfos: knownSyncInfos, - knownTimeouts: knownTimeouts, + knownTxs: lru.NewCache[common.Hash, struct{}](maxKnownTxs), + knowOrderTxs: lru.NewCache[common.Hash, struct{}](maxKnownOrderTxs), + knowLendingTxs: lru.NewCache[common.Hash, struct{}](maxKnownLendingTxs), + knownVotes: lru.NewCache[common.Hash, struct{}](maxKnownVote), + knownSyncInfos: lru.NewCache[common.Hash, struct{}](maxKnownSyncInfo), + knownTimeouts: lru.NewCache[common.Hash, struct{}](maxKnownTimeout), orderpool: nil, lendingpool: nil, orderTxSub: nil, @@ -776,9 +767,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "transaction %d is nil", i) } p.MarkTransaction(tx.Hash()) - exist, _ := pm.knownTxs.ContainsOrAdd(tx.Hash(), true) - if exist { + if pm.knownTxs.Contains(tx.Hash()) { log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce(), "to", tx.To()) + } else { + pm.knownTxs.Add(tx.Hash(), struct{}{}) } } @@ -801,11 +793,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "transaction %d is nil", i) } p.MarkOrderTransaction(tx.Hash()) - exist, _ := pm.knowOrderTxs.ContainsOrAdd(tx.Hash(), true) - if exist { + if pm.knowOrderTxs.Contains(tx.Hash()) { log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce()) + } else { + pm.knowOrderTxs.Add(tx.Hash(), struct{}{}) } - } if pm.orderpool != nil { @@ -829,11 +821,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "transaction %d is nil", i) } p.MarkLendingTransaction(tx.Hash()) - exist, _ := pm.knowLendingTxs.ContainsOrAdd(tx.Hash(), true) - if exist { + if pm.knowLendingTxs.Contains(tx.Hash()) { log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce()) + } else { + pm.knowLendingTxs.Add(tx.Hash(), struct{}{}) } - } if pm.lendingpool != nil { @@ -850,11 +842,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } p.MarkVote(vote.Hash()) - exist, _ := pm.knownVotes.ContainsOrAdd(vote.Hash(), true) - if !exist { - go pm.bft.Vote(p.id, &vote) - } else { + if pm.knownVotes.Contains(vote.Hash()) { log.Trace("Discarded vote, known vote", "vote hash", vote.Hash(), "voted block hash", vote.ProposedBlockInfo.Hash.Hex(), "number", vote.ProposedBlockInfo.Number, "round", vote.ProposedBlockInfo.Round) + } else { + pm.knownVotes.Add(vote.Hash(), struct{}{}) + go pm.bft.Vote(p.id, &vote) } case msg.Code == TimeoutMsg: @@ -868,12 +860,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } p.MarkTimeout(timeout.Hash()) - exist, _ := pm.knownTimeouts.ContainsOrAdd(timeout.Hash(), true) - - if !exist { - go pm.bft.Timeout(p.id, &timeout) - } else { + if pm.knownTimeouts.Contains(timeout.Hash()) { log.Trace("Discarded Timeout, known Timeout", "Signature", timeout.Signature, "hash", timeout.Hash(), "round", timeout.Round) + } else { + pm.knownTimeouts.Add(timeout.Hash(), struct{}{}) + go pm.bft.Timeout(p.id, &timeout) } case msg.Code == SyncInfoMsg: @@ -887,11 +878,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } p.MarkSyncInfo(syncInfo.Hash()) - exist, _ := pm.knownSyncInfos.ContainsOrAdd(syncInfo.Hash(), true) - if !exist { - go pm.bft.SyncInfo(p.id, &syncInfo) - } else { + if pm.knownSyncInfos.Contains(syncInfo.Hash()) { log.Trace("Discarded SyncInfo, known SyncInfo", "hash", syncInfo.Hash()) + } else { + pm.knownSyncInfos.Add(syncInfo.Hash(), struct{}{}) + go pm.bft.SyncInfo(p.id, &syncInfo) } default: diff --git a/eth/hooks/engine_v1_hooks.go b/eth/hooks/engine_v1_hooks.go index 553ffc591671..74f55ed278a9 100644 --- a/eth/hooks/engine_v1_hooks.go +++ b/eth/hooks/engine_v1_hooks.go @@ -141,15 +141,14 @@ func AttachConsensusV1Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf if blockNumber%common.MergeSignRange == 0 { mapBlockHash[bhash] = true } - signData, ok := adaptor.GetCachedSigningTxs(bhash) + signingTxs, ok := adaptor.GetCachedSigningTxs(bhash) if !ok { block := chain.GetBlock(bhash, blockNumber) txs := block.Transactions() - signData = adaptor.CacheSigningTxs(bhash, txs) + signingTxs = adaptor.CacheSigningTxs(bhash, txs) } - txs := signData.([]*types.Transaction) // Check signer signed? - for _, tx := range txs { + for _, tx := range signingTxs { blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:]) from := *tx.From() if mapBlockHash[blkHash] { diff --git a/eth/hooks/engine_v2_hooks.go b/eth/hooks/engine_v2_hooks.go index fde8e924879f..bd5b0ffdd1df 100644 --- a/eth/hooks/engine_v2_hooks.go +++ b/eth/hooks/engine_v2_hooks.go @@ -115,15 +115,14 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf if blockNumber%common.MergeSignRange == 0 { mapBlockHash[bhash] = true } - signData, ok := adaptor.GetCachedSigningTxs(bhash) + signingTxs, ok := adaptor.GetCachedSigningTxs(bhash) if !ok { block := chain.GetBlock(bhash, blockNumber) txs := block.Transactions() - signData = adaptor.CacheSigningTxs(bhash, txs) + signingTxs = adaptor.CacheSigningTxs(bhash, txs) } - txs := signData.([]*types.Transaction) // Check signer signed? - for _, tx := range txs { + for _, tx := range signingTxs { blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:]) from := *tx.From() if mapBlockHash[blkHash] { @@ -245,15 +244,14 @@ func GetSigningTxCount(c *XDPoS.XDPoS, chain consensus.ChainReader, header *type } } mapBlkHash[i] = header.Hash() - signData, ok := c.GetCachedSigningTxs(header.Hash()) + signingTxs, ok := c.GetCachedSigningTxs(header.Hash()) if !ok { log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i) block := chain.GetBlock(header.Hash(), i) txs := block.Transactions() - signData = c.CacheSigningTxs(header.Hash(), txs) + signingTxs = c.CacheSigningTxs(header.Hash(), txs) } - txs := signData.([]*types.Transaction) - for _, tx := range txs { + for _, tx := range signingTxs { blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:]) from := *tx.From() data[blkHash] = append(data[blkHash], from) diff --git a/go.mod b/go.mod index 28a24f8b6b38..d948f4cea3b8 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,6 @@ require ( github.com/golang/protobuf v1.5.3 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/gorilla/websocket v1.4.2 - github.com/hashicorp/golang-lru v0.5.4 github.com/holiman/uint256 v1.2.4 github.com/huin/goupnp v1.3.0 github.com/jackpal/go-nat-pmp v1.0.2 diff --git a/go.sum b/go.sum index 68019c92aba9..bb2ab2b777cb 100644 --- a/go.sum +++ b/go.sum @@ -92,8 +92,6 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= diff --git a/light/lightchain.go b/light/lightchain.go index 236d1ed85bf9..26b5df09172b 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -25,6 +25,7 @@ import ( "time" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/lru" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/rawdb" @@ -35,7 +36,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rlp" - lru "github.com/hashicorp/golang-lru" ) var ( @@ -59,9 +59,9 @@ type LightChain struct { mu sync.RWMutex chainmu sync.RWMutex - bodyCache *lru.Cache // Cache for the most recent block bodies - bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format - blockCache *lru.Cache // Cache for the most recent entire blocks + bodyCache *lru.Cache[common.Hash, *types.Body] + bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue] + blockCache *lru.Cache[common.Hash, *types.Block] quit chan struct{} running int32 // running must be called automically @@ -76,17 +76,13 @@ type LightChain struct { // available in the database. It initialises the default Ethereum header // validator. func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine) (*LightChain, error) { - bodyCache, _ := lru.New(bodyCacheLimit) - bodyRLPCache, _ := lru.New(bodyCacheLimit) - blockCache, _ := lru.New(blockCacheLimit) - bc := &LightChain{ chainDb: odr.Database(), odr: odr, quit: make(chan struct{}), - bodyCache: bodyCache, - bodyRLPCache: bodyRLPCache, - blockCache: blockCache, + bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit), + bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit), + blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit), engine: engine, } var err error @@ -218,9 +214,8 @@ func (lc *LightChain) State() (*state.StateDB, error) { // or ODR service by hash, caching it if found. func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Body, error) { // Short circuit if the body's already in the cache, retrieve otherwise - if cached, ok := lc.bodyCache.Get(hash); ok { - body := cached.(*types.Body) - return body, nil + if cached, ok := lc.bodyCache.Get(hash); ok && cached != nil { + return cached, nil } body, err := GetBody(ctx, lc.odr, hash, lc.hc.GetBlockNumber(hash)) if err != nil { @@ -236,7 +231,7 @@ func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Bod func (lc *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.RawValue, error) { // Short circuit if the body's already in the cache, retrieve otherwise if cached, ok := lc.bodyRLPCache.Get(hash); ok { - return cached.(rlp.RawValue), nil + return cached, nil } body, err := GetBodyRLP(ctx, lc.odr, hash, lc.hc.GetBlockNumber(hash)) if err != nil { @@ -258,8 +253,8 @@ func (lc *LightChain) HasBlock(hash common.Hash, number uint64) bool { // caching it if found. func (lc *LightChain) GetBlock(ctx context.Context, hash common.Hash, number uint64) (*types.Block, error) { // Short circuit if the block's already in the cache, retrieve otherwise - if block, ok := lc.blockCache.Get(hash); ok { - return block.(*types.Block), nil + if block, ok := lc.blockCache.Get(hash); ok && block != nil { + return block, nil } block, err := GetBlock(ctx, lc.odr, hash, number) if err != nil { From 00785b096fa19443a90a8816be5d32324bd79ac4 Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Sun, 22 Dec 2024 19:34:09 -0800 Subject: [PATCH 015/121] fix tc cross epoch different masternode counts issue --- .../XDPoS/engines/engine_v2/epochSwitch.go | 2 +- consensus/XDPoS/engines/engine_v2/timeout.go | 22 ++- .../tests/engine_v2_tests/sync_info_test.go | 126 ++++++++++++++++++ core/types/consensus_v2.go | 6 +- 4 files changed, 145 insertions(+), 11 deletions(-) diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index 8f718de0bec8..907f1071990f 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -152,7 +152,7 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) { log.Info("[IsEpochSwitch] true, parent equals V2.SwitchBlock", "round", round, "number", header.Number.Uint64(), "hash", header.Hash()) return true, epochNum, nil } - log.Debug("[IsEpochSwitch]", "is", parentRound < epochStartRound, "parentRound", parentRound, "round", round, "number", header.Number.Uint64(), "epochNum", epochNum, "hash", header.Hash()) + log.Debug("[IsEpochSwitch]", "is", parentRound < epochStartRound, "parentRound", parentRound, "round", round, "number", header.Number.Uint64(), "epochNum", epochNum, "hash", header.Hash().Hex()) // if isEpochSwitch, add to cache if parentRound < epochStartRound { x.round2epochBlockInfo.Add(round, &types.BlockInfo{ diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index 2f077b2a0018..86647850c362 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -95,7 +95,7 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time snap, err := x.getSnapshot(chain, timeoutCert.GapNumber, true) if err != nil { - log.Error("[verifyTC] Fail to get snapshot when verifying TC!", "TCGapNumber", timeoutCert.GapNumber) + log.Error("[verifyTC] Fail to get snapshot when verifying TC!", "tcGapNumber", timeoutCert.GapNumber) return fmt.Errorf("[verifyTC] Unable to get snapshot, %s", err) } if snap == nil || len(snap.NextEpochCandidates) == 0 { @@ -109,16 +109,22 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time log.Warn("[verifyQC] duplicated signature in QC", "duplicate", common.Bytes2Hex(d)) } } + tcEpoch := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(timeoutCert.Round)/x.config.Epoch + epochBlockInfo, err := x.GetBlockByEpochNumber(chain, tcEpoch) + if err != nil { + log.Error("[verifyTC] Error when getting epoch block info by tc round", "error", err) + return fmt.Errorf("fail on verifyTC due to failure in getting epoch block info tc round, %s", err) + } - epochInfo, err := x.getEpochSwitchInfo(chain, chain.CurrentHeader(), chain.CurrentHeader().Hash()) + epochInfo, err := x.getEpochSwitchInfo(chain, nil, epochBlockInfo.Hash) if err != nil { - log.Error("[verifyTC] Error when getting epoch switch Info", "error", err) + log.Error("[verifyTC] Error when getting epoch switch info", "error", err) return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err) } certThreshold := x.config.V2.Config(uint64(timeoutCert.Round)).CertThreshold if float64(len(signatures)) < float64(epochInfo.MasternodesLen)*certThreshold { - log.Warn("[verifyTC] Invalid TC Signature is nil or empty", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(timeoutCert.Signatures), "CertThreshold", float64(epochInfo.MasternodesLen)*certThreshold) + log.Warn("[verifyTC] Invalid TC Signature is less or empty", "tcRound", timeoutCert.Round, "tcGapNumber", timeoutCert.GapNumber, "tcSignLen", len(timeoutCert.Signatures), "certThreshold", float64(epochInfo.MasternodesLen)*certThreshold) return utils.ErrInvalidTCSignatures } @@ -138,14 +144,14 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time defer wg.Done() verified, _, err := x.verifyMsgSignature(signedTimeoutObj, sig, snap.NextEpochCandidates) if err != nil || !verified { - log.Error("[verifyTC] Error or verification failure", "Signature", sig, "Error", err) + log.Error("[verifyTC] Error or verification failure", "signature", sig, "error", err) mutex.Lock() // Lock before accessing haveError if haveError == nil { if err != nil { - log.Error("[verifyTC] Error while verfying TC message signatures", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures), "Error", err) + log.Error("[verifyTC] Error while verfying TC message signatures", "tcRound", timeoutCert.Round, "tcGapNumber", timeoutCert.GapNumber, "tcSignLen", len(signatures), "error", err) haveError = fmt.Errorf("error while verifying TC message signatures, %s", err) } else { - log.Warn("[verifyTC] Signature not verified doing TC verification", "timeoutCert.Round", timeoutCert.Round, "timeoutCert.GapNumber", timeoutCert.GapNumber, "Signatures len", len(signatures)) + log.Warn("[verifyTC] Signature not verified doing TC verification", "tcRound", timeoutCert.Round, "tcGapNumber", timeoutCert.GapNumber, "tcSignLen", len(signatures)) haveError = errors.New("fail to verify TC due to signature mis-match") } } @@ -219,6 +225,8 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error { Signature: signedHash, GapNumber: gapNumber, } + + timeoutMsg.SetSigner(x.signer) log.Warn("[sendTimeout] Timeout message generated, ready to send!", "timeoutMsgRound", timeoutMsg.Round, "timeoutMsgGapNumber", timeoutMsg.GapNumber, "whosTurn", x.whosTurn) err = x.timeoutHandler(chain, timeoutMsg) if err != nil { diff --git a/consensus/tests/engine_v2_tests/sync_info_test.go b/consensus/tests/engine_v2_tests/sync_info_test.go index 8219b37a4e15..e3ac910b235b 100644 --- a/consensus/tests/engine_v2_tests/sync_info_test.go +++ b/consensus/tests/engine_v2_tests/sync_info_test.go @@ -1,9 +1,11 @@ package engine_v2_tests import ( + "fmt" "math/big" "testing" + "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -100,3 +102,127 @@ func TestSkipVerifySyncInfoIfBothQcTcNotQualified(t *testing.T) { assert.False(t, verified) assert.Nil(t, err) } + +func TestVerifySyncInfoIfTcUseDifferentEpoch(t *testing.T) { + config := params.TestXDPoSMockChainConfig + blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 1349, config, nil) + adaptor := blockchain.Engine().(*XDPoS.XDPoS) + x := adaptor.EngineV2 + + // Insert block 1350 + t.Logf("Inserting block with propose at 1350...") + blockCoinbaseA := "0xaaa0000000000000000000000000000000001350" + // NOTE: voterAddr never exist in the Masternode list, but all acc1,2,3 already does + tx, err := voteTX(37117, 0, signer.String()) + if err != nil { + t.Fatal(err) + } + //Get from block validator error message + merkleRoot := "8a355a8636d1aae24d5a63df0318534e09110891d6ab7bf20587da64725083be" + header := &types.Header{ + Root: common.HexToHash(merkleRoot), + Number: big.NewInt(int64(1350)), + ParentHash: currentBlock.Hash(), + Coinbase: common.HexToAddress(blockCoinbaseA), + } + + header.Extra = generateV2Extra(450, currentBlock, signer, signFn, nil) + + parentBlock, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx}, signer, signFn, config) + assert.Nil(t, err) + err = blockchain.InsertBlock(parentBlock) + assert.Nil(t, err) + // 1350 is a gap block, need to update the snapshot + err = blockchain.UpdateM1() + assert.Nil(t, err) + t.Logf("Inserting block from 1351 to 1799...") + for i := 1351; i <= 1799; i++ { + blockCoinbase := fmt.Sprintf("0xaaa000000000000000000000000000000000%4d", i) + //Get from block validator error message + header = &types.Header{ + Root: common.HexToHash(merkleRoot), + Number: big.NewInt(int64(i)), + ParentHash: parentBlock.Hash(), + Coinbase: common.HexToAddress(blockCoinbase), + } + + header.Extra = generateV2Extra(int64(i)-900, parentBlock, signer, signFn, nil) + + block, err := createBlockFromHeader(blockchain, header, nil, signer, signFn, config) + if err != nil { + t.Fatal(err) + } + err = blockchain.InsertBlock(block) + assert.Nil(t, err) + parentBlock = block + } + t.Logf("build epoch block with new set of masternodes") + blockCoinbase := fmt.Sprintf("0xaaa0000000000000000000000000000000001800") + //Get from block validator error message + header = &types.Header{ + Root: common.HexToHash(merkleRoot), + Number: big.NewInt(int64(1800)), + ParentHash: parentBlock.Hash(), + Coinbase: common.HexToAddress(blockCoinbase), + } + + header.Extra = generateV2Extra(900, parentBlock, signer, signFn, nil) + validators := []byte{} + + snap, err := x.GetSnapshot(blockchain, parentBlock.Header()) + assert.Nil(t, err) + + for _, v := range snap.NextEpochCandidates { + validators = append(validators, v[:]...) + } + // set up 1 more masternode to make it difference + validators = append(validators, voterAddr[:]...) + header.Validators = validators + block, err := createBlockFromHeader(blockchain, header, nil, signer, signFn, config) + if err != nil { + t.Fatal(err) + } + err = blockchain.InsertBlock(block) + assert.Nil(t, err) + parentBlock = block + + var extraField types.ExtraFields_v2 + err = utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField) + if err != nil { + t.Fatal("Fail to decode extra data", err) + } + + timeoutForSign := &types.TimeoutForSign{ + Round: types.Round(899), + GapNumber: 450, + } + + // Sign from acc 1, 2, 3 and voter + acc1SignedHash := SignHashByPK(acc1Key, types.TimeoutSigHash(timeoutForSign).Bytes()) + acc2SignedHash := SignHashByPK(acc2Key, types.TimeoutSigHash(timeoutForSign).Bytes()) + acc3SignedHash := SignHashByPK(acc3Key, types.TimeoutSigHash(timeoutForSign).Bytes()) + voterSignedHash := SignHashByPK(voterKey, types.TimeoutSigHash(timeoutForSign).Bytes()) + + var signatures []types.Signature + signatures = append(signatures, acc1SignedHash, acc2SignedHash, acc3SignedHash, voterSignedHash) + + newTC := &types.TimeoutCert{ + Round: timeoutForSign.Round, + Signatures: signatures, + GapNumber: timeoutForSign.GapNumber, + } + + syncInfoMsg := &types.SyncInfo{ + HighestQuorumCert: extraField.QuorumCert, + HighestTimeoutCert: newTC, + } + + x.SetPropertiesFaker(syncInfoMsg.HighestQuorumCert, &types.TimeoutCert{ + Round: types.Round(898), + Signatures: []types.Signature{}, + }) + + verified, err := x.VerifySyncInfoMessage(blockchain, syncInfoMsg) + assert.True(t, verified) + assert.Nil(t, err) +} diff --git a/core/types/consensus_v2.go b/core/types/consensus_v2.go index 8dae6aaa0728..f69892532dea 100644 --- a/core/types/consensus_v2.go +++ b/core/types/consensus_v2.go @@ -21,7 +21,7 @@ type BlockInfo struct { // Vote message in XDPoS 2.0 type Vote struct { - signer common.Address //field not exported + signer common.Address //field not exported ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"` Signature Signature `json:"signature"` GapNumber uint64 `json:"gapNumber"` @@ -81,9 +81,9 @@ func (s *SyncInfo) Hash() common.Hash { // Quorum Certificate struct in XDPoS 2.0 type QuorumCert struct { - ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"` + ProposedBlockInfo *BlockInfo `json:"proposedBlockInfo"` Signatures []Signature `json:"signatures"` - GapNumber uint64 `json:"gapNumber"` + GapNumber uint64 `json:"gapNumber"` } // Timeout Certificate struct in XDPoS 2.0 From 25462bde4ca405306b6a79e66bbac4ed22fb8d5e Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Sun, 22 Dec 2024 19:34:49 -0800 Subject: [PATCH 016/121] fix tc cross epoch different masternode counts issue --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 45407ecbb3e9..23a1aad9acc8 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 2 // Major version component of the current release VersionMinor = 4 // Minor version component of the current release - VersionPatch = 4 // Patch version component of the current release + VersionPatch = 5 // Patch version component of the current release VersionMeta = "beta1" // Version metadata to append to the version string ) From 332380c8894c51c1557ae489669577f30f979398 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Mon, 23 Dec 2024 23:09:45 -0800 Subject: [PATCH 017/121] fix only timeout round exists in next epoch (#772) * fix only timeout round exists in next epoch * bump version --------- Co-authored-by: liam.lai --- consensus/XDPoS/engines/engine_v2/timeout.go | 12 +++++ .../tests/engine_v2_tests/sync_info_test.go | 49 +++++++++++++++++++ params/version.go | 2 +- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index 86647850c362..4a9c8d3017b0 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -109,7 +109,19 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time log.Warn("[verifyQC] duplicated signature in QC", "duplicate", common.Bytes2Hex(d)) } } + latestBlockRound, err := x.GetRoundNumber(chain.CurrentHeader()) + if err != nil { + log.Error("[verifyTC] Error when getting current header round", "error", err) + return fmt.Errorf("fail on verifyTC due to error when getting current header round, %s", err) + } + tcEpoch := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(timeoutCert.Round)/x.config.Epoch + + //tcEpoch maybe not existed if there is no QC round in this epoch, there is no epoch switch block generated, so it needs to use currentRound to find epochBlockInfo + if latestBlockRound < timeoutCert.Round { + tcEpoch = x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(latestBlockRound)/x.config.Epoch + } + epochBlockInfo, err := x.GetBlockByEpochNumber(chain, tcEpoch) if err != nil { log.Error("[verifyTC] Error when getting epoch block info by tc round", "error", err) diff --git a/consensus/tests/engine_v2_tests/sync_info_test.go b/consensus/tests/engine_v2_tests/sync_info_test.go index e3ac910b235b..ebe2e4db6873 100644 --- a/consensus/tests/engine_v2_tests/sync_info_test.go +++ b/consensus/tests/engine_v2_tests/sync_info_test.go @@ -103,6 +103,55 @@ func TestSkipVerifySyncInfoIfBothQcTcNotQualified(t *testing.T) { assert.Nil(t, err) } +func TestVerifySyncInfoIfTCRoundIsAtNextEpoch(t *testing.T) { + blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) + engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 + + // Make the Highest QC in syncInfo point to an old block to simulate it's no longer qualified + parentBlock := blockchain.GetBlockByNumber(903) + var extraField types.ExtraFields_v2 + err := utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField) + if err != nil { + t.Fatal("Fail to decode extra data", err) + } + + highestTC := &types.TimeoutCert{ + Round: types.Round(899), + Signatures: []types.Signature{}, + } + + timeoutForSign := &types.TimeoutForSign{ + Round: types.Round(900), + GapNumber: 450, + } + + // Sign from acc 1, 2, 3 and voter + acc1SignedHash := SignHashByPK(acc1Key, types.TimeoutSigHash(timeoutForSign).Bytes()) + acc2SignedHash := SignHashByPK(acc2Key, types.TimeoutSigHash(timeoutForSign).Bytes()) + acc3SignedHash := SignHashByPK(acc3Key, types.TimeoutSigHash(timeoutForSign).Bytes()) + voterSignedHash := SignHashByPK(voterKey, types.TimeoutSigHash(timeoutForSign).Bytes()) + + var signatures []types.Signature + signatures = append(signatures, acc1SignedHash, acc2SignedHash, acc3SignedHash, voterSignedHash) + + syncInfoTC := &types.TimeoutCert{ + Round: timeoutForSign.Round, + Signatures: signatures, + GapNumber: timeoutForSign.GapNumber, + } + + syncInfoMsg := &types.SyncInfo{ + HighestQuorumCert: extraField.QuorumCert, + HighestTimeoutCert: syncInfoTC, + } + + engineV2.SetPropertiesFaker(syncInfoMsg.HighestQuorumCert, highestTC) + + verified, err := engineV2.VerifySyncInfoMessage(blockchain, syncInfoMsg) + assert.True(t, verified) + assert.Nil(t, err) +} + func TestVerifySyncInfoIfTcUseDifferentEpoch(t *testing.T) { config := params.TestXDPoSMockChainConfig blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 1349, config, nil) diff --git a/params/version.go b/params/version.go index 23a1aad9acc8..6dad86457668 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 2 // Major version component of the current release VersionMinor = 4 // Minor version component of the current release - VersionPatch = 5 // Patch version component of the current release + VersionPatch = 6 // Patch version component of the current release VersionMeta = "beta1" // Version metadata to append to the version string ) From c8aae5e53752ca32e67ada9ed334220f18a7c27d Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Tue, 24 Dec 2024 01:53:40 -0800 Subject: [PATCH 018/121] Get right tc epoch (#773) * get right tc epoch * fix debug message * merge test * merge test --------- Co-authored-by: liam.lai --- .github/workflows/ci.yml | 6 ++-- consensus/XDPoS/engines/engine_v2/timeout.go | 33 +++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c41c2b2a65f..64dfde9142b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,8 @@ jobs: script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[d-i].*") - name: J-N tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[j-n].*") - - name: O-R tests - script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[o-r].*") - - name: S tests - script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/s.*") + - name: O-S tests + script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[o-s].*") - name: T-Z tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[t-z].*") steps: diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index 4a9c8d3017b0..875dd22c9c99 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -109,24 +109,33 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time log.Warn("[verifyQC] duplicated signature in QC", "duplicate", common.Bytes2Hex(d)) } } - latestBlockRound, err := x.GetRoundNumber(chain.CurrentHeader()) + + epochSwitchInfo, err := x.getEpochSwitchInfo(chain, (chain.CurrentHeader()), (chain.CurrentHeader()).Hash()) if err != nil { - log.Error("[verifyTC] Error when getting current header round", "error", err) - return fmt.Errorf("fail on verifyTC due to error when getting current header round, %s", err) + log.Error("[verifyTC] Error when getting epoch switch info", "error", err) + return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err) } - tcEpoch := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(timeoutCert.Round)/x.config.Epoch + epochRound := epochSwitchInfo.EpochSwitchBlockInfo.Round + tempTCEpoch := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochRound)/x.config.Epoch - //tcEpoch maybe not existed if there is no QC round in this epoch, there is no epoch switch block generated, so it needs to use currentRound to find epochBlockInfo - if latestBlockRound < timeoutCert.Round { - tcEpoch = x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(latestBlockRound)/x.config.Epoch + epochBlockInfo := &types.BlockInfo{ + Hash: epochSwitchInfo.EpochSwitchBlockInfo.Hash, + Round: epochRound, + Number: epochSwitchInfo.EpochSwitchBlockInfo.Number, } - - epochBlockInfo, err := x.GetBlockByEpochNumber(chain, tcEpoch) - if err != nil { - log.Error("[verifyTC] Error when getting epoch block info by tc round", "error", err) - return fmt.Errorf("fail on verifyTC due to failure in getting epoch block info tc round, %s", err) + log.Info("[verifyTC] Init epochInfo", "number", epochBlockInfo.Number, "round", epochRound, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch) + for epochBlockInfo.Round > timeoutCert.Round { + tempTCEpoch-- + epochBlockInfo, err = x.GetBlockByEpochNumber(chain, tempTCEpoch) + if err != nil { + log.Error("[verifyTC] Error when getting epoch block info by tc round", "error", err) + return fmt.Errorf("fail on verifyTC due to failure in getting epoch block info tc round, %s", err) + } + log.Debug("[verifyTC] Loop to get right epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch) } + tcEpoch := tempTCEpoch + log.Info("[verifyTC] Final TC epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tcEpoch) epochInfo, err := x.getEpochSwitchInfo(chain, nil, epochBlockInfo.Hash) if err != nil { From 6114a3a13b6899389608ec6102a845ddcfabe7b1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 25 Dec 2024 17:17:25 +0800 Subject: [PATCH 019/121] core: remove unused function reorgTxMatches --- core/blockchain.go | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 25ec81a7aa75..96dd45474573 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2315,9 +2315,6 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } }() } - if bc.chainConfig.IsTIPXDCXReceiver(commonBlock.Number()) && bc.chainConfig.XDPoS != nil && commonBlock.NumberU64() > bc.chainConfig.XDPoS.Epoch { - bc.reorgTxMatches(deletedTxs, newChain) - } return nil } @@ -2702,44 +2699,6 @@ func (bc *BlockChain) logExchangeData(block *types.Block) { } } -func (bc *BlockChain) reorgTxMatches(deletedTxs types.Transactions, newChain types.Blocks) { - engine, ok := bc.Engine().(*XDPoS.XDPoS) - if !ok || engine == nil { - return - } - XDCXService := engine.GetXDCXService() - lendingService := engine.GetLendingService() - if XDCXService == nil || !XDCXService.IsSDKNode() { - return - } - start := time.Now() - defer func() { - //The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns - // That's why we should put this log statement in an anonymous function - log.Debug("reorgTxMatches takes", "time", common.PrettyDuration(time.Since(start))) - }() - for _, deletedTx := range deletedTxs { - if deletedTx.IsTradingTransaction() { - log.Debug("Rollback reorg txMatch", "txhash", deletedTx.Hash()) - if err := XDCXService.RollbackReorgTxMatch(deletedTx.Hash()); err != nil { - log.Crit("Reorg trading failed", "err", err, "hash", deletedTx.Hash()) - } - } - if lendingService != nil && (deletedTx.IsLendingTransaction() || deletedTx.IsLendingFinalizedTradeTransaction()) { - log.Debug("Rollback reorg lendingItem", "txhash", deletedTx.Hash()) - if err := lendingService.RollbackLendingData(deletedTx.Hash()); err != nil { - log.Crit("Reorg lending failed", "err", err, "hash", deletedTx.Hash()) - } - } - } - - // apply new chain - for i := len(newChain) - 1; i >= 0; i-- { - bc.logExchangeData(newChain[i]) - bc.logLendingData(newChain[i]) - } -} - func (bc *BlockChain) logLendingData(block *types.Block) { engine, ok := bc.Engine().(*XDPoS.XDPoS) if !ok || engine == nil { From a5c48e77bdb89909ab4e395fcc7aebb7aace4f3b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 25 Dec 2024 17:22:28 +0800 Subject: [PATCH 020/121] core: remove unused function writeHeader --- core/blockchain.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 96dd45474573..5fe2d5390ddd 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2442,26 +2442,6 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i return bc.hc.InsertHeaderChain(chain, whFunc, start) } -// writeHeader writes a header into the local chain, given that its parent is -// already known. If the total difficulty of the newly inserted header becomes -// greater than the current known TD, the canonical chain is re-routed. -// -// Note: This method is not concurrent-safe with inserting blocks simultaneously -// into the chain, as side effects caused by reorganisations cannot be emulated -// without the real blocks. Hence, writing headers directly should only be done -// in two scenarios: pure-header mode of operation (light clients), or properly -// separated header/block phases (non-archive clients). -func (bc *BlockChain) writeHeader(header *types.Header) error { - bc.wg.Add(1) - defer bc.wg.Done() - - bc.mu.Lock() - defer bc.mu.Unlock() - - _, err := bc.hc.WriteHeader(header) - return err -} - // CurrentHeader retrieves the current head header of the canonical chain. The // header is retrieved from the HeaderChain's internal cache. func (bc *BlockChain) CurrentHeader() *types.Header { From e2afaec8b0268786007ba84075075be8d3073f89 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 25 Dec 2024 17:25:51 +0800 Subject: [PATCH 021/121] core: remove unused variables in BlockChain struct --- core/blockchain.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 5fe2d5390ddd..217e3be9e00a 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -153,7 +153,6 @@ type BlockChain struct { chainmu sync.RWMutex // blockchain insertion lock procmu sync.RWMutex // block processor lock - checkpoint int // checkpoint counts towards the new checkpoint currentBlock atomic.Value // Current head of the block chain currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!) @@ -181,9 +180,8 @@ type BlockChain struct { validator Validator // block and state validator interface vmConfig vm.Config - shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block. - IPCEndpoint string - Client bind.ContractBackend // Global ipc client instance. + IPCEndpoint string + Client bind.ContractBackend // Global ipc client instance. // Blocks hash array by block number // cache field for tracking finality purpose, can't use for tracking block vs block relationship From 0686b4428fcf8bb35b1bb80dc25259f8de72caf8 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Wed, 25 Dec 2024 22:59:24 -0800 Subject: [PATCH 022/121] upgrade to golang 1.22 (#763) Co-authored-by: liam.lai --- .github/workflows/ci.yml | 2 +- .travis.yml.bak | 180 --------------------------------------- Dockerfile | 2 +- Dockerfile.bootnode | 2 +- Dockerfile.node | 2 +- Makefile | 2 +- build/ci.go | 2 +- cicd/Dockerfile | 2 +- go.mod | 2 +- 9 files changed, 8 insertions(+), 188 deletions(-) delete mode 100644 .travis.yml.bak diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c41c2b2a65f..9d568dc50938 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: uses: actions/setup-go@v5 with: cache: false - go-version: '1.21.x' + go-version: '1.22.x' - name: Run tests run: ${{ matrix.script }} env: diff --git a/.travis.yml.bak b/.travis.yml.bak deleted file mode 100644 index b4e3db53b3b4..000000000000 --- a/.travis.yml.bak +++ /dev/null @@ -1,180 +0,0 @@ -sudo: required -language: go -go_import_path: github.com/XinFinOrg/XDPoSChain - -on: - branches: - - master - - dev-upgrade - tags: true - -env: - global: - - GOPROXY=https://proxy.golang.org - - GO111MODULE=on - # Terraform env - - tf_version=1.3.0 - # Setting terraform init CLI options - https://www.terraform.io/docs/commands/init.html - - tf_init_cli_options=" -input=false" - # Set terraform validation CLI options - https://www.terraform.io/docs/commands/validate.html - - tf_validation_cli_options="" - # Set terraform plan CLI options - https://www.terraform.io/docs/commands/plan.html - - tf_plan_cli_options=" -lock=false -input=false" - # Set terraform apply CLI options - https://www.terraform.io/docs/commands/apply.html - - tf_apply_cli_options=" -auto-approve -input=false" - - -jobs: - include: - - stage: Tests - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: A-B tests - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[a-b].*") - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[a-m].*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: C-[a-m] tests - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[n-o].*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: C-[n-o] tests - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[p-z].*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: C-[p-z] tests - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[d-i].*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: D-I tests - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[j-n].*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: J-N tests - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[o-r].*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: O-R tests - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/s.*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: S tests - - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[t-z].*") - os: linux - dist: bionic - go: 1.21.x - env: - - GO111MODULE=auto - name: T-Z tests - - - stage: TAG Build - if: tag IS present - services: - - docker - install: skip - before_script: - - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - - docker --version # document the version travis is using - - docker build -t xinfinorg/xdposchain:$TRAVIS_TAG -f cicd/Dockerfile . - script: - - docker push xinfinorg/xdposchain:$TRAVIS_TAG - - - stage: (Devnet) Build, and push images - if: branch = dev-upgrade AND type = push AND tag IS blank - services: - - docker - install: skip - before_script: - - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - - docker --version # document the version travis is using - - docker pull xinfinorg/devnet:latest # build the "previous" tag so that our devnet environment can run with both old and new code at the same time. - - docker tag xinfinorg/devnet:latest xinfinorg/devnet:previous - - docker rmi xinfinorg/devnet:latest - - docker build -t xinfinorg/devnet:latest -f cicd/Dockerfile . - script: - - docker push xinfinorg/devnet:latest - - docker push xinfinorg/devnet:previous - - - stage: (Devnet)Terraform plan - if: branch = dev-upgrade AND type = push AND tag IS blank - dist: xenial - language: bash - install: - - wget https://releases.hashicorp.com/terraform/"$tf_version"/terraform_"$tf_version"_linux_amd64.zip - - unzip terraform_"$tf_version"_linux_amd64.zip - - sudo mv terraform /usr/local/bin/ - - rm terraform_"$tf_version"_linux_amd64.zip - script: - - echo "Pull request detected, creating change plan(Devnet)" - - cd cicd/devnet/terraform - # Terraform init, validate, then create change plan. If any fail, fail validation - - terraform init $tf_init_cli_options - - terraform validate $tf_validation_cli_options - - terraform plan $tf_plan_cli_options - - - stage: (Devnet) Terraform apply - if: branch = dev-upgrade AND type = push AND tag IS blank - dist: xenial - language: bash - install: - # Download and install terraform before each run - - wget https://releases.hashicorp.com/terraform/"$tf_version"/terraform_"$tf_version"_linux_amd64.zip - - unzip terraform_"$tf_version"_linux_amd64.zip - - sudo mv terraform /usr/local/bin/ - - rm terraform_"$tf_version"_linux_amd64.zip - - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - - unzip awscliv2.zip - - sudo ./aws/install - - export PATH=$PATH:$HOME/.local/bin # put aws in the path - script: - - echo "Merge detected, executing changes(Devnet)" - - cd cicd/devnet/terraform - # Terraform init and then apply changes to environment - - terraform init $tf_init_cli_options - - terraform apply $tf_apply_cli_options - - sleep 5 - - | - source .env - for ((i=$us_east_2_start;i<$us_east_2_end;i++)); do - echo "Force deploy xdc-$i" - aws ecs update-service --region us-east-2 --cluster devnet-xdcnode-cluster --service ecs-service-xdc$i --force-new-deployment --no-cli-pager; - done - for ((i=$eu_west_1_start;i<$eu_west_1_end;i++)); do - echo "Force deploy xdc-$i" - aws ecs update-service --region eu-west-1 --cluster devnet-xdcnode-cluster --service ecs-service-xdc$i --force-new-deployment --no-cli-pager; - done - for ((i=$ap_southeast_2_start;i<$ap_southeast_2_end;i++)); do - echo "Force deploy xdc-$i" - aws ecs update-service --region ap-southeast-2 --cluster devnet-xdcnode-cluster --service ecs-service-xdc$i --force-new-deployment --no-cli-pager; - done - aws ecs update-service --region ap-southeast-1 --cluster devnet-xdcnode-cluster --service ecs-service-rpc1 --force-new-deployment --no-cli-pager; - - - stage: (Devnet) Send Deployment Notification - if: branch = dev-upgrade AND type = push AND tag IS blank - language: bash - script: - - curl --location --request POST "66.94.98.186:8080/deploy?environment=devnet&service=xdc&version=$TRAVIS_COMMIT" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 1207545aa792..5aba541a4915 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine as builder +FROM golang:1.22-alpine as builder RUN apk add --no-cache make gcc musl-dev linux-headers git diff --git a/Dockerfile.bootnode b/Dockerfile.bootnode index bb906b581f30..374bea3d3cd9 100644 --- a/Dockerfile.bootnode +++ b/Dockerfile.bootnode @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine as builder +FROM golang:1.22-alpine as builder RUN apk add --no-cache make gcc musl-dev linux-headers diff --git a/Dockerfile.node b/Dockerfile.node index 3d6f58495bc0..b3e0f299d928 100644 --- a/Dockerfile.node +++ b/Dockerfile.node @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine as builder +FROM golang:1.22-alpine as builder RUN apk add --no-cache make gcc musl-dev linux-headers git diff --git a/Makefile b/Makefile index 1ab433b070ef..3bd726906ce2 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ GOBIN = $(shell pwd)/build/bin GOFMT = gofmt -GO ?= 1.21.3 +GO ?= 1.22.10 GO_PACKAGES = . GO_FILES := $(shell find $(shell go list -f '{{.Dir}}' $(GO_PACKAGES)) -name \*.go) diff --git a/build/ci.go b/build/ci.go index 7d09ec7c9db6..ff3ea89d10f6 100644 --- a/build/ci.go +++ b/build/ci.go @@ -115,7 +115,7 @@ func doInstall(cmdline []string) { if minor < 21 { log.Println("You have Go version", runtime.Version()) - log.Println("XDC requires at least Go version 1.21 and cannot") + log.Println("XDC requires at least Go version 1.22 and cannot") log.Println("be compiled with an earlier version. Please upgrade your Go installation.") os.Exit(1) } diff --git a/cicd/Dockerfile b/cicd/Dockerfile index bf5b4b5c7988..055492e548bd 100644 --- a/cicd/Dockerfile +++ b/cicd/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine as builder +FROM golang:1.22-alpine as builder RUN apk add make build-base linux-headers diff --git a/go.mod b/go.mod index d948f4cea3b8..23a0995a49e8 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/XinFinOrg/XDPoSChain -go 1.21 +go 1.22 require ( github.com/VictoriaMetrics/fastcache v1.12.2 From 48d1f22fdeb11b72813bc4432bef6592021d46bf Mon Sep 17 00:00:00 2001 From: JukLee0ira Date: Mon, 23 Dec 2024 17:53:28 +0800 Subject: [PATCH 023/121] all: simplify function TransitionDb (#20830) --- accounts/abi/bind/backends/simulated.go | 3 +- core/state_processor.go | 2 +- core/state_transition.go | 18 ++++++------ core/token_validator.go | 2 +- eth/api_tracer.go | 4 +-- eth/tracers/testing/calltrace_test.go | 4 +-- eth/tracers/tracers_test.go | 6 ++-- internal/ethapi/api.go | 38 ++++++++++++------------- les/odr_test.go | 4 +-- light/odr_test.go | 2 +- tests/state_test_util.go | 2 +- 11 files changed, 42 insertions(+), 43 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 12005705c710..bbc8f4373ffd 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -478,8 +478,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.Cal vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, b.config, vm.Config{NoBaseFee: true}) gaspool := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - res, err, _ := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) - return res, err + return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) } // SendTransaction updates the pending block to include the given transaction. diff --git a/core/state_processor.go b/core/state_processor.go index 5fc975c7c72d..2f7980db6326 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -403,7 +403,7 @@ func applyTransaction(config *params.ChainConfig, tokensFee map[common.Address]* // End Bypass blacklist address // Apply the transaction to the current state (included in the env) - result, err, _ := ApplyMessage(evm, msg, gp, coinbaseOwner) + result, err := ApplyMessage(evm, msg, gp, coinbaseOwner) if err != nil { return nil, 0, err, false diff --git a/core/state_transition.go b/core/state_transition.go index 42e044a8de73..e18064501041 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -194,7 +194,7 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition // the gas used (which includes gas refunds) and an error if it failed. An error always // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. -func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) (*ExecutionResult, error, error) { +func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) (*ExecutionResult, error) { return NewStateTransition(evm, msg, gp).TransitionDb(owner) } @@ -317,7 +317,7 @@ func (st *StateTransition) preCheck() error { // // However if any consensus issue encountered, return the error directly with // nil evm execution result. -func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, error, error) { +func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, error) { // First check this message satisfies all consensus rules before // applying the message. The rules include these clauses // @@ -330,7 +330,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, // Check clauses 1-3, buy gas if everything is correct if err := st.preCheck(); err != nil { - return nil, err, nil + return nil, err } var ( @@ -345,16 +345,16 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, // Check clauses 4-5, subtract intrinsic gas if everything is correct gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, homestead, rules.IsEIP1559) if err != nil { - return nil, err, nil + return nil, err } if st.gas < gas { - return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas), nil + return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas) } st.gas -= gas // Check whether the init code size has been exceeded. if rules.IsEIP1559 && contractCreation && len(st.data) > params.MaxInitCodeSize { - return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(st.data), params.MaxInitCodeSize), nil + return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(st.data), params.MaxInitCodeSize) } // Execute the preparatory steps for state transition which includes: @@ -365,10 +365,10 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, // Check clause 6 value, overflow := uint256.FromBig(msg.Value()) if overflow { - return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex()), nil + return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex()) } if !value.IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From(), value.ToBig()) { - return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex()), nil + return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex()) } var ( @@ -406,7 +406,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, UsedGas: st.gasUsed(), Err: vmerr, ReturnData: ret, - }, nil, vmerr + }, nil } func (st *StateTransition) refundGas(refundQuotient uint64) { diff --git a/core/token_validator.go b/core/token_validator.go index e888f37b102e..070a3342ce8e 100644 --- a/core/token_validator.go +++ b/core/token_validator.go @@ -117,7 +117,7 @@ func CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext, vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, chain.Config(), vm.Config{}) gaspool := new(GasPool).AddGas(1000000) owner := common.Address{} - result, err, _ := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) + result, err := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) if err != nil { return nil, err } diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 35297da7f880..18c0fc010945 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -526,7 +526,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, vmenv := vm.NewEVM(blockCtx, txContext, statedb, XDCxState, api.config, vm.Config{}) owner := common.Address{} - if _, err, _ := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil { + if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil { failed = err break } @@ -750,7 +750,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, t statedb.SetTxContext(txctx.TxHash, txctx.TxIndex) owner := common.Address{} - result, err, _ := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner) + result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner) if err != nil { return nil, fmt.Errorf("tracing failed: %v", err) } diff --git a/eth/tracers/testing/calltrace_test.go b/eth/tracers/testing/calltrace_test.go index 35d9407cd93a..102e6f7416cc 100644 --- a/eth/tracers/testing/calltrace_test.go +++ b/eth/tracers/testing/calltrace_test.go @@ -120,7 +120,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon @@ -231,7 +231,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { evm := vm.NewEVM(context, txContext, statedb, nil, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) snap := statedb.Snapshot() st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err = st.TransitionDb(common.Address{}); err != nil { b.Fatalf("failed to execute transaction: %v", err) } if _, err = tracer.GetResult(); err != nil { diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 4b3198c95e0f..af01acda6741 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -158,7 +158,7 @@ func TestZeroValueToNotExitCall(t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon @@ -244,7 +244,7 @@ func TestPrestateTracerCreate2(t *testing.T) { t.Fatalf("failed to prepare transaction for tracing: %v", err) } st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err, _ = st.TransitionDb(common.Address{}); err != nil { + if _, err = st.TransitionDb(common.Address{}); err != nil { t.Fatalf("failed to execute transaction: %v", err) } // Retrieve the trace result and compare against the etalon @@ -346,7 +346,7 @@ func BenchmarkTransactionTrace(b *testing.B) { for i := 0; i < b.N; i++ { snap := statedb.Snapshot() st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - _, err, _ = st.TransitionDb(common.Address{}) + _, err = st.TransitionDb(common.Address{}) if err != nil { b.Fatal(err) } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index f8687bf626a3..44c39bdc6495 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1322,18 +1322,18 @@ func (s *PublicBlockChainAPI) getCandidatesFromSmartContract() ([]utils.Masterno return candidatesWithStakeInfo, nil } -func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error, error) { +func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) statedb, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if statedb == nil || err != nil { - return nil, err, nil + return nil, err } if header == nil { - return nil, errors.New("nil header in DoCall"), nil + return nil, errors.New("nil header in DoCall") } if err := overrides.Apply(statedb); err != nil { - return nil, err, nil + return nil, err } // Setup context so it may be cancelled the call has completed @@ -1350,32 +1350,32 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) if err != nil { - return nil, err, nil + return nil, err } if block == nil { - return nil, fmt.Errorf("nil block in DoCall: number=%d, hash=%s", header.Number.Uint64(), header.Hash().Hex()), nil + return nil, fmt.Errorf("nil block in DoCall: number=%d, hash=%s", header.Number.Uint64(), header.Hash().Hex()) } author, err := b.GetEngine().Author(block.Header()) if err != nil { - return nil, err, nil + return nil, err } XDCxState, err := b.XDCxService().GetTradingState(block, author) if err != nil { - return nil, err, nil + return nil, err } // TODO: replace header.BaseFee with blockCtx.BaseFee // reference: https://github.com/ethereum/go-ethereum/pull/29051 msg, err := args.ToMessage(b, header.Number, globalGasCap, header.BaseFee) if err != nil { - return nil, err, nil + return nil, err } msg.SetBalanceTokenFeeForCall() // Get a new instance of the EVM. evm, vmError, err := b.GetEVM(ctx, msg, statedb, XDCxState, header, &vm.Config{NoBaseFee: true}) if err != nil { - return nil, err, nil + return nil, err } // Wait for the context to be done and cancel the evm. Even if the // EVM has finished, cancelling may be done (repeatedly) @@ -1387,19 +1387,19 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash // Execute the message. gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - result, err, vmErr := core.ApplyMessage(evm, msg, gp, owner) + result, err := core.ApplyMessage(evm, msg, gp, owner) if err := vmError(); err != nil { - return nil, err, nil + return nil, err } // If the timer caused an abort, return an appropriate error message if evm.Cancelled() { - return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout), nil + return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) } if err != nil { - return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()), nil + return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()) } - return result, err, vmErr + return result, err } func newRevertError(res []byte) *revertError { @@ -1443,7 +1443,7 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, bl if args.To != nil && *args.To == common.MasternodeVotingSMCBinary { timeout = 0 } - result, err, vmErr := DoCall(ctx, s.b, args, *blockNrOrHash, overrides, timeout, s.b.RPCGasCap()) + result, err := DoCall(ctx, s.b, args, *blockNrOrHash, overrides, timeout, s.b.RPCGasCap()) if err != nil { return nil, err } @@ -1451,7 +1451,7 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, bl if result.Failed() && len(result.Return()) > 0 { return nil, newRevertError(result.Return()) } - return result.Return(), vmErr + return result.Return(), nil } type estimateGasError struct { @@ -1515,7 +1515,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr executable := func(gas uint64) (bool, *core.ExecutionResult, error) { args.Gas = (*hexutil.Uint64)(&gas) - result, err, _ := DoCall(ctx, b, args, blockNrOrHash, nil, 0, gasCap) + result, err := DoCall(ctx, b, args, blockNrOrHash, nil, 0, gasCap) if err != nil { if errors.Is(err, vm.ErrOutOfGas) || errors.Is(err, core.ErrIntrinsicGas) { return true, nil, nil // Special case, raise gas limit @@ -2096,7 +2096,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH return nil, 0, nil, err } // TODO: determine the value of owner - res, err, _ := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner) + res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner) if err != nil { return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) } diff --git a/les/odr_test.go b/les/odr_test.go index 031a1df5dc1e..706853d504b2 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -142,7 +142,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - result, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + result, _ := core.ApplyMessage(vmenv, msg, gp, owner) res = append(res, result.Return()...) } } else { @@ -160,7 +160,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai vmenv := vm.NewEVM(context, txContext, statedb, nil, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - result, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + result, _ := core.ApplyMessage(vmenv, msg, gp, owner) if statedb.Error() == nil { res = append(res, result.Return()...) } diff --git a/light/odr_test.go b/light/odr_test.go index 1562f955d9fe..79d3241c2048 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -191,7 +191,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain vmenv := vm.NewEVM(context, txContext, st, nil, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} - result, _, _ := core.ApplyMessage(vmenv, msg, gp, owner) + result, _ := core.ApplyMessage(vmenv, msg, gp, owner) res = append(res, result.Return()...) if st.Error() != nil { return res, st.Error() diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 1452ecd5d6a0..6f9ace8ec3ef 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -166,7 +166,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD gaspool.AddGas(block.GasLimit()) coinbase := &t.json.Env.Coinbase - if _, err, _ := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil { + if _, err := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil { statedb.RevertToSnapshot(snapshot) } if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) { From 517f4a16a6faf3aa4d199b64cabcdeb37aaa1d85 Mon Sep 17 00:00:00 2001 From: JukLee0ira Date: Mon, 23 Dec 2024 17:55:41 +0800 Subject: [PATCH 024/121] internal/ethapi: fix Call handle revert error --- internal/ethapi/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 44c39bdc6495..47d50b864f3d 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1448,7 +1448,7 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, bl return nil, err } // If the result contains a revert reason, try to unpack and return it. - if result.Failed() && len(result.Return()) > 0 { + if result.Failed() { return nil, newRevertError(result.Return()) } return result.Return(), nil From efa2605f26efe84bd307be0704e6b9484af1ffc4 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Sat, 21 Dec 2024 15:56:24 +0800 Subject: [PATCH 025/121] accounts/abi/bind/backends: fix wrong gas returned by EstimateGas --- accounts/abi/bind/backends/simulated.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index bbc8f4373ffd..d0c7562e155c 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -368,7 +368,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call b.pendingState.RevertToSnapshot(snapshot) if err != nil { - if err == core.ErrIntrinsicGas { + if errors.Is(err, core.ErrIntrinsicGas) { return true, nil, nil // Special case, raise gas limit } return true, nil, err // Bail out From 240757a1cea7dc70d0eeb4ed8f8e28c13fc373be Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 25 Dec 2024 09:16:01 +0800 Subject: [PATCH 026/121] all: remove empty function SaveData() --- XDCx/XDCx.go | 2 -- XDCxlending/XDCxlending.go | 3 --- core/blockchain.go | 9 ++------- eth/backend.go | 4 ---- ethstats/ethstats.go | 2 -- les/backend.go | 4 ---- light/lightchain.go | 3 --- node/node.go | 3 --- node/node_example_test.go | 1 - node/service.go | 3 +-- node/utils_test.go | 4 +--- p2p/simulations/adapters/exec.go | 2 -- p2p/simulations/examples/ping-pong.go | 3 --- p2p/simulations/http_test.go | 2 -- p2p/testing/protocoltester.go | 6 ------ 15 files changed, 4 insertions(+), 47 deletions(-) diff --git a/XDCx/XDCx.go b/XDCx/XDCx.go index 3fbaf0c783e2..fbb737240289 100644 --- a/XDCx/XDCx.go +++ b/XDCx/XDCx.go @@ -71,8 +71,6 @@ func (XDCx *XDCX) Start(server *p2p.Server) error { return nil } -func (XDCx *XDCX) SaveData() { -} func (XDCx *XDCX) Stop() error { return nil } diff --git a/XDCxlending/XDCxlending.go b/XDCxlending/XDCxlending.go index 1bf2496ff237..a1f8e9749fd1 100644 --- a/XDCxlending/XDCxlending.go +++ b/XDCxlending/XDCxlending.go @@ -54,9 +54,6 @@ func (l *Lending) Start(server *p2p.Server) error { return nil } -func (l *Lending) SaveData() { -} - func (l *Lending) Stop() error { return nil } diff --git a/core/blockchain.go b/core/blockchain.go index 217e3be9e00a..48509e652057 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -922,12 +922,7 @@ func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) { return bc.stateCache.TrieDB().Node(hash) } -func (bc *BlockChain) SaveData() { - bc.wg.Add(1) - defer bc.wg.Done() - // Make sure no inconsistent state is leaked during insertion - bc.mu.Lock() - defer bc.mu.Unlock() +func (bc *BlockChain) saveData() { // Ensure the state of a recent block is also stored to disk before exiting. // We're writing three different states to catch different restart scenarios: // - HEAD: So we don't need to reprocess any blocks in the general case @@ -1011,7 +1006,7 @@ func (bc *BlockChain) Stop() { close(bc.quit) atomic.StoreInt32(&bc.procInterrupt, 1) bc.wg.Wait() - bc.SaveData() + bc.saveData() log.Info("Blockchain manager stopped") } diff --git a/eth/backend.go b/eth/backend.go index b9cef04b11c8..6a3920dcc277 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -557,10 +557,6 @@ func (e *Ethereum) Start(srvr *p2p.Server) error { return nil } -func (e *Ethereum) SaveData() { - e.blockchain.SaveData() -} - // Stop implements node.Service, terminating all internal goroutines used by the // Ethereum protocol. func (e *Ethereum) Stop() error { diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index 4510478bb0e5..edcb255fbc03 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -179,8 +179,6 @@ func (s *Service) Start(server *p2p.Server) error { log.Info("Stats daemon started") return nil } -func (s *Service) SaveData() { -} // Stop implements node.Service, terminating the monitoring and reporting daemon. func (s *Service) Stop() error { diff --git a/les/backend.go b/les/backend.go index 08933f93a0a4..e982603d2fdb 100644 --- a/les/backend.go +++ b/les/backend.go @@ -228,10 +228,6 @@ func (s *LightEthereum) Start(srvr *p2p.Server) error { return nil } -func (s *LightEthereum) SaveData() { - s.blockchain.SaveData() -} - // Stop implements node.Service, terminating all internal goroutines used by the // Ethereum protocol. func (s *LightEthereum) Stop() error { diff --git a/light/lightchain.go b/light/lightchain.go index 26b5df09172b..9cbf95ddf9c6 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -281,9 +281,6 @@ func (lc *LightChain) GetBlockByNumber(ctx context.Context, number uint64) (*typ return lc.GetBlock(ctx, hash, number) } -func (bc *LightChain) SaveData() { -} - // Stop stops the blockchain service. If any imports are currently in progress // it will abort them using the procInterrupt. func (lc *LightChain) Stop() { diff --git a/node/node.go b/node/node.go index 40cef4bab342..b8deaa1e857c 100644 --- a/node/node.go +++ b/node/node.go @@ -478,9 +478,6 @@ func (n *Node) Stop() error { return ErrNodeStopped } - for _, service := range n.services { - service.SaveData() - } // Terminate the API, services and the p2p server. n.stopWS() n.stopHTTP() diff --git a/node/node_example_test.go b/node/node_example_test.go index b2ad1a8ed3e0..c16aad73ab27 100644 --- a/node/node_example_test.go +++ b/node/node_example_test.go @@ -38,7 +38,6 @@ type SampleService struct{} func (s *SampleService) Protocols() []p2p.Protocol { return nil } func (s *SampleService) APIs() []rpc.API { return nil } func (s *SampleService) Start(*p2p.Server) error { fmt.Println("Service starting..."); return nil } -func (s *SampleService) SaveData() {} func (s *SampleService) Stop() error { fmt.Println("Service stopping..."); return nil } func ExampleService() { diff --git a/node/service.go b/node/service.go index 5d0358b93123..8bfc71884f50 100644 --- a/node/service.go +++ b/node/service.go @@ -97,8 +97,7 @@ type Service interface { // Start is called after all services have been constructed and the networking // layer was also initialized to spawn any goroutines required by the service. Start(server *p2p.Server) error - //Save data before stop - SaveData() + // Stop terminates all goroutines belonging to the service, blocking until they // are all terminated. Stop() error diff --git a/node/utils_test.go b/node/utils_test.go index d6aff608e05d..4f6034f47eca 100644 --- a/node/utils_test.go +++ b/node/utils_test.go @@ -32,7 +32,6 @@ type NoopService struct{} func (s *NoopService) Protocols() []p2p.Protocol { return nil } func (s *NoopService) APIs() []rpc.API { return nil } func (s *NoopService) Start(*p2p.Server) error { return nil } -func (s *NoopService) SaveData() {} func (s *NoopService) Stop() error { return nil } func NewNoopService(*ServiceContext) (Service, error) { return new(NoopService), nil } @@ -79,8 +78,7 @@ func (s *InstrumentedService) Start(server *p2p.Server) error { } return s.start } -func (s *InstrumentedService) SaveData() { -} + func (s *InstrumentedService) Stop() error { if s.stopHook != nil { s.stopHook() diff --git a/p2p/simulations/adapters/exec.go b/p2p/simulations/adapters/exec.go index 1ab534f8d07f..153aa32d6491 100644 --- a/p2p/simulations/adapters/exec.go +++ b/p2p/simulations/adapters/exec.go @@ -504,8 +504,6 @@ func (s *snapshotService) Start(*p2p.Server) error { return nil } -func (s *snapshotService) SaveData() { -} func (s *snapshotService) Stop() error { return nil } diff --git a/p2p/simulations/examples/ping-pong.go b/p2p/simulations/examples/ping-pong.go index 450ab047906e..144035348b69 100644 --- a/p2p/simulations/examples/ping-pong.go +++ b/p2p/simulations/examples/ping-pong.go @@ -127,9 +127,6 @@ func (p *pingPongService) Start(server *p2p.Server) error { return nil } -func (p *pingPongService) SaveData() { -} - func (p *pingPongService) Stop() error { p.log.Info("ping-pong service stopping") return nil diff --git a/p2p/simulations/http_test.go b/p2p/simulations/http_test.go index 2bc2e0fecc78..7121cc4c0d8c 100644 --- a/p2p/simulations/http_test.go +++ b/p2p/simulations/http_test.go @@ -117,8 +117,6 @@ func (t *testService) Start(server *p2p.Server) error { return nil } -func (t *testService) SaveData() { -} func (t *testService) Stop() error { return nil } diff --git a/p2p/testing/protocoltester.go b/p2p/testing/protocoltester.go index 622d63bfe324..df291202a0ff 100644 --- a/p2p/testing/protocoltester.go +++ b/p2p/testing/protocoltester.go @@ -145,9 +145,6 @@ func (tn *testNode) Start(server *p2p.Server) error { return nil } -func (tn *testNode) SaveData() { -} - func (tn *testNode) Stop() error { return nil } @@ -201,9 +198,6 @@ func (mn *mockNode) Expect(exp ...Expect) error { return <-mn.err } -func (mn *mockNode) SaveData() { -} - func (mn *mockNode) Stop() error { mn.stopOnce.Do(func() { close(mn.stop) }) return nil From 89c51c5e6911d814b7370b10a2c6a1cb7d79e560 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 18 Dec 2024 17:50:26 +0800 Subject: [PATCH 027/121] common: improve documentation comments (#16701) --- XDCx/order_processor.go | 2 +- XDCx/tradingstate/dump.go | 22 +++---- XDCx/tradingstate/state_lendingbook.go | 2 +- XDCx/tradingstate/state_orderbook.go | 8 +-- XDCx/tradingstate/statedb.go | 4 +- XDCxlending/lendingstate/dump.go | 22 +++---- XDCxlending/lendingstate/state_lendingbook.go | 10 +-- .../lendingstate/state_liquidationtime.go | 2 +- XDCxlending/lendingstate/statedb.go | 4 +- XDCxlending/order_processor.go | 2 +- common/bytes.go | 23 +++++-- common/math/big.go | 13 ++-- common/number/int.go | 47 +++++++------- common/path.go | 6 +- common/types.go | 47 ++++++-------- common/types_template.go | 64 ------------------- core/blockchain.go | 4 +- core/state/state_test.go | 2 +- core/state/trc21_reader.go | 10 +-- core/txpool/order_pool.go | 2 +- eth/downloader/downloader.go | 2 +- 21 files changed, 118 insertions(+), 180 deletions(-) delete mode 100644 common/types_template.go diff --git a/XDCx/order_processor.go b/XDCx/order_processor.go index a950ca43b788..441bb2ec8b60 100644 --- a/XDCx/order_processor.go +++ b/XDCx/order_processor.go @@ -525,7 +525,7 @@ func DoSettleBalance(coinbase common.Address, takerOrder, makerOrder *tradingsta matchingFee = new(big.Int).Add(matchingFee, common.RelayerFee) matchingFee = new(big.Int).Add(matchingFee, common.RelayerFee) - if common.EmptyHash(takerExOwner.Hash()) || common.EmptyHash(makerExOwner.Hash()) { + if takerExOwner.Hash().IsZero() || makerExOwner.Hash().IsZero() { return fmt.Errorf("empty echange owner: taker: %v , maker : %v", takerExOwner, makerExOwner) } mapBalances := map[common.Address]map[common.Address]*big.Int{} diff --git a/XDCx/tradingstate/dump.go b/XDCx/tradingstate/dump.go index 58026ed2a158..f813743870d1 100644 --- a/XDCx/tradingstate/dump.go +++ b/XDCx/tradingstate/dump.go @@ -56,7 +56,7 @@ func (t *TradingStateDB) DumpAskTrie(orderBook common.Hash) (map[*big.Int]DumpOr it := trie.NewIterator(exhangeObject.getAsksTrie(t.db).NodeIterator(nil)) for it.Next() { priceHash := common.BytesToHash(it.Key) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { continue } price := new(big.Int).SetBytes(priceHash.Bytes()) @@ -99,7 +99,7 @@ func (t *TradingStateDB) DumpBidTrie(orderBook common.Hash) (map[*big.Int]DumpOr it := trie.NewIterator(exhangeObject.getBidsTrie(t.db).NodeIterator(nil)) for it.Next() { priceHash := common.BytesToHash(it.Key) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { continue } price := new(big.Int).SetBytes(priceHash.Bytes()) @@ -142,7 +142,7 @@ func (t *TradingStateDB) GetBids(orderBook common.Hash) (map[*big.Int]*big.Int, it := trie.NewIterator(exhangeObject.getBidsTrie(t.db).NodeIterator(nil)) for it.Next() { priceHash := common.BytesToHash(it.Key) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { continue } price := new(big.Int).SetBytes(priceHash.Bytes()) @@ -185,7 +185,7 @@ func (t *TradingStateDB) GetAsks(orderBook common.Hash) (map[*big.Int]*big.Int, it := trie.NewIterator(exhangeObject.getAsksTrie(t.db).NodeIterator(nil)) for it.Next() { priceHash := common.BytesToHash(it.Key) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { continue } price := new(big.Int).SetBytes(priceHash.Bytes()) @@ -224,7 +224,7 @@ func (s *stateOrderList) DumpOrderList(db Database) DumpOrderList { orderListIt := trie.NewIterator(s.getTrie(db).NodeIterator(nil)) for orderListIt.Next() { keyHash := common.BytesToHash(orderListIt.Key) - if common.EmptyHash(keyHash) { + if keyHash.IsZero() { continue } if _, exist := s.cachedStorage[keyHash]; exist { @@ -235,7 +235,7 @@ func (s *stateOrderList) DumpOrderList(db Database) DumpOrderList { } } for key, value := range s.cachedStorage { - if !common.EmptyHash(value) { + if !value.IsZero() { mapResult.Orders[new(big.Int).SetBytes(key.Bytes())] = new(big.Int).SetBytes(value.Bytes()) } } @@ -277,7 +277,7 @@ func (s *stateLendingBook) DumpOrderList(db Database) DumpOrderList { orderListIt := trie.NewIterator(s.getTrie(db).NodeIterator(nil)) for orderListIt.Next() { keyHash := common.BytesToHash(orderListIt.Key) - if common.EmptyHash(keyHash) { + if keyHash.IsZero() { continue } if _, exist := s.cachedStorage[keyHash]; exist { @@ -288,7 +288,7 @@ func (s *stateLendingBook) DumpOrderList(db Database) DumpOrderList { } } for key, value := range s.cachedStorage { - if !common.EmptyHash(value) { + if !value.IsZero() { mapResult.Orders[new(big.Int).SetBytes(key.Bytes())] = new(big.Int).SetBytes(value.Bytes()) } } @@ -311,7 +311,7 @@ func (l *liquidationPriceState) DumpLendingBook(db Database) (DumpLendingBook, e it := trie.NewIterator(l.getTrie(db).NodeIterator(nil)) for it.Next() { lendingBook := common.BytesToHash(it.Key) - if common.EmptyHash(lendingBook) { + if lendingBook.IsZero() { continue } if _, exist := l.stateLendingBooks[lendingBook]; exist { @@ -326,7 +326,7 @@ func (l *liquidationPriceState) DumpLendingBook(db Database) (DumpLendingBook, e } } for lendingBook, stateLendingBook := range l.stateLendingBooks { - if !common.EmptyHash(lendingBook) { + if !lendingBook.IsZero() { result.LendingBooks[lendingBook] = stateLendingBook.DumpOrderList(db) } } @@ -342,7 +342,7 @@ func (t *TradingStateDB) DumpLiquidationPriceTrie(orderBook common.Hash) (map[*b it := trie.NewIterator(exhangeObject.getLiquidationPriceTrie(t.db).NodeIterator(nil)) for it.Next() { priceHash := common.BytesToHash(it.Key) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { continue } price := new(big.Int).SetBytes(priceHash.Bytes()) diff --git a/XDCx/tradingstate/state_lendingbook.go b/XDCx/tradingstate/state_lendingbook.go index 6f8b77695bec..f30faf60a951 100644 --- a/XDCx/tradingstate/state_lendingbook.go +++ b/XDCx/tradingstate/state_lendingbook.go @@ -118,7 +118,7 @@ func (s *stateLendingBook) getAllTradeIds(db Database) []common.Hash { return tradeIds } for id, value := range s.cachedStorage { - if !common.EmptyHash(value) { + if !value.IsZero() { tradeIds = append(tradeIds, id) } } diff --git a/XDCx/tradingstate/state_orderbook.go b/XDCx/tradingstate/state_orderbook.go index 8d74d748e404..39a4db730e5e 100644 --- a/XDCx/tradingstate/state_orderbook.go +++ b/XDCx/tradingstate/state_orderbook.go @@ -85,16 +85,16 @@ func (te *tradingExchanges) empty() bool { if te.data.TotalQuantity != nil && te.data.TotalQuantity.Sign() > 0 { return false } - if !common.EmptyHash(te.data.AskRoot) { + if !te.data.AskRoot.IsZero() { return false } - if !common.EmptyHash(te.data.BidRoot) { + if !te.data.BidRoot.IsZero() { return false } - if !common.EmptyHash(te.data.OrderRoot) { + if !te.data.OrderRoot.IsZero() { return false } - if !common.EmptyHash(te.data.LiquidationPriceRoot) { + if !te.data.LiquidationPriceRoot.IsZero() { return false } return true diff --git a/XDCx/tradingstate/statedb.go b/XDCx/tradingstate/statedb.go index 036b5cac4cbf..7520947db15c 100644 --- a/XDCx/tradingstate/statedb.go +++ b/XDCx/tradingstate/statedb.go @@ -358,7 +358,7 @@ func (t *TradingStateDB) GetBestAskPrice(orderBook common.Hash) (*big.Int, *big. stateObject := t.getStateExchangeObject(orderBook) if stateObject != nil { priceHash := stateObject.getBestPriceAsksTrie(t.db) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { return Zero, Zero } orderList := stateObject.getStateOrderListAskObject(t.db, priceHash) @@ -375,7 +375,7 @@ func (t *TradingStateDB) GetBestBidPrice(orderBook common.Hash) (*big.Int, *big. stateObject := t.getStateExchangeObject(orderBook) if stateObject != nil { priceHash := stateObject.getBestBidsTrie(t.db) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { return Zero, Zero } orderList := stateObject.getStateBidOrderListObject(t.db, priceHash) diff --git a/XDCxlending/lendingstate/dump.go b/XDCxlending/lendingstate/dump.go index f3fe43742e48..978f67fc8e71 100644 --- a/XDCxlending/lendingstate/dump.go +++ b/XDCxlending/lendingstate/dump.go @@ -48,7 +48,7 @@ func (ls *LendingStateDB) DumpInvestingTrie(orderBook common.Hash) (map[*big.Int it := trie.NewIterator(exhangeObject.getInvestingTrie(ls.db).NodeIterator(nil)) for it.Next() { interestHash := common.BytesToHash(it.Key) - if common.EmptyHash(interestHash) { + if interestHash.IsZero() { continue } interest := new(big.Int).SetBytes(interestHash.Bytes()) @@ -91,7 +91,7 @@ func (ls *LendingStateDB) DumpBorrowingTrie(orderBook common.Hash) (map[*big.Int it := trie.NewIterator(exhangeObject.getBorrowingTrie(ls.db).NodeIterator(nil)) for it.Next() { interestHash := common.BytesToHash(it.Key) - if common.EmptyHash(interestHash) { + if interestHash.IsZero() { continue } interest := new(big.Int).SetBytes(interestHash.Bytes()) @@ -134,7 +134,7 @@ func (ls *LendingStateDB) GetInvestings(orderBook common.Hash) (map[*big.Int]*bi it := trie.NewIterator(exhangeObject.getInvestingTrie(ls.db).NodeIterator(nil)) for it.Next() { interestHash := common.BytesToHash(it.Key) - if common.EmptyHash(interestHash) { + if interestHash.IsZero() { continue } interest := new(big.Int).SetBytes(interestHash.Bytes()) @@ -177,7 +177,7 @@ func (ls *LendingStateDB) GetBorrowings(orderBook common.Hash) (map[*big.Int]*bi it := trie.NewIterator(exhangeObject.getBorrowingTrie(ls.db).NodeIterator(nil)) for it.Next() { interestHash := common.BytesToHash(it.Key) - if common.EmptyHash(interestHash) { + if interestHash.IsZero() { continue } interest := new(big.Int).SetBytes(interestHash.Bytes()) @@ -216,7 +216,7 @@ func (il *itemListState) DumpItemList(db Database) DumpOrderList { orderListIt := trie.NewIterator(il.getTrie(db).NodeIterator(nil)) for orderListIt.Next() { keyHash := common.BytesToHash(orderListIt.Key) - if common.EmptyHash(keyHash) { + if keyHash.IsZero() { continue } if _, exist := il.cachedStorage[keyHash]; exist { @@ -227,7 +227,7 @@ func (il *itemListState) DumpItemList(db Database) DumpOrderList { } } for key, value := range il.cachedStorage { - if !common.EmptyHash(value) { + if !value.IsZero() { mapResult.Orders[new(big.Int).SetBytes(key.Bytes())] = new(big.Int).SetBytes(value.Bytes()) } } @@ -265,7 +265,7 @@ func (lts *liquidationTimeState) DumpItemList(db Database) DumpOrderList { orderListIt := trie.NewIterator(lts.getTrie(db).NodeIterator(nil)) for orderListIt.Next() { keyHash := common.BytesToHash(orderListIt.Key) - if common.EmptyHash(keyHash) { + if keyHash.IsZero() { continue } if _, exist := lts.cachedStorage[keyHash]; exist { @@ -276,7 +276,7 @@ func (lts *liquidationTimeState) DumpItemList(db Database) DumpOrderList { } } for key, value := range lts.cachedStorage { - if !common.EmptyHash(value) { + if !value.IsZero() { mapResult.Orders[new(big.Int).SetBytes(key.Bytes())] = new(big.Int).SetBytes(value.Bytes()) } } @@ -303,7 +303,7 @@ func (ls *LendingStateDB) DumpLiquidationTimeTrie(orderBook common.Hash) (map[*b it := trie.NewIterator(exhangeObject.getLiquidationTimeTrie(ls.db).NodeIterator(nil)) for it.Next() { unixTimeHash := common.BytesToHash(it.Key) - if common.EmptyHash(unixTimeHash) { + if unixTimeHash.IsZero() { continue } unixTime := new(big.Int).SetBytes(unixTimeHash.Bytes()) @@ -346,7 +346,7 @@ func (ls *LendingStateDB) DumpLendingOrderTrie(orderBook common.Hash) (map[*big. it := trie.NewIterator(exhangeObject.getLendingItemTrie(ls.db).NodeIterator(nil)) for it.Next() { orderIdHash := common.BytesToHash(it.Key) - if common.EmptyHash(orderIdHash) { + if orderIdHash.IsZero() { continue } orderId := new(big.Int).SetBytes(orderIdHash.Bytes()) @@ -386,7 +386,7 @@ func (ls *LendingStateDB) DumpLendingTradeTrie(orderBook common.Hash) (map[*big. it := trie.NewIterator(exhangeObject.getLendingTradeTrie(ls.db).NodeIterator(nil)) for it.Next() { tradeIdHash := common.BytesToHash(it.Key) - if common.EmptyHash(tradeIdHash) { + if tradeIdHash.IsZero() { continue } tradeId := new(big.Int).SetBytes(tradeIdHash.Bytes()) diff --git a/XDCxlending/lendingstate/state_lendingbook.go b/XDCxlending/lendingstate/state_lendingbook.go index 1cc3fda0778a..c6103790e274 100644 --- a/XDCxlending/lendingstate/state_lendingbook.go +++ b/XDCxlending/lendingstate/state_lendingbook.go @@ -70,19 +70,19 @@ func (s *lendingExchangeState) empty() bool { if s.data.TradeNonce != 0 { return false } - if !common.EmptyHash(s.data.InvestingRoot) { + if !s.data.InvestingRoot.IsZero() { return false } - if !common.EmptyHash(s.data.BorrowingRoot) { + if !s.data.BorrowingRoot.IsZero() { return false } - if !common.EmptyHash(s.data.LendingItemRoot) { + if !s.data.LendingItemRoot.IsZero() { return false } - if !common.EmptyHash(s.data.LendingTradeRoot) { + if !s.data.LendingTradeRoot.IsZero() { return false } - if !common.EmptyHash(s.data.LiquidationTimeRoot) { + if !s.data.LiquidationTimeRoot.IsZero() { return false } return true diff --git a/XDCxlending/lendingstate/state_liquidationtime.go b/XDCxlending/lendingstate/state_liquidationtime.go index 558650989a97..77ab934abfbb 100644 --- a/XDCxlending/lendingstate/state_liquidationtime.go +++ b/XDCxlending/lendingstate/state_liquidationtime.go @@ -116,7 +116,7 @@ func (lt *liquidationTimeState) getAllTradeIds(db Database) []common.Hash { return tradeIds } for id, value := range lt.cachedStorage { - if !common.EmptyHash(value) { + if !value.IsZero() { tradeIds = append(tradeIds, id) } } diff --git a/XDCxlending/lendingstate/statedb.go b/XDCxlending/lendingstate/statedb.go index e5a5cbf6ede6..a1b3899803d3 100644 --- a/XDCxlending/lendingstate/statedb.go +++ b/XDCxlending/lendingstate/statedb.go @@ -343,7 +343,7 @@ func (ls *LendingStateDB) GetBestInvestingRate(orderBook common.Hash) (*big.Int, stateObject := ls.getLendingExchange(orderBook) if stateObject != nil { investingHash := stateObject.getBestInvestingInterest(ls.db) - if common.EmptyHash(investingHash) { + if investingHash.IsZero() { return Zero, Zero } orderList := stateObject.getInvestingOrderList(ls.db, investingHash) @@ -360,7 +360,7 @@ func (ls *LendingStateDB) GetBestBorrowRate(orderBook common.Hash) (*big.Int, *b stateObject := ls.getLendingExchange(orderBook) if stateObject != nil { priceHash := stateObject.getBestBorrowingInterest(ls.db) - if common.EmptyHash(priceHash) { + if priceHash.IsZero() { return Zero, Zero } orderList := stateObject.getBorrowingOrderList(ls.db, priceHash) diff --git a/XDCxlending/order_processor.go b/XDCxlending/order_processor.go index 0a41347acdb8..a46b9dafedca 100644 --- a/XDCxlending/order_processor.go +++ b/XDCxlending/order_processor.go @@ -581,7 +581,7 @@ func DoSettleBalance(coinbase common.Address, takerOrder, makerOrder *lendingsta // masternodes only charge borrower relayer fee matchingFee = new(big.Int).Add(matchingFee, common.RelayerLendingFee) - if common.EmptyHash(takerExOwner.Hash()) || common.EmptyHash(makerExOwner.Hash()) { + if takerExOwner.Hash().IsZero() || makerExOwner.Hash().IsZero() { return fmt.Errorf("empty echange owner: taker: %v , maker : %v", takerExOwner, makerExOwner) } mapBalances := map[common.Address]map[common.Address]*big.Int{} diff --git a/common/bytes.go b/common/bytes.go index 79caa1f49ce7..6be6116bb979 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -19,15 +19,20 @@ package common import "encoding/hex" +// ToHex returns the hex representation of b, prefixed with '0x'. +// For empty slices, the return value is "0x0". +// +// Deprecated: use hexutil.Encode instead. func ToHex(b []byte) string { hex := Bytes2Hex(b) - // Prefer output of "0x0" instead of "0x" if len(hex) == 0 { hex = "0" } return "0x" + hex } +// FromHex returns the bytes represented by the hexadecimal string s. +// s may be prefixed with "0x". func FromHex(s string) []byte { if len(s) > 1 { if s[0:2] == "0x" || s[0:2] == "0X" { @@ -43,9 +48,7 @@ func FromHex(s string) []byte { return Hex2Bytes(s) } -// Copy bytes -// -// Returns an exact copy of the provided bytes +// CopyBytes returns an exact copy of the provided bytes. func CopyBytes(b []byte) (copiedBytes []byte) { if b == nil { return nil @@ -55,17 +58,23 @@ func CopyBytes(b []byte) (copiedBytes []byte) { return } + +// hasXDCPrefix validates str begins with 'xdc' or 'XDC'. func hasXDCPrefix(str string) bool { return len(str) >= 3 && (str[0] == 'x' || str[0] == 'X') && (str[1] == 'd' || str[1] == 'D') && (str[2] == 'c' || str[2] == 'C') } + +// hasHexPrefix validates str begins with '0x' or '0X'. func hasHexPrefix(str string) bool { return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') } +// isHexCharacter returns bool of c being a valid hexadecimal. func isHexCharacter(c byte) bool { return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') } +// isHex validates whether each byte is valid hexadecimal string. func isHex(str string) bool { if len(str)%2 != 0 { return false @@ -78,16 +87,18 @@ func isHex(str string) bool { return true } +// Bytes2Hex returns the hexadecimal encoding of d. func Bytes2Hex(d []byte) string { return hex.EncodeToString(d) } +// Hex2Bytes returns the bytes represented by the hexadecimal string str. func Hex2Bytes(str string) []byte { h, _ := hex.DecodeString(str) - return h } +// Hex2BytesFixed returns bytes of a specified fixed length flen. func Hex2BytesFixed(str string, flen int) []byte { h, _ := hex.DecodeString(str) if len(h) == flen { @@ -103,6 +114,7 @@ func Hex2BytesFixed(str string, flen int) []byte { } } +// RightPadBytes zero-pads slice to the right up to length l. func RightPadBytes(slice []byte, l int) []byte { if l <= len(slice) { return slice @@ -114,6 +126,7 @@ func RightPadBytes(slice []byte, l int) []byte { return padded } +// LeftPadBytes zero-pads slice to the left up to length l. func LeftPadBytes(slice []byte, l int) []byte { if l <= len(slice) { return slice diff --git a/common/math/big.go b/common/math/big.go index 78727865032a..d2cfb6ed5a9b 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -78,7 +78,7 @@ func ParseBig256(s string) (*big.Int, bool) { return bigint, ok } -// MustParseBig parses s as a 256 bit big integer and panics if the string is invalid. +// MustParseBig256 parses s as a 256 bit big integer and panics if the string is invalid. func MustParseBig256(s string) *big.Int { v, ok := ParseBig256(s) if !ok { @@ -179,16 +179,15 @@ func U256(x *big.Int) *big.Int { // S256 interprets x as a two's complement number. // x must not exceed 256 bits (the result is undefined if it does) and is not modified. // -// S256(0) = 0 -// S256(1) = 1 -// S256(2**255) = -2**255 -// S256(2**256-1) = -1 +// S256(0) = 0 +// S256(1) = 1 +// S256(2**255) = -2**255 +// S256(2**256-1) = -1 func S256(x *big.Int) *big.Int { if x.Cmp(tt255) < 0 { return x - } else { - return new(big.Int).Sub(x, tt256) } + return new(big.Int).Sub(x, tt256) } // Exp implements exponentiation by squaring. diff --git a/common/number/int.go b/common/number/int.go index 7a4f9f8ca14e..de55c6be878f 100644 --- a/common/number/int.go +++ b/common/number/int.go @@ -34,13 +34,12 @@ func limitUnsigned256(x *Number) *Number { func limitSigned256(x *Number) *Number { if x.num.Cmp(tt255) < 0 { return x - } else { - x.num.Sub(x.num, tt256) - return x } + x.num.Sub(x.num, tt256) + return x } -// Number function +// Initialiser is a Number function type Initialiser func(n int64) *Number // A Number represents a generic integer with a bounding function limiter. Limit is called after each operations @@ -58,58 +57,58 @@ func NewInitialiser(limiter func(*Number) *Number) Initialiser { } } -// Return a Number with a UNSIGNED limiter up to 256 bits +// Uint256 returns a Number with a UNSIGNED limiter up to 256 bits func Uint256(n int64) *Number { return &Number{big.NewInt(n), limitUnsigned256} } -// Return a Number with a SIGNED limiter up to 256 bits +// Int256 returns Number with a SIGNED limiter up to 256 bits func Int256(n int64) *Number { return &Number{big.NewInt(n), limitSigned256} } -// Returns a Number with a SIGNED unlimited size +// Big returns a Number with a SIGNED unlimited size func Big(n int64) *Number { return &Number{big.NewInt(n), func(x *Number) *Number { return x }} } -// Sets i to sum of x+y +// Add sets i to sum of x+y func (i *Number) Add(x, y *Number) *Number { i.num.Add(x.num, y.num) return i.limit(i) } -// Sets i to difference of x-y +// Sub sets i to difference of x-y func (i *Number) Sub(x, y *Number) *Number { i.num.Sub(x.num, y.num) return i.limit(i) } -// Sets i to product of x*y +// Mul sets i to product of x*y func (i *Number) Mul(x, y *Number) *Number { i.num.Mul(x.num, y.num) return i.limit(i) } -// Sets i to the quotient prodject of x/y +// Div sets i to the quotient prodject of x/y func (i *Number) Div(x, y *Number) *Number { i.num.Div(x.num, y.num) return i.limit(i) } -// Sets i to x % y +// Mod sets i to x % y func (i *Number) Mod(x, y *Number) *Number { i.num.Mod(x.num, y.num) return i.limit(i) } -// Sets i to x << s +// Lsh sets i to x << s func (i *Number) Lsh(x *Number, s uint) *Number { i.num.Lsh(x.num, s) return i.limit(i) } -// Sets i to x^y +// Pow sets i to x^y func (i *Number) Pow(x, y *Number) *Number { i.num.Exp(x.num, y.num, big.NewInt(0)) return i.limit(i) @@ -117,13 +116,13 @@ func (i *Number) Pow(x, y *Number) *Number { // Setters -// Set x to i +// Set sets x to i func (i *Number) Set(x *Number) *Number { i.num.Set(x.num) return i.limit(i) } -// Set x bytes to i +// SetBytes sets x bytes to i func (i *Number) SetBytes(x []byte) *Number { i.num.SetBytes(x) return i.limit(i) @@ -131,21 +130,21 @@ func (i *Number) SetBytes(x []byte) *Number { // Cmp compares x and y and returns: // -// -1 if x < y -// 0 if x == y -// +1 if x > y +// -1 if x < y +// 0 if x == y +// +1 if x > y func (i *Number) Cmp(x *Number) int { return i.num.Cmp(x.num) } // Getters -// Returns the string representation of i +// String returns the string representation of i func (i *Number) String() string { return i.num.String() } -// Returns the byte representation of i +// Bytes returns the byte representation of i func (i *Number) Bytes() []byte { return i.num.Bytes() } @@ -160,17 +159,17 @@ func (i *Number) Int64() int64 { return i.num.Int64() } -// Returns the signed version of i +// Int256 returns the signed version of i func (i *Number) Int256() *Number { return Int(0).Set(i) } -// Returns the unsigned version of i +// Uint256 returns the unsigned version of i func (i *Number) Uint256() *Number { return Uint(0).Set(i) } -// Returns the index of the first bit that's set to 1 +// FirstBitSet returns the index of the first bit that's set to 1 func (i *Number) FirstBitSet() int { for j := 0; j < i.num.BitLen(); j++ { if i.num.Bit(j) > 0 { diff --git a/common/path.go b/common/path.go index bd8da86e749e..69820cfe5dec 100644 --- a/common/path.go +++ b/common/path.go @@ -30,6 +30,7 @@ func MakeName(name, version string) string { return fmt.Sprintf("%s/v%s/%s/%s", name, version, runtime.GOOS, runtime.Version()) } +// FileExist checks if a file exists at filePath. func FileExist(filePath string) bool { _, err := os.Stat(filePath) if err != nil && os.IsNotExist(err) { @@ -39,9 +40,10 @@ func FileExist(filePath string) bool { return true } -func AbsolutePath(Datadir string, filename string) string { +// AbsolutePath returns datadir + filename, or filename if it is absolute. +func AbsolutePath(datadir string, filename string) string { if filepath.IsAbs(filename) { return filename } - return filepath.Join(Datadir, filename) + return filepath.Join(datadir, filename) } diff --git a/common/types.go b/common/types.go index 533aa562d915..a33fe35bcc34 100644 --- a/common/types.go +++ b/common/types.go @@ -106,7 +106,7 @@ func (h Hash) Cmp(other Hash) int { // IsZero returns if a Hash is empty func (h Hash) IsZero() bool { return h == Hash{} } -// Get the string representation of the underlying hash +// Str get the string representation of the underlying hash func (h Hash) Str() string { return string(h[:]) } // Bytes gets the byte representation of the underlying hash. @@ -161,14 +161,6 @@ func (h *Hash) SetBytes(b []byte) { copy(h[HashLength-len(b):], b) } -// Set string `s` to h. If s is larger than len(h) s will be cropped (from left) to fit. -func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) } - -// Sets h to other -func (h *Hash) Set(other Hash) { - copy(h[:], other[:]) -} - // Generate implements testing/quick.Generator. func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { m := rand.Intn(len(h)) @@ -178,10 +170,6 @@ func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { return reflect.ValueOf(h) } -func EmptyHash(h Hash) bool { - return h == Hash{} -} - // UnprefixedHash allows marshaling a Hash without 0x prefix. type UnprefixedHash Hash @@ -200,6 +188,8 @@ func (h UnprefixedHash) MarshalText() ([]byte, error) { // Address represents the 20 byte address of an Ethereum account. type Address [AddressLength]byte +// BytesToAddress returns Address with value b. +// If b is larger than len(h), b will be cropped from the left. func BytesToAddress(b []byte) Address { var a Address a.SetBytes(b) @@ -231,11 +221,17 @@ func IsHexAddress(s string) bool { // IsZero returns if a address is empty func (a Address) IsZero() bool { return a == Address{} } -// Get the string representation of the underlying address -func (a Address) Str() string { return string(a[:]) } +// Str gets the string representation of the underlying address +func (a Address) Str() string { return string(a[:]) } + +// Bytes gets the string representation of the underlying address. func (a Address) Bytes() []byte { return a[:] } + +// Big converts an address to a big integer. func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) } -func (a Address) Hash() Hash { return BytesToHash(a[:]) } + +// Hash converts an address to a hash by left-padding it with zeros. +func (a Address) Hash() Hash { return BytesToHash(a[:]) } // Hex returns an EIP55-compliant hex string representation of the address. func (a Address) Hex() string { @@ -259,7 +255,7 @@ func (a Address) Hex() string { return "xdc" + string(result) } -// String implements the stringer interface and is used also by the logger. +// String implements fmt.Stringer. func (a Address) String() string { return a.Hex() } @@ -270,7 +266,8 @@ func (a Address) Format(s fmt.State, c rune) { fmt.Fprintf(s, "%"+string(c), a[:]) } -// Sets the address to the value of b. If b is larger than len(a) it will panic +// SetBytes sets the address to the value of b. +// If b is larger than len(a) it will panic. func (a *Address) SetBytes(b []byte) { if len(b) > len(a) { b = b[len(b)-AddressLength:] @@ -278,14 +275,6 @@ func (a *Address) SetBytes(b []byte) { copy(a[AddressLength-len(b):], b) } -// Set string `s` to a. If s is larger than len(a) it will panic -func (a *Address) SetString(s string) { a.SetBytes([]byte(s)) } - -// Sets a to other -func (a *Address) Set(other Address) { - copy(a[:], other[:]) -} - // MarshalText returns the hex representation of a. func (a Address) MarshalText() ([]byte, error) { // Handle '0x' or 'xdc' prefix here. @@ -306,7 +295,7 @@ func (a *Address) UnmarshalJSON(input []byte) error { return hexutil.UnmarshalFixedJSON(addressT, input, a[:]) } -// UnprefixedHash allows marshaling an Address without 0x prefix. +// UnprefixedAddress allows marshaling an Address without 0x prefix. type UnprefixedAddress Address // UnmarshalText decodes the address from hex. The 0x prefix is optional. @@ -319,7 +308,7 @@ func (a UnprefixedAddress) MarshalText() ([]byte, error) { return []byte(hex.EncodeToString(a[:])), nil } -// Extract validators from byte array. +// RemoveItemFromArray extracts validators from byte array. func RemoveItemFromArray(array []Address, items []Address) []Address { // Create newArray to stop append change array value newArray := make([]Address, len(array)) @@ -340,7 +329,7 @@ func RemoveItemFromArray(array []Address, items []Address) []Address { return newArray } -// Extract validators from byte array. +// ExtractAddressToBytes extracts validators from byte array. func ExtractAddressToBytes(penalties []Address) []byte { data := []byte{} for _, signer := range penalties { diff --git a/common/types_template.go b/common/types_template.go deleted file mode 100644 index 9a8f29977b6a..000000000000 --- a/common/types_template.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// +build none -//sed -e 's/_N_/Hash/g' -e 's/_S_/32/g' -e '1d' types_template.go | gofmt -w hash.go - -package common - -import "math/big" - -type _N_ [_S_]byte - -func BytesTo_N_(b []byte) _N_ { - var h _N_ - h.SetBytes(b) - return h -} -func StringTo_N_(s string) _N_ { return BytesTo_N_([]byte(s)) } -func BigTo_N_(b *big.Int) _N_ { return BytesTo_N_(b.Bytes()) } -func HexTo_N_(s string) _N_ { return BytesTo_N_(FromHex(s)) } - -// Don't use the default 'String' method in case we want to overwrite - -// Get the string representation of the underlying hash -func (h _N_) Str() string { return string(h[:]) } -func (h _N_) Bytes() []byte { return h[:] } -func (h _N_) Big() *big.Int { return new(big.Int).SetBytes(h[:]) } -func (h _N_) Hex() string { return "0x" + Bytes2Hex(h[:]) } - -// Sets the hash to the value of b. If b is larger than len(h) it will panic -func (h *_N_) SetBytes(b []byte) { - // Use the right most bytes - if len(b) > len(h) { - b = b[len(b)-_S_:] - } - - // Reverse the loop - for i := len(b) - 1; i >= 0; i-- { - h[_S_-len(b)+i] = b[i] - } -} - -// Set string `s` to h. If s is larger than len(h) it will panic -func (h *_N_) SetString(s string) { h.SetBytes([]byte(s)) } - -// Sets h to other -func (h *_N_) Set(other _N_) { - for i, v := range other { - h[i] = v - } -} diff --git a/core/blockchain.go b/core/blockchain.go index 48509e652057..6c75b759aa9a 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -957,7 +957,7 @@ func (bc *BlockChain) saveData() { author, _ := bc.Engine().Author(recent.Header()) if tradingService != nil { tradingRoot, _ := tradingService.GetTradingStateRoot(recent, author) - if !common.EmptyHash(tradingRoot) && tradingTriedb != nil { + if !tradingRoot.IsZero() && tradingTriedb != nil { if err := tradingTriedb.Commit(tradingRoot, true); err != nil { log.Error("Failed to commit trading state recent state trie", "err", err) } @@ -965,7 +965,7 @@ func (bc *BlockChain) saveData() { } if lendingService != nil { lendingRoot, _ := lendingService.GetLendingStateRoot(recent, author) - if !common.EmptyHash(lendingRoot) && lendingTriedb != nil { + if !lendingRoot.IsZero() && lendingTriedb != nil { if err := lendingTriedb.Commit(lendingRoot, true); err != nil { log.Error("Failed to commit lending state recent state trie", "err", err) } diff --git a/core/state/state_test.go b/core/state/state_test.go index ddc7df61ce2e..c4b49628d26b 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -100,7 +100,7 @@ func (s *StateSuite) TestNull(c *checker.C) { s.state.SetState(address, common.Hash{}, value) s.state.Commit(false) value = s.state.GetState(address, common.Hash{}) - if !common.EmptyHash(value) { + if !value.IsZero() { c.Errorf("expected empty hash. got %x", value) } } diff --git a/core/state/trc21_reader.go b/core/state/trc21_reader.go index 561cebb5c766..994575e6c068 100644 --- a/core/state/trc21_reader.go +++ b/core/state/trc21_reader.go @@ -51,7 +51,7 @@ func GetTRC21FeeCapacityFromState(statedb *StateDB) map[common.Address]*big.Int for i := uint64(0); i < tokenCount; i++ { key := GetLocDynamicArrAtElement(slotTokensHash, i, 1) value := statedb.GetState(common.TRC21IssuerSMC, key) - if !common.EmptyHash(value) { + if !value.IsZero() { token := common.BytesToAddress(value.Bytes()) balanceKey := GetLocMappingAtKey(token.Hash(), slotTokensState) balanceHash := statedb.GetState(common.TRC21IssuerSMC, common.BigToHash(balanceKey)) @@ -68,14 +68,14 @@ func PayFeeWithTRC21TxFail(statedb *StateDB, from common.Address, token common.A slotBalanceTrc21 := SlotTRC21Token["balances"] balanceKey := GetLocMappingAtKey(from.Hash(), slotBalanceTrc21) balanceHash := statedb.GetState(token, common.BigToHash(balanceKey)) - if !common.EmptyHash(balanceHash) { + if !balanceHash.IsZero() { balance := balanceHash.Big() feeUsed := big.NewInt(0) if balance.Cmp(feeUsed) <= 0 { return } issuerTokenKey := GetLocSimpleVariable(SlotTRC21Token["issuer"]) - if common.EmptyHash(issuerTokenKey) { + if issuerTokenKey.IsZero() { return } issuerAddr := common.BytesToAddress(statedb.GetState(token, issuerTokenKey).Bytes()) @@ -106,7 +106,7 @@ func ValidateTRC21Tx(statedb *StateDB, from common.Address, token common.Address balanceKey := GetLocMappingAtKey(from.Hash(), slotBalanceTrc21) balanceHash := statedb.GetState(token, common.BigToHash(balanceKey)) - if !common.EmptyHash(balanceHash) { + if !balanceHash.IsZero() { balance := balanceHash.Big() minFeeTokenKey := GetLocSimpleVariable(SlotTRC21Token["minFee"]) minFeeHash := statedb.GetState(token, minFeeTokenKey) @@ -129,7 +129,7 @@ func ValidateTRC21Tx(statedb *StateDB, from common.Address, token common.Address } else { // we both accept tx with balance = 0 and fee = 0 minFeeTokenKey := GetLocSimpleVariable(SlotTRC21Token["minFee"]) - if !common.EmptyHash(minFeeTokenKey) { + if !minFeeTokenKey.IsZero() { return true } } diff --git a/core/txpool/order_pool.go b/core/txpool/order_pool.go index 87ef9e80dc65..4857d993886e 100644 --- a/core/txpool/order_pool.go +++ b/core/txpool/order_pool.go @@ -492,7 +492,7 @@ func (pool *OrderPool) validateOrder(tx *types.OrderTransaction) error { var signer = types.OrderTxSigner{} if !tx.IsCancelledOrder() { - if !common.EmptyHash(tx.OrderHash()) { + if !tx.OrderHash().IsZero() { if signer.Hash(tx) != tx.OrderHash() { return ErrInvalidOrderHash } diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index f5fb6d1c5851..ec779eb07732 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -682,7 +682,7 @@ func (d *Downloader) findAncestor(p *peerConnection, height uint64) (uint64, err } } // If the head fetch already found an ancestor, return - if !common.EmptyHash(hash) { + if !hash.IsZero() { if int64(number) <= floor { p.log.Warn("Ancestor below allowance", "number", number, "hash", hash, "allowance", floor) return 0, errInvalidAncestor From 7cd3e56d18dcffe708fef3507fd9fb199f1cbccd Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 12 Dec 2024 17:56:39 +0800 Subject: [PATCH 028/121] accounts/abi/bind: stop using goimports in the binding generator (#17768 #20311) --- accounts/abi/bind/bind.go | 6 +- accounts/abi/bind/bind_test.go | 170 +++++++++++++++++++++++++++++---- accounts/abi/bind/template.go | 24 +++++ internal/build/util.go | 23 ----- 4 files changed, 181 insertions(+), 42 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 79d05afb445d..0c4ba0a81e44 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -23,13 +23,13 @@ package bind import ( "bytes" "fmt" + "go/format" "regexp" "strings" "text/template" "unicode" "github.com/XinFinOrg/XDPoSChain/accounts/abi" - "golang.org/x/tools/imports" ) // Lang is a target programming language selector to generate bindings for. @@ -143,9 +143,9 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La if err := tmpl.Execute(buffer, data); err != nil { return "", err } - // For Go bindings pass the code through goimports to clean it up and double check + // For Go bindings pass the code through gofmt to clean it up if lang == LangGo { - code, err := imports.Process(".", buffer.Bytes(), nil) + code, err := format.Source(buffer.Bytes()) if err != nil { return "", fmt.Errorf("%v\n%s", err, buffer) } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 2c477882ebf3..448ffe2b6acc 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -27,7 +27,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/params" - "golang.org/x/tools/imports" ) var bindTests = []struct { @@ -35,6 +34,7 @@ var bindTests = []struct { contract string bytecode string abi string + imports string tester string }{ // Test that the binding is available in combined and separate forms too @@ -43,6 +43,7 @@ var bindTests = []struct { `contract NilContract {}`, `606060405260068060106000396000f3606060405200`, `[]`, + `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewEmpty(common.Address{}, nil); b == nil || err != nil { t.Fatalf("combined binding (%v) nil or error (%v) not nil", b, nil) @@ -61,6 +62,7 @@ var bindTests = []struct { `https://ethereum.org/token`, `60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`, `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`, + `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewToken(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -72,6 +74,7 @@ var bindTests = []struct { `https://ethereum.org/crowdsale`, `606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56`, `[{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"funders","outputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]`, + `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewCrowdsale(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -83,6 +86,7 @@ var bindTests = []struct { `https://ethereum.org/dao`, `606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688`, `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]`, + `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewDAO(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -102,6 +106,11 @@ var bindTests = []struct { {"type":"function","name":"mixedInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"str","type":"string"}],"outputs":[]} ] `, + ` + "fmt" + + "github.com/XinFinOrg/XDPoSChain/common" + `, `if b, err := NewInputChecker(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) } else if false { // Don't run, just compile and test types @@ -131,6 +140,11 @@ var bindTests = []struct { {"type":"function","name":"mixedOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"str","type":"string"}]} ] `, + ` + "fmt" + + "github.com/XinFinOrg/XDPoSChain/common" + `, `if b, err := NewOutputChecker(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) } else if false { // Don't run, just compile and test types @@ -160,6 +174,13 @@ var bindTests = []struct { {"type":"event","name":"dynamic","inputs":[{"name":"idxStr","type":"string","indexed":true},{"name":"idxDat","type":"bytes","indexed":true},{"name":"str","type":"string"},{"name":"dat","type":"bytes"}]} ] `, + ` + "fmt" + "math/big" + "reflect" + + "github.com/XinFinOrg/XDPoSChain/common" + `, `if e, err := NewEventChecker(common.Address{}, nil); e == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", e, nil) } else if false { // Don't run, just compile and test types @@ -225,6 +246,15 @@ var bindTests = []struct { `, `6060604052604051610328380380610328833981016040528051018060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10608d57805160ff19168380011785555b50607c9291505b8082111560ba57838155600101606b565b50505061026a806100be6000396000f35b828001600101855582156064579182015b828111156064578251826000505591602001919060010190609e565b509056606060405260e060020a60003504630d86a0e181146100315780636874e8091461008d578063d736c513146100ea575b005b610190600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b61019060008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b60206004803580820135601f81018490049093026080908101604052606084815261002f946024939192918401918190838280828437509496505050505050508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023157805160ff19168380011785555b506102619291505b808211156102665760008155830161017d565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b82800160010185558215610175579182015b82811115610175578251826000505591602001919060010190610243565b505050565b509056`, `[{"constant":true,"inputs":[],"name":"transactString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[],"name":"deployString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"str","type":"string"}],"name":"transact","outputs":[],"type":"function"},{"inputs":[{"name":"str","type":"string"}],"type":"constructor"}]`, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -266,6 +296,15 @@ var bindTests = []struct { `, `606060405260dc8060106000396000f3606060405260e060020a6000350463993a04b78114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`, `[{"constant":true,"inputs":[],"name":"getter","outputs":[{"name":"","type":"string"},{"name":"","type":"int256"},{"name":"","type":"bytes32"}],"type":"function"}]`, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -298,6 +337,15 @@ var bindTests = []struct { `, `606060405260dc8060106000396000f3606060405260e060020a60003504633175aae28114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`, `[{"constant":true,"inputs":[],"name":"tuple","outputs":[{"name":"a","type":"string"},{"name":"b","type":"int256"},{"name":"c","type":"bytes32"}],"type":"function"}]`, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -340,6 +388,17 @@ var bindTests = []struct { `, `606060405261015c806100126000396000f3606060405260e060020a6000350463be1127a3811461003c578063d88becc014610092578063e15a3db71461003c578063f637e5891461003c575b005b604080516020600480358082013583810285810185019096528085526100ee959294602494909392850192829185019084908082843750949650505050505050604080516020810190915260009052805b919050565b604080516102e0818101909252610138916004916102e491839060179083908390808284375090955050505050506102e0604051908101604052806017905b60008152602001906001900390816100d15790505081905061008d565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b60405180826102e0808381846000600461015cf15090500191505060405180910390f3`, `[{"constant":true,"inputs":[{"name":"input","type":"address[]"}],"name":"echoAddresses","outputs":[{"name":"output","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"uint24[23]"}],"name":"echoFancyInts","outputs":[{"name":"output","type":"uint24[23]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"int256[]"}],"name":"echoInts","outputs":[{"name":"output","type":"int256[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"bool[]"}],"name":"echoBools","outputs":[{"name":"output","type":"bool[]"}],"type":"function"}]`, + ` + "math/big" + "reflect" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -374,6 +433,15 @@ var bindTests = []struct { `, `6060604052606a8060106000396000f360606040523615601d5760e060020a6000350463fc9c8d3981146040575b605e6000805473ffffffffffffffffffffffffffffffffffffffff191633179055565b606060005473ffffffffffffffffffffffffffffffffffffffff1681565b005b6060908152602090f3`, `[{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"type":"function"}]`, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -409,6 +477,12 @@ var bindTests = []struct { `, `6060604052609f8060106000396000f3606060405260e060020a6000350463f97a60058114601a575b005b600060605260c0604052600d60809081527f4920646f6e27742065786973740000000000000000000000000000000000000060a052602060c0908152600d60e081905281906101009060a09080838184600060046012f15050815172ffffffffffffffffffffffffffffffffffffff1916909152505060405161012081900392509050f3`, `[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`, + ` + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Create a simulator and wrap a non-deployed contract sim := backends.NewXDCSimulatedBackend(nil, uint64(10000000000), params.TestXDPoSMockChainConfig) @@ -443,6 +517,15 @@ var bindTests = []struct { `, `606060405261021c806100126000396000f3606060405260e060020a600035046323fcf32a81146100265780634f28bf0e1461007b575b005b6040805160206004803580820135601f8101849004840285018401909552848452610024949193602493909291840191908190840183828082843750949650505050505050620186a05a101561014e57610002565b6100db60008054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281529291908301828280156102145780601f106101e957610100808354040283529160200191610214565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561013b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b505050565b8060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101b557805160ff19168380011785555b506101499291505b808211156101e557600081556001016101a1565b82800160010185558215610199579182015b828111156101995782518260005055916020019190600101906101c7565b5090565b820191906000526020600020905b8154815290600101906020018083116101f757829003601f168201915b50505050508156`, `[{"constant":false,"inputs":[{"name":"value","type":"string"}],"name":"SetField","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"field","outputs":[{"name":"","type":"string"}],"type":"function"}]`, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -478,6 +561,16 @@ var bindTests = []struct { } `, `6060604052346000575b6086806100176000396000f300606060405263ffffffff60e060020a60003504166349f8e98281146022575b6000565b34600057602c6055565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b335b905600a165627a7a72305820aef6b7685c0fa24ba6027e4870404a57df701473fe4107741805c19f5138417c0029`, `[{"constant":true,"inputs":[],"name":"callFrom","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"}]`, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -538,6 +631,16 @@ var bindTests = []struct { } `, `6060604052341561000f57600080fd5b6103858061001e6000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461009357806346546dbe146100c357806367e6633d146100ec5780639df4848514610181578063af7486ab146101b1578063b564b34d146101e1578063e02ab24d14610211578063e409ca4514610241575b600080fd5b341561009e57600080fd5b6100a6610271565b604051808381526020018281526020019250505060405180910390f35b34156100ce57600080fd5b6100d6610286565b6040518082815260200191505060405180910390f35b34156100f757600080fd5b6100ff61028e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561014557808201518184015260208101905061012a565b50505050905090810190601f1680156101725780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561018c57600080fd5b6101946102dc565b604051808381526020018281526020019250505060405180910390f35b34156101bc57600080fd5b6101c46102f1565b604051808381526020018281526020019250505060405180910390f35b34156101ec57600080fd5b6101f4610306565b604051808381526020018281526020019250505060405180910390f35b341561021c57600080fd5b61022461031b565b604051808381526020018281526020019250505060405180910390f35b341561024c57600080fd5b610254610330565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600080905090565b6000610298610345565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820d1a53d9de9d1e3d55cb3dc591900b63c4f1ded79114f7b79b332684840e186a40029`, `[{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_under_scored_func","outputs":[{"name":"_int","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UnderscoredOutput","outputs":[{"name":"_int","type":"int256"},{"name":"_string","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperLowerCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"AllPurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"__","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperUpperCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerLowerCollision","outputs":[{"name":"_res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"}]`, + ` + "fmt" + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -608,6 +711,17 @@ var bindTests = []struct { `, `6060604052341561000f57600080fd5b61042c8061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063528300ff1461005c578063630c31e2146100fc578063c7d116dd14610156575b600080fd5b341561006757600080fd5b6100fa600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610194565b005b341561010757600080fd5b610154600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035600019169060200190919080351515906020019091908035906020019091905050610367565b005b341561016157600080fd5b610192600480803590602001909190803560010b90602001909190803563ffffffff169060200190919050506103c3565b005b806040518082805190602001908083835b6020831015156101ca57805182526020820191506020810190506020830392506101a5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020826040518082805190602001908083835b60208310151561022d5780518252602082019150602081019050602083039250610208565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f3281fd4f5e152dd3385df49104a3f633706e21c9e80672e88d3bcddf33101f008484604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102c15780820151818401526020810190506102a6565b50505050905090810190601f1680156102ee5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561032757808201518184015260208101905061030c565b50505050905090810190601f1680156103545780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a35050565b81151583600019168573ffffffffffffffffffffffffffffffffffffffff167f1f097de4289df643bd9c11011cc61367aa12983405c021056e706eb5ba1250c8846040518082815260200191505060405180910390a450505050565b8063ffffffff168260010b847f3ca7f3a77e5e6e15e781850bc82e32adfa378a2a609370db24b4d0fae10da2c960405160405180910390a45050505600a165627a7a72305820d1f8a8bbddbc5bb29f285891d6ae1eef8420c52afdc05e1573f6114d8e1714710029`, `[{"constant":false,"inputs":[{"name":"str","type":"string"},{"name":"blob","type":"bytes"}],"name":"raiseDynamicEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"id","type":"bytes32"},{"name":"flag","type":"bool"},{"name":"value","type":"uint256"}],"name":"raiseSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"number","type":"uint256"},{"name":"short","type":"int16"},{"name":"long","type":"uint32"}],"name":"raiseNodataEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Addr","type":"address"},{"indexed":true,"name":"Id","type":"bytes32"},{"indexed":true,"name":"Flag","type":"bool"},{"indexed":false,"name":"Value","type":"uint256"}],"name":"SimpleEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Number","type":"uint256"},{"indexed":true,"name":"Short","type":"int16"},{"indexed":true,"name":"Long","type":"uint32"}],"name":"NodataEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"IndexedString","type":"string"},{"indexed":true,"name":"IndexedBytes","type":"bytes"},{"indexed":false,"name":"NonIndexedString","type":"string"},{"indexed":false,"name":"NonIndexedBytes","type":"bytes"}],"name":"DynamicEvent","type":"event"}]`, + ` + "math/big" + "time" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -757,6 +871,15 @@ var bindTests = []struct { `, `6060604052341561000f57600080fd5b6106438061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063344248551461005c5780638ed4573a1461011457806398ed1856146101ab575b600080fd5b341561006757600080fd5b610112600480806107800190600580602002604051908101604052809291906000905b828210156101055783826101800201600480602002604051908101604052809291906000905b828210156100f25783826060020160038060200260405190810160405280929190826003602002808284378201915050505050815260200190600101906100b0565b505050508152602001906001019061008a565b5050505091905050610208565b005b341561011f57600080fd5b61012761021d565b604051808260056000925b8184101561019b578284602002015160046000925b8184101561018d5782846020020151600360200280838360005b8381101561017c578082015181840152602081019050610161565b505050509050019260010192610147565b925050509260010192610132565b9250505091505060405180910390f35b34156101b657600080fd5b6101de6004808035906020019091908035906020019091908035906020019091905050610309565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b80600090600561021992919061035f565b5050565b6102256103b0565b6000600580602002604051908101604052809291906000905b8282101561030057838260040201600480602002604051908101604052809291906000905b828210156102ed578382016003806020026040519081016040528092919082600380156102d9576020028201916000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff16815260200190600801906020826007010492830192600103820291508084116102945790505b505050505081526020019060010190610263565b505050508152602001906001019061023e565b50505050905090565b60008360058110151561031857fe5b600402018260048110151561032957fe5b018160038110151561033757fe5b6004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b826005600402810192821561039f579160200282015b8281111561039e5782518290600461038e9291906103df565b5091602001919060040190610375565b5b5090506103ac919061042d565b5090565b610780604051908101604052806005905b6103c9610459565b8152602001906001900390816103c15790505090565b826004810192821561041c579160200282015b8281111561041b5782518290600361040b929190610488565b50916020019190600101906103f2565b5b5090506104299190610536565b5090565b61045691905b8082111561045257600081816104499190610562565b50600401610433565b5090565b90565b610180604051908101604052806004905b6104726105a7565b81526020019060019003908161046a5790505090565b82600380016004900481019282156105255791602002820160005b838211156104ef57835183826101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555092602001926008016020816007010492830192600103026104a3565b80156105235782816101000a81549067ffffffffffffffff02191690556008016020816007010492830192600103026104ef565b505b50905061053291906105d9565b5090565b61055f91905b8082111561055b57600081816105529190610610565b5060010161053c565b5090565b90565b50600081816105719190610610565b50600101600081816105839190610610565b50600101600081816105959190610610565b5060010160006105a59190610610565b565b6060604051908101604052806003905b600067ffffffffffffffff168152602001906001900390816105b75790505090565b61060d91905b8082111561060957600081816101000a81549067ffffffffffffffff0219169055506001016105df565b5090565b90565b50600090555600a165627a7a7230582087e5a43f6965ab6ef7a4ff056ab80ed78fd8c15cff57715a1bf34ec76a93661c0029`, `[{"constant":false,"inputs":[{"name":"arr","type":"uint64[3][4][5]"}],"name":"storeDeepUintArray","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"retrieveDeepArray","outputs":[{"name":"","type":"uint64[3][4][5]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"deepUint64Array","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"}]`, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -820,15 +943,6 @@ func TestBindings(t *testing.T) { t.Skip("go sdk not found for testing") } t.Log("Using config", params.TestXDPoSMockChainConfig) - // Skip the test if the go-ethereum sources are symlinked (https://github.com/golang/go/issues/14845) - linkTestCode := "package linktest\nfunc CheckSymlinks(){\nfmt.Println(backends.NewSimulatedBackend(nil))\n}" - linkTestDeps, err := imports.Process(os.TempDir(), []byte(linkTestCode), nil) - if err != nil { - t.Fatalf("failed check for goimports symlink bug: %v", err) - } - if !strings.Contains(string(linkTestDeps), "go-ethereum") { - t.Skip("symlinked environment doesn't support bind (https://github.com/golang/go/issues/14845)") - } // Create a temporary workspace for the test suite ws, err := os.MkdirTemp("", "") if err != nil { @@ -851,15 +965,39 @@ func TestBindings(t *testing.T) { t.Fatalf("test %d: failed to write binding: %v", i, err) } // Generate the test file with the injected test code - code := fmt.Sprintf("package bindtest\nimport \"testing\"\nfunc Test%s(t *testing.T){\n%s\n}", tt.name, tt.tester) - blob, err := imports.Process("", []byte(code), nil) - if err != nil { - t.Fatalf("test %d: failed to generate tests: %v", i, err) - } - if err := os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), blob, 0600); err != nil { + code := fmt.Sprintf(` + package bindtest + + import ( + "testing" + %s + ) + + func Test%s(t *testing.T) { + %s + } + `, tt.imports, tt.name, tt.tester) + if err := os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), []byte(code), 0600); err != nil { t.Fatalf("test %d: failed to write tests: %v", i, err) } } + // Convert the package to go modules and use the current source for go-ethereum + moder := exec.Command(gocmd, "mod", "init", "bindtest") + moder.Dir = pkg + if out, err := moder.CombinedOutput(); err != nil { + t.Fatalf("failed to convert binding test to modules: %v\n%s", err, out) + } + pwd, _ := os.Getwd() + replacer := exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/XinFinOrg/XDPoSChain@v0.0.0", "-replace", "github.com/XinFinOrg/XDPoSChain="+filepath.Join(pwd, "..", "..", "..")) // Repo root + replacer.Dir = pkg + if out, err := replacer.CombinedOutput(); err != nil { + t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out) + } + tidier := exec.Command(gocmd, "mod", "tidy") + tidier.Dir = pkg + if out, err := tidier.CombinedOutput(); err != nil { + t.Fatalf("failed to tidy Go module file: %v\n%s", err, out) + } // Test the entire package and report any failures cmd := exec.Command(gocmd, "test", "-v", "-count", "1") cmd.Dir = pkg diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 61951dcd7c00..ad3cb74f9529 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -63,6 +63,30 @@ const tmplSourceGo = ` package {{.Package}} +import ( + "math/big" + "strings" + + ethereum "github.com/XinFinOrg/XDPoSChain" + "github.com/XinFinOrg/XDPoSChain/accounts/abi" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.ErrNotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + {{range $contract := .Contracts}} // {{.Type}}ABI is the input ABI used to generate the binding from. const {{.Type}}ABI = "{{.InputABI}}" diff --git a/internal/build/util.go b/internal/build/util.go index 387c2a7d6f2a..3fcb411c70de 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -20,7 +20,6 @@ import ( "bytes" "flag" "fmt" - "io" "log" "os" "os/exec" @@ -87,28 +86,6 @@ func readGitFile(file string) string { return strings.TrimSpace(string(content)) } -// CopyFile copies a file. -func CopyFile(dst, src string, mode os.FileMode) { - if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil { - log.Fatal(err) - } - destFile, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode) - if err != nil { - log.Fatal(err) - } - defer destFile.Close() - - srcFile, err := os.Open(src) - if err != nil { - log.Fatal(err) - } - defer srcFile.Close() - - if _, err := io.Copy(destFile, srcFile); err != nil { - log.Fatal(err) - } -} - // GoTool returns the command that runs a go tool. This uses go from GOROOT instead of PATH // so that go commands executed by build use the same version of Go as the 'host' that runs // build code. e.g. From c0f547ca78cbef8b025ad67596373d0974617baf Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 13 Dec 2024 10:27:25 +0800 Subject: [PATCH 029/121] cmd/utils: fix bug when checking for flag value conflicts (#17803) --- cmd/utils/flags.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 18ce92a23fc8..d244803b84d3 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1318,11 +1318,14 @@ func checkExclusive(ctx *cli.Context, args ...interface{}) { if i+1 < len(args) { switch option := args[i+1].(type) { case string: - // Extended flag, expand the name and shift the arguments + // Extended flag check, make sure value set doesn't conflict with passed in option if ctx.String(flag.Names()[0]) == option { name += "=" + option + set = append(set, "--"+name) } + // shift arguments and continue i++ + continue case cli.Flag: default: From e58441b317e67547f49bfdcf578cf786aec14fd7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 12 Dec 2024 16:00:43 +0800 Subject: [PATCH 030/121] accounts/abi: change unpacking of abi fields w/ underscores (#16513) --- accounts/abi/argument.go | 19 +++++++-------- accounts/abi/bind/bind.go | 42 ++++----------------------------- accounts/abi/reflect.go | 2 +- accounts/abi/unpack_test.go | 47 +++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 49 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 5ff473f62493..2b3a8bb00cf5 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -278,21 +278,20 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { return ret, nil } -// capitalise makes the first character of a string upper case, also removing any -// prefixing underscores from the variable names. -func capitalise(input string) string { - for len(input) > 0 && input[0] == '_' { - input = input[1:] - } - if len(input) == 0 { - return "" +// ToCamelCase converts an under-score string to a camel-case string +func ToCamelCase(input string) string { + parts := strings.Split(input, "_") + for i, s := range parts { + if len(s) > 0 { + parts[i] = strings.ToUpper(s[:1]) + s[1:] + } } - return strings.ToUpper(input[:1]) + input[1:] + return strings.Join(parts, "") } // unpackStruct extracts each argument into its corresponding struct field func unpackStruct(value, reflectValue reflect.Value, arg Argument) error { - name := capitalise(arg.Name) + name := ToCamelCase(arg.Name) typ := value.Type() for j := 0; j < typ.NumField(); j++ { // TODO read tags: `abi:"fieldName"` diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 0c4ba0a81e44..e2a5110af5a0 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -327,48 +327,14 @@ var methodNormalizer = map[Lang]func(string) string{ // capitalise makes a camel-case string which starts with an upper case character. func capitalise(input string) string { - for len(input) > 0 && input[0] == '_' { - input = input[1:] - } - if len(input) == 0 { - return "" - } - return toCamelCase(strings.ToUpper(input[:1]) + input[1:]) + return abi.ToCamelCase(input) } // decapitalise makes a camel-case string which starts with a lower case character. func decapitalise(input string) string { - for len(input) > 0 && input[0] == '_' { - input = input[1:] - } - if len(input) == 0 { - return "" - } - return toCamelCase(strings.ToLower(input[:1]) + input[1:]) -} - -// toCamelCase converts an under-score string to a camel-case string -func toCamelCase(input string) string { - toupper := false - - result := "" - for k, v := range input { - switch { - case k == 0: - result = strings.ToUpper(string(input[0])) - - case toupper: - result += strings.ToUpper(string(v)) - toupper = false - - case v == '_': - toupper = true - - default: - result += string(v) - } - } - return result + // NOTE: This is the current behavior, it doesn't match the comment + // above and needs to be investigated. + return abi.ToCamelCase(input) } // structured checks whether a list of ABI data types has enough information to diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index c1d411ac9560..b2755adf65fb 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -116,7 +116,7 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, func requireUniqueStructFieldNames(args Arguments) error { exists := make(map[string]bool) for _, arg := range args { - field := capitalise(arg.Name) + field := ToCamelCase(arg.Name) if field == "" { return errors.New("abi: purely underscored output cannot unpack to struct") } diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index a6a16d3f700c..5e39d0d0fbcd 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -273,6 +273,53 @@ var unpackTests = []unpackTest{ Int2 *big.Int }{big.NewInt(1), big.NewInt(2)}, }, + { + def: `[{"name":"int_one","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int__one","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int_one_","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int_one","type":"int256"}, {"name":"intone","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + Intone *big.Int + }{big.NewInt(1), big.NewInt(2)}, + }, + { + def: `[{"name":"___","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + Intone *big.Int + }{}, + err: "abi: purely underscored output cannot unpack to struct", + }, + { + def: `[{"name":"int_one","type":"int256"},{"name":"IntOne","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + Int1 *big.Int + Int2 *big.Int + }{}, + err: "abi: multiple outputs mapping to the same struct field 'IntOne'", + }, { def: `[{"name":"int","type":"int256"},{"name":"Int","type":"int256"}]`, enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", From 75c14d2cdb7cbb56e5a8eb6b9ea5665fadca6416 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 12 Dec 2024 16:14:00 +0800 Subject: [PATCH 031/121] accounts/abi: fix case of generated java functions (#18372) --- accounts/abi/bind/bind.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index e2a5110af5a0..b0fd35373fcc 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -322,7 +322,7 @@ var namedType = map[Lang]func(string, abi.Type) string{ // methodNormalizer is a name transformer that modifies Solidity method names to // conform to target language naming concentions. var methodNormalizer = map[Lang]func(string) string{ - LangGo: capitalise, + LangGo: abi.ToCamelCase, } // capitalise makes a camel-case string which starts with an upper case character. @@ -332,9 +332,12 @@ func capitalise(input string) string { // decapitalise makes a camel-case string which starts with a lower case character. func decapitalise(input string) string { - // NOTE: This is the current behavior, it doesn't match the comment - // above and needs to be investigated. - return abi.ToCamelCase(input) + if len(input) == 0 { + return input + } + + goForm := abi.ToCamelCase(input) + return strings.ToLower(goForm[:1]) + goForm[1:] } // structured checks whether a list of ABI data types has enough information to From 2772e096b48d18fcdd47b0bd16f9d692b06c291b Mon Sep 17 00:00:00 2001 From: Javier Sagredo Date: Sun, 3 Feb 2019 12:41:38 +0100 Subject: [PATCH 032/121] common/compiler: fixed testSource (#18978) --- common/compiler/solidity_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/compiler/solidity_test.go b/common/compiler/solidity_test.go index 20573d73ca34..0f6f0f7ce70f 100644 --- a/common/compiler/solidity_test.go +++ b/common/compiler/solidity_test.go @@ -23,9 +23,10 @@ import ( const ( testSource = ` +pragma solidity >0.0.0; contract test { /// @notice Will multiply ` + "`a`" + ` by 7. - function multiply(uint a) returns(uint d) { + function multiply(uint a) public returns(uint d) { return a * 7; } } From f19422e1c7a7f5b74e60f9211c70cb70a69d2076 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 11 Dec 2024 17:53:29 +0800 Subject: [PATCH 033/121] cmd/utils: relinquish GC cache to read cache in archive mode (#18991) --- cmd/utils/flags.go | 2 +- common/size.go | 16 ++++++++-------- common/size_test.go | 4 ++-- core/blockchain.go | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d244803b84d3..9c25f50df4c0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -298,7 +298,7 @@ var ( CacheGCFlag = &cli.IntFlag{ Name: "cache-gc", Aliases: []string{"cache.gc"}, - Usage: "Percentage of cache memory allowance to use for trie pruning", + Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", Value: 25, Category: flags.PerfCategory, } diff --git a/common/size.go b/common/size.go index bd0fc85c7dcc..6381499a4871 100644 --- a/common/size.go +++ b/common/size.go @@ -26,10 +26,10 @@ type StorageSize float64 // String implements the stringer interface. func (s StorageSize) String() string { - if s > 1000000 { - return fmt.Sprintf("%.2f mB", s/1000000) - } else if s > 1000 { - return fmt.Sprintf("%.2f kB", s/1000) + if s > 1048576 { + return fmt.Sprintf("%.2f MiB", s/1048576) + } else if s > 1024 { + return fmt.Sprintf("%.2f KiB", s/1024) } else { return fmt.Sprintf("%.2f B", s) } @@ -38,10 +38,10 @@ func (s StorageSize) String() string { // TerminalString implements log.TerminalStringer, formatting a string for console // output during logging. func (s StorageSize) TerminalString() string { - if s > 1000000 { - return fmt.Sprintf("%.2fmB", s/1000000) - } else if s > 1000 { - return fmt.Sprintf("%.2fkB", s/1000) + if s > 1048576 { + return fmt.Sprintf("%.2fMiB", s/1048576) + } else if s > 1024 { + return fmt.Sprintf("%.2fKiB", s/1024) } else { return fmt.Sprintf("%.2fB", s) } diff --git a/common/size_test.go b/common/size_test.go index f5b6c725e237..0938d483c4bb 100644 --- a/common/size_test.go +++ b/common/size_test.go @@ -25,8 +25,8 @@ func TestStorageSizeString(t *testing.T) { size StorageSize str string }{ - {2381273, "2.38 mB"}, - {2192, "2.19 kB"}, + {2381273, "2.27 MiB"}, + {2192, "2.14 KiB"}, {12, "12.00 B"}, } diff --git a/core/blockchain.go b/core/blockchain.go index 6c75b759aa9a..3c74fc6f8e84 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2123,7 +2123,7 @@ const statsReportLimit = 8 * time.Second // report prints statistics if some number of blocks have been processed // or more than a few seconds have passed since the last message. -func (st *insertStats) report(chain []*types.Block, index int, cache common.StorageSize) { +func (st *insertStats) report(chain []*types.Block, index int, dirty common.StorageSize) { // Fetch the timings for the batch var ( now = mclock.Now() @@ -2138,7 +2138,7 @@ func (st *insertStats) report(chain []*types.Block, index int, cache common.Stor context := []interface{}{ "blocks", st.processed, "txs", txs, "mgas", float64(st.usedGas) / 1000000, "elapsed", common.PrettyDuration(elapsed), "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), - "number", end.Number(), "hash", end.Hash(), "cache", cache, + "number", end.Number(), "hash", end.Hash(), "dirty", dirty, } if st.queued > 0 { context = append(context, []interface{}{"queued", st.queued}...) From cd1ff5d3227fea17c492d267c921e530a43c3076 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 11 Dec 2024 18:46:00 +0800 Subject: [PATCH 034/121] common: remove function Big() for type Address (#19210) --- common/types.go | 3 --- common/types_test.go | 4 ++-- core/mkalloc.go | 12 ++++++------ 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/common/types.go b/common/types.go index a33fe35bcc34..e2dd3b4b2db6 100644 --- a/common/types.go +++ b/common/types.go @@ -227,9 +227,6 @@ func (a Address) Str() string { return string(a[:]) } // Bytes gets the string representation of the underlying address. func (a Address) Bytes() []byte { return a[:] } -// Big converts an address to a big integer. -func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) } - // Hash converts an address to a hash by left-padding it with zeros. func (a Address) Hash() Hash { return BytesToHash(a[:]) } diff --git a/common/types_test.go b/common/types_test.go index 7c2822854ab8..ea0fb22d2480 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -118,8 +118,8 @@ func TestAddressUnmarshalJSON(t *testing.T) { if test.ShouldErr { t.Errorf("test #%d: expected error, got none", i) } - if v.Big().Cmp(test.Output) != 0 { - t.Errorf("test #%d: address mismatch: have %v, want %v", i, v.Big(), test.Output) + if got := new(big.Int).SetBytes(v.Bytes()); got.Cmp(test.Output) != 0 { + t.Errorf("test #%d: address mismatch: have %v, want %v", i, got, test.Output) } } } diff --git a/core/mkalloc.go b/core/mkalloc.go index 6bc4e55d890a..6c8a5d0ee5e4 100644 --- a/core/mkalloc.go +++ b/core/mkalloc.go @@ -14,15 +14,14 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build none // +build none /* +The mkalloc tool creates the genesis allocation constants in genesis_alloc.go +It outputs a const declaration that contains an RLP-encoded list of (address, balance) tuples. - The mkalloc tool creates the genesis allocation constants in genesis_alloc.go - It outputs a const declaration that contains an RLP-encoded list of (address, balance) tuples. - - go run mkalloc.go genesis.json - + go run mkalloc.go genesis.json */ package main @@ -52,7 +51,8 @@ func makelist(g *core.Genesis) allocList { if len(account.Storage) > 0 || len(account.Code) > 0 || account.Nonce != 0 { panic(fmt.Sprintf("can't encode account %x", addr)) } - a = append(a, allocItem{addr.Big(), account.Balance}) + bigAddr := new(big.Int).SetBytes(addr.Bytes()) + a = append(a, allocItem{bigAddr, account.Balance}) } sort.Sort(a) return a From 66921899e9ed2a32bd018d3fc225fb51b249e690 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 12 Dec 2024 11:36:58 +0800 Subject: [PATCH 035/121] cmd/abigen: support Vyper (#19120) --- cmd/abigen/main.go | 77 ++++++++++++++--- common/compiler/helpers.go | 64 ++++++++++++++ common/compiler/solidity.go | 70 ++++++--------- common/compiler/solidity_test.go | 6 +- common/compiler/test.v.py | 3 + common/compiler/test_bad.v.py | 3 + common/compiler/vyper.go | 144 +++++++++++++++++++++++++++++++ common/compiler/vyper_test.go | 71 +++++++++++++++ 8 files changed, 381 insertions(+), 57 deletions(-) create mode 100644 common/compiler/helpers.go create mode 100644 common/compiler/test.v.py create mode 100644 common/compiler/test_bad.v.py create mode 100644 common/compiler/vyper.go create mode 100644 common/compiler/vyper_test.go diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 9a19efe96fca..46a9f987194b 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -19,6 +19,7 @@ package main import ( "encoding/json" "fmt" + "io" "os" "strings" @@ -59,6 +60,15 @@ var ( Usage: "Solidity compiler to use if source builds are requested", Value: "solc", } + vyFlag = &cli.StringFlag{ + Name: "vy", + Usage: "Path to the Ethereum contract Vyper source to build and bind", + } + vyperFlag = &cli.StringFlag{ + Name: "vyper", + Usage: "Vyper compiler to use if source builds are requested", + Value: "vyper", + } excFlag = &cli.StringFlag{ Name: "exc", Usage: "Comma separated types to exclude from binding", @@ -87,6 +97,8 @@ func init() { typeFlag, solFlag, solcFlag, + vyFlag, + vyperFlag, excFlag, pkgFlag, outFlag, @@ -96,11 +108,14 @@ func init() { } func abigen(c *cli.Context) error { - if c.String(abiFlag.Name) == "" && c.String(solFlag.Name) == "" { - fmt.Printf("No contract ABI (--abi) or Solidity source (--sol) specified\n") + if c.String(abiFlag.Name) == "" && c.String(solFlag.Name) == "" && c.String(vyFlag.Name) == "" { + fmt.Printf("No contract ABI (--abi), Solidity source (--sol), or Vyper source (--vy) specified\n") + os.Exit(-1) + } else if (c.String(abiFlag.Name) != "" || c.String(binFlag.Name) != "" || c.String(typeFlag.Name) != "") && (c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "") { + fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity (--sol) and Vyper (--vy) flags\n") os.Exit(-1) - } else if (c.String(abiFlag.Name) != "" || c.String(binFlag.Name) != "" || c.String(typeFlag.Name) != "") && c.String(solFlag.Name) != "" { - fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag\n") + } else if c.String(solFlag.Name) != "" && c.String(vyFlag.Name) == "" { + fmt.Printf("Solidity (--sol) and Vyper (--vy) flags are mutually exclusive\n") os.Exit(-1) } if c.String(pkgFlag.Name) == "" { @@ -121,23 +136,47 @@ func abigen(c *cli.Context) error { bins []string types []string ) - if c.String(solFlag.Name) != "" { + if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || (c.String(abiFlag.Name) == "-" && c.String(pkgFlag.Name) == "") { // Generate the list of types to exclude from binding exclude := make(map[string]bool) for _, kind := range strings.Split(c.String(excFlag.Name), ",") { exclude[strings.ToLower(kind)] = true } - contracts, err := compiler.CompileSolidity(c.String(solcFlag.Name), c.String(solFlag.Name)) - if err != nil { - fmt.Printf("Failed to build Solidity contract: %v\n", err) - os.Exit(-1) + + var contracts map[string]*compiler.Contract + var err error + + switch { + case c.String(solFlag.Name) != "": + contracts, err = compiler.CompileSolidity(c.String(solcFlag.Name), c.String(solFlag.Name)) + if err != nil { + fmt.Printf("Failed to build Solidity contract: %v\n", err) + os.Exit(-1) + } + case c.String(vyFlag.Name) != "": + contracts, err = compiler.CompileVyper(c.String(vyperFlag.Name), c.String(vyFlag.Name)) + if err != nil { + fmt.Printf("Failed to build Vyper contract: %v\n", err) + os.Exit(-1) + } + default: + contracts, err = contractsFromStdin() + if err != nil { + fmt.Printf("Failed to read input ABIs from STDIN: %v\n", err) + os.Exit(-1) + } } + // Gather all non-excluded contract for binding for name, contract := range contracts { if exclude[strings.ToLower(name)] { continue } - abi, _ := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse + abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse + if err != nil { + fmt.Printf("Failed to parse ABIs from compiler output: %v\n", err) + os.Exit(-1) + } abis = append(abis, string(abi)) bins = append(bins, contract.Code) @@ -146,14 +185,20 @@ func abigen(c *cli.Context) error { } } else { // Otherwise load up the ABI, optional bytecode and type name from the parameters - abi, err := os.ReadFile(c.String(abiFlag.Name)) + var abi []byte + var err error + if c.String(abiFlag.Name) == "-" { + abi, err = io.ReadAll(os.Stdin) + } else { + abi, err = os.ReadFile(c.String(abiFlag.Name)) + } if err != nil { fmt.Printf("Failed to read input ABI: %v\n", err) os.Exit(-1) } abis = append(abis, string(abi)) - bin := []byte{} + var bin []byte if c.String(binFlag.Name) != "" { if bin, err = os.ReadFile(c.String(binFlag.Name)); err != nil { fmt.Printf("Failed to read input bytecode: %v\n", err) @@ -194,3 +239,11 @@ func main() { os.Exit(1) } } + +func contractsFromStdin() (map[string]*compiler.Contract, error) { + bytes, err := io.ReadAll(os.Stdin) + if err != nil { + return nil, err + } + return compiler.ParseCombinedJSON(bytes, "", "", "", "") +} diff --git a/common/compiler/helpers.go b/common/compiler/helpers.go new file mode 100644 index 000000000000..c2d4a20e3649 --- /dev/null +++ b/common/compiler/helpers.go @@ -0,0 +1,64 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). +package compiler + +import ( + "bytes" + "os" + "regexp" +) + +var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`) + +// Contract contains information about a compiled contract, alongside its code and runtime code. +type Contract struct { + Code string `json:"code"` + RuntimeCode string `json:"runtime-code"` + Info ContractInfo `json:"info"` +} + +// ContractInfo contains information about a compiled contract, including access +// to the ABI definition, source mapping, user and developer docs, and metadata. +// +// Depending on the source, language version, compiler version, and compiler +// options will provide information about how the contract was compiled. +type ContractInfo struct { + Source string `json:"source"` + Language string `json:"language"` + LanguageVersion string `json:"languageVersion"` + CompilerVersion string `json:"compilerVersion"` + CompilerOptions string `json:"compilerOptions"` + SrcMap interface{} `json:"srcMap"` + SrcMapRuntime string `json:"srcMapRuntime"` + AbiDefinition interface{} `json:"abiDefinition"` + UserDoc interface{} `json:"userDoc"` + DeveloperDoc interface{} `json:"developerDoc"` + Metadata string `json:"metadata"` +} + +func slurpFiles(files []string) (string, error) { + var concat bytes.Buffer + for _, file := range files { + content, err := os.ReadFile(file) + if err != nil { + return "", err + } + concat.Write(content) + } + return concat.String(), nil +} diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index f34020123982..7ed9c2633e53 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -1,4 +1,4 @@ -// Copyright 2015 The go-ethereum Authors +// Copyright 2019 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package compiler wraps the Solidity compiler executable (solc). +// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). package compiler import ( @@ -22,32 +22,11 @@ import ( "encoding/json" "errors" "fmt" - "os" "os/exec" - "regexp" "strconv" "strings" ) -var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`) - -type Contract struct { - Code string `json:"code"` - Info ContractInfo `json:"info"` -} - -type ContractInfo struct { - Source string `json:"source"` - Language string `json:"language"` - LanguageVersion string `json:"languageVersion"` - CompilerVersion string `json:"compilerVersion"` - CompilerOptions string `json:"compilerOptions"` - AbiDefinition interface{} `json:"abiDefinition"` - UserDoc interface{} `json:"userDoc"` - DeveloperDoc interface{} `json:"developerDoc"` - Metadata string `json:"metadata"` -} - // Solidity contains information about the solidity compiler. type Solidity struct { Path, Version, FullVersion string @@ -57,14 +36,16 @@ type Solidity struct { // --combined-output format type solcOutput struct { Contracts map[string]struct { - Bin, Abi, Devdoc, Userdoc, Metadata string + BinRuntime string `json:"bin-runtime"` + SrcMapRuntime string `json:"srcmap-runtime"` + Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string } Version string } func (s *Solidity) makeArgs() []string { p := []string{ - "--combined-json", "bin,abi,userdoc,devdoc", + "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc", "--optimize", // code optimizer switched on } if s.Major > 0 || s.Minor > 4 || s.Patch > 6 { @@ -142,8 +123,22 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro if err := cmd.Run(); err != nil { return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes()) } + + return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) +} + +// ParseCombinedJSON takes the direct output of a solc --combined-output run and +// parses it into a map of string contract name to Contract structs. The +// provided source, language and compiler version, and compiler options are all +// passed through into the Contract structs. +// +// The solc output is expected to contain ABI, source mapping, user docs, and dev docs. +// +// Returns an error if the JSON is malformed or missing data, or if the JSON +// embedded within the JSON is malformed. +func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { var output solcOutput - if err := json.Unmarshal(stdout.Bytes(), &output); err != nil { + if err := json.Unmarshal(combinedJSON, &output); err != nil { return nil, err } @@ -164,13 +159,16 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro return nil, fmt.Errorf("solc: error reading dev doc: %v", err) } contracts[name] = &Contract{ - Code: "0x" + info.Bin, + Code: "0x" + info.Bin, + RuntimeCode: "0x" + info.BinRuntime, Info: ContractInfo{ Source: source, Language: "Solidity", - LanguageVersion: s.Version, - CompilerVersion: s.Version, - CompilerOptions: strings.Join(s.makeArgs(), " "), + LanguageVersion: languageVersion, + CompilerVersion: compilerVersion, + CompilerOptions: compilerOptions, + SrcMap: info.SrcMap, + SrcMapRuntime: info.SrcMapRuntime, AbiDefinition: abi, UserDoc: userdoc, DeveloperDoc: devdoc, @@ -180,15 +178,3 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro } return contracts, nil } - -func slurpFiles(files []string) (string, error) { - var concat bytes.Buffer - for _, file := range files { - content, err := os.ReadFile(file) - if err != nil { - return "", err - } - concat.Write(content) - } - return concat.String(), nil -} diff --git a/common/compiler/solidity_test.go b/common/compiler/solidity_test.go index 0f6f0f7ce70f..bd68eaee31a2 100644 --- a/common/compiler/solidity_test.go +++ b/common/compiler/solidity_test.go @@ -1,4 +1,4 @@ -// Copyright 2015 The go-ethereum Authors +// Copyright 2019 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -39,7 +39,7 @@ func skipWithoutSolc(t *testing.T) { } } -func TestCompiler(t *testing.T) { +func TestSolidityCompiler(t *testing.T) { t.SkipNow() skipWithoutSolc(t) @@ -68,7 +68,7 @@ func TestCompiler(t *testing.T) { } } -func TestCompileError(t *testing.T) { +func TestSolidityCompileError(t *testing.T) { skipWithoutSolc(t) contracts, err := CompileSolidityString("", testSource[4:]) diff --git a/common/compiler/test.v.py b/common/compiler/test.v.py new file mode 100644 index 000000000000..35af56c8f6ef --- /dev/null +++ b/common/compiler/test.v.py @@ -0,0 +1,3 @@ +@public +def test(): + hello: int128 diff --git a/common/compiler/test_bad.v.py b/common/compiler/test_bad.v.py new file mode 100644 index 000000000000..443ef7826325 --- /dev/null +++ b/common/compiler/test_bad.v.py @@ -0,0 +1,3 @@ +lic +def test(): + hello: int128 diff --git a/common/compiler/vyper.go b/common/compiler/vyper.go new file mode 100644 index 000000000000..a9bca95e5901 --- /dev/null +++ b/common/compiler/vyper.go @@ -0,0 +1,144 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). +package compiler + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "os/exec" + "strconv" + "strings" +) + +// Vyper contains information about the vyper compiler. +type Vyper struct { + Path, Version, FullVersion string + Major, Minor, Patch int +} + +func (s *Vyper) makeArgs() []string { + p := []string{ + "-f", "combined_json", + } + return p +} + +// VyperVersion runs vyper and parses its version output. +func VyperVersion(vyper string) (*Vyper, error) { + if vyper == "" { + vyper = "vyper" + } + var out bytes.Buffer + cmd := exec.Command(vyper, "--version") + cmd.Stdout = &out + err := cmd.Run() + if err != nil { + return nil, err + } + matches := versionRegexp.FindStringSubmatch(out.String()) + if len(matches) != 4 { + return nil, fmt.Errorf("can't parse vyper version %q", out.String()) + } + s := &Vyper{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]} + if s.Major, err = strconv.Atoi(matches[1]); err != nil { + return nil, err + } + if s.Minor, err = strconv.Atoi(matches[2]); err != nil { + return nil, err + } + if s.Patch, err = strconv.Atoi(matches[3]); err != nil { + return nil, err + } + return s, nil +} + +// CompileVyper compiles all given Vyper source files. +func CompileVyper(vyper string, sourcefiles ...string) (map[string]*Contract, error) { + if len(sourcefiles) == 0 { + return nil, errors.New("vyper: no source files") + } + source, err := slurpFiles(sourcefiles) + if err != nil { + return nil, err + } + s, err := VyperVersion(vyper) + if err != nil { + return nil, err + } + args := s.makeArgs() + cmd := exec.Command(s.Path, append(args, sourcefiles...)...) + return s.run(cmd, source) +} + +func (s *Vyper) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) { + var stderr, stdout bytes.Buffer + cmd.Stderr = &stderr + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("vyper: %v\n%s", err, stderr.Bytes()) + } + + return ParseVyperJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) +} + +// ParseVyperJSON takes the direct output of a vyper --f combined_json run and +// parses it into a map of string contract name to Contract structs. The +// provided source, language and compiler version, and compiler options are all +// passed through into the Contract structs. +// +// The vyper output is expected to contain ABI and source mapping. +// +// Returns an error if the JSON is malformed or missing data, or if the JSON +// embedded within the JSON is malformed. +func ParseVyperJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { + var output map[string]interface{} + if err := json.Unmarshal(combinedJSON, &output); err != nil { + return nil, err + } + + // Compilation succeeded, assemble and return the contracts. + contracts := make(map[string]*Contract) + for name, info := range output { + // Parse the individual compilation results. + if name == "version" { + continue + } + c := info.(map[string]interface{}) + + contracts[name] = &Contract{ + Code: c["bytecode"].(string), + RuntimeCode: c["bytecode_runtime"].(string), + Info: ContractInfo{ + Source: source, + Language: "Vyper", + LanguageVersion: languageVersion, + CompilerVersion: compilerVersion, + CompilerOptions: compilerOptions, + SrcMap: c["source_map"], + SrcMapRuntime: "", + AbiDefinition: c["abi"], + UserDoc: "", + DeveloperDoc: "", + Metadata: "", + }, + } + } + return contracts, nil +} diff --git a/common/compiler/vyper_test.go b/common/compiler/vyper_test.go new file mode 100644 index 000000000000..7761c92affc5 --- /dev/null +++ b/common/compiler/vyper_test.go @@ -0,0 +1,71 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package compiler + +import ( + "os/exec" + "testing" +) + +func skipWithoutVyper(t *testing.T) { + if _, err := exec.LookPath("vyper"); err != nil { + t.Skip(err) + } +} + +func TestVyperCompiler(t *testing.T) { + skipWithoutVyper(t) + + testSource := []string{"test.v.py"} + source, err := slurpFiles(testSource) + if err != nil { + t.Error("couldn't read test files") + } + contracts, err := CompileVyper("", testSource...) + if err != nil { + t.Fatalf("error compiling test.v.py. result %v: %v", contracts, err) + } + if len(contracts) != 1 { + t.Errorf("one contract expected, got %d", len(contracts)) + } + c, ok := contracts["test.v.py"] + if !ok { + c, ok = contracts[":test"] + if !ok { + t.Fatal("info for contract 'test.v.py' not present in result") + } + } + if c.Code == "" { + t.Error("empty code") + } + if c.Info.Source != source { + t.Error("wrong source") + } + if c.Info.CompilerVersion == "" { + t.Error("empty version") + } +} + +func TestVyperCompileError(t *testing.T) { + skipWithoutVyper(t) + + contracts, err := CompileVyper("", "test_bad.v.py") + if err == nil { + t.Errorf("error expected compiling test_bad.v.py. got none. result %v", contracts) + } + t.Logf("error: %v", err) +} From a747a9861d8c16db7cfb002924d795b1a11e078a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 12 Dec 2024 12:25:28 +0800 Subject: [PATCH 036/121] common: improve functions of StorageSize (#19244) --- common/size.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/common/size.go b/common/size.go index 6381499a4871..097b6304a8d0 100644 --- a/common/size.go +++ b/common/size.go @@ -26,7 +26,11 @@ type StorageSize float64 // String implements the stringer interface. func (s StorageSize) String() string { - if s > 1048576 { + if s > 1099511627776 { + return fmt.Sprintf("%.2f TiB", s/1099511627776) + } else if s > 1073741824 { + return fmt.Sprintf("%.2f GiB", s/1073741824) + } else if s > 1048576 { return fmt.Sprintf("%.2f MiB", s/1048576) } else if s > 1024 { return fmt.Sprintf("%.2f KiB", s/1024) @@ -38,7 +42,11 @@ func (s StorageSize) String() string { // TerminalString implements log.TerminalStringer, formatting a string for console // output during logging. func (s StorageSize) TerminalString() string { - if s > 1048576 { + if s > 1099511627776 { + return fmt.Sprintf("%.2fTiB", s/1099511627776) + } else if s > 1073741824 { + return fmt.Sprintf("%.2fGiB", s/1073741824) + } else if s > 1048576 { return fmt.Sprintf("%.2fMiB", s/1048576) } else if s > 1024 { return fmt.Sprintf("%.2fKiB", s/1024) From b711dc811da60c01d234e05141ca0ec3ec462a12 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 13 Dec 2024 16:31:41 +0800 Subject: [PATCH 037/121] cmd/abigen: allow using abigen --pkg flag with standard input (#19207) --- cmd/abigen/main.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 46a9f987194b..7a696fce418b 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -136,7 +136,7 @@ func abigen(c *cli.Context) error { bins []string types []string ) - if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || (c.String(abiFlag.Name) == "-" && c.String(pkgFlag.Name) == "") { + if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || c.String(abiFlag.Name) == "-" { // Generate the list of types to exclude from binding exclude := make(map[string]bool) for _, kind := range strings.Split(c.String(excFlag.Name), ",") { @@ -185,13 +185,8 @@ func abigen(c *cli.Context) error { } } else { // Otherwise load up the ABI, optional bytecode and type name from the parameters - var abi []byte - var err error - if c.String(abiFlag.Name) == "-" { - abi, err = io.ReadAll(os.Stdin) - } else { - abi, err = os.ReadFile(c.String(abiFlag.Name)) - } + abi, err := os.ReadFile(c.String(abiFlag.Name)) + if err != nil { fmt.Printf("Failed to read input ABI: %v\n", err) os.Exit(-1) From 91570dce8abe5ee960c8169494de5fe07f177366 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 12 Dec 2024 16:28:30 +0800 Subject: [PATCH 038/121] accounts/abi: fix mobile interface (#19180) --- accounts/abi/bind/bind.go | 154 +++++++-------------------------- accounts/abi/bind/bind_test.go | 2 +- 2 files changed, 30 insertions(+), 126 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index b0fd35373fcc..ca9e3e8b52b7 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -161,139 +161,43 @@ var bindType = map[Lang]func(kind abi.Type) string{ LangGo: bindTypeGo, } -// Helper function for the binding generators. -// It reads the unmatched characters after the inner type-match, -// -// (since the inner type is a prefix of the total type declaration), -// looks for valid arrays (possibly a dynamic one) wrapping the inner type, -// and returns the sizes of these arrays. -// -// Returned array sizes are in the same order as solidity signatures; inner array size first. -// Array sizes may also be "", indicating a dynamic array. -func wrapArray(stringKind string, innerLen int, innerMapping string) (string, []string) { - remainder := stringKind[innerLen:] - //find all the sizes - matches := regexp.MustCompile(`\[(\d*)\]`).FindAllStringSubmatch(remainder, -1) - parts := make([]string, 0, len(matches)) - for _, match := range matches { - //get group 1 from the regex match - parts = append(parts, match[1]) - } - return innerMapping, parts -} - -// Translates the array sizes to a Go-lang declaration of a (nested) array of the inner type. -// Simply returns the inner type if arraySizes is empty. -func arrayBindingGo(inner string, arraySizes []string) string { - out := "" - //prepend all array sizes, from outer (end arraySizes) to inner (start arraySizes) - for i := len(arraySizes) - 1; i >= 0; i-- { - out += "[" + arraySizes[i] + "]" - } - out += inner - return out -} - -// bindTypeGo converts a Solidity type to a Go one. Since there is no clear mapping -// from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly -// mapped will use an upscaled type (e.g. *big.Int). -func bindTypeGo(kind abi.Type) string { - stringKind := kind.String() - innerLen, innerMapping := bindUnnestedTypeGo(stringKind) - return arrayBindingGo(wrapArray(stringKind, innerLen, innerMapping)) -} - -// The inner function of bindTypeGo, this finds the inner type of stringKind. -// (Or just the type itself if it is not an array or slice) -// The length of the matched part is returned, with the the translated type. -func bindUnnestedTypeGo(stringKind string) (int, string) { - - switch { - case strings.HasPrefix(stringKind, "address"): - return len("address"), "common.Address" - - case strings.HasPrefix(stringKind, "bytes"): - parts := regexp.MustCompile(`bytes([0-9]*)`).FindStringSubmatch(stringKind) - return len(parts[0]), fmt.Sprintf("[%s]byte", parts[1]) - - case strings.HasPrefix(stringKind, "int") || strings.HasPrefix(stringKind, "uint"): - parts := regexp.MustCompile(`(u)?int([0-9]*)`).FindStringSubmatch(stringKind) +// bindBasicTypeGo converts basic solidity types(except array, slice and tuple) to Go one. +func bindBasicTypeGo(kind abi.Type) string { + switch kind.T { + case abi.AddressTy: + return "common.Address" + case abi.IntTy, abi.UintTy: + parts := regexp.MustCompile(`(u)?int([0-9]*)`).FindStringSubmatch(kind.String()) switch parts[2] { case "8", "16", "32", "64": - return len(parts[0]), fmt.Sprintf("%sint%s", parts[1], parts[2]) + return fmt.Sprintf("%sint%s", parts[1], parts[2]) } - return len(parts[0]), "*big.Int" - - case strings.HasPrefix(stringKind, "bool"): - return len("bool"), "bool" - - case strings.HasPrefix(stringKind, "string"): - return len("string"), "string" - + return "*big.Int" + case abi.FixedBytesTy: + return fmt.Sprintf("[%d]byte", kind.Size) + case abi.BytesTy: + return "[]byte" + case abi.FunctionTy: + // todo(rjl493456442) + return "" default: - return len(stringKind), stringKind + // string, bool types + return kind.String() } } -// Translates the array sizes to a Java declaration of a (nested) array of the inner type. -// Simply returns the inner type if arraySizes is empty. -func arrayBindingJava(inner string, arraySizes []string) string { - // Java array type declarations do not include the length. - return inner + strings.Repeat("[]", len(arraySizes)) -} - -// The inner function of bindTypeJava, this finds the inner type of stringKind. -// (Or just the type itself if it is not an array or slice) -// The length of the matched part is returned, with the the translated type. -func bindUnnestedTypeJava(stringKind string) (int, string) { - - switch { - case strings.HasPrefix(stringKind, "address"): - parts := regexp.MustCompile(`address(\[[0-9]*\])?`).FindStringSubmatch(stringKind) - if len(parts) != 2 { - return len(stringKind), stringKind - } - if parts[1] == "" { - return len("address"), "Address" - } - return len(parts[0]), "Addresses" - - case strings.HasPrefix(stringKind, "bytes"): - parts := regexp.MustCompile(`bytes([0-9]*)`).FindStringSubmatch(stringKind) - if len(parts) != 2 { - return len(stringKind), stringKind - } - return len(parts[0]), "byte[]" - - case strings.HasPrefix(stringKind, "int") || strings.HasPrefix(stringKind, "uint"): - //Note that uint and int (without digits) are also matched, - // these are size 256, and will translate to BigInt (the default). - parts := regexp.MustCompile(`(u)?int([0-9]*)`).FindStringSubmatch(stringKind) - if len(parts) != 3 { - return len(stringKind), stringKind - } - - namedSize := map[string]string{ - "8": "byte", - "16": "short", - "32": "int", - "64": "long", - }[parts[2]] - - //default to BigInt - if namedSize == "" { - namedSize = "BigInt" - } - return len(parts[0]), namedSize - - case strings.HasPrefix(stringKind, "bool"): - return len("bool"), "boolean" - - case strings.HasPrefix(stringKind, "string"): - return len("string"), "String" - +// bindTypeGo converts solidity types to Go ones. Since there is no clear mapping +// from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly +// mapped will use an upscaled type (e.g. BigDecimal). +func bindTypeGo(kind abi.Type) string { + // todo(rjl493456442) tuple + switch kind.T { + case abi.ArrayTy: + return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem) + case abi.SliceTy: + return "[]" + bindTypeGo(*kind.Elem) default: - return len(stringKind), stringKind + return bindBasicTypeGo(kind) } } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 448ffe2b6acc..55116c5a1072 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -936,7 +936,7 @@ var bindTests = []struct { // Tests that packages generated by the binder can be successfully compiled and // the requested tester run against it. -func TestBindings(t *testing.T) { +func TestGolangBindings(t *testing.T) { // Skip the test if no Go command can be found gocmd := runtime.GOROOT() + "/bin/go" if !common.FileExist(gocmd) { From 7455b91800d4f1d209f0690ce7b544a219f3501e Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 12 Dec 2024 17:11:08 +0800 Subject: [PATCH 039/121] accounts/abi/bind: accept function ptr parameter (#19755) --- accounts/abi/bind/bind.go | 8 +++-- accounts/abi/bind/bind_test.go | 61 +++++++++++++++++++++++++++++++++- accounts/abi/bind/template.go | 10 ++++++ cmd/abigen/main.go | 4 ++- common/compiler/helpers.go | 7 ++-- common/compiler/solidity.go | 4 ++- 6 files changed, 85 insertions(+), 9 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index ca9e3e8b52b7..e6312657bd12 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -43,7 +43,7 @@ const ( // to be used as is in client code, but rather as an intermediate struct which // enforces compile time type safety and naming convention opposed to having to // manually maintain hard coded strings that break on runtime. -func Bind(types []string, abis []string, bytecodes []string, pkg string, lang Lang) (string, error) { +func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang) (string, error) { // Process each individual contract requested binding contracts := make(map[string]*tmplContract) @@ -124,6 +124,9 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La Transacts: transacts, Events: events, } + if len(fsigs) > i { + contracts[types[i]].FuncSigs = fsigs[i] + } } // Generate the contract template data content and render it data := &tmplData{ @@ -178,8 +181,7 @@ func bindBasicTypeGo(kind abi.Type) string { case abi.BytesTy: return "[]byte" case abi.FunctionTy: - // todo(rjl493456442) - return "" + return "[24]byte" default: // string, bool types return kind.String() diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 55116c5a1072..8a73fc8b6415 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -36,6 +36,7 @@ var bindTests = []struct { abi string imports string tester string + fsigs []map[string]string }{ // Test that the binding is available in combined and separate forms too { @@ -55,6 +56,7 @@ var bindTests = []struct { t.Fatalf("transactor binding (%v) nil or error (%v) not nil", b, nil) } `, + nil, }, // Test that all the official sample contracts bind correctly { @@ -68,6 +70,7 @@ var bindTests = []struct { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) } `, + nil, }, { `Crowdsale`, @@ -80,6 +83,7 @@ var bindTests = []struct { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) } `, + nil, }, { `DAO`, @@ -92,6 +96,7 @@ var bindTests = []struct { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) } `, + nil, }, // Test that named and anonymous inputs are handled correctly { @@ -125,6 +130,7 @@ var bindTests = []struct { fmt.Println(err) }`, + nil, }, // Test that named and anonymous outputs are handled correctly { @@ -161,6 +167,7 @@ var bindTests = []struct { fmt.Println(str1, str2, res.Str1, res.Str2, err) }`, + nil, }, // Tests that named, anonymous and indexed events are handled correctly { @@ -226,6 +233,7 @@ var bindTests = []struct { if _, ok := reflect.TypeOf(&EventChecker{}).MethodByName("FilterAnonymous"); ok { t.Errorf("binding has disallowed method (FilterAnonymous)") }`, + nil, }, // Test that contract interactions (deploy, transact and call) generate working code { @@ -283,6 +291,7 @@ var bindTests = []struct { t.Fatalf("Transact string mismatch: have '%s', want 'Transact string'", str) } `, + nil, }, // Tests that plain values can be properly returned and deserialized { @@ -324,6 +333,7 @@ var bindTests = []struct { t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", str, num, "Hi", 1) } `, + nil, }, // Tests that tuples can be properly returned and deserialized { @@ -365,6 +375,7 @@ var bindTests = []struct { t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", res.A, res.B, "Hi", 1) } `, + nil, }, // Tests that arrays/slices can be properly returned and deserialized. // Only addresses are tested, remainder just compiled to keep the test small. @@ -418,6 +429,7 @@ var bindTests = []struct { t.Fatalf("Slice return mismatch: have %v, want %v", out, []common.Address{auth.From, common.Address{}}) } `, + nil, }, // Tests that anonymous default methods can be correctly invoked { @@ -464,6 +476,7 @@ var bindTests = []struct { t.Fatalf("Address mismatch: have %v, want %v", caller, auth.From) } `, + nil, }, // Tests that non-existent contracts are reported as such (though only simulator test) { @@ -498,6 +511,7 @@ var bindTests = []struct { t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode) } `, + nil, }, // Tests that gas estimation works for contracts with weird gas mechanics too. { @@ -549,6 +563,7 @@ var bindTests = []struct { t.Fatalf("Field mismatch: have %v, want %v", field, "automatic") } `, + nil, }, // Test that constant functions can be called from an (optional) specified address { @@ -598,6 +613,7 @@ var bindTests = []struct { } } `, + nil, }, // Tests that methods and returns with underscores inside work correctly. { @@ -673,6 +689,7 @@ var bindTests = []struct { fmt.Println(a, b, err) `, + nil, }, // Tests that logs can be successfully filtered and decoded. { @@ -855,6 +872,7 @@ var bindTests = []struct { case <-time.After(250 * time.Millisecond): } `, + nil, }, { `DeeplyNestedArray`, @@ -931,6 +949,47 @@ var bindTests = []struct { t.Fatalf("Retrieved value does not match expected value! got: %d, expected: %d. %v", retrievedArr[4][3][2], testArr[4][3][2], err) } `, + nil, + }, + { + `CallbackParam`, + ` + contract FunctionPointerTest { + function test(function(uint256) external callback) external { + callback(1); + } + } + `, + `608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063d7a5aba214610040575b600080fd5b34801561004c57600080fd5b506100be6004803603602081101561006357600080fd5b810190808035806c0100000000000000000000000090049068010000000000000000900463ffffffff1677ffffffffffffffffffffffffffffffffffffffffffffffff169091602001919093929190939291905050506100c0565b005b818160016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561011657600080fd5b505af115801561012a573d6000803e3d6000fd5b50505050505056fea165627a7a7230582062f87455ff84be90896dbb0c4e4ddb505c600d23089f8e80a512548440d7e2580029`, + `[ + { + "constant": false, + "inputs": [ + { + "name": "callback", + "type": "function" + } + ], + "name": "test", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ]`, + ` + "strings" + `, + ` + if strings.Compare("test(function)", CallbackParamFuncSigs["d7a5aba2"]) != 0 { + t.Fatalf("") + } + `, + []map[string]string{ + { + "test(function)": "d7a5aba2", + }, + }, }, } @@ -957,7 +1016,7 @@ func TestGolangBindings(t *testing.T) { // Generate the test suite for all the contracts for i, tt := range bindTests { // Generate the binding and create a Go source file in the workspace - bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, "bindtest", LangGo) + bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, tt.fsigs, "bindtest", LangGo) if err != nil { t.Fatalf("test %d: failed to generate binding: %v", i, err) } diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index ad3cb74f9529..f65c16bdcd9c 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -29,6 +29,7 @@ type tmplContract struct { Type string // Type name of the main contract binding InputABI string // JSON ABI used as the input to generate the binding from InputBin string // Optional EVM bytecode used to denetare deploy code from + FuncSigs map[string]string // Optional map: string signature -> 4-byte signature Constructor abi.Method // Contract constructor for deploy parametrization Calls map[string]*tmplMethod // Contract calls that only read state data Transacts map[string]*tmplMethod // Contract calls that write state data @@ -91,6 +92,15 @@ var ( // {{.Type}}ABI is the input ABI used to generate the binding from. const {{.Type}}ABI = "{{.InputABI}}" + {{if $contract.FuncSigs}} + // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. + var {{.Type}}FuncSigs = map[string]string{ + {{range $strsig, $binsig := .FuncSigs}} + "{{$binsig}}": "{{$strsig}}", + {{end}} + } + {{end}} + {{if .InputBin}} // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. const {{.Type}}Bin = ` + "`" + `{{.InputBin}}` + "`" + ` diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 7a696fce418b..b6b15335540e 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -135,6 +135,7 @@ func abigen(c *cli.Context) error { abis []string bins []string types []string + sigs []map[string]string ) if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || c.String(abiFlag.Name) == "-" { // Generate the list of types to exclude from binding @@ -179,6 +180,7 @@ func abigen(c *cli.Context) error { } abis = append(abis, string(abi)) bins = append(bins, contract.Code) + sigs = append(sigs, contract.Hashes) nameParts := strings.Split(name, ":") types = append(types, nameParts[len(nameParts)-1]) @@ -209,7 +211,7 @@ func abigen(c *cli.Context) error { types = append(types, kind) } // Generate the contract binding - code, err := bind.Bind(types, abis, bins, c.String(pkgFlag.Name), lang) + code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang) if err != nil { fmt.Printf("Failed to generate ABI binding: %v\n", err) os.Exit(-1) diff --git a/common/compiler/helpers.go b/common/compiler/helpers.go index c2d4a20e3649..59d242af3df6 100644 --- a/common/compiler/helpers.go +++ b/common/compiler/helpers.go @@ -27,9 +27,10 @@ var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`) // Contract contains information about a compiled contract, alongside its code and runtime code. type Contract struct { - Code string `json:"code"` - RuntimeCode string `json:"runtime-code"` - Info ContractInfo `json:"info"` + Code string `json:"code"` + RuntimeCode string `json:"runtime-code"` + Info ContractInfo `json:"info"` + Hashes map[string]string `json:"hashes"` } // ContractInfo contains information about a compiled contract, including access diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index 7ed9c2633e53..56e01ee334ca 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -39,6 +39,7 @@ type solcOutput struct { BinRuntime string `json:"bin-runtime"` SrcMapRuntime string `json:"srcmap-runtime"` Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string + Hashes map[string]string } Version string } @@ -49,7 +50,7 @@ func (s *Solidity) makeArgs() []string { "--optimize", // code optimizer switched on } if s.Major > 0 || s.Minor > 4 || s.Patch > 6 { - p[1] += ",metadata" + p[1] += ",metadata,hashes" } return p } @@ -161,6 +162,7 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin contracts[name] = &Contract{ Code: "0x" + info.Bin, RuntimeCode: "0x" + info.BinRuntime, + Hashes: info.Hashes, Info: ContractInfo{ Source: source, Language: "Solidity", From 993bc6963eb1ff410bfe78b92153fbd8b0a0e777 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 13 Dec 2024 12:03:12 +0800 Subject: [PATCH 040/121] accounts/abi/bind: link dependent libs in deploy (#19718) --- accounts/abi/bind/bind.go | 32 ++++- accounts/abi/bind/bind_test.go | 206 ++++++++++++++++++++++++++------- accounts/abi/bind/template.go | 12 +- cmd/abigen/main.go | 7 +- 4 files changed, 206 insertions(+), 51 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index e6312657bd12..92dd5ba374a5 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -30,6 +30,7 @@ import ( "unicode" "github.com/XinFinOrg/XDPoSChain/accounts/abi" + "github.com/XinFinOrg/XDPoSChain/log" ) // Lang is a target programming language selector to generate bindings for. @@ -43,10 +44,13 @@ const ( // to be used as is in client code, but rather as an intermediate struct which // enforces compile time type safety and naming convention opposed to having to // manually maintain hard coded strings that break on runtime. -func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang) (string, error) { +func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string) (string, error) { // Process each individual contract requested binding contracts := make(map[string]*tmplContract) + // Map used to flag each encountered library as such + isLib := make(map[string]struct{}) + for i := 0; i < len(types); i++ { // Parse the actual ABI to generate the binding for evmABI, err := abi.JSON(strings.NewReader(abis[i])) @@ -115,23 +119,47 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // Append the event to the accumulator list events[original.Name] = &tmplEvent{Original: original, Normalized: normalized} } + contracts[types[i]] = &tmplContract{ Type: capitalise(types[i]), InputABI: strings.ReplaceAll(strippedABI, "\"", "\\\""), - InputBin: strings.TrimSpace(bytecodes[i]), + InputBin: strings.TrimPrefix(strings.TrimSpace(bytecodes[i]), "0x"), Constructor: evmABI.Constructor, Calls: calls, Transacts: transacts, Events: events, + Libraries: make(map[string]string), } + // Function 4-byte signatures are stored in the same sequence + // as types, if available. if len(fsigs) > i { contracts[types[i]].FuncSigs = fsigs[i] } + // Parse library references. + for pattern, name := range libs { + matched, err := regexp.Match("__\\$"+pattern+"\\$__", []byte(contracts[types[i]].InputBin)) + if err != nil { + log.Error("Could not search for pattern", "pattern", pattern, "contract", contracts[types[i]], "err", err) + } + if matched { + contracts[types[i]].Libraries[pattern] = name + // keep track that this type is a library + if _, ok := isLib[name]; !ok { + isLib[name] = struct{}{} + } + } + } + } + // Check if that type has already been identified as a library + for i := 0; i < len(types); i++ { + _, ok := isLib[types[i]] + contracts[types[i]].Library = ok } // Generate the contract template data content and render it data := &tmplData{ Package: pkg, Contracts: contracts, + Libraries: libs, } buffer := new(bytes.Buffer) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 8a73fc8b6415..5382861f1392 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -32,18 +32,20 @@ import ( var bindTests = []struct { name string contract string - bytecode string - abi string + bytecode []string + abi []string imports string tester string fsigs []map[string]string + libs map[string]string + types []string }{ // Test that the binding is available in combined and separate forms too { `Empty`, `contract NilContract {}`, - `606060405260068060106000396000f3606060405200`, - `[]`, + []string{`606060405260068060106000396000f3606060405200`}, + []string{`[]`}, `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewEmpty(common.Address{}, nil); b == nil || err != nil { @@ -57,13 +59,15 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Test that all the official sample contracts bind correctly { `Token`, `https://ethereum.org/token`, - `60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`, - `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`, + []string{`60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`}, + []string{`[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`}, `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewToken(common.Address{}, nil); b == nil || err != nil { @@ -71,12 +75,14 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, { `Crowdsale`, `https://ethereum.org/crowdsale`, - `606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56`, - `[{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"funders","outputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]`, + []string{`606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56`}, + []string{`[{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"funders","outputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]`}, `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewCrowdsale(common.Address{}, nil); b == nil || err != nil { @@ -84,12 +90,14 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, { `DAO`, `https://ethereum.org/dao`, - `606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688`, - `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]`, + []string{`606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688`}, + []string{`[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]`}, `"github.com/XinFinOrg/XDPoSChain/common"`, ` if b, err := NewDAO(common.Address{}, nil); b == nil || err != nil { @@ -97,11 +105,13 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Test that named and anonymous inputs are handled correctly { - `InputChecker`, ``, ``, - ` + `InputChecker`, ``, []string{``}, + []string{` [ {"type":"function","name":"noInput","constant":true,"inputs":[],"outputs":[]}, {"type":"function","name":"namedInput","constant":true,"inputs":[{"name":"str","type":"string"}],"outputs":[]}, @@ -110,7 +120,7 @@ var bindTests = []struct { {"type":"function","name":"anonInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"","type":"string"}],"outputs":[]}, {"type":"function","name":"mixedInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"str","type":"string"}],"outputs":[]} ] - `, + `}, ` "fmt" @@ -131,11 +141,13 @@ var bindTests = []struct { fmt.Println(err) }`, nil, + nil, + nil, }, // Test that named and anonymous outputs are handled correctly { - `OutputChecker`, ``, ``, - ` + `OutputChecker`, ``, []string{``}, + []string{` [ {"type":"function","name":"noOutput","constant":true,"inputs":[],"outputs":[]}, {"type":"function","name":"namedOutput","constant":true,"inputs":[],"outputs":[{"name":"str","type":"string"}]}, @@ -145,7 +157,7 @@ var bindTests = []struct { {"type":"function","name":"anonOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"","type":"string"}]}, {"type":"function","name":"mixedOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"str","type":"string"}]} ] - `, + `}, ` "fmt" @@ -168,11 +180,13 @@ var bindTests = []struct { fmt.Println(str1, str2, res.Str1, res.Str2, err) }`, nil, + nil, + nil, }, // Tests that named, anonymous and indexed events are handled correctly { - `EventChecker`, ``, ``, - ` + `EventChecker`, ``, []string{``}, + []string{` [ {"type":"event","name":"empty","inputs":[]}, {"type":"event","name":"indexed","inputs":[{"name":"addr","type":"address","indexed":true},{"name":"num","type":"int256","indexed":true}]}, @@ -180,7 +194,7 @@ var bindTests = []struct { {"type":"event","name":"anonymous","anonymous":true,"inputs":[]}, {"type":"event","name":"dynamic","inputs":[{"name":"idxStr","type":"string","indexed":true},{"name":"idxDat","type":"bytes","indexed":true},{"name":"str","type":"string"},{"name":"dat","type":"bytes"}]} ] - `, + `}, ` "fmt" "math/big" @@ -234,6 +248,8 @@ var bindTests = []struct { t.Errorf("binding has disallowed method (FilterAnonymous)") }`, nil, + nil, + nil, }, // Test that contract interactions (deploy, transact and call) generate working code { @@ -252,8 +268,8 @@ var bindTests = []struct { } } `, - `6060604052604051610328380380610328833981016040528051018060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10608d57805160ff19168380011785555b50607c9291505b8082111560ba57838155600101606b565b50505061026a806100be6000396000f35b828001600101855582156064579182015b828111156064578251826000505591602001919060010190609e565b509056606060405260e060020a60003504630d86a0e181146100315780636874e8091461008d578063d736c513146100ea575b005b610190600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b61019060008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b60206004803580820135601f81018490049093026080908101604052606084815261002f946024939192918401918190838280828437509496505050505050508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023157805160ff19168380011785555b506102619291505b808211156102665760008155830161017d565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b82800160010185558215610175579182015b82811115610175578251826000505591602001919060010190610243565b505050565b509056`, - `[{"constant":true,"inputs":[],"name":"transactString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[],"name":"deployString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"str","type":"string"}],"name":"transact","outputs":[],"type":"function"},{"inputs":[{"name":"str","type":"string"}],"type":"constructor"}]`, + []string{`6060604052604051610328380380610328833981016040528051018060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10608d57805160ff19168380011785555b50607c9291505b8082111560ba57838155600101606b565b50505061026a806100be6000396000f35b828001600101855582156064579182015b828111156064578251826000505591602001919060010190609e565b509056606060405260e060020a60003504630d86a0e181146100315780636874e8091461008d578063d736c513146100ea575b005b610190600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b61019060008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b60206004803580820135601f81018490049093026080908101604052606084815261002f946024939192918401918190838280828437509496505050505050508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023157805160ff19168380011785555b506102619291505b808211156102665760008155830161017d565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b82800160010185558215610175579182015b82811115610175578251826000505591602001919060010190610243565b505050565b509056`}, + []string{`[{"constant":true,"inputs":[],"name":"transactString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[],"name":"deployString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"str","type":"string"}],"name":"transact","outputs":[],"type":"function"},{"inputs":[{"name":"str","type":"string"}],"type":"constructor"}]`}, ` "math/big" @@ -292,6 +308,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Tests that plain values can be properly returned and deserialized { @@ -303,8 +321,8 @@ var bindTests = []struct { } } `, - `606060405260dc8060106000396000f3606060405260e060020a6000350463993a04b78114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`, - `[{"constant":true,"inputs":[],"name":"getter","outputs":[{"name":"","type":"string"},{"name":"","type":"int256"},{"name":"","type":"bytes32"}],"type":"function"}]`, + []string{`606060405260dc8060106000396000f3606060405260e060020a6000350463993a04b78114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`}, + []string{`[{"constant":true,"inputs":[],"name":"getter","outputs":[{"name":"","type":"string"},{"name":"","type":"int256"},{"name":"","type":"bytes32"}],"type":"function"}]`}, ` "math/big" @@ -334,6 +352,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Tests that tuples can be properly returned and deserialized { @@ -345,8 +365,8 @@ var bindTests = []struct { } } `, - `606060405260dc8060106000396000f3606060405260e060020a60003504633175aae28114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`, - `[{"constant":true,"inputs":[],"name":"tuple","outputs":[{"name":"a","type":"string"},{"name":"b","type":"int256"},{"name":"c","type":"bytes32"}],"type":"function"}]`, + []string{`606060405260dc8060106000396000f3606060405260e060020a60003504633175aae28114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`}, + []string{`[{"constant":true,"inputs":[],"name":"tuple","outputs":[{"name":"a","type":"string"},{"name":"b","type":"int256"},{"name":"c","type":"bytes32"}],"type":"function"}]`}, ` "math/big" @@ -376,6 +396,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Tests that arrays/slices can be properly returned and deserialized. // Only addresses are tested, remainder just compiled to keep the test small. @@ -397,8 +419,8 @@ var bindTests = []struct { } } `, - `606060405261015c806100126000396000f3606060405260e060020a6000350463be1127a3811461003c578063d88becc014610092578063e15a3db71461003c578063f637e5891461003c575b005b604080516020600480358082013583810285810185019096528085526100ee959294602494909392850192829185019084908082843750949650505050505050604080516020810190915260009052805b919050565b604080516102e0818101909252610138916004916102e491839060179083908390808284375090955050505050506102e0604051908101604052806017905b60008152602001906001900390816100d15790505081905061008d565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b60405180826102e0808381846000600461015cf15090500191505060405180910390f3`, - `[{"constant":true,"inputs":[{"name":"input","type":"address[]"}],"name":"echoAddresses","outputs":[{"name":"output","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"uint24[23]"}],"name":"echoFancyInts","outputs":[{"name":"output","type":"uint24[23]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"int256[]"}],"name":"echoInts","outputs":[{"name":"output","type":"int256[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"bool[]"}],"name":"echoBools","outputs":[{"name":"output","type":"bool[]"}],"type":"function"}]`, + []string{`606060405261015c806100126000396000f3606060405260e060020a6000350463be1127a3811461003c578063d88becc014610092578063e15a3db71461003c578063f637e5891461003c575b005b604080516020600480358082013583810285810185019096528085526100ee959294602494909392850192829185019084908082843750949650505050505050604080516020810190915260009052805b919050565b604080516102e0818101909252610138916004916102e491839060179083908390808284375090955050505050506102e0604051908101604052806017905b60008152602001906001900390816100d15790505081905061008d565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b60405180826102e0808381846000600461015cf15090500191505060405180910390f3`}, + []string{`[{"constant":true,"inputs":[{"name":"input","type":"address[]"}],"name":"echoAddresses","outputs":[{"name":"output","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"uint24[23]"}],"name":"echoFancyInts","outputs":[{"name":"output","type":"uint24[23]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"int256[]"}],"name":"echoInts","outputs":[{"name":"output","type":"int256[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"bool[]"}],"name":"echoBools","outputs":[{"name":"output","type":"bool[]"}],"type":"function"}]`}, ` "math/big" "reflect" @@ -430,6 +452,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Tests that anonymous default methods can be correctly invoked { @@ -443,8 +467,8 @@ var bindTests = []struct { } } `, - `6060604052606a8060106000396000f360606040523615601d5760e060020a6000350463fc9c8d3981146040575b605e6000805473ffffffffffffffffffffffffffffffffffffffff191633179055565b606060005473ffffffffffffffffffffffffffffffffffffffff1681565b005b6060908152602090f3`, - `[{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"type":"function"}]`, + []string{`6060604052606a8060106000396000f360606040523615601d5760e060020a6000350463fc9c8d3981146040575b605e6000805473ffffffffffffffffffffffffffffffffffffffff191633179055565b606060005473ffffffffffffffffffffffffffffffffffffffff1681565b005b6060908152602090f3`}, + []string{`[{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"type":"function"}]`}, ` "math/big" @@ -477,6 +501,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Tests that non-existent contracts are reported as such (though only simulator test) { @@ -488,8 +514,8 @@ var bindTests = []struct { } } `, - `6060604052609f8060106000396000f3606060405260e060020a6000350463f97a60058114601a575b005b600060605260c0604052600d60809081527f4920646f6e27742065786973740000000000000000000000000000000000000060a052602060c0908152600d60e081905281906101009060a09080838184600060046012f15050815172ffffffffffffffffffffffffffffffffffffff1916909152505060405161012081900392509050f3`, - `[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`, + []string{`6060604052609f8060106000396000f3606060405260e060020a6000350463f97a60058114601a575b005b600060605260c0604052600d60809081527f4920646f6e27742065786973740000000000000000000000000000000000000060a052602060c0908152600d60e081905281906101009060a09080838184600060046012f15050815172ffffffffffffffffffffffffffffffffffffff1916909152505060405161012081900392509050f3`}, + []string{`[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`}, ` "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" @@ -512,6 +538,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Tests that gas estimation works for contracts with weird gas mechanics too. { @@ -529,8 +557,8 @@ var bindTests = []struct { } } `, - `606060405261021c806100126000396000f3606060405260e060020a600035046323fcf32a81146100265780634f28bf0e1461007b575b005b6040805160206004803580820135601f8101849004840285018401909552848452610024949193602493909291840191908190840183828082843750949650505050505050620186a05a101561014e57610002565b6100db60008054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281529291908301828280156102145780601f106101e957610100808354040283529160200191610214565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561013b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b505050565b8060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101b557805160ff19168380011785555b506101499291505b808211156101e557600081556001016101a1565b82800160010185558215610199579182015b828111156101995782518260005055916020019190600101906101c7565b5090565b820191906000526020600020905b8154815290600101906020018083116101f757829003601f168201915b50505050508156`, - `[{"constant":false,"inputs":[{"name":"value","type":"string"}],"name":"SetField","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"field","outputs":[{"name":"","type":"string"}],"type":"function"}]`, + []string{`606060405261021c806100126000396000f3606060405260e060020a600035046323fcf32a81146100265780634f28bf0e1461007b575b005b6040805160206004803580820135601f8101849004840285018401909552848452610024949193602493909291840191908190840183828082843750949650505050505050620186a05a101561014e57610002565b6100db60008054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281529291908301828280156102145780601f106101e957610100808354040283529160200191610214565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561013b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b505050565b8060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101b557805160ff19168380011785555b506101499291505b808211156101e557600081556001016101a1565b82800160010185558215610199579182015b828111156101995782518260005055916020019190600101906101c7565b5090565b820191906000526020600020905b8154815290600101906020018083116101f757829003601f168201915b50505050508156`}, + []string{`[{"constant":false,"inputs":[{"name":"value","type":"string"}],"name":"SetField","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"field","outputs":[{"name":"","type":"string"}],"type":"function"}]`}, ` "math/big" @@ -564,6 +592,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Test that constant functions can be called from an (optional) specified address { @@ -574,8 +604,9 @@ var bindTests = []struct { return msg.sender; } } - `, `6060604052346000575b6086806100176000396000f300606060405263ffffffff60e060020a60003504166349f8e98281146022575b6000565b34600057602c6055565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b335b905600a165627a7a72305820aef6b7685c0fa24ba6027e4870404a57df701473fe4107741805c19f5138417c0029`, - `[{"constant":true,"inputs":[],"name":"callFrom","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"}]`, + `, + []string{`6060604052346000575b6086806100176000396000f300606060405263ffffffff60e060020a60003504166349f8e98281146022575b6000565b34600057602c6055565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b335b905600a165627a7a72305820aef6b7685c0fa24ba6027e4870404a57df701473fe4107741805c19f5138417c0029`}, + []string{`[{"constant":true,"inputs":[],"name":"callFrom","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"}]`}, ` "math/big" @@ -614,6 +645,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, // Tests that methods and returns with underscores inside work correctly. { @@ -645,8 +678,9 @@ var bindTests = []struct { return 0; } } - `, `6060604052341561000f57600080fd5b6103858061001e6000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461009357806346546dbe146100c357806367e6633d146100ec5780639df4848514610181578063af7486ab146101b1578063b564b34d146101e1578063e02ab24d14610211578063e409ca4514610241575b600080fd5b341561009e57600080fd5b6100a6610271565b604051808381526020018281526020019250505060405180910390f35b34156100ce57600080fd5b6100d6610286565b6040518082815260200191505060405180910390f35b34156100f757600080fd5b6100ff61028e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561014557808201518184015260208101905061012a565b50505050905090810190601f1680156101725780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561018c57600080fd5b6101946102dc565b604051808381526020018281526020019250505060405180910390f35b34156101bc57600080fd5b6101c46102f1565b604051808381526020018281526020019250505060405180910390f35b34156101ec57600080fd5b6101f4610306565b604051808381526020018281526020019250505060405180910390f35b341561021c57600080fd5b61022461031b565b604051808381526020018281526020019250505060405180910390f35b341561024c57600080fd5b610254610330565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600080905090565b6000610298610345565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820d1a53d9de9d1e3d55cb3dc591900b63c4f1ded79114f7b79b332684840e186a40029`, - `[{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_under_scored_func","outputs":[{"name":"_int","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UnderscoredOutput","outputs":[{"name":"_int","type":"int256"},{"name":"_string","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperLowerCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"AllPurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"__","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperUpperCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerLowerCollision","outputs":[{"name":"_res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"}]`, + `, + []string{`6060604052341561000f57600080fd5b6103858061001e6000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461009357806346546dbe146100c357806367e6633d146100ec5780639df4848514610181578063af7486ab146101b1578063b564b34d146101e1578063e02ab24d14610211578063e409ca4514610241575b600080fd5b341561009e57600080fd5b6100a6610271565b604051808381526020018281526020019250505060405180910390f35b34156100ce57600080fd5b6100d6610286565b6040518082815260200191505060405180910390f35b34156100f757600080fd5b6100ff61028e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561014557808201518184015260208101905061012a565b50505050905090810190601f1680156101725780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561018c57600080fd5b6101946102dc565b604051808381526020018281526020019250505060405180910390f35b34156101bc57600080fd5b6101c46102f1565b604051808381526020018281526020019250505060405180910390f35b34156101ec57600080fd5b6101f4610306565b604051808381526020018281526020019250505060405180910390f35b341561021c57600080fd5b61022461031b565b604051808381526020018281526020019250505060405180910390f35b341561024c57600080fd5b610254610330565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600080905090565b6000610298610345565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820d1a53d9de9d1e3d55cb3dc591900b63c4f1ded79114f7b79b332684840e186a40029`}, + []string{`[{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_under_scored_func","outputs":[{"name":"_int","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UnderscoredOutput","outputs":[{"name":"_int","type":"int256"},{"name":"_string","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperLowerCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"AllPurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"__","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperUpperCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerLowerCollision","outputs":[{"name":"_res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"}]`}, ` "fmt" "math/big" @@ -690,6 +724,8 @@ var bindTests = []struct { fmt.Println(a, b, err) `, nil, + nil, + nil, }, // Tests that logs can be successfully filtered and decoded. { @@ -726,8 +762,8 @@ var bindTests = []struct { } } `, - `6060604052341561000f57600080fd5b61042c8061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063528300ff1461005c578063630c31e2146100fc578063c7d116dd14610156575b600080fd5b341561006757600080fd5b6100fa600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610194565b005b341561010757600080fd5b610154600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035600019169060200190919080351515906020019091908035906020019091905050610367565b005b341561016157600080fd5b610192600480803590602001909190803560010b90602001909190803563ffffffff169060200190919050506103c3565b005b806040518082805190602001908083835b6020831015156101ca57805182526020820191506020810190506020830392506101a5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020826040518082805190602001908083835b60208310151561022d5780518252602082019150602081019050602083039250610208565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f3281fd4f5e152dd3385df49104a3f633706e21c9e80672e88d3bcddf33101f008484604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102c15780820151818401526020810190506102a6565b50505050905090810190601f1680156102ee5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561032757808201518184015260208101905061030c565b50505050905090810190601f1680156103545780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a35050565b81151583600019168573ffffffffffffffffffffffffffffffffffffffff167f1f097de4289df643bd9c11011cc61367aa12983405c021056e706eb5ba1250c8846040518082815260200191505060405180910390a450505050565b8063ffffffff168260010b847f3ca7f3a77e5e6e15e781850bc82e32adfa378a2a609370db24b4d0fae10da2c960405160405180910390a45050505600a165627a7a72305820d1f8a8bbddbc5bb29f285891d6ae1eef8420c52afdc05e1573f6114d8e1714710029`, - `[{"constant":false,"inputs":[{"name":"str","type":"string"},{"name":"blob","type":"bytes"}],"name":"raiseDynamicEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"id","type":"bytes32"},{"name":"flag","type":"bool"},{"name":"value","type":"uint256"}],"name":"raiseSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"number","type":"uint256"},{"name":"short","type":"int16"},{"name":"long","type":"uint32"}],"name":"raiseNodataEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Addr","type":"address"},{"indexed":true,"name":"Id","type":"bytes32"},{"indexed":true,"name":"Flag","type":"bool"},{"indexed":false,"name":"Value","type":"uint256"}],"name":"SimpleEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Number","type":"uint256"},{"indexed":true,"name":"Short","type":"int16"},{"indexed":true,"name":"Long","type":"uint32"}],"name":"NodataEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"IndexedString","type":"string"},{"indexed":true,"name":"IndexedBytes","type":"bytes"},{"indexed":false,"name":"NonIndexedString","type":"string"},{"indexed":false,"name":"NonIndexedBytes","type":"bytes"}],"name":"DynamicEvent","type":"event"}]`, + []string{`6060604052341561000f57600080fd5b61042c8061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063528300ff1461005c578063630c31e2146100fc578063c7d116dd14610156575b600080fd5b341561006757600080fd5b6100fa600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610194565b005b341561010757600080fd5b610154600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035600019169060200190919080351515906020019091908035906020019091905050610367565b005b341561016157600080fd5b610192600480803590602001909190803560010b90602001909190803563ffffffff169060200190919050506103c3565b005b806040518082805190602001908083835b6020831015156101ca57805182526020820191506020810190506020830392506101a5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020826040518082805190602001908083835b60208310151561022d5780518252602082019150602081019050602083039250610208565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f3281fd4f5e152dd3385df49104a3f633706e21c9e80672e88d3bcddf33101f008484604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102c15780820151818401526020810190506102a6565b50505050905090810190601f1680156102ee5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561032757808201518184015260208101905061030c565b50505050905090810190601f1680156103545780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a35050565b81151583600019168573ffffffffffffffffffffffffffffffffffffffff167f1f097de4289df643bd9c11011cc61367aa12983405c021056e706eb5ba1250c8846040518082815260200191505060405180910390a450505050565b8063ffffffff168260010b847f3ca7f3a77e5e6e15e781850bc82e32adfa378a2a609370db24b4d0fae10da2c960405160405180910390a45050505600a165627a7a72305820d1f8a8bbddbc5bb29f285891d6ae1eef8420c52afdc05e1573f6114d8e1714710029`}, + []string{`[{"constant":false,"inputs":[{"name":"str","type":"string"},{"name":"blob","type":"bytes"}],"name":"raiseDynamicEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"id","type":"bytes32"},{"name":"flag","type":"bool"},{"name":"value","type":"uint256"}],"name":"raiseSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"number","type":"uint256"},{"name":"short","type":"int16"},{"name":"long","type":"uint32"}],"name":"raiseNodataEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Addr","type":"address"},{"indexed":true,"name":"Id","type":"bytes32"},{"indexed":true,"name":"Flag","type":"bool"},{"indexed":false,"name":"Value","type":"uint256"}],"name":"SimpleEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Number","type":"uint256"},{"indexed":true,"name":"Short","type":"int16"},{"indexed":true,"name":"Long","type":"uint32"}],"name":"NodataEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"IndexedString","type":"string"},{"indexed":true,"name":"IndexedBytes","type":"bytes"},{"indexed":false,"name":"NonIndexedString","type":"string"},{"indexed":false,"name":"NonIndexedBytes","type":"bytes"}],"name":"DynamicEvent","type":"event"}]`}, ` "math/big" "time" @@ -873,6 +909,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, { `DeeplyNestedArray`, @@ -887,8 +925,8 @@ var bindTests = []struct { } } `, - `6060604052341561000f57600080fd5b6106438061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063344248551461005c5780638ed4573a1461011457806398ed1856146101ab575b600080fd5b341561006757600080fd5b610112600480806107800190600580602002604051908101604052809291906000905b828210156101055783826101800201600480602002604051908101604052809291906000905b828210156100f25783826060020160038060200260405190810160405280929190826003602002808284378201915050505050815260200190600101906100b0565b505050508152602001906001019061008a565b5050505091905050610208565b005b341561011f57600080fd5b61012761021d565b604051808260056000925b8184101561019b578284602002015160046000925b8184101561018d5782846020020151600360200280838360005b8381101561017c578082015181840152602081019050610161565b505050509050019260010192610147565b925050509260010192610132565b9250505091505060405180910390f35b34156101b657600080fd5b6101de6004808035906020019091908035906020019091908035906020019091905050610309565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b80600090600561021992919061035f565b5050565b6102256103b0565b6000600580602002604051908101604052809291906000905b8282101561030057838260040201600480602002604051908101604052809291906000905b828210156102ed578382016003806020026040519081016040528092919082600380156102d9576020028201916000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff16815260200190600801906020826007010492830192600103820291508084116102945790505b505050505081526020019060010190610263565b505050508152602001906001019061023e565b50505050905090565b60008360058110151561031857fe5b600402018260048110151561032957fe5b018160038110151561033757fe5b6004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b826005600402810192821561039f579160200282015b8281111561039e5782518290600461038e9291906103df565b5091602001919060040190610375565b5b5090506103ac919061042d565b5090565b610780604051908101604052806005905b6103c9610459565b8152602001906001900390816103c15790505090565b826004810192821561041c579160200282015b8281111561041b5782518290600361040b929190610488565b50916020019190600101906103f2565b5b5090506104299190610536565b5090565b61045691905b8082111561045257600081816104499190610562565b50600401610433565b5090565b90565b610180604051908101604052806004905b6104726105a7565b81526020019060019003908161046a5790505090565b82600380016004900481019282156105255791602002820160005b838211156104ef57835183826101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555092602001926008016020816007010492830192600103026104a3565b80156105235782816101000a81549067ffffffffffffffff02191690556008016020816007010492830192600103026104ef565b505b50905061053291906105d9565b5090565b61055f91905b8082111561055b57600081816105529190610610565b5060010161053c565b5090565b90565b50600081816105719190610610565b50600101600081816105839190610610565b50600101600081816105959190610610565b5060010160006105a59190610610565b565b6060604051908101604052806003905b600067ffffffffffffffff168152602001906001900390816105b75790505090565b61060d91905b8082111561060957600081816101000a81549067ffffffffffffffff0219169055506001016105df565b5090565b90565b50600090555600a165627a7a7230582087e5a43f6965ab6ef7a4ff056ab80ed78fd8c15cff57715a1bf34ec76a93661c0029`, - `[{"constant":false,"inputs":[{"name":"arr","type":"uint64[3][4][5]"}],"name":"storeDeepUintArray","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"retrieveDeepArray","outputs":[{"name":"","type":"uint64[3][4][5]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"deepUint64Array","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"}]`, + []string{`6060604052341561000f57600080fd5b6106438061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063344248551461005c5780638ed4573a1461011457806398ed1856146101ab575b600080fd5b341561006757600080fd5b610112600480806107800190600580602002604051908101604052809291906000905b828210156101055783826101800201600480602002604051908101604052809291906000905b828210156100f25783826060020160038060200260405190810160405280929190826003602002808284378201915050505050815260200190600101906100b0565b505050508152602001906001019061008a565b5050505091905050610208565b005b341561011f57600080fd5b61012761021d565b604051808260056000925b8184101561019b578284602002015160046000925b8184101561018d5782846020020151600360200280838360005b8381101561017c578082015181840152602081019050610161565b505050509050019260010192610147565b925050509260010192610132565b9250505091505060405180910390f35b34156101b657600080fd5b6101de6004808035906020019091908035906020019091908035906020019091905050610309565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b80600090600561021992919061035f565b5050565b6102256103b0565b6000600580602002604051908101604052809291906000905b8282101561030057838260040201600480602002604051908101604052809291906000905b828210156102ed578382016003806020026040519081016040528092919082600380156102d9576020028201916000905b82829054906101000a900467ffffffffffffffff1667ffffffffffffffff16815260200190600801906020826007010492830192600103820291508084116102945790505b505050505081526020019060010190610263565b505050508152602001906001019061023e565b50505050905090565b60008360058110151561031857fe5b600402018260048110151561032957fe5b018160038110151561033757fe5b6004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b826005600402810192821561039f579160200282015b8281111561039e5782518290600461038e9291906103df565b5091602001919060040190610375565b5b5090506103ac919061042d565b5090565b610780604051908101604052806005905b6103c9610459565b8152602001906001900390816103c15790505090565b826004810192821561041c579160200282015b8281111561041b5782518290600361040b929190610488565b50916020019190600101906103f2565b5b5090506104299190610536565b5090565b61045691905b8082111561045257600081816104499190610562565b50600401610433565b5090565b90565b610180604051908101604052806004905b6104726105a7565b81526020019060019003908161046a5790505090565b82600380016004900481019282156105255791602002820160005b838211156104ef57835183826101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555092602001926008016020816007010492830192600103026104a3565b80156105235782816101000a81549067ffffffffffffffff02191690556008016020816007010492830192600103026104ef565b505b50905061053291906105d9565b5090565b61055f91905b8082111561055b57600081816105529190610610565b5060010161053c565b5090565b90565b50600081816105719190610610565b50600101600081816105839190610610565b50600101600081816105959190610610565b5060010160006105a59190610610565b565b6060604051908101604052806003905b600067ffffffffffffffff168152602001906001900390816105b75790505090565b61060d91905b8082111561060957600081816101000a81549067ffffffffffffffff0219169055506001016105df565b5090565b90565b50600090555600a165627a7a7230582087e5a43f6965ab6ef7a4ff056ab80ed78fd8c15cff57715a1bf34ec76a93661c0029`}, + []string{`[{"constant":false,"inputs":[{"name":"arr","type":"uint64[3][4][5]"}],"name":"storeDeepUintArray","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"retrieveDeepArray","outputs":[{"name":"","type":"uint64[3][4][5]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"deepUint64Array","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"}]`}, ` "math/big" @@ -950,6 +988,8 @@ var bindTests = []struct { } `, nil, + nil, + nil, }, { `CallbackParam`, @@ -960,8 +1000,8 @@ var bindTests = []struct { } } `, - `608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063d7a5aba214610040575b600080fd5b34801561004c57600080fd5b506100be6004803603602081101561006357600080fd5b810190808035806c0100000000000000000000000090049068010000000000000000900463ffffffff1677ffffffffffffffffffffffffffffffffffffffffffffffff169091602001919093929190939291905050506100c0565b005b818160016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561011657600080fd5b505af115801561012a573d6000803e3d6000fd5b50505050505056fea165627a7a7230582062f87455ff84be90896dbb0c4e4ddb505c600d23089f8e80a512548440d7e2580029`, - `[ + []string{`608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063d7a5aba214610040575b600080fd5b34801561004c57600080fd5b506100be6004803603602081101561006357600080fd5b810190808035806c0100000000000000000000000090049068010000000000000000900463ffffffff1677ffffffffffffffffffffffffffffffffffffffffffffffff169091602001919093929190939291905050506100c0565b005b818160016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561011657600080fd5b505af115801561012a573d6000803e3d6000fd5b50505050505056fea165627a7a7230582062f87455ff84be90896dbb0c4e4ddb505c600d23089f8e80a512548440d7e2580029`}, + []string{`[ { "constant": false, "inputs": [ @@ -976,7 +1016,7 @@ var bindTests = []struct { "stateMutability": "nonpayable", "type": "function" } - ]`, + ]`}, ` "strings" `, @@ -990,6 +1030,76 @@ var bindTests = []struct { "test(function)": "d7a5aba2", }, }, + nil, + nil, + }, + { + `UseLibrary`, + ` + library Math { + function add(uint a, uint b) public view returns(uint) { + return a + b; + } + } + + contract UseLibrary { + function add (uint c, uint d) public view returns(uint) { + return Math.add(c,d); + } + } + `, + []string{ + // Bytecode for the UseLibrary contract + `608060405234801561001057600080fd5b5061011d806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063771602f714602d575b600080fd5b604d60048036036040811015604157600080fd5b5080359060200135605f565b60408051918252519081900360200190f35b600073__$b98c933f0a6ececcd167bd4f9d3299b1a0$__63771602f784846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b5051939250505056fea265627a7a72305820eb5c38f42445604cfa43d85e3aa5ecc48b0a646456c902dd48420ae7241d06f664736f6c63430005090032`, + // Bytecode for the Math contract + `60a3610024600b82828239805160001a607314601757fe5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063771602f7146038575b600080fd5b605860048036036040811015604c57600080fd5b5080359060200135606a565b60408051918252519081900360200190f35b019056fea265627a7a723058206fc6c05f3078327f9c763edffdb5ab5f8bd212e293a1306c7d0ad05af3ad35f464736f6c63430005090032`, + }, + []string{ + `[{"constant":true,"inputs":[{"name":"c","type":"uint256"},{"name":"d","type":"uint256"}],"name":"add","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`, + `[{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"add","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`, + }, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + // Generate a new random account and a funded simulator + key, _ := crypto.GenerateKey() + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + + // Deploy the test contract + _, _, testContract, err := DeployUseLibrary(auth, sim) + if err != nil { + t.Fatalf("Failed to deploy test contract: %v", err) + } + + // Finish deploy. + sim.Commit() + + // Check that the library contract has been deployed + // by calling the contract's add function. + res, err := testContract.Add(&bind.CallOpts{ + From: auth.From, + Pending: false, + }, big.NewInt(1), big.NewInt(2)) + if err != nil { + t.Fatalf("Failed to call linked contract: %v", err) + } + if res.Cmp(big.NewInt(3)) != 0 { + t.Fatalf("Add did not return the correct result: %d != %d", res, 3) + } + `, + nil, + map[string]string{ + "b98c933f0a6ececcd167bd4f9d3299b1a0": "Math", + }, + []string{"UseLibrary", "Math"}, }, } @@ -1015,8 +1125,14 @@ func TestGolangBindings(t *testing.T) { } // Generate the test suite for all the contracts for i, tt := range bindTests { + var types []string + if tt.types != nil { + types = tt.types + } else { + types = []string{tt.name} + } // Generate the binding and create a Go source file in the workspace - bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, tt.fsigs, "bindtest", LangGo) + bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs) if err != nil { t.Fatalf("test %d: failed to generate binding: %v", i, err) } diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index f65c16bdcd9c..10e8ae9f0579 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -22,6 +22,7 @@ import "github.com/XinFinOrg/XDPoSChain/accounts/abi" type tmplData struct { Package string // Name of the package to place the generated file in Contracts map[string]*tmplContract // List of contracts to generate into this file + Libraries map[string]string // Map the bytecode's link pattern to the library name } // tmplContract contains the data needed to generate an individual contract binding. @@ -34,6 +35,8 @@ type tmplContract struct { Calls map[string]*tmplMethod // Contract calls that only read state data Transacts map[string]*tmplMethod // Contract calls that write state data Events map[string]*tmplEvent // Contract events accessors + Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs + Library bool } // tmplMethod is a wrapper around an abi.Method that contains a few preprocessed @@ -95,15 +98,14 @@ var ( {{if $contract.FuncSigs}} // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. var {{.Type}}FuncSigs = map[string]string{ - {{range $strsig, $binsig := .FuncSigs}} - "{{$binsig}}": "{{$strsig}}", + {{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}", {{end}} } {{end}} {{if .InputBin}} // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. - const {{.Type}}Bin = ` + "`" + `{{.InputBin}}` + "`" + ` + var {{.Type}}Bin = "0x{{.InputBin}}" // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { @@ -111,6 +113,10 @@ var ( if err != nil { return common.Address{}, nil, nil, err } + {{range $pattern, $name := .Libraries}} + {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) + {{$contract.Type}}Bin = strings.Replace({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:], -1) + {{end}} address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) if err != nil { return common.Address{}, nil, nil, err diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index b6b15335540e..1c4a2aa06980 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -25,6 +25,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/common/compiler" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/internal/flags" "github.com/XinFinOrg/XDPoSChain/log" "github.com/urfave/cli/v2" @@ -136,6 +137,7 @@ func abigen(c *cli.Context) error { bins []string types []string sigs []map[string]string + libs = make(map[string]string) ) if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || c.String(abiFlag.Name) == "-" { // Generate the list of types to exclude from binding @@ -184,6 +186,9 @@ func abigen(c *cli.Context) error { nameParts := strings.Split(name, ":") types = append(types, nameParts[len(nameParts)-1]) + + libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] + libs[libPattern] = nameParts[len(nameParts)-1] } } else { // Otherwise load up the ABI, optional bytecode and type name from the parameters @@ -211,7 +216,7 @@ func abigen(c *cli.Context) error { types = append(types, kind) } // Generate the contract binding - code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang) + code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs) if err != nil { fmt.Printf("Failed to generate ABI binding: %v\n", err) os.Exit(-1) From d6957d928334f0beb560b2bd086828e8234b40de Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 13 Dec 2024 17:07:00 +0800 Subject: [PATCH 041/121] accounts/abi/bind: remove test case UseLibrary --- accounts/abi/bind/bind_test.go | 68 ---------------------------------- 1 file changed, 68 deletions(-) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 5382861f1392..538dd3c38e43 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1033,74 +1033,6 @@ var bindTests = []struct { nil, nil, }, - { - `UseLibrary`, - ` - library Math { - function add(uint a, uint b) public view returns(uint) { - return a + b; - } - } - - contract UseLibrary { - function add (uint c, uint d) public view returns(uint) { - return Math.add(c,d); - } - } - `, - []string{ - // Bytecode for the UseLibrary contract - `608060405234801561001057600080fd5b5061011d806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063771602f714602d575b600080fd5b604d60048036036040811015604157600080fd5b5080359060200135605f565b60408051918252519081900360200190f35b600073__$b98c933f0a6ececcd167bd4f9d3299b1a0$__63771602f784846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801560b757600080fd5b505af415801560ca573d6000803e3d6000fd5b505050506040513d602081101560df57600080fd5b5051939250505056fea265627a7a72305820eb5c38f42445604cfa43d85e3aa5ecc48b0a646456c902dd48420ae7241d06f664736f6c63430005090032`, - // Bytecode for the Math contract - `60a3610024600b82828239805160001a607314601757fe5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063771602f7146038575b600080fd5b605860048036036040811015604c57600080fd5b5080359060200135606a565b60408051918252519081900360200190f35b019056fea265627a7a723058206fc6c05f3078327f9c763edffdb5ab5f8bd212e293a1306c7d0ad05af3ad35f464736f6c63430005090032`, - }, - []string{ - `[{"constant":true,"inputs":[{"name":"c","type":"uint256"},{"name":"d","type":"uint256"}],"name":"add","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`, - `[{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"add","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`, - }, - ` - "math/big" - - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" - "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/params" - `, - ` - // Generate a new random account and a funded simulator - key, _ := crypto.GenerateKey() - auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) - - // Deploy the test contract - _, _, testContract, err := DeployUseLibrary(auth, sim) - if err != nil { - t.Fatalf("Failed to deploy test contract: %v", err) - } - - // Finish deploy. - sim.Commit() - - // Check that the library contract has been deployed - // by calling the contract's add function. - res, err := testContract.Add(&bind.CallOpts{ - From: auth.From, - Pending: false, - }, big.NewInt(1), big.NewInt(2)) - if err != nil { - t.Fatalf("Failed to call linked contract: %v", err) - } - if res.Cmp(big.NewInt(3)) != 0 { - t.Fatalf("Add did not return the correct result: %d != %d", res, 3) - } - `, - nil, - map[string]string{ - "b98c933f0a6ececcd167bd4f9d3299b1a0": "Math", - }, - []string{"UseLibrary", "Math"}, - }, } // Tests that packages generated by the binder can be successfully compiled and From 057a7dd780272e3400c871e4069520fdbc406bfd Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 13 Dec 2024 16:52:03 +0800 Subject: [PATCH 042/121] cmd/abigen: refactor command line interface (#19797) --- cmd/abigen/main.go | 133 ++++++++++++++++-------------------- cmd/utils/flags.go | 16 ++--- common/compiler/solidity.go | 13 ++-- 3 files changed, 71 insertions(+), 91 deletions(-) diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 1c4a2aa06980..6bd6efb4c249 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/cmd/utils" "github.com/XinFinOrg/XDPoSChain/common/compiler" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/internal/flags" @@ -52,6 +53,10 @@ var ( Name: "type", Usage: "Struct name for the binding (default = package name)", } + jsonFlag = &cli.StringFlag{ + Name: "combined-json", + Usage: "Path to the combined-json file generated by compiler", + } solFlag = &cli.StringFlag{ Name: "sol", Usage: "Path to the Ethereum contract Solidity source to build and bind", @@ -96,6 +101,7 @@ func init() { abiFlag, binFlag, typeFlag, + jsonFlag, solFlag, solcFlag, vyFlag, @@ -109,28 +115,11 @@ func init() { } func abigen(c *cli.Context) error { - if c.String(abiFlag.Name) == "" && c.String(solFlag.Name) == "" && c.String(vyFlag.Name) == "" { - fmt.Printf("No contract ABI (--abi), Solidity source (--sol), or Vyper source (--vy) specified\n") - os.Exit(-1) - } else if (c.String(abiFlag.Name) != "" || c.String(binFlag.Name) != "" || c.String(typeFlag.Name) != "") && (c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "") { - fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity (--sol) and Vyper (--vy) flags\n") - os.Exit(-1) - } else if c.String(solFlag.Name) != "" && c.String(vyFlag.Name) == "" { - fmt.Printf("Solidity (--sol) and Vyper (--vy) flags are mutually exclusive\n") - os.Exit(-1) - } + utils.CheckExclusive(c, abiFlag, jsonFlag, solFlag, vyFlag) // Only one source can be selected. if c.String(pkgFlag.Name) == "" { - fmt.Printf("No destination package specified (--pkg)\n") - os.Exit(-1) - } - var lang bind.Lang - switch c.String(langFlag.Name) { - case "go": - lang = bind.LangGo - default: - fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", c.String(langFlag.Name)) - os.Exit(-1) + utils.Fatalf("No destination package specified (--pkg)") } + lang := bind.LangGo // If the entire solidity code was specified, build and bind based on that var ( abis []string @@ -139,37 +128,69 @@ func abigen(c *cli.Context) error { sigs []map[string]string libs = make(map[string]string) ) - if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || c.String(abiFlag.Name) == "-" { + if c.String(abiFlag.Name) != "" { + // Load up the ABI, optional bytecode and type name from the parameters + var ( + abi []byte + err error + ) + input := c.String(abiFlag.Name) + if input == "-" { + abi, err = io.ReadAll(os.Stdin) + } else { + abi, err = os.ReadFile(input) + } + if err != nil { + utils.Fatalf("Failed to read input ABI: %v", err) + } + abis = append(abis, string(abi)) + + var bin []byte + if binFile := c.String(binFlag.Name); binFile != "" { + if bin, err = os.ReadFile(binFile); err != nil { + utils.Fatalf("Failed to read input bytecode: %v", err) + } + if strings.Contains(string(bin), "//") { + utils.Fatalf("Contract has additional library references, please use other mode(e.g. --combined-json) to catch library infos") + } + } + bins = append(bins, string(bin)) + + kind := c.String(typeFlag.Name) + if kind == "" { + kind = c.String(pkgFlag.Name) + } + types = append(types, kind) + } else { // Generate the list of types to exclude from binding exclude := make(map[string]bool) for _, kind := range strings.Split(c.String(excFlag.Name), ",") { exclude[strings.ToLower(kind)] = true } - - var contracts map[string]*compiler.Contract var err error + var contracts map[string]*compiler.Contract switch { - case c.String(solFlag.Name) != "": + case c.IsSet(solFlag.Name): contracts, err = compiler.CompileSolidity(c.String(solcFlag.Name), c.String(solFlag.Name)) if err != nil { - fmt.Printf("Failed to build Solidity contract: %v\n", err) - os.Exit(-1) + utils.Fatalf("Failed to build Solidity contract: %v", err) } - case c.String(vyFlag.Name) != "": + case c.IsSet(vyFlag.Name): contracts, err = compiler.CompileVyper(c.String(vyperFlag.Name), c.String(vyFlag.Name)) if err != nil { - fmt.Printf("Failed to build Vyper contract: %v\n", err) - os.Exit(-1) + utils.Fatalf("Failed to build Vyper contract: %v", err) } - default: - contracts, err = contractsFromStdin() + case c.IsSet(jsonFlag.Name): + jsonOutput, err := os.ReadFile(c.String(jsonFlag.Name)) if err != nil { - fmt.Printf("Failed to read input ABIs from STDIN: %v\n", err) - os.Exit(-1) + utils.Fatalf("Failed to read combined-json from compiler: %v", err) + } + contracts, err = compiler.ParseCombinedJSON(jsonOutput, "", "", "", "") + if err != nil { + utils.Fatalf("Failed to read contract information from json output: %v", err) } } - // Gather all non-excluded contract for binding for name, contract := range contracts { if exclude[strings.ToLower(name)] { @@ -177,58 +198,30 @@ func abigen(c *cli.Context) error { } abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse if err != nil { - fmt.Printf("Failed to parse ABIs from compiler output: %v\n", err) - os.Exit(-1) + utils.Fatalf("Failed to parse ABIs from compiler output: %v", err) } abis = append(abis, string(abi)) bins = append(bins, contract.Code) sigs = append(sigs, contract.Hashes) - nameParts := strings.Split(name, ":") types = append(types, nameParts[len(nameParts)-1]) libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] libs[libPattern] = nameParts[len(nameParts)-1] } - } else { - // Otherwise load up the ABI, optional bytecode and type name from the parameters - abi, err := os.ReadFile(c.String(abiFlag.Name)) - - if err != nil { - fmt.Printf("Failed to read input ABI: %v\n", err) - os.Exit(-1) - } - abis = append(abis, string(abi)) - - var bin []byte - if c.String(binFlag.Name) != "" { - if bin, err = os.ReadFile(c.String(binFlag.Name)); err != nil { - fmt.Printf("Failed to read input bytecode: %v\n", err) - os.Exit(-1) - } - } - bins = append(bins, string(bin)) - - kind := c.String(typeFlag.Name) - if kind == "" { - kind = c.String(pkgFlag.Name) - } - types = append(types, kind) } // Generate the contract binding code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs) if err != nil { - fmt.Printf("Failed to generate ABI binding: %v\n", err) - os.Exit(-1) + utils.Fatalf("Failed to generate ABI binding: %v", err) } // Either flush it out to a file or display on the standard output - if c.String(outFlag.Name) == "" { + if !c.IsSet(outFlag.Name) { fmt.Printf("%s\n", code) return nil } if err := os.WriteFile(c.String(outFlag.Name), []byte(code), 0600); err != nil { - fmt.Printf("Failed to write ABI binding: %v\n", err) - os.Exit(-1) + utils.Fatalf("Failed to write ABI binding: %v", err) } return nil } @@ -241,11 +234,3 @@ func main() { os.Exit(1) } } - -func contractsFromStdin() (map[string]*compiler.Contract, error) { - bytes, err := io.ReadAll(os.Stdin) - if err != nil { - return nil, err - } - return compiler.ParseCombinedJSON(bytes, "", "", "", "") -} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 9c25f50df4c0..64dc4b05004b 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1024,7 +1024,7 @@ func setWS(ctx *cli.Context, cfg *node.Config) { // setIPC creates an IPC path configuration from the set command line flags, // returning an empty string if IPC was explicitly disabled, or the set path. func setIPC(ctx *cli.Context, cfg *node.Config) { - checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag) + CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag) switch { case ctx.Bool(IPCDisabledFlag.Name): cfg.IPCPath = "" @@ -1034,7 +1034,7 @@ func setIPC(ctx *cli.Context, cfg *node.Config) { } func setPrefix(ctx *cli.Context, cfg *node.Config) { - checkExclusive(ctx, Enable0xPrefixFlag, EnableXDCPrefixFlag) + CheckExclusive(ctx, Enable0xPrefixFlag, EnableXDCPrefixFlag) } // MakeDatabaseHandles raises out the number of allowed file handles per process @@ -1301,10 +1301,10 @@ func setEthash(ctx *cli.Context, cfg *ethconfig.Config) { } } -// checkExclusive verifies that only a single isntance of the provided flags was +// CheckExclusive verifies that only a single isntance of the provided flags was // set by the user. Each flag might optionally be followed by a string type to // specialize it further. -func checkExclusive(ctx *cli.Context, args ...interface{}) { +func CheckExclusive(ctx *cli.Context, args ...interface{}) { set := make([]string, 0, 1) for i := 0; i < len(args); i++ { // Make sure the next argument is a flag and skip if not set @@ -1381,10 +1381,10 @@ func SetXDCXConfig(ctx *cli.Context, cfg *XDCx.Config, XDCDataDir string) { // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // Avoid conflicting network flags - checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag) - checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag) - checkExclusive(ctx, LightServFlag, LightModeFlag) - checkExclusive(ctx, LightServFlag, SyncModeFlag, "light") + CheckExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag) + CheckExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag) + CheckExclusive(ctx, LightServFlag, LightModeFlag) + CheckExclusive(ctx, LightServFlag, SyncModeFlag, "light") ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) setEtherbase(ctx, ks, cfg) diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index 56e01ee334ca..16b91bf747f4 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -142,7 +142,6 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin if err := json.Unmarshal(combinedJSON, &output); err != nil { return nil, err } - // Compilation succeeded, assemble and return the contracts. contracts := make(map[string]*Contract) for name, info := range output.Contracts { @@ -151,14 +150,10 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil { return nil, fmt.Errorf("solc: error reading abi definition (%v)", err) } - var userdoc interface{} - if err := json.Unmarshal([]byte(info.Userdoc), &userdoc); err != nil { - return nil, fmt.Errorf("solc: error reading user doc: %v", err) - } - var devdoc interface{} - if err := json.Unmarshal([]byte(info.Devdoc), &devdoc); err != nil { - return nil, fmt.Errorf("solc: error reading dev doc: %v", err) - } + var userdoc, devdoc interface{} + json.Unmarshal([]byte(info.Userdoc), &userdoc) + json.Unmarshal([]byte(info.Devdoc), &devdoc) + contracts[name] = &Contract{ Code: "0x" + info.Bin, RuntimeCode: "0x" + info.BinRuntime, From 5a8110b2929152ef6619807b2bb3d8fe6f232d35 Mon Sep 17 00:00:00 2001 From: David Chase Date: Wed, 17 Jul 2019 04:23:43 -0400 Subject: [PATCH 043/121] common/bitutil: use result of TestBytes to prevent dead code elimination (#19846) Gollvm has very aggressive dead code elimination that completely removes one of these two benchmarks. To prevent this, use the result of the benchmark (a boolean), and to be "fair", make the transformation to both benchmarks. To be reliably assured of not removing the code, "use" means assigning to an exported global. Non-exported globals and //go:noinline functions are possibly subject to this optimization. --- common/bitutil/bitutil_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/common/bitutil/bitutil_test.go b/common/bitutil/bitutil_test.go index 93647031ef84..307bf731f765 100644 --- a/common/bitutil/bitutil_test.go +++ b/common/bitutil/bitutil_test.go @@ -190,6 +190,8 @@ func benchmarkBaseOR(b *testing.B, size int) { } } +var GloBool bool // Exported global will not be dead-code eliminated, at least not yet. + // Benchmarks the potentially optimized bit testing performance. func BenchmarkFastTest1KB(b *testing.B) { benchmarkFastTest(b, 1024) } func BenchmarkFastTest2KB(b *testing.B) { benchmarkFastTest(b, 2048) } @@ -197,9 +199,11 @@ func BenchmarkFastTest4KB(b *testing.B) { benchmarkFastTest(b, 4096) } func benchmarkFastTest(b *testing.B, size int) { p := make([]byte, size) + a := false for i := 0; i < b.N; i++ { - TestBytes(p) + a = a != TestBytes(p) } + GloBool = a // Use of benchmark "result" to prevent total dead code elimination. } // Benchmarks the baseline bit testing performance. @@ -209,7 +213,9 @@ func BenchmarkBaseTest4KB(b *testing.B) { benchmarkBaseTest(b, 4096) } func benchmarkBaseTest(b *testing.B, size int) { p := make([]byte, size) + a := false for i := 0; i < b.N; i++ { - safeTestBytes(p) + a = a != safeTestBytes(p) } + GloBool = a // Use of benchmark "result" to prevent total dead code elimination. } From 94b69fdf1e6f69f55839c69fb13a4c43b34641b3 Mon Sep 17 00:00:00 2001 From: shiqinfeng1 <150627601@qq.com> Date: Thu, 15 Aug 2019 16:33:06 +0800 Subject: [PATCH 044/121] common/compiler: support relative import paths (#17374 #19967) --- common/compiler/solidity.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index 16b91bf747f4..f0363dc92b18 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -47,7 +47,8 @@ type solcOutput struct { func (s *Solidity) makeArgs() []string { p := []string{ "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc", - "--optimize", // code optimizer switched on + "--optimize", // code optimizer switched on + "--allow-paths", "., ./, ../", // default to support relative paths } if s.Major > 0 || s.Minor > 4 || s.Patch > 6 { p[1] += ",metadata,hashes" From 7f63a690eeef9fda43f389ae9e4c85f1eac881d7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 16 Dec 2024 17:14:34 +0800 Subject: [PATCH 045/121] common: unify hex prefix check code (#19937) --- common/bytes.go | 37 ++++++++++++++++--------------------- common/types.go | 7 +++---- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/common/bytes.go b/common/bytes.go index 6be6116bb979..703705ee3f06 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -34,13 +34,10 @@ func ToHex(b []byte) string { // FromHex returns the bytes represented by the hexadecimal string s. // s may be prefixed with "0x". func FromHex(s string) []byte { - if len(s) > 1 { - if s[0:2] == "0x" || s[0:2] == "0X" { - s = s[2:] - } - if (s[0] == 'x' || s[0] == 'X') && (s[1] == 'd' || s[1] == 'D') && (s[2] == 'c' || s[2] == 'C') { - s = s[3:] - } + if has0xPrefix(s) { + s = s[2:] + } else if hasXdcPrefix(s) { + s = s[3:] } if len(s)%2 == 1 { s = "0" + s @@ -59,14 +56,14 @@ func CopyBytes(b []byte) (copiedBytes []byte) { return } -// hasXDCPrefix validates str begins with 'xdc' or 'XDC'. -func hasXDCPrefix(str string) bool { - return len(str) >= 3 && (str[0] == 'x' || str[0] == 'X') && (str[1] == 'd' || str[1] == 'D') && (str[2] == 'c' || str[2] == 'C') +// has0xPrefix validates str begins with '0x' or '0X'. +func has0xPrefix(str string) bool { + return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') } -// hasHexPrefix validates str begins with '0x' or '0X'. -func hasHexPrefix(str string) bool { - return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') +// hasXdcPrefix validates s begins with 'xdc' or 'XDC'. +func hasXdcPrefix(s string) bool { + return len(s) >= 3 && (s[0] == 'x' || s[0] == 'X') && (s[1] == 'd' || s[1] == 'D') && (s[2] == 'c' || s[2] == 'C') } // isHexCharacter returns bool of c being a valid hexadecimal. @@ -103,15 +100,13 @@ func Hex2BytesFixed(str string, flen int) []byte { h, _ := hex.DecodeString(str) if len(h) == flen { return h - } else { - if len(h) > flen { - return h[len(h)-flen:] - } else { - hh := make([]byte, flen) - copy(hh[flen-len(h):flen], h[:]) - return hh - } } + if len(h) > flen { + return h[len(h)-flen:] + } + hh := make([]byte, flen) + copy(hh[flen-len(h):flen], h[:]) + return hh } // RightPadBytes zero-pads slice to the right up to length l. diff --git a/common/types.go b/common/types.go index e2dd3b4b2db6..cf79aaa87027 100644 --- a/common/types.go +++ b/common/types.go @@ -209,11 +209,10 @@ func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } // IsHexAddress verifies whether a string can represent a valid hex-encoded // Ethereum address or not. func IsHexAddress(s string) bool { - if hasXDCPrefix(s) { - s = s[3:] - } - if hasHexPrefix(s) { + if has0xPrefix(s) { s = s[2:] + } else if hasXdcPrefix(s) { + s = s[3:] } return len(s) == 2*AddressLength && isHex(s) } From 56e242b06ce6f5a2e66356c649c645d65aa6e167 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 16 Dec 2024 17:26:11 +0800 Subject: [PATCH 046/121] core/state: optimize some internals during encoding (#20038) --- common/bytes.go | 11 ++++++++ core/state/state_object.go | 2 +- core/state/state_object_test.go | 48 +++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 core/state/state_object_test.go diff --git a/common/bytes.go b/common/bytes.go index 703705ee3f06..9025e98b19a5 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -132,3 +132,14 @@ func LeftPadBytes(slice []byte, l int) []byte { return padded } + +// TrimLeftZeroes returns a subslice of s without leading zeroes +func TrimLeftZeroes(s []byte) []byte { + idx := 0 + for ; idx < len(s); idx++ { + if s[idx] != 0 { + break + } + } + return s[idx:] +} diff --git a/core/state/state_object.go b/core/state/state_object.go index bb19597cc6f9..7eda5c4d4d75 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -282,7 +282,7 @@ func (s *stateObject) updateTrie(db Database) Trie { continue } // Encoding []byte cannot fail, ok to ignore the error. - v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) + v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(value[:])) s.setError(tr.TryUpdate(key[:], v)) } return tr diff --git a/core/state/state_object_test.go b/core/state/state_object_test.go new file mode 100644 index 000000000000..a5b28dec88f6 --- /dev/null +++ b/core/state/state_object_test.go @@ -0,0 +1,48 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "bytes" + "testing" + + "github.com/XinFinOrg/XDPoSChain/common" +) + +func BenchmarkCutOriginal(b *testing.B) { + value := common.HexToHash("0x01") + for i := 0; i < b.N; i++ { + bytes.TrimLeft(value[:], "\x00") + } +} + +func BenchmarkCutsetterFn(b *testing.B) { + value := common.HexToHash("0x01") + cutSetFn := func(r rune) bool { + return int32(r) == int32(0) + } + for i := 0; i < b.N; i++ { + bytes.TrimLeftFunc(value[:], cutSetFn) + } +} + +func BenchmarkCutCustomTrim(b *testing.B) { + value := common.HexToHash("0x01") + for i := 0; i < b.N; i++ { + common.TrimLeftZeroes(value[:]) + } +} From f5e90eecff3435408ec80edd3433872d8539e673 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 16 Dec 2024 17:41:47 +0800 Subject: [PATCH 047/121] common: improve test (#20354) --- common/bytes_test.go | 52 +++++++++++++++++++++++--------------------- common/main_test.go | 25 --------------------- 2 files changed, 27 insertions(+), 50 deletions(-) delete mode 100644 common/main_test.go diff --git a/common/bytes_test.go b/common/bytes_test.go index 97dd34d159de..7cf6553377fd 100644 --- a/common/bytes_test.go +++ b/common/bytes_test.go @@ -19,41 +19,43 @@ package common import ( "bytes" "testing" - - checker "gopkg.in/check.v1" ) -type BytesSuite struct{} - -var _ = checker.Suite(&BytesSuite{}) +func TestCopyBytes(t *testing.T) { + input := []byte{1, 2, 3, 4} -func (s *BytesSuite) TestCopyBytes(c *checker.C) { - data1 := []byte{1, 2, 3, 4} - exp1 := []byte{1, 2, 3, 4} - res1 := CopyBytes(data1) - c.Assert(res1, checker.DeepEquals, exp1) + v := CopyBytes(input) + if !bytes.Equal(v, []byte{1, 2, 3, 4}) { + t.Fatal("not equal after copy") + } + v[0] = 99 + if bytes.Equal(v, input) { + t.Fatal("result is not a copy") + } } -func (s *BytesSuite) TestLeftPadBytes(c *checker.C) { - val1 := []byte{1, 2, 3, 4} - exp1 := []byte{0, 0, 0, 0, 1, 2, 3, 4} - - res1 := LeftPadBytes(val1, 8) - res2 := LeftPadBytes(val1, 2) +func TestLeftPadBytes(t *testing.T) { + val := []byte{1, 2, 3, 4} + padded := []byte{0, 0, 0, 0, 1, 2, 3, 4} - c.Assert(res1, checker.DeepEquals, exp1) - c.Assert(res2, checker.DeepEquals, val1) + if r := LeftPadBytes(val, 8); !bytes.Equal(r, padded) { + t.Fatalf("LeftPadBytes(%v, 8) == %v", val, r) + } + if r := LeftPadBytes(val, 2); !bytes.Equal(r, val) { + t.Fatalf("LeftPadBytes(%v, 2) == %v", val, r) + } } -func (s *BytesSuite) TestRightPadBytes(c *checker.C) { +func TestRightPadBytes(t *testing.T) { val := []byte{1, 2, 3, 4} - exp := []byte{1, 2, 3, 4, 0, 0, 0, 0} - - resstd := RightPadBytes(val, 8) - resshrt := RightPadBytes(val, 2) + padded := []byte{1, 2, 3, 4, 0, 0, 0, 0} - c.Assert(resstd, checker.DeepEquals, exp) - c.Assert(resshrt, checker.DeepEquals, val) + if r := RightPadBytes(val, 8); !bytes.Equal(r, padded) { + t.Fatalf("RightPadBytes(%v, 8) == %v", val, r) + } + if r := RightPadBytes(val, 2); !bytes.Equal(r, val) { + t.Fatalf("RightPadBytes(%v, 2) == %v", val, r) + } } func TestFromHex(t *testing.T) { diff --git a/common/main_test.go b/common/main_test.go deleted file mode 100644 index 149d09928a9c..000000000000 --- a/common/main_test.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package common - -import ( - "testing" - - checker "gopkg.in/check.v1" -) - -func Test(t *testing.T) { checker.TestingT(t) } From 30f835c6a4a21249c7c71639a2a52978b26d2db9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 13:57:52 +0800 Subject: [PATCH 048/121] accounts/abi: common/math: moved U256Bytes (#21020) --- accounts/abi/abi_test.go | 24 +++++++++++-------- accounts/abi/bind/template.go | 1 - accounts/abi/numbers.go | 6 ----- accounts/abi/numbers_test.go | 44 ----------------------------------- accounts/abi/pack.go | 6 ++--- common/math/big.go | 6 +++++ common/math/big_test.go | 10 ++++++++ 7 files changed, 33 insertions(+), 64 deletions(-) delete mode 100644 accounts/abi/numbers_test.go diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 790505b8c043..1d8cd0162980 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -29,6 +29,7 @@ import ( "reflect" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" ) @@ -522,7 +523,7 @@ func TestInputFixedArrayAndVariableInputLength(t *testing.T) { strvalue = common.RightPadBytes([]byte(strin), 32) fixedarrin1value1 = common.LeftPadBytes(fixedarrin1[0].Bytes(), 32) fixedarrin1value2 = common.LeftPadBytes(fixedarrin1[1].Bytes(), 32) - dynarroffset = U256(big.NewInt(int64(256 + ((len(strin)/32)+1)*32))) + dynarroffset = math.U256Bytes(big.NewInt(int64(256 + ((len(strin)/32)+1)*32))) dynarrlength = make([]byte, 32) dynarrlength[31] = byte(len(dynarrin)) dynarrinvalue1 = common.LeftPadBytes(dynarrin[0].Bytes(), 32) @@ -620,16 +621,19 @@ func TestBareEvents(t *testing.T) { } // TestUnpackEvent is based on this contract: -// contract T { -// event received(address sender, uint amount, bytes memo); -// event receivedAddr(address sender); -// function receive(bytes memo) external payable { -// received(msg.sender, msg.value, memo); -// receivedAddr(msg.sender); -// } -// } +// +// contract T { +// event received(address sender, uint amount, bytes memo); +// event receivedAddr(address sender); +// function receive(bytes memo) external payable { +// received(msg.sender, msg.value, memo); +// receivedAddr(msg.sender); +// } +// } +// // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: -// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} +// +// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} func TestUnpackEvent(t *testing.T) { const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` abi, err := JSON(strings.NewReader(abiJSON)) diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 10e8ae9f0579..f7b1ebb62a86 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -84,7 +84,6 @@ var ( _ = big.NewInt _ = strings.NewReader _ = ethereum.ErrNotFound - _ = abi.U256 _ = bind.Bind _ = common.Big1 _ = types.BloomLookup diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go index ac053c2da70d..d389db33b705 100644 --- a/accounts/abi/numbers.go +++ b/accounts/abi/numbers.go @@ -21,7 +21,6 @@ import ( "reflect" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/common/math" ) var ( @@ -44,11 +43,6 @@ var ( int64_ts = reflect.TypeOf([]int64(nil)) ) -// U256 converts a big Int into a 256bit EVM number. -func U256(n *big.Int) []byte { - return math.PaddedBigBytes(math.U256(n), 32) -} - // checks whether the given reflect value is signed. This also works for slices with a number type func isSigned(v reflect.Value) bool { switch v.Type() { diff --git a/accounts/abi/numbers_test.go b/accounts/abi/numbers_test.go deleted file mode 100644 index b9ff5aef17d3..000000000000 --- a/accounts/abi/numbers_test.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package abi - -import ( - "bytes" - "math/big" - "reflect" - "testing" -) - -func TestNumberTypes(t *testing.T) { - ubytes := make([]byte, 32) - ubytes[31] = 1 - - unsigned := U256(big.NewInt(1)) - if !bytes.Equal(unsigned, ubytes) { - t.Errorf("expected %x got %x", ubytes, unsigned) - } -} - -func TestSigned(t *testing.T) { - if isSigned(reflect.ValueOf(uint(10))) { - t.Error("signed") - } - - if !isSigned(reflect.ValueOf(int(10))) { - t.Error("not signed") - } -} diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go index c38be40c918c..0041349894e5 100644 --- a/accounts/abi/pack.go +++ b/accounts/abi/pack.go @@ -69,11 +69,11 @@ func packElement(t Type, reflectValue reflect.Value) []byte { func packNum(value reflect.Value) []byte { switch kind := value.Kind(); kind { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return U256(new(big.Int).SetUint64(value.Uint())) + return math.U256Bytes(new(big.Int).SetUint64(value.Uint())) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return U256(big.NewInt(value.Int())) + return math.U256Bytes(big.NewInt(value.Int())) case reflect.Ptr: - return U256(value.Interface().(*big.Int)) + return math.U256Bytes(value.Interface().(*big.Int)) default: panic("abi: fatal error") } diff --git a/common/math/big.go b/common/math/big.go index d2cfb6ed5a9b..7254efed4823 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -176,6 +176,12 @@ func U256(x *big.Int) *big.Int { return x.And(x, tt256m1) } +// U256Bytes converts a big Int into a 256bit EVM number. +// This operation is destructive. +func U256Bytes(n *big.Int) []byte { + return PaddedBigBytes(U256(n), 32) +} + // S256 interprets x as a two's complement number. // x must not exceed 256 bits (the result is undefined if it does) and is not modified. // diff --git a/common/math/big_test.go b/common/math/big_test.go index 2c607bad5fa3..d9e5723c61c6 100644 --- a/common/math/big_test.go +++ b/common/math/big_test.go @@ -212,6 +212,16 @@ func TestU256(t *testing.T) { } } +func TestU256Bytes(t *testing.T) { + ubytes := make([]byte, 32) + ubytes[31] = 1 + + unsigned := U256Bytes(big.NewInt(1)) + if !bytes.Equal(unsigned, ubytes) { + t.Errorf("expected %x got %x", ubytes, unsigned) + } +} + func TestBigEndianByteAt(t *testing.T) { tests := []struct { x string From d3a943d0b33343533e2b7bc4d429e1d92b9cc691 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 9 Jul 2020 17:45:49 +0200 Subject: [PATCH 049/121] common/math: use math/bits intrinsics for Safe* (#21316) This is a resubmit of ledgerwatch/turbo-geth#556. The performance benefit of this change is negligible, but it does remove a TODO. --- common/math/integer.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/common/math/integer.go b/common/math/integer.go index 7eff4d3b0001..17a9fb1375d1 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -18,6 +18,7 @@ package math import ( "fmt" + "math/bits" "strconv" ) @@ -78,22 +79,20 @@ func MustParseUint64(s string) uint64 { return v } -// NOTE: The following methods need to be optimised using either bit checking or asm - -// SafeSub returns subtraction result and whether overflow occurred. +// SafeSub returns x-y and checks for overflow. func SafeSub(x, y uint64) (uint64, bool) { - return x - y, x < y + diff, borrowOut := bits.Sub64(x, y, 0) + return diff, borrowOut != 0 } -// SafeAdd returns the result and whether overflow occurred. +// SafeAdd returns x+y and checks for overflow. func SafeAdd(x, y uint64) (uint64, bool) { - return x + y, y > MaxUint64-x + sum, carryOut := bits.Add64(x, y, 0) + return sum, carryOut != 0 } -// SafeMul returns multiplication result and whether overflow occurred. +// SafeMul returns x*y and checks for overflow. func SafeMul(x, y uint64) (uint64, bool) { - if x == 0 || y == 0 { - return 0, false - } - return x * y, y > MaxUint64/x + hi, lo := bits.Mul64(x, y) + return lo, hi != 0 } From cf0c5c8cd223815cc75f122abdf6d8addcfa2265 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 16 Dec 2024 18:52:16 +0800 Subject: [PATCH 050/121] common/prque: refactor LazyQueue (#21236) --- common/prque/lazyqueue.go | 56 +++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index 035b8ff9e7b9..fc6b9b2f26e9 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -26,9 +26,10 @@ import ( // LazyQueue is a priority queue data structure where priorities can change over // time and are only evaluated on demand. // Two callbacks are required: -// - priority evaluates the actual priority of an item -// - maxPriority gives an upper estimate for the priority in any moment between -// now and the given absolute time +// - priority evaluates the actual priority of an item +// - maxPriority gives an upper estimate for the priority in any moment between +// now and the given absolute time +// // If the upper estimate is exceeded then Update should be called for that item. // A global Refresh function should also be called periodically. type LazyQueue struct { @@ -36,14 +37,15 @@ type LazyQueue struct { // Items are stored in one of two internal queues ordered by estimated max // priority until the next and the next-after-next refresh. Update and Refresh // always places items in queue[1]. - queue [2]*sstack - popQueue *sstack - period time.Duration - maxUntil mclock.AbsTime - indexOffset int - setIndex SetIndexCallback - priority PriorityCallback - maxPriority MaxPriorityCallback + queue [2]*sstack + popQueue *sstack + period time.Duration + maxUntil mclock.AbsTime + indexOffset int + setIndex SetIndexCallback + priority PriorityCallback + maxPriority MaxPriorityCallback + lastRefresh1, lastRefresh2 mclock.AbsTime } type ( @@ -54,14 +56,17 @@ type ( // NewLazyQueue creates a new lazy queue func NewLazyQueue(setIndex SetIndexCallback, priority PriorityCallback, maxPriority MaxPriorityCallback, clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue { q := &LazyQueue{ - popQueue: newSstack(nil), - setIndex: setIndex, - priority: priority, - maxPriority: maxPriority, - clock: clock, - period: refreshPeriod} + popQueue: newSstack(nil), + setIndex: setIndex, + priority: priority, + maxPriority: maxPriority, + clock: clock, + period: refreshPeriod, + lastRefresh1: clock.Now(), + lastRefresh2: clock.Now(), + } q.Reset() - q.Refresh() + q.refresh(clock.Now()) return q } @@ -71,9 +76,19 @@ func (q *LazyQueue) Reset() { q.queue[1] = newSstack(q.setIndex1) } -// Refresh should be called at least with the frequency specified by the refreshPeriod parameter +// Refresh performs queue re-evaluation if necessary func (q *LazyQueue) Refresh() { - q.maxUntil = q.clock.Now() + mclock.AbsTime(q.period) + now := q.clock.Now() + for time.Duration(now-q.lastRefresh2) >= q.period*2 { + q.refresh(now) + q.lastRefresh2 = q.lastRefresh1 + q.lastRefresh1 = now + } +} + +// refresh re-evaluates items in the older queue and swaps the two queues +func (q *LazyQueue) refresh(now mclock.AbsTime) { + q.maxUntil = now + mclock.AbsTime(q.period) for q.queue[0].Len() != 0 { q.Push(heap.Pop(q.queue[0]).(*item).value) } @@ -139,6 +154,7 @@ func (q *LazyQueue) MultiPop(callback func(data interface{}, priority int64) boo } return } + nextIndex = q.peekIndex() // re-check because callback is allowed to push items back } } } From 28739d786310766d3faef1f576eb85882dcbe4de Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 16 Dec 2024 19:19:30 +0800 Subject: [PATCH 051/121] common: remove usage of deprecated function (#21610) --- accounts/abi/abi_test.go | 6 +++--- common/bytes.go | 16 +++------------- .../XDPoS/engines/engine_v2/verifyHeader.go | 3 ++- contracts/blocksigner/blocksigner_test.go | 6 +++--- contracts/randomize/randomize_test.go | 3 ++- contracts/validator/validator_test.go | 3 ++- core/types/transaction.go | 9 +++++---- ethclient/ethclient.go | 6 +++--- 8 files changed, 23 insertions(+), 29 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 1d8cd0162980..968cdb694141 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -23,12 +23,12 @@ import ( "fmt" "log" "math/big" + "reflect" "strings" "testing" - "reflect" - "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" ) @@ -713,7 +713,7 @@ func TestABI_MethodById(t *testing.T) { } b := fmt.Sprintf("%v", m2) if a != b { - t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, common.ToHex(m.Id())) + t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, hexutil.Encode(m.Id())) } } diff --git a/common/bytes.go b/common/bytes.go index 9025e98b19a5..3aaf97bd68c7 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -17,19 +17,9 @@ // Package common contains various helper functions. package common -import "encoding/hex" - -// ToHex returns the hex representation of b, prefixed with '0x'. -// For empty slices, the return value is "0x0". -// -// Deprecated: use hexutil.Encode instead. -func ToHex(b []byte) string { - hex := Bytes2Hex(b) - if len(hex) == 0 { - hex = "0" - } - return "0x" + hex -} +import ( + "encoding/hex" +) // FromHex returns the bytes represented by the hexadecimal string s. // s may be prefixed with "0x". diff --git a/consensus/XDPoS/engines/engine_v2/verifyHeader.go b/consensus/XDPoS/engines/engine_v2/verifyHeader.go index 8341ae1c6be8..b90f942d0712 100644 --- a/consensus/XDPoS/engines/engine_v2/verifyHeader.go +++ b/consensus/XDPoS/engines/engine_v2/verifyHeader.go @@ -6,6 +6,7 @@ import ( "time" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/consensus/misc" @@ -171,7 +172,7 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade for index, mn := range masterNodes { log.Error("[verifyHeader] masternode list during validator verification", "Masternode Address", mn.Hex(), "index", index) } - log.Error("[verifyHeader] Error while verifying header validator signature", "BlockNumber", header.Number, "Hash", header.Hash().Hex(), "validator in hex", common.ToHex(header.Validator)) + log.Error("[verifyHeader] Error while verifying header validator signature", "BlockNumber", header.Number, "Hash", header.Hash().Hex(), "validator in hex", hexutil.Encode(header.Validator)) return err } if !verified { diff --git a/contracts/blocksigner/blocksigner_test.go b/contracts/blocksigner/blocksigner_test.go index 54f89b29026e..d1f8cbc0f486 100644 --- a/contracts/blocksigner/blocksigner_test.go +++ b/contracts/blocksigner/blocksigner_test.go @@ -18,14 +18,14 @@ package blocksigner import ( "context" "math/big" + "math/rand" "testing" "time" - "math/rand" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" @@ -50,7 +50,7 @@ func TestBlockSigner(t *testing.T) { ctx, cancel := context.WithDeadline(context.Background(), d) defer cancel() code, _ := contractBackend.CodeAt(ctx, blockSignerAddress, nil) - t.Log("contract code", common.ToHex(code)) + t.Log("contract code", hexutil.Encode(code)) f := func(key, val common.Hash) bool { t.Log(key.Hex(), val.Hex()) return true diff --git a/contracts/randomize/randomize_test.go b/contracts/randomize/randomize_test.go index 3d4dead11d55..14d229196c6c 100644 --- a/contracts/randomize/randomize_test.go +++ b/contracts/randomize/randomize_test.go @@ -24,6 +24,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/contracts" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -56,7 +57,7 @@ func TestRandomize(t *testing.T) { ctx, cancel := context.WithDeadline(context.Background(), d) defer cancel() code, _ := contractBackend.CodeAt(ctx, randomizeAddress, nil) - t.Log("contract code", common.ToHex(code)) + t.Log("contract code", hexutil.Encode(code)) f := func(key, val common.Hash) bool { t.Log(key.Hex(), val.Hex()) return true diff --git a/contracts/validator/validator_test.go b/contracts/validator/validator_test.go index 6ebe924b5cf2..c2b5d0fde123 100644 --- a/contracts/validator/validator_test.go +++ b/contracts/validator/validator_test.go @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" contractValidator "github.com/XinFinOrg/XDPoSChain/contracts/validator/contract" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" @@ -68,7 +69,7 @@ func TestValidator(t *testing.T) { ctx, cancel := context.WithDeadline(context.Background(), d) defer cancel() code, _ := contractBackend.CodeAt(ctx, validatorAddress, nil) - t.Log("contract code", common.ToHex(code)) + t.Log("contract code", hexutil.Encode(code)) f := func(key, val common.Hash) bool { t.Log(key.Hex(), val.Hex()) return true diff --git a/core/types/transaction.go b/core/types/transaction.go index f0afdca06092..dca1ef50a5bf 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -27,6 +27,7 @@ import ( "time" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/rlp" @@ -513,7 +514,7 @@ func (tx *Transaction) IsSigningTransaction() bool { if len(data) != (32*2 + 4) { return false } - method := common.ToHex(data[0:4]) + method := hexutil.Encode(data[0:4]) return method == common.SignMethod } @@ -524,7 +525,7 @@ func (tx *Transaction) IsVotingTransaction() (bool, *common.Address) { } var end int data := tx.Data() - method := common.ToHex(data[0:4]) + method := hexutil.Encode(data[0:4]) if method == common.VoteMethod || method == common.ProposeMethod || method == common.ResignMethod { end = len(data) } else if method == common.UnvoteMethod { @@ -558,7 +559,7 @@ func (tx *Transaction) IsXDCXApplyTransaction() bool { if len(data) != (32 + 4) { return false } - method := common.ToHex(data[0:4]) + method := hexutil.Encode(data[0:4]) return method == common.XDCXApplyMethod } @@ -581,7 +582,7 @@ func (tx *Transaction) IsXDCZApplyTransaction() bool { if len(data) != (32 + 4) { return false } - method := common.ToHex(data[0:4]) + method := hexutil.Encode(data[0:4]) return method == common.XDCZApplyMethod } diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 936c08153421..6b391d03db0c 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -527,7 +527,7 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er if err != nil { return err } - return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) + return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)) } func toBlockNumArg(number *big.Int) string { @@ -550,7 +550,7 @@ func (ec *Client) SendOrderTransaction(ctx context.Context, tx *types.OrderTrans if err != nil { return err } - return ec.c.CallContext(ctx, nil, "XDCx_sendOrderRawTransaction", common.ToHex(data)) + return ec.c.CallContext(ctx, nil, "XDCx_sendOrderRawTransaction", hexutil.Encode(data)) } // SendLendingTransaction send lending to pool @@ -559,7 +559,7 @@ func (ec *Client) SendLendingTransaction(ctx context.Context, tx *types.LendingT if err != nil { return err } - return ec.c.CallContext(ctx, nil, "XDCx_sendLendingRawTransaction", common.ToHex(data)) + return ec.c.CallContext(ctx, nil, "XDCx_sendLendingRawTransaction", hexutil.Encode(data)) } func toCallArg(msg ethereum.CallMsg) interface{} { From dd318fc563bf0e369dee8aa622c503122e048f74 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 16 Dec 2024 19:24:01 +0800 Subject: [PATCH 052/121] common/hexutil: remove redundant conversion (#21903) --- common/hexutil/json_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/hexutil/json_test.go b/common/hexutil/json_test.go index 8a6b8643a1e9..ed7d6fad1a8e 100644 --- a/common/hexutil/json_test.go +++ b/common/hexutil/json_test.go @@ -88,7 +88,7 @@ func TestUnmarshalBytes(t *testing.T) { if !checkError(t, test.input, err, test.wantErr) { continue } - if !bytes.Equal(test.want.([]byte), []byte(v)) { + if !bytes.Equal(test.want.([]byte), v) { t.Errorf("input %s: value mismatch: got %x, want %x", test.input, &v, test.want) continue } From c2db0e42d7a3e68487864fc65034ccfc0a305f7c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 10:24:15 +0800 Subject: [PATCH 053/121] common: improve printing of Hash and Address (#21834) --- common/types.go | 94 +++++++++++++++++++----- common/types_test.go | 166 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+), 18 deletions(-) diff --git a/common/types.go b/common/types.go index cf79aaa87027..d28075c273e1 100644 --- a/common/types.go +++ b/common/types.go @@ -130,10 +130,34 @@ func (h Hash) String() string { return h.Hex() } -// Format implements fmt.Formatter, forcing the byte slice to be formatted as is, -// without going through the stringer interface used for logging. +// Format implements fmt.Formatter. +// Hash supports the %v, %s, %v, %x, %X and %d format verbs. func (h Hash) Format(s fmt.State, c rune) { - fmt.Fprintf(s, "%"+string(c), h[:]) + hexb := make([]byte, 2+len(h)*2) + copy(hexb, "0x") + hex.Encode(hexb[2:], h[:]) + + switch c { + case 'x', 'X': + if !s.Flag('#') { + hexb = hexb[2:] + } + if c == 'X' { + hexb = bytes.ToUpper(hexb) + } + fallthrough + case 'v', 's': + s.Write(hexb) + case 'q': + q := []byte{'"'} + s.Write(q) + s.Write(hexb) + s.Write(q) + case 'd': + fmt.Fprint(s, ([len(h)]byte)(h)) + default: + fmt.Fprintf(s, "%%!%c(hash=%x)", c, h) + } } // UnmarshalText parses a hash in hex syntax. @@ -231,35 +255,69 @@ func (a Address) Hash() Hash { return BytesToHash(a[:]) } // Hex returns an EIP55-compliant hex string representation of the address. func (a Address) Hex() string { - unchecksummed := hex.EncodeToString(a[:]) + checksumed := a.checksumHex() + return "xdc" + string(checksumed[2:]) +} + +// String implements fmt.Stringer. +func (a Address) String() string { + return a.Hex() +} + +func (a *Address) checksumHex() []byte { + buf := a.hex() + + // compute checksum sha := sha3.NewLegacyKeccak256() - sha.Write([]byte(unchecksummed)) + sha.Write(buf[2:]) hash := sha.Sum(nil) - - result := []byte(unchecksummed) - for i := 0; i < len(result); i++ { - hashByte := hash[i/2] + for i := 2; i < len(buf); i++ { + hashByte := hash[(i-2)/2] if i%2 == 0 { hashByte = hashByte >> 4 } else { hashByte &= 0xf } - if result[i] > '9' && hashByte > 7 { - result[i] -= 32 + if buf[i] > '9' && hashByte > 7 { + buf[i] -= 32 } } - return "xdc" + string(result) + return buf[:] } -// String implements fmt.Stringer. -func (a Address) String() string { - return a.Hex() +func (a Address) hex() []byte { + var buf [len(a)*2 + 2]byte + copy(buf[:2], "0x") + hex.Encode(buf[2:], a[:]) + return buf[:] } -// Format implements fmt.Formatter, forcing the byte slice to be formatted as is, -// without going through the stringer interface used for logging. +// Format implements fmt.Formatter. +// Address supports the %v, %s, %q, %x, %X and %d format verbs. func (a Address) Format(s fmt.State, c rune) { - fmt.Fprintf(s, "%"+string(c), a[:]) + switch c { + case 'v', 's': + s.Write(a.checksumHex()) + case 'q': + q := []byte{'"'} + s.Write(q) + s.Write(a.checksumHex()) + s.Write(q) + case 'x', 'X': + // %x disables the checksum. + hex := a.hex() + if !s.Flag('#') { + hex = hex[2:] + } + if c == 'X' { + hex = bytes.ToUpper(hex) + } + s.Write(hex) + case 'd': + fmt.Fprint(s, ([len(a)]byte)(a)) + default: + fmt.Fprintf(s, "%%!%c(address=%x)", c, a) + } } // SetBytes sets the address to the value of b. diff --git a/common/types_test.go b/common/types_test.go index ea0fb22d2480..598286c08978 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -17,7 +17,9 @@ package common import ( + "bytes" "encoding/json" + "fmt" "math/big" "strings" "testing" @@ -156,6 +158,170 @@ func BenchmarkAddressHex(b *testing.B) { } } +func TestAddress_Format(t *testing.T) { + b := []byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + } + var addr Address + addr.SetBytes(b) + + tests := []struct { + name string + out string + want string + }{ + { + name: "println", + out: fmt.Sprintln(addr), + want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15\n", + }, + { + name: "print", + out: fmt.Sprint(addr), + want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", + }, + { + name: "printf-s", + out: func() string { + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "%s", addr) + return buf.String() + }(), + want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", + }, + { + name: "printf-q", + out: fmt.Sprintf("%q", addr), + want: `"0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15"`, + }, + { + name: "printf-x", + out: fmt.Sprintf("%x", addr), + want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15", + }, + { + name: "printf-X", + out: fmt.Sprintf("%X", addr), + want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15", + }, + { + name: "printf-#x", + out: fmt.Sprintf("%#x", addr), + want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15", + }, + { + name: "printf-v", + out: fmt.Sprintf("%v", addr), + want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", + }, + // The original default formatter for byte slice + { + name: "printf-d", + out: fmt.Sprintf("%d", addr), + want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21]", + }, + // Invalid format char. + { + name: "printf-t", + out: fmt.Sprintf("%t", addr), + want: "%!t(address=b26f2b342aab24bcf63ea218c6a9274d30ab9a15)", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.out != tt.want { + t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) + } + }) + } +} + +func TestHash_Format(t *testing.T) { + var hash Hash + hash.SetBytes([]byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + 0x10, 0x00, + }) + + tests := []struct { + name string + out string + want string + }{ + { + name: "println", + out: fmt.Sprintln(hash), + want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000\n", + }, + { + name: "print", + out: fmt.Sprint(hash), + want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", + }, + { + name: "printf-s", + out: func() string { + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "%s", hash) + return buf.String() + }(), + want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", + }, + { + name: "printf-q", + out: fmt.Sprintf("%q", hash), + want: `"0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000"`, + }, + { + name: "printf-x", + out: fmt.Sprintf("%x", hash), + want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", + }, + { + name: "printf-X", + out: fmt.Sprintf("%X", hash), + want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", + }, + { + name: "printf-#x", + out: fmt.Sprintf("%#x", hash), + want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", + }, + { + name: "printf-#X", + out: fmt.Sprintf("%#X", hash), + want: "0XB26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", + }, + { + name: "printf-v", + out: fmt.Sprintf("%v", hash), + want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", + }, + // The original default formatter for byte slice + { + name: "printf-d", + out: fmt.Sprintf("%d", hash), + want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21 162 24 198 169 39 77 48 171 154 21 16 0]", + }, + // Invalid format char. + { + name: "printf-t", + out: fmt.Sprintf("%t", hash), + want: "%!t(hash=b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000)", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.out != tt.want { + t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) + } + }) + } +} + func TestRemoveItemInArray(t *testing.T) { array := []Address{HexToAddress("0x0000003"), HexToAddress("0x0000001"), HexToAddress("0x0000002"), HexToAddress("0x0000003")} remove := []Address{HexToAddress("0x0000002"), HexToAddress("0x0000004"), HexToAddress("0x0000003")} From f01e639f6fd6c2dd34fddfba5f20fc83a48a695d Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 5 Jan 2021 14:48:22 +0100 Subject: [PATCH 054/121] common/compiler: fix parsing of solc output with solidity v.0.8.0 (#22092) Solidity 0.8.0 changes the way that output is marshalled. This patch allows to parse both the legacy format used previously and the new format. See also https://docs.soliditylang.org/en/breaking/080-breaking-changes.html#interface-changes --- common/compiler/solidity.go | 50 +++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index f0363dc92b18..a023b5685c02 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -44,6 +44,20 @@ type solcOutput struct { Version string } +// solidity v.0.8 changes the way ABI, Devdoc and Userdoc are serialized +type solcOutputV8 struct { + Contracts map[string]struct { + BinRuntime string `json:"bin-runtime"` + SrcMapRuntime string `json:"srcmap-runtime"` + Bin, SrcMap, Metadata string + Abi interface{} + Devdoc interface{} + Userdoc interface{} + Hashes map[string]string + } + Version string +} + func (s *Solidity) makeArgs() []string { p := []string{ "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc", @@ -125,7 +139,6 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro if err := cmd.Run(); err != nil { return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes()) } - return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) } @@ -141,7 +154,8 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { var output solcOutput if err := json.Unmarshal(combinedJSON, &output); err != nil { - return nil, err + // Try to parse the output with the new solidity v.0.8.0 rules + return parseCombinedJSONV8(combinedJSON, source, languageVersion, compilerVersion, compilerOptions) } // Compilation succeeded, assemble and return the contracts. contracts := make(map[string]*Contract) @@ -176,3 +190,35 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin } return contracts, nil } + +// parseCombinedJSONV8 parses the direct output of solc --combined-output +// and parses it using the rules from solidity v.0.8.0 and later. +func parseCombinedJSONV8(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { + var output solcOutputV8 + if err := json.Unmarshal(combinedJSON, &output); err != nil { + return nil, err + } + // Compilation succeeded, assemble and return the contracts. + contracts := make(map[string]*Contract) + for name, info := range output.Contracts { + contracts[name] = &Contract{ + Code: "0x" + info.Bin, + RuntimeCode: "0x" + info.BinRuntime, + Hashes: info.Hashes, + Info: ContractInfo{ + Source: source, + Language: "Solidity", + LanguageVersion: languageVersion, + CompilerVersion: compilerVersion, + CompilerOptions: compilerOptions, + SrcMap: info.SrcMap, + SrcMapRuntime: info.SrcMapRuntime, + AbiDefinition: info.Abi, + UserDoc: info.Userdoc, + DeveloperDoc: info.Devdoc, + Metadata: info.Metadata, + }, + } + } + return contracts, nil +} From d852f8cf88690847a272c6efc048e2d433204a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 11 Jan 2021 10:31:03 +0200 Subject: [PATCH 055/121] common/prque: pull in tests and benchmarks from upstream (#22157) --- common/prque/prque_test.go | 130 ++++++++++++++++++++++++++++++++++++ common/prque/sstack_test.go | 100 +++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 common/prque/prque_test.go create mode 100644 common/prque/sstack_test.go diff --git a/common/prque/prque_test.go b/common/prque/prque_test.go new file mode 100644 index 000000000000..1cffcebad437 --- /dev/null +++ b/common/prque/prque_test.go @@ -0,0 +1,130 @@ +// CookieJar - A contestant's algorithm toolbox +// Copyright (c) 2013 Peter Szilagyi. All rights reserved. +// +// CookieJar is dual licensed: use of this source code is governed by a BSD +// license that can be found in the LICENSE file. Alternatively, the CookieJar +// toolbox may be used in accordance with the terms and conditions contained +// in a signed written agreement between you and the author(s). + +package prque + +import ( + "math/rand" + "testing" +) + +func TestPrque(t *testing.T) { + // Generate a batch of random data and a specific priority order + size := 16 * blockSize + prio := rand.Perm(size) + data := make([]int, size) + for i := 0; i < size; i++ { + data[i] = rand.Int() + } + queue := New(nil) + for rep := 0; rep < 2; rep++ { + // Fill a priority queue with the above data + for i := 0; i < size; i++ { + queue.Push(data[i], int64(prio[i])) + if queue.Size() != i+1 { + t.Errorf("queue size mismatch: have %v, want %v.", queue.Size(), i+1) + } + } + // Create a map the values to the priorities for easier verification + dict := make(map[int64]int) + for i := 0; i < size; i++ { + dict[int64(prio[i])] = data[i] + } + // Pop out the elements in priority order and verify them + prevPrio := int64(size + 1) + for !queue.Empty() { + val, prio := queue.Pop() + if prio > prevPrio { + t.Errorf("invalid priority order: %v after %v.", prio, prevPrio) + } + prevPrio = prio + if val != dict[prio] { + t.Errorf("push/pop mismatch: have %v, want %v.", val, dict[prio]) + } + delete(dict, prio) + } + } +} + +func TestReset(t *testing.T) { + // Generate a batch of random data and a specific priority order + size := 16 * blockSize + prio := rand.Perm(size) + data := make([]int, size) + for i := 0; i < size; i++ { + data[i] = rand.Int() + } + queue := New(nil) + for rep := 0; rep < 2; rep++ { + // Fill a priority queue with the above data + for i := 0; i < size; i++ { + queue.Push(data[i], int64(prio[i])) + if queue.Size() != i+1 { + t.Errorf("queue size mismatch: have %v, want %v.", queue.Size(), i+1) + } + } + // Create a map the values to the priorities for easier verification + dict := make(map[int64]int) + for i := 0; i < size; i++ { + dict[int64(prio[i])] = data[i] + } + // Pop out half the elements in priority order and verify them + prevPrio := int64(size + 1) + for i := 0; i < size/2; i++ { + val, prio := queue.Pop() + if prio > prevPrio { + t.Errorf("invalid priority order: %v after %v.", prio, prevPrio) + } + prevPrio = prio + if val != dict[prio] { + t.Errorf("push/pop mismatch: have %v, want %v.", val, dict[prio]) + } + delete(dict, prio) + } + // Reset and ensure it's empty + queue.Reset() + if !queue.Empty() { + t.Errorf("priority queue not empty after reset: %v", queue) + } + } +} + +func BenchmarkPush(b *testing.B) { + // Create some initial data + data := make([]int, b.N) + prio := make([]int64, b.N) + for i := 0; i < len(data); i++ { + data[i] = rand.Int() + prio[i] = rand.Int63() + } + // Execute the benchmark + b.ResetTimer() + queue := New(nil) + for i := 0; i < len(data); i++ { + queue.Push(data[i], prio[i]) + } +} + +func BenchmarkPop(b *testing.B) { + // Create some initial data + data := make([]int, b.N) + prio := make([]int64, b.N) + for i := 0; i < len(data); i++ { + data[i] = rand.Int() + prio[i] = rand.Int63() + } + queue := New(nil) + for i := 0; i < len(data); i++ { + queue.Push(data[i], prio[i]) + } + // Execute the benchmark + b.ResetTimer() + for !queue.Empty() { + queue.Pop() + } +} diff --git a/common/prque/sstack_test.go b/common/prque/sstack_test.go new file mode 100644 index 000000000000..2ff093579da9 --- /dev/null +++ b/common/prque/sstack_test.go @@ -0,0 +1,100 @@ +// CookieJar - A contestant's algorithm toolbox +// Copyright (c) 2013 Peter Szilagyi. All rights reserved. +// +// CookieJar is dual licensed: use of this source code is governed by a BSD +// license that can be found in the LICENSE file. Alternatively, the CookieJar +// toolbox may be used in accordance with the terms and conditions contained +// in a signed written agreement between you and the author(s). + +package prque + +import ( + "math/rand" + "sort" + "testing" +) + +func TestSstack(t *testing.T) { + // Create some initial data + size := 16 * blockSize + data := make([]*item, size) + for i := 0; i < size; i++ { + data[i] = &item{rand.Int(), rand.Int63()} + } + stack := newSstack(nil) + for rep := 0; rep < 2; rep++ { + // Push all the data into the stack, pop out every second + secs := []*item{} + for i := 0; i < size; i++ { + stack.Push(data[i]) + if i%2 == 0 { + secs = append(secs, stack.Pop().(*item)) + } + } + rest := []*item{} + for stack.Len() > 0 { + rest = append(rest, stack.Pop().(*item)) + } + // Make sure the contents of the resulting slices are ok + for i := 0; i < size; i++ { + if i%2 == 0 && data[i] != secs[i/2] { + t.Errorf("push/pop mismatch: have %v, want %v.", secs[i/2], data[i]) + } + if i%2 == 1 && data[i] != rest[len(rest)-i/2-1] { + t.Errorf("push/pop mismatch: have %v, want %v.", rest[len(rest)-i/2-1], data[i]) + } + } + } +} + +func TestSstackSort(t *testing.T) { + // Create some initial data + size := 16 * blockSize + data := make([]*item, size) + for i := 0; i < size; i++ { + data[i] = &item{rand.Int(), int64(i)} + } + // Push all the data into the stack + stack := newSstack(nil) + for _, val := range data { + stack.Push(val) + } + // Sort and pop the stack contents (should reverse the order) + sort.Sort(stack) + for _, val := range data { + out := stack.Pop() + if out != val { + t.Errorf("push/pop mismatch after sort: have %v, want %v.", out, val) + } + } +} + +func TestSstackReset(t *testing.T) { + // Create some initial data + size := 16 * blockSize + data := make([]*item, size) + for i := 0; i < size; i++ { + data[i] = &item{rand.Int(), rand.Int63()} + } + stack := newSstack(nil) + for rep := 0; rep < 2; rep++ { + // Push all the data into the stack, pop out every second + secs := []*item{} + for i := 0; i < size; i++ { + stack.Push(data[i]) + if i%2 == 0 { + secs = append(secs, stack.Pop().(*item)) + } + } + // Reset and verify both pulled and stack contents + stack.Reset() + if stack.Len() != 0 { + t.Errorf("stack not empty after reset: %v", stack) + } + for i := 0; i < size; i++ { + if i%2 == 0 && data[i] != secs[i/2] { + t.Errorf("push/pop mismatch: have %v, want %v.", secs[i/2], data[i]) + } + } + } +} From 6f19ace5e2a9a76ac6168c73af11d1d32a0e1d9c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 11:02:22 +0800 Subject: [PATCH 056/121] common/mclock: remove dependency on github.com/aristanetworks/goarista (#22211) --- common/mclock/mclock.go | 12 ++++++++---- common/mclock/mclock.s | 1 + go.mod | 1 - go.sum | 2 -- 4 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 common/mclock/mclock.s diff --git a/common/mclock/mclock.go b/common/mclock/mclock.go index 3aca257cb368..c05738cf2bf0 100644 --- a/common/mclock/mclock.go +++ b/common/mclock/mclock.go @@ -20,15 +20,19 @@ package mclock import ( "time" - "github.com/aristanetworks/goarista/monotime" + _ "unsafe" // for go:linkname ) +//go:noescape +//go:linkname nanotime runtime.nanotime +func nanotime() int64 + // AbsTime represents absolute monotonic time. -type AbsTime time.Duration +type AbsTime int64 // Now returns the current absolute monotonic time. func Now() AbsTime { - return AbsTime(monotime.Now()) + return AbsTime(nanotime()) } // Add returns t + d as absolute time. @@ -74,7 +78,7 @@ type System struct{} // Now returns the current monotonic time. func (c System) Now() AbsTime { - return AbsTime(monotime.Now()) + return Now() } // Sleep blocks for the given duration. diff --git a/common/mclock/mclock.s b/common/mclock/mclock.s new file mode 100644 index 000000000000..99a7a878f0da --- /dev/null +++ b/common/mclock/mclock.s @@ -0,0 +1 @@ +// This file exists in order to be able to use go:linkname. diff --git a/go.mod b/go.mod index 23a0995a49e8..9adb083eca74 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.22 require ( github.com/VictoriaMetrics/fastcache v1.12.2 - github.com/aristanetworks/goarista v0.0.0-20231019142648-8c6f0862ab98 github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 github.com/cespare/cp v1.1.1 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index bb2ab2b777cb..e59acf391656 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,6 @@ github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjC github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/aristanetworks/goarista v0.0.0-20231019142648-8c6f0862ab98 h1:7buXGE+m4OPjyo8rUJgA8RmARNMq+m99JJLR+Z+ZWN0= -github.com/aristanetworks/goarista v0.0.0-20231019142648-8c6f0862ab98/go.mod h1:DLTg9Gp4FAXF5EpqYBQnUeBbRsNLY7b2HR94TE5XQtE= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI= From e52587df53c7df46b11099266f8ca174448abfa3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 11:22:11 +0800 Subject: [PATCH 057/121] common: do not pass current time as param in priority funcs (#22183) --- common/prque/lazyqueue.go | 5 ++--- common/prque/lazyqueue_test.go | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index fc6b9b2f26e9..1a9c1e0007c8 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -49,7 +49,7 @@ type LazyQueue struct { } type ( - PriorityCallback func(data interface{}, now mclock.AbsTime) int64 // actual priority callback + PriorityCallback func(data interface{}) int64 // actual priority callback MaxPriorityCallback func(data interface{}, until mclock.AbsTime) int64 // estimated maximum priority callback ) @@ -140,11 +140,10 @@ func (q *LazyQueue) peekIndex() int { // Pop multiple times. Popped items are passed to the callback. MultiPop returns // when the callback returns false or there are no more items to pop. func (q *LazyQueue) MultiPop(callback func(data interface{}, priority int64) bool) { - now := q.clock.Now() nextIndex := q.peekIndex() for nextIndex != -1 { data := heap.Pop(q.queue[nextIndex]).(*item).value - heap.Push(q.popQueue, &item{data, q.priority(data, now)}) + heap.Push(q.popQueue, &item{data, q.priority(data)}) nextIndex = q.peekIndex() for q.popQueue.Len() != 0 && (nextIndex == -1 || q.queue[nextIndex].blocks[0][0].priority < q.popQueue.blocks[0][0].priority) { i := heap.Pop(q.popQueue).(*item) diff --git a/common/prque/lazyqueue_test.go b/common/prque/lazyqueue_test.go index bb43bd06d79f..090d7120e311 100644 --- a/common/prque/lazyqueue_test.go +++ b/common/prque/lazyqueue_test.go @@ -40,7 +40,7 @@ type lazyItem struct { index int } -func testPriority(a interface{}, now mclock.AbsTime) int64 { +func testPriority(a interface{}) int64 { return a.(*lazyItem).p } @@ -56,7 +56,6 @@ func testSetIndex(a interface{}, i int) { } func TestLazyQueue(t *testing.T) { - rand.Seed(time.Now().UnixNano()) clock := &mclock.Simulated{} q := NewLazyQueue(testSetIndex, testPriority, testMaxPriority, clock, testQueueRefresh) From e2eb22dcac3dea0d4e5266c637e7a9ed995852b3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 11:37:21 +0800 Subject: [PATCH 058/121] common/prque: make Prque wrap-around priority handling optional (#22495) --- common/prque/lazyqueue.go | 6 +++--- common/prque/prque.go | 11 ++++++++--- common/prque/sstack.go | 20 +++++++++++++------- common/prque/sstack_test.go | 6 +++--- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index 1a9c1e0007c8..85d7bf6eee7e 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -56,7 +56,7 @@ type ( // NewLazyQueue creates a new lazy queue func NewLazyQueue(setIndex SetIndexCallback, priority PriorityCallback, maxPriority MaxPriorityCallback, clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue { q := &LazyQueue{ - popQueue: newSstack(nil), + popQueue: newSstack(nil, false), setIndex: setIndex, priority: priority, maxPriority: maxPriority, @@ -72,8 +72,8 @@ func NewLazyQueue(setIndex SetIndexCallback, priority PriorityCallback, maxPrior // Reset clears the contents of the queue func (q *LazyQueue) Reset() { - q.queue[0] = newSstack(q.setIndex0) - q.queue[1] = newSstack(q.setIndex1) + q.queue[0] = newSstack(q.setIndex0, false) + q.queue[1] = newSstack(q.setIndex1, false) } // Refresh performs queue re-evaluation if necessary diff --git a/common/prque/prque.go b/common/prque/prque.go index 3cc5a1adaf15..fb02e3418c28 100755 --- a/common/prque/prque.go +++ b/common/prque/prque.go @@ -28,7 +28,12 @@ type Prque struct { // New creates a new priority queue. func New(setIndex SetIndexCallback) *Prque { - return &Prque{newSstack(setIndex)} + return &Prque{newSstack(setIndex, false)} +} + +// NewWrapAround creates a new priority queue with wrap-around priority handling. +func NewWrapAround(setIndex SetIndexCallback) *Prque { + return &Prque{newSstack(setIndex, true)} } // Pushes a value with a given priority into the queue, expanding if necessary. @@ -36,13 +41,13 @@ func (p *Prque) Push(data interface{}, priority int64) { heap.Push(p.cont, &item{data, priority}) } -// Peek returns the value with the greates priority but does not pop it off. +// Peek returns the value with the greatest priority but does not pop it off. func (p *Prque) Peek() (interface{}, int64) { item := p.cont.blocks[0][0] return item.value, item.priority } -// Pops the value with the greates priority off the stack and returns it. +// Pops the value with the greatest priority off the stack and returns it. // Currently no shrinking is done. func (p *Prque) Pop() (interface{}, int64) { item := heap.Pop(p.cont).(*item) diff --git a/common/prque/sstack.go b/common/prque/sstack.go index 8518af54ff1a..b06a95413df0 100755 --- a/common/prque/sstack.go +++ b/common/prque/sstack.go @@ -31,22 +31,24 @@ type SetIndexCallback func(data interface{}, index int) // the stack (heap) functionality and the Len, Less and Swap methods for the // sortability requirements of the heaps. type sstack struct { - setIndex SetIndexCallback - size int - capacity int - offset int + setIndex SetIndexCallback + size int + capacity int + offset int + wrapAround bool blocks [][]*item active []*item } // Creates a new, empty stack. -func newSstack(setIndex SetIndexCallback) *sstack { +func newSstack(setIndex SetIndexCallback, wrapAround bool) *sstack { result := new(sstack) result.setIndex = setIndex result.active = make([]*item, blockSize) result.blocks = [][]*item{result.active} result.capacity = blockSize + result.wrapAround = wrapAround return result } @@ -94,7 +96,11 @@ func (s *sstack) Len() int { // Compares the priority of two elements of the stack (higher is first). // Required by sort.Interface. func (s *sstack) Less(i, j int) bool { - return (s.blocks[i/blockSize][i%blockSize].priority - s.blocks[j/blockSize][j%blockSize].priority) > 0 + a, b := s.blocks[i/blockSize][i%blockSize].priority, s.blocks[j/blockSize][j%blockSize].priority + if s.wrapAround { + return a-b > 0 + } + return a > b } // Swaps two elements in the stack. Required by sort.Interface. @@ -110,5 +116,5 @@ func (s *sstack) Swap(i, j int) { // Resets the stack, effectively clearing its contents. func (s *sstack) Reset() { - *s = *newSstack(s.setIndex) + *s = *newSstack(s.setIndex, false) } diff --git a/common/prque/sstack_test.go b/common/prque/sstack_test.go index 2ff093579da9..bc6298979cbc 100644 --- a/common/prque/sstack_test.go +++ b/common/prque/sstack_test.go @@ -21,7 +21,7 @@ func TestSstack(t *testing.T) { for i := 0; i < size; i++ { data[i] = &item{rand.Int(), rand.Int63()} } - stack := newSstack(nil) + stack := newSstack(nil, false) for rep := 0; rep < 2; rep++ { // Push all the data into the stack, pop out every second secs := []*item{} @@ -55,7 +55,7 @@ func TestSstackSort(t *testing.T) { data[i] = &item{rand.Int(), int64(i)} } // Push all the data into the stack - stack := newSstack(nil) + stack := newSstack(nil, false) for _, val := range data { stack.Push(val) } @@ -76,7 +76,7 @@ func TestSstackReset(t *testing.T) { for i := 0; i < size; i++ { data[i] = &item{rand.Int(), rand.Int63()} } - stack := newSstack(nil) + stack := newSstack(nil, false) for rep := 0; rep < 2; rep++ { // Push all the data into the stack, pop out every second secs := []*item{} From fb17f56852a26a5594d44863dc80dbad1d87f2b8 Mon Sep 17 00:00:00 2001 From: Paul-Armand Verhaegen Date: Thu, 10 Jun 2021 09:53:23 +0200 Subject: [PATCH 059/121] common: rename unused function with typo (#23025) This function is not used in the code base, so probably safe to do rename, or remove in its entirety, but I'm assuming the logic from the original creator still applies so rename probably better. --- common/debug.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/debug.go b/common/debug.go index 3ed8c1c796a2..8ad7ead5488e 100644 --- a/common/debug.go +++ b/common/debug.go @@ -37,8 +37,8 @@ func Report(extra ...interface{}) { fmt.Fprintln(os.Stderr, "#### BUG! PLEASE REPORT ####") } -// PrintDepricationWarning prinst the given string in a box using fmt.Println. -func PrintDepricationWarning(str string) { +// PrintDeprecationWarning prints the given string in a box using fmt.Println. +func PrintDeprecationWarning(str string) { line := strings.Repeat("#", len(str)+4) emptyLine := strings.Repeat(" ", len(str)) fmt.Printf(` From 4db72a0548047f7c4634eac135ade7e240333c85 Mon Sep 17 00:00:00 2001 From: Alexander Yastrebov Date: Tue, 31 Aug 2021 10:22:20 +0200 Subject: [PATCH 060/121] common: fixes format verb (#23495) --- common/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/types.go b/common/types.go index d28075c273e1..24e8338af70f 100644 --- a/common/types.go +++ b/common/types.go @@ -131,7 +131,7 @@ func (h Hash) String() string { } // Format implements fmt.Formatter. -// Hash supports the %v, %s, %v, %x, %X and %d format verbs. +// Hash supports the %v, %s, %q, %x, %X and %d format verbs. func (h Hash) Format(s fmt.State, c rune) { hexb := make([]byte, 2+len(h)*2) copy(hexb, "0x") From 49dc5e85e19e477811f4e4ee0f47cd080b480858 Mon Sep 17 00:00:00 2001 From: lmittmann Date: Thu, 21 Oct 2021 11:43:23 +0200 Subject: [PATCH 061/121] common/hexutil: improve performance of EncodeBig (#23780) - use Text instead of fmt.Sprintf - reduced allocs from 6 to 2 - improved speed --- common/hexutil/hexutil.go | 11 ++++++----- common/hexutil/hexutil_test.go | 12 ++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/common/hexutil/hexutil.go b/common/hexutil/hexutil.go index 02c488a3f178..81e68046500b 100644 --- a/common/hexutil/hexutil.go +++ b/common/hexutil/hexutil.go @@ -18,7 +18,7 @@ Package hexutil implements hex encoding with 0x prefix. This encoding is used by the Ethereum RPC API to transport binary data in JSON payloads. -Encoding Rules +# Encoding Rules All hex data must have prefix "0x". @@ -175,13 +175,14 @@ func MustDecodeBig(input string) *big.Int { } // EncodeBig encodes bigint as a hex string with 0x prefix. -// The sign of the integer is ignored. func EncodeBig(bigint *big.Int) string { - nbits := bigint.BitLen() - if nbits == 0 { + if sign := bigint.Sign(); sign == 0 { return "0x0" + } else if sign > 0 { + return "0x" + bigint.Text(16) + } else { + return "-0x" + bigint.Text(16)[1:] } - return fmt.Sprintf("%#x", bigint) } func has0xPrefix(input string) bool { diff --git a/common/hexutil/hexutil_test.go b/common/hexutil/hexutil_test.go index ed6fccc3ca6f..f2b800d82c9d 100644 --- a/common/hexutil/hexutil_test.go +++ b/common/hexutil/hexutil_test.go @@ -201,3 +201,15 @@ func TestDecodeUint64(t *testing.T) { } } } + +func BenchmarkEncodeBig(b *testing.B) { + for _, bench := range encodeBigTests { + b.Run(bench.want, func(b *testing.B) { + b.ReportAllocs() + bigint := bench.input.(*big.Int) + for i := 0; i < b.N; i++ { + EncodeBig(bigint) + } + }) + } +} From 69ea5327b805adda15ca667e96e7058b348b4586 Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Wed, 30 Mar 2022 04:38:59 +0800 Subject: [PATCH 062/121] common/compiler: add extra include paths to solidity compiler (#24541) This PR adds a ExtraAllowedPath field to Solidity and exposes two APIs: CompileSource and CompileFiles, which were hidden inside CompileSolidityString and CompileSolidity before. --- common/compiler/solidity.go | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index a023b5685c02..eb7fd079b380 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -31,6 +31,7 @@ import ( type Solidity struct { Path, Version, FullVersion string Major, Minor, Patch int + ExtraAllowedPath []string } // --combined-output format @@ -58,11 +59,19 @@ type solcOutputV8 struct { Version string } +func (s *Solidity) allowedPaths() string { + paths := []string{".", "./", "../"} // default to support relative paths + if len(s.ExtraAllowedPath) > 0 { + paths = append(paths, s.ExtraAllowedPath...) + } + return strings.Join(paths, ", ") +} + func (s *Solidity) makeArgs() []string { p := []string{ "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc", - "--optimize", // code optimizer switched on - "--allow-paths", "., ./, ../", // default to support relative paths + "--optimize", // code optimizer switched on + "--allow-paths", s.allowedPaths(), } if s.Major > 0 || s.Minor > 4 || s.Patch > 6 { p[1] += ",metadata,hashes" @@ -108,10 +117,7 @@ func CompileSolidityString(solc, source string) (map[string]*Contract, error) { if err != nil { return nil, err } - args := append(s.makeArgs(), "--") - cmd := exec.Command(s.Path, append(args, "-")...) - cmd.Stdin = strings.NewReader(source) - return s.run(cmd, source) + return s.CompileSource(source) } // CompileSolidity compiles all given Solidity source files. @@ -119,11 +125,25 @@ func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract, if len(sourcefiles) == 0 { return nil, errors.New("solc: no source files") } - source, err := slurpFiles(sourcefiles) + s, err := SolidityVersion(solc) if err != nil { return nil, err } - s, err := SolidityVersion(solc) + + return s.CompileFiles(sourcefiles...) +} + +// CompileSource builds and returns all the contracts contained within a source string. +func (s *Solidity) CompileSource(source string) (map[string]*Contract, error) { + args := append(s.makeArgs(), "--") + cmd := exec.Command(s.Path, append(args, "-")...) + cmd.Stdin = strings.NewReader(source) + return s.run(cmd, source) +} + +// CompileFiles compiles all given Solidity source files. +func (s *Solidity) CompileFiles(sourcefiles ...string) (map[string]*Contract, error) { + source, err := slurpFiles(sourcefiles) if err != nil { return nil, err } From d6d6906881e88bf7bc5011965738c7266878fa3b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 15:31:54 +0800 Subject: [PATCH 063/121] internal: add db operations to api (#24739) --- common/bytes.go | 12 ++++++++++++ internal/ethapi/api.go | 9 +++++++++ internal/web3ext/web3ext.go | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/common/bytes.go b/common/bytes.go index 3aaf97bd68c7..fae05026a3d9 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -19,6 +19,9 @@ package common import ( "encoding/hex" + "errors" + + "github.com/XinFinOrg/XDPoSChain/common/hexutil" ) // FromHex returns the bytes represented by the hexadecimal string s. @@ -99,6 +102,15 @@ func Hex2BytesFixed(str string, flen int) []byte { return hh } +// ParseHexOrString tries to hexdecode b, but if the prefix is missing, it instead just returns the raw bytes +func ParseHexOrString(str string) ([]byte, error) { + b, err := hexutil.Decode(str) + if errors.Is(err, hexutil.ErrMissingPrefix) { + return []byte(str), nil + } + return b, err +} + // RightPadBytes zero-pads slice to the right up to length l. func RightPadBytes(slice []byte, l int) []byte { if l <= len(slice) { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 47d50b864f3d..f88c79d4940f 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -3499,6 +3499,15 @@ func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) { api.b.SetHead(uint64(number)) } +// DbGet returns the raw value of a key stored in the database. +func (api *PrivateDebugAPI) DbGet(key string) (hexutil.Bytes, error) { + blob, err := common.ParseHexOrString(key) + if err != nil { + return nil, err + } + return api.b.ChainDb().Get(blob) +} + // PublicNetAPI offers network related RPC methods type PublicNetAPI struct { net *p2p.Server diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index f726b5d6205b..68ec05444a00 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -470,6 +470,11 @@ web3._extend({ params: 2, inputFormatter:[null, null], }), + new web3._extend.Method({ + name: 'dbGet', + call: 'debug_dbGet', + params: 1 + }), ], properties: [] }); From ebc036682e23734537c8a2cd30dce554966a85a7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 16:05:35 +0800 Subject: [PATCH 064/121] common/compiler, cmd/abigen: remove solc/vyper compiler integration (#24936) --- cmd/abigen/main.go | 38 +------- common/compiler/helpers.go | 20 ----- common/compiler/solidity.go | 117 +------------------------ common/compiler/solidity_test.go | 79 ----------------- common/compiler/test.v.py | 3 - common/compiler/test_bad.v.py | 3 - common/compiler/vyper.go | 144 ------------------------------- common/compiler/vyper_test.go | 71 --------------- 8 files changed, 3 insertions(+), 472 deletions(-) delete mode 100644 common/compiler/solidity_test.go delete mode 100644 common/compiler/test.v.py delete mode 100644 common/compiler/test_bad.v.py delete mode 100644 common/compiler/vyper.go delete mode 100644 common/compiler/vyper_test.go diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 6bd6efb4c249..9cdc47d61ff1 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -57,24 +57,6 @@ var ( Name: "combined-json", Usage: "Path to the combined-json file generated by compiler", } - solFlag = &cli.StringFlag{ - Name: "sol", - Usage: "Path to the Ethereum contract Solidity source to build and bind", - } - solcFlag = &cli.StringFlag{ - Name: "solc", - Usage: "Solidity compiler to use if source builds are requested", - Value: "solc", - } - vyFlag = &cli.StringFlag{ - Name: "vy", - Usage: "Path to the Ethereum contract Vyper source to build and bind", - } - vyperFlag = &cli.StringFlag{ - Name: "vyper", - Usage: "Vyper compiler to use if source builds are requested", - Value: "vyper", - } excFlag = &cli.StringFlag{ Name: "exc", Usage: "Comma separated types to exclude from binding", @@ -102,10 +84,6 @@ func init() { binFlag, typeFlag, jsonFlag, - solFlag, - solcFlag, - vyFlag, - vyperFlag, excFlag, pkgFlag, outFlag, @@ -115,7 +93,7 @@ func init() { } func abigen(c *cli.Context) error { - utils.CheckExclusive(c, abiFlag, jsonFlag, solFlag, vyFlag) // Only one source can be selected. + utils.CheckExclusive(c, abiFlag, jsonFlag) // Only one source can be selected. if c.String(pkgFlag.Name) == "" { utils.Fatalf("No destination package specified (--pkg)") } @@ -167,21 +145,9 @@ func abigen(c *cli.Context) error { for _, kind := range strings.Split(c.String(excFlag.Name), ",") { exclude[strings.ToLower(kind)] = true } - var err error var contracts map[string]*compiler.Contract - switch { - case c.IsSet(solFlag.Name): - contracts, err = compiler.CompileSolidity(c.String(solcFlag.Name), c.String(solFlag.Name)) - if err != nil { - utils.Fatalf("Failed to build Solidity contract: %v", err) - } - case c.IsSet(vyFlag.Name): - contracts, err = compiler.CompileVyper(c.String(vyperFlag.Name), c.String(vyFlag.Name)) - if err != nil { - utils.Fatalf("Failed to build Vyper contract: %v", err) - } - case c.IsSet(jsonFlag.Name): + if c.IsSet(jsonFlag.Name) { jsonOutput, err := os.ReadFile(c.String(jsonFlag.Name)) if err != nil { utils.Fatalf("Failed to read combined-json from compiler: %v", err) diff --git a/common/compiler/helpers.go b/common/compiler/helpers.go index 59d242af3df6..063fc1081102 100644 --- a/common/compiler/helpers.go +++ b/common/compiler/helpers.go @@ -17,14 +17,6 @@ // Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). package compiler -import ( - "bytes" - "os" - "regexp" -) - -var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`) - // Contract contains information about a compiled contract, alongside its code and runtime code. type Contract struct { Code string `json:"code"` @@ -51,15 +43,3 @@ type ContractInfo struct { DeveloperDoc interface{} `json:"developerDoc"` Metadata string `json:"metadata"` } - -func slurpFiles(files []string) (string, error) { - var concat bytes.Buffer - for _, file := range files { - content, err := os.ReadFile(file) - if err != nil { - return "", err - } - concat.Write(content) - } - return concat.String(), nil -} diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index eb7fd079b380..a83fdf3f0969 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -14,26 +14,14 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). +// Package compiler wraps the ABI compilation outputs. package compiler import ( - "bytes" "encoding/json" - "errors" "fmt" - "os/exec" - "strconv" - "strings" ) -// Solidity contains information about the solidity compiler. -type Solidity struct { - Path, Version, FullVersion string - Major, Minor, Patch int - ExtraAllowedPath []string -} - // --combined-output format type solcOutput struct { Contracts map[string]struct { @@ -59,109 +47,6 @@ type solcOutputV8 struct { Version string } -func (s *Solidity) allowedPaths() string { - paths := []string{".", "./", "../"} // default to support relative paths - if len(s.ExtraAllowedPath) > 0 { - paths = append(paths, s.ExtraAllowedPath...) - } - return strings.Join(paths, ", ") -} - -func (s *Solidity) makeArgs() []string { - p := []string{ - "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc", - "--optimize", // code optimizer switched on - "--allow-paths", s.allowedPaths(), - } - if s.Major > 0 || s.Minor > 4 || s.Patch > 6 { - p[1] += ",metadata,hashes" - } - return p -} - -// SolidityVersion runs solc and parses its version output. -func SolidityVersion(solc string) (*Solidity, error) { - if solc == "" { - solc = "solc" - } - var out bytes.Buffer - cmd := exec.Command(solc, "--version") - cmd.Stdout = &out - err := cmd.Run() - if err != nil { - return nil, err - } - matches := versionRegexp.FindStringSubmatch(out.String()) - if len(matches) != 4 { - return nil, fmt.Errorf("can't parse solc version %q", out.String()) - } - s := &Solidity{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]} - if s.Major, err = strconv.Atoi(matches[1]); err != nil { - return nil, err - } - if s.Minor, err = strconv.Atoi(matches[2]); err != nil { - return nil, err - } - if s.Patch, err = strconv.Atoi(matches[3]); err != nil { - return nil, err - } - return s, nil -} - -// CompileSolidityString builds and returns all the contracts contained within a source string. -func CompileSolidityString(solc, source string) (map[string]*Contract, error) { - if len(source) == 0 { - return nil, errors.New("solc: empty source string") - } - s, err := SolidityVersion(solc) - if err != nil { - return nil, err - } - return s.CompileSource(source) -} - -// CompileSolidity compiles all given Solidity source files. -func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract, error) { - if len(sourcefiles) == 0 { - return nil, errors.New("solc: no source files") - } - s, err := SolidityVersion(solc) - if err != nil { - return nil, err - } - - return s.CompileFiles(sourcefiles...) -} - -// CompileSource builds and returns all the contracts contained within a source string. -func (s *Solidity) CompileSource(source string) (map[string]*Contract, error) { - args := append(s.makeArgs(), "--") - cmd := exec.Command(s.Path, append(args, "-")...) - cmd.Stdin = strings.NewReader(source) - return s.run(cmd, source) -} - -// CompileFiles compiles all given Solidity source files. -func (s *Solidity) CompileFiles(sourcefiles ...string) (map[string]*Contract, error) { - source, err := slurpFiles(sourcefiles) - if err != nil { - return nil, err - } - args := append(s.makeArgs(), "--") - cmd := exec.Command(s.Path, append(args, sourcefiles...)...) - return s.run(cmd, source) -} - -func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) { - var stderr, stdout bytes.Buffer - cmd.Stderr = &stderr - cmd.Stdout = &stdout - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes()) - } - return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) -} - // ParseCombinedJSON takes the direct output of a solc --combined-output run and // parses it into a map of string contract name to Contract structs. The // provided source, language and compiler version, and compiler options are all diff --git a/common/compiler/solidity_test.go b/common/compiler/solidity_test.go deleted file mode 100644 index bd68eaee31a2..000000000000 --- a/common/compiler/solidity_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package compiler - -import ( - "os/exec" - "testing" -) - -const ( - testSource = ` -pragma solidity >0.0.0; -contract test { - /// @notice Will multiply ` + "`a`" + ` by 7. - function multiply(uint a) public returns(uint d) { - return a * 7; - } -} -` -) - -func skipWithoutSolc(t *testing.T) { - if _, err := exec.LookPath("solc"); err != nil { - t.Skip(err) - } -} - -func TestSolidityCompiler(t *testing.T) { - t.SkipNow() - skipWithoutSolc(t) - - contracts, err := CompileSolidityString("", testSource) - if err != nil { - t.Fatalf("error compiling source. result %v: %v", contracts, err) - } - if len(contracts) != 1 { - t.Errorf("one contract expected, got %d", len(contracts)) - } - c, ok := contracts["test"] - if !ok { - c, ok = contracts[":test"] - if !ok { - t.Fatal("info for contract 'test' not present in result") - } - } - if c.Code == "" { - t.Error("empty code") - } - if c.Info.Source != testSource { - t.Error("wrong source") - } - if c.Info.CompilerVersion == "" { - t.Error("empty version") - } -} - -func TestSolidityCompileError(t *testing.T) { - skipWithoutSolc(t) - - contracts, err := CompileSolidityString("", testSource[4:]) - if err == nil { - t.Errorf("error expected compiling source. got none. result %v", contracts) - } - t.Logf("error: %v", err) -} diff --git a/common/compiler/test.v.py b/common/compiler/test.v.py deleted file mode 100644 index 35af56c8f6ef..000000000000 --- a/common/compiler/test.v.py +++ /dev/null @@ -1,3 +0,0 @@ -@public -def test(): - hello: int128 diff --git a/common/compiler/test_bad.v.py b/common/compiler/test_bad.v.py deleted file mode 100644 index 443ef7826325..000000000000 --- a/common/compiler/test_bad.v.py +++ /dev/null @@ -1,3 +0,0 @@ -lic -def test(): - hello: int128 diff --git a/common/compiler/vyper.go b/common/compiler/vyper.go deleted file mode 100644 index a9bca95e5901..000000000000 --- a/common/compiler/vyper.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). -package compiler - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "os/exec" - "strconv" - "strings" -) - -// Vyper contains information about the vyper compiler. -type Vyper struct { - Path, Version, FullVersion string - Major, Minor, Patch int -} - -func (s *Vyper) makeArgs() []string { - p := []string{ - "-f", "combined_json", - } - return p -} - -// VyperVersion runs vyper and parses its version output. -func VyperVersion(vyper string) (*Vyper, error) { - if vyper == "" { - vyper = "vyper" - } - var out bytes.Buffer - cmd := exec.Command(vyper, "--version") - cmd.Stdout = &out - err := cmd.Run() - if err != nil { - return nil, err - } - matches := versionRegexp.FindStringSubmatch(out.String()) - if len(matches) != 4 { - return nil, fmt.Errorf("can't parse vyper version %q", out.String()) - } - s := &Vyper{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]} - if s.Major, err = strconv.Atoi(matches[1]); err != nil { - return nil, err - } - if s.Minor, err = strconv.Atoi(matches[2]); err != nil { - return nil, err - } - if s.Patch, err = strconv.Atoi(matches[3]); err != nil { - return nil, err - } - return s, nil -} - -// CompileVyper compiles all given Vyper source files. -func CompileVyper(vyper string, sourcefiles ...string) (map[string]*Contract, error) { - if len(sourcefiles) == 0 { - return nil, errors.New("vyper: no source files") - } - source, err := slurpFiles(sourcefiles) - if err != nil { - return nil, err - } - s, err := VyperVersion(vyper) - if err != nil { - return nil, err - } - args := s.makeArgs() - cmd := exec.Command(s.Path, append(args, sourcefiles...)...) - return s.run(cmd, source) -} - -func (s *Vyper) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) { - var stderr, stdout bytes.Buffer - cmd.Stderr = &stderr - cmd.Stdout = &stdout - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("vyper: %v\n%s", err, stderr.Bytes()) - } - - return ParseVyperJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) -} - -// ParseVyperJSON takes the direct output of a vyper --f combined_json run and -// parses it into a map of string contract name to Contract structs. The -// provided source, language and compiler version, and compiler options are all -// passed through into the Contract structs. -// -// The vyper output is expected to contain ABI and source mapping. -// -// Returns an error if the JSON is malformed or missing data, or if the JSON -// embedded within the JSON is malformed. -func ParseVyperJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { - var output map[string]interface{} - if err := json.Unmarshal(combinedJSON, &output); err != nil { - return nil, err - } - - // Compilation succeeded, assemble and return the contracts. - contracts := make(map[string]*Contract) - for name, info := range output { - // Parse the individual compilation results. - if name == "version" { - continue - } - c := info.(map[string]interface{}) - - contracts[name] = &Contract{ - Code: c["bytecode"].(string), - RuntimeCode: c["bytecode_runtime"].(string), - Info: ContractInfo{ - Source: source, - Language: "Vyper", - LanguageVersion: languageVersion, - CompilerVersion: compilerVersion, - CompilerOptions: compilerOptions, - SrcMap: c["source_map"], - SrcMapRuntime: "", - AbiDefinition: c["abi"], - UserDoc: "", - DeveloperDoc: "", - Metadata: "", - }, - } - } - return contracts, nil -} diff --git a/common/compiler/vyper_test.go b/common/compiler/vyper_test.go deleted file mode 100644 index 7761c92affc5..000000000000 --- a/common/compiler/vyper_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package compiler - -import ( - "os/exec" - "testing" -) - -func skipWithoutVyper(t *testing.T) { - if _, err := exec.LookPath("vyper"); err != nil { - t.Skip(err) - } -} - -func TestVyperCompiler(t *testing.T) { - skipWithoutVyper(t) - - testSource := []string{"test.v.py"} - source, err := slurpFiles(testSource) - if err != nil { - t.Error("couldn't read test files") - } - contracts, err := CompileVyper("", testSource...) - if err != nil { - t.Fatalf("error compiling test.v.py. result %v: %v", contracts, err) - } - if len(contracts) != 1 { - t.Errorf("one contract expected, got %d", len(contracts)) - } - c, ok := contracts["test.v.py"] - if !ok { - c, ok = contracts[":test"] - if !ok { - t.Fatal("info for contract 'test.v.py' not present in result") - } - } - if c.Code == "" { - t.Error("empty code") - } - if c.Info.Source != source { - t.Error("wrong source") - } - if c.Info.CompilerVersion == "" { - t.Error("empty version") - } -} - -func TestVyperCompileError(t *testing.T) { - skipWithoutVyper(t) - - contracts, err := CompileVyper("", "test_bad.v.py") - if err == nil { - t.Errorf("error expected compiling test_bad.v.py. got none. result %v", contracts) - } - t.Logf("error: %v", err) -} From febb456ddd3e96aad420a8764d3632ef42c28af6 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 14 Jun 2022 14:08:43 +0200 Subject: [PATCH 065/121] common: improve pretty duration regex (#25073) --- common/format.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/common/format.go b/common/format.go index fccc299620dc..197e8697d9af 100644 --- a/common/format.go +++ b/common/format.go @@ -17,7 +17,6 @@ package common import ( - "fmt" "regexp" "strings" "time" @@ -27,12 +26,12 @@ import ( // the unnecessary precision off from the formatted textual representation. type PrettyDuration time.Duration -var prettyDurationRe = regexp.MustCompile(`\.[0-9]+`) +var prettyDurationRe = regexp.MustCompile(`\.[0-9]{4,}`) // String implements the Stringer interface, allowing pretty printing of duration // values rounded to three decimals. func (d PrettyDuration) String() string { - label := fmt.Sprintf("%v", time.Duration(d)) + label := time.Duration(d).String() if match := prettyDurationRe.FindString(label); len(match) > 4 { label = strings.Replace(label, match, match[:4], 1) } From a03e11186ce0aa1c12eed059bb76aba67bf84e62 Mon Sep 17 00:00:00 2001 From: "Seungbae.yu" <72970043+dbadoy@users.noreply.github.com> Date: Wed, 29 Jun 2022 19:13:00 +0900 Subject: [PATCH 066/121] common: increase StorageSize test coverage (#25188) --- common/size_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/common/size_test.go b/common/size_test.go index 0938d483c4bb..28f053d39f5d 100644 --- a/common/size_test.go +++ b/common/size_test.go @@ -25,6 +25,8 @@ func TestStorageSizeString(t *testing.T) { size StorageSize str string }{ + {2839274474874, "2.58 TiB"}, + {2458492810, "2.29 GiB"}, {2381273, "2.27 MiB"}, {2192, "2.14 KiB"}, {12, "12.00 B"}, @@ -36,3 +38,22 @@ func TestStorageSizeString(t *testing.T) { } } } + +func TestStorageSizeTerminalString(t *testing.T) { + tests := []struct { + size StorageSize + str string + }{ + {2839274474874, "2.58TiB"}, + {2458492810, "2.29GiB"}, + {2381273, "2.27MiB"}, + {2192, "2.14KiB"}, + {12, "12.00B"}, + } + + for _, test := range tests { + if test.size.TerminalString() != test.str { + t.Errorf("%f: got %q, want %q", float64(test.size), test.size.TerminalString(), test.str) + } + } +} From 1bff428a39337e96f69f96587a4c93f051327516 Mon Sep 17 00:00:00 2001 From: "Seungbae.yu" <72970043+dbadoy@users.noreply.github.com> Date: Thu, 30 Jun 2022 13:24:04 +0900 Subject: [PATCH 067/121] common/prque: fix typo (#25206) --- common/prque/lazyqueue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index 85d7bf6eee7e..1fa744f399bc 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -164,7 +164,7 @@ func (q *LazyQueue) PopItem() interface{} { return i } -// Remove removes removes the item with the given index. +// Remove removes the item with the given index. func (q *LazyQueue) Remove(index int) interface{} { if index < 0 { return nil From e3edcc8429eb6ee9da82eb743395eaf710b46fcb Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 16:30:54 +0800 Subject: [PATCH 068/121] common/math: lint whitespace --- common/math/big_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/math/big_test.go b/common/math/big_test.go index d9e5723c61c6..8ae7578319a7 100644 --- a/common/math/big_test.go +++ b/common/math/big_test.go @@ -171,7 +171,6 @@ func BenchmarkByteAt(b *testing.B) { } func BenchmarkByteAtOld(b *testing.B) { - bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") for i := 0; i < b.N; i++ { PaddedBigBytes(bigint, 32) @@ -244,9 +243,9 @@ func TestBigEndianByteAt(t *testing.T) { if actual != test.exp { t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) } - } } + func TestLittleEndianByteAt(t *testing.T) { tests := []struct { x string @@ -277,7 +276,6 @@ func TestLittleEndianByteAt(t *testing.T) { if actual != test.exp { t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) } - } } From 32e033df3af376e4c037b04777155ac4e4a89028 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 17 Dec 2024 16:49:30 +0800 Subject: [PATCH 069/121] common, p2p: use AbsTime.Add instead of conversion (#25417) --- common/mclock/simclock.go | 4 ++-- common/prque/lazyqueue.go | 4 ++-- p2p/discv5/ticket.go | 8 ++++---- p2p/discv5/topic.go | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/common/mclock/simclock.go b/common/mclock/simclock.go index 766ca0f8736c..f5ad3f8bc0aa 100644 --- a/common/mclock/simclock.go +++ b/common/mclock/simclock.go @@ -58,7 +58,7 @@ func (s *Simulated) Run(d time.Duration) { s.mu.Lock() s.init() - end := s.now + AbsTime(d) + end := s.now.Add(d) var do []func() for len(s.scheduled) > 0 && s.scheduled[0].at <= end { ev := heap.Pop(&s.scheduled).(*simTimer) @@ -134,7 +134,7 @@ func (s *Simulated) AfterFunc(d time.Duration, fn func()) Timer { func (s *Simulated) schedule(d time.Duration, fn func()) *simTimer { s.init() - at := s.now + AbsTime(d) + at := s.now.Add(d) ev := &simTimer{do: fn, at: at, s: s} heap.Push(&s.scheduled, ev) s.cond.Broadcast() diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index 1fa744f399bc..883d210735ce 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -88,13 +88,13 @@ func (q *LazyQueue) Refresh() { // refresh re-evaluates items in the older queue and swaps the two queues func (q *LazyQueue) refresh(now mclock.AbsTime) { - q.maxUntil = now + mclock.AbsTime(q.period) + q.maxUntil = now.Add(q.period) for q.queue[0].Len() != 0 { q.Push(heap.Pop(q.queue[0]).(*item).value) } q.queue[0], q.queue[1] = q.queue[1], q.queue[0] q.indexOffset = 1 - q.indexOffset - q.maxUntil += mclock.AbsTime(q.period) + q.maxUntil = q.maxUntil.Add(q.period) } // Push adds an item to the queue diff --git a/p2p/discv5/ticket.go b/p2p/discv5/ticket.go index 4780e8b8661e..2ccbfad7ff71 100644 --- a/p2p/discv5/ticket.go +++ b/p2p/discv5/ticket.go @@ -107,7 +107,7 @@ func pongToTicket(localTime mclock.AbsTime, topics []Topic, node *Node, p *ingre } // Convert wait periods to local absolute time. for i, wp := range wps { - t.regTime[i] = localTime + mclock.AbsTime(time.Second*time.Duration(wp)) + t.regTime[i] = localTime.Add(time.Second * time.Duration(wp)) } return t, nil } @@ -349,7 +349,7 @@ func (s *ticketStore) nextFilteredTicket() (*ticketRef, time.Duration) { } log.Trace("Found discovery ticket to register", "node", ticket.t.node, "serial", ticket.t.serial, "wait", wait) - regTime := now + mclock.AbsTime(wait) + regTime := now.Add(wait) topic := ticket.t.topics[ticket.idx] if s.tickets[topic] != nil && regTime >= s.tickets[topic].nextReg { return ticket, wait @@ -614,7 +614,7 @@ func (s *ticketStore) cleanupTopicQueries(now mclock.AbsTime) { delete(s.queriesSent, n) } } - s.nextTopicQueryCleanup = now + mclock.AbsTime(topicQueryTimeout) + s.nextTopicQueryCleanup = now.Add(topicQueryTimeout) } func (s *ticketStore) gotTopicNodes(from *Node, hash common.Hash, nodes []rpcNode) (timeout bool) { @@ -625,7 +625,7 @@ func (s *ticketStore) gotTopicNodes(from *Node, hash common.Hash, nodes []rpcNod return true } q, ok := qq[hash] - if !ok || now > q.sent+mclock.AbsTime(topicQueryTimeout) { + if !ok || now > q.sent.Add(topicQueryTimeout) { return true } inside := float64(0) diff --git a/p2p/discv5/topic.go b/p2p/discv5/topic.go index c7c4ca93683e..060395e9633a 100644 --- a/p2p/discv5/topic.go +++ b/p2p/discv5/topic.go @@ -194,7 +194,7 @@ func (t *topicTable) addEntry(node *Node, topic Topic) { topic: topic, fifoIdx: fifoIdx, node: node, - expire: tm + mclock.AbsTime(fallbackRegistrationExpiry), + expire: tm.Add(fallbackRegistrationExpiry), } if printTestImgLogs { fmt.Printf("*+ %d %v %016x %016x\n", tm/1000000, topic, t.self.sha[:8], node.sha[:8]) @@ -251,7 +251,7 @@ func (t *topicTable) useTicket(node *Node, serialNo uint32, topics []Topic, idx } if serialNo != n.lastUsedTicket { n.lastUsedTicket = serialNo - n.noRegUntil = tm + mclock.AbsTime(noRegTimeout()) + n.noRegUntil = tm.Add(noRegTimeout()) t.storeTicketCounters(node) } @@ -263,7 +263,7 @@ func (t *topicTable) useTicket(node *Node, serialNo uint32, topics []Topic, idx t.addEntry(node, topics[idx]) } else { // if there is an active entry, don't move to the front of the FIFO but prolong expire time - e.expire = tm + mclock.AbsTime(fallbackRegistrationExpiry) + e.expire = tm.Add(fallbackRegistrationExpiry) } return true } @@ -293,7 +293,7 @@ func (topictab *topicTable) getTicket(node *Node, topics []Topic) *ticket { waitPeriod = minWaitPeriod } - t.regTime[i] = now + mclock.AbsTime(waitPeriod) + t.regTime[i] = now.Add(waitPeriod) } return t } From 3eb2ec42b5b0386ccc87b627f3f97aaba297b0b1 Mon Sep 17 00:00:00 2001 From: Henry <101552941+henry-0@users.noreply.github.com> Date: Mon, 1 Aug 2022 19:47:21 +0800 Subject: [PATCH 070/121] common/compiler: json unmarshalling error checks (#25449) complier/solidity:add json.Unmarshal err check --- common/compiler/solidity.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index a83fdf3f0969..bf42a18041ae 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -66,13 +66,16 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin contracts := make(map[string]*Contract) for name, info := range output.Contracts { // Parse the individual compilation results. - var abi interface{} + var abi, userdoc, devdoc interface{} if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil { return nil, fmt.Errorf("solc: error reading abi definition (%v)", err) } - var userdoc, devdoc interface{} - json.Unmarshal([]byte(info.Userdoc), &userdoc) - json.Unmarshal([]byte(info.Devdoc), &devdoc) + if err := json.Unmarshal([]byte(info.Userdoc), &userdoc); err != nil { + return nil, fmt.Errorf("solc: error reading userdoc definition (%v)", err) + } + if err := json.Unmarshal([]byte(info.Devdoc), &devdoc); err != nil { + return nil, fmt.Errorf("solc: error reading devdoc definition (%v)", err) + } contracts[name] = &Contract{ Code: "0x" + info.Bin, From 50591149927028e189f2102f68d4139c54757af6 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 8 Nov 2022 03:14:11 -0800 Subject: [PATCH 071/121] common/types: add `Address.Big` (#26132) Many of the other types have a function to convert the type to a big.Int, but Address was missing this function. It is useful to be able to turn an Address into a big.Int when doing EVM-like computations natively in Go. Sometimes a Solidity address type is casted to a uint256 and having a Big method on the Address type makes this easy. --- common/types.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/types.go b/common/types.go index 24e8338af70f..d32343ccd4bc 100644 --- a/common/types.go +++ b/common/types.go @@ -253,6 +253,9 @@ func (a Address) Bytes() []byte { return a[:] } // Hash converts an address to a hash by left-padding it with zeros. func (a Address) Hash() Hash { return BytesToHash(a[:]) } +// Big converts an address to a big integer. +func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) } + // Hex returns an EIP55-compliant hex string representation of the address. func (a Address) Hex() string { checksumed := a.checksumHex() From 39e9d8f94def2a5e3eaaaf0ebf487614d15c3ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 9 Feb 2023 13:03:54 +0200 Subject: [PATCH 072/121] common/prque: generic priority queue (#26290) --- XDCx/XDCx.go | 8 ++-- XDCxlending/XDCxlending.go | 8 ++-- common/prque/lazyqueue.go | 78 +++++++++++++++++----------------- common/prque/prque.go | 44 +++++++++---------- common/prque/prque_test.go | 27 ++++++------ common/prque/sstack.go | 65 +++++++++++++--------------- common/prque/sstack_test.go | 30 ++++++------- consensus/XDPoS/utils/types.go | 4 +- core/blockchain.go | 18 ++++---- core/txpool/lending_pool.go | 6 +-- core/txpool/order_pool.go | 6 +-- core/txpool/txpool.go | 6 +-- eth/downloader/queue.go | 48 ++++++++++----------- eth/fetcher/fetcher.go | 11 +++-- go.mod | 1 + go.sum | 2 + trie/sync.go | 4 +- 17 files changed, 178 insertions(+), 188 deletions(-) diff --git a/XDCx/XDCx.go b/XDCx/XDCx.go index fbb737240289..1c09249874a0 100644 --- a/XDCx/XDCx.go +++ b/XDCx/XDCx.go @@ -52,8 +52,8 @@ type XDCX struct { // Order related db XDCxDAO.XDCXDAO mongodb XDCxDAO.XDCXDAO - Triegc *prque.Prque // Priority queue mapping block numbers to tries to gc - StateCache tradingstate.Database // State database to reuse between imports (contains state cache) *XDCx_state.TradingStateDB + Triegc *prque.Prque[int64, common.Hash] // Priority queue mapping block numbers to tries to gc + StateCache tradingstate.Database // State database to reuse between imports (contains state cache) *XDCx_state.TradingStateDB orderNonce map[common.Address]*big.Int @@ -94,7 +94,7 @@ func NewMongoDBEngine(cfg *Config) *XDCxDAO.MongoDatabase { func New(cfg *Config) *XDCX { XDCX := &XDCX{ orderNonce: make(map[common.Address]*big.Int), - Triegc: prque.New(nil), + Triegc: prque.New[int64, common.Hash](nil), tokenDecimalCache: lru.NewCache[common.Address, *big.Int](defaultCacheLimit), orderCache: lru.NewCache[common.Hash, map[common.Hash]tradingstate.OrderHistoryItem](tradingstate.OrderCacheLimit), } @@ -579,7 +579,7 @@ func (XDCx *XDCX) HasTradingState(block *types.Block, author common.Address) boo return err == nil } -func (XDCx *XDCX) GetTriegc() *prque.Prque { +func (XDCx *XDCX) GetTriegc() *prque.Prque[int64, common.Hash] { return XDCx.Triegc } diff --git a/XDCxlending/XDCxlending.go b/XDCxlending/XDCxlending.go index a1f8e9749fd1..34a00095548a 100644 --- a/XDCxlending/XDCxlending.go +++ b/XDCxlending/XDCxlending.go @@ -36,8 +36,8 @@ var ( ) type Lending struct { - Triegc *prque.Prque // Priority queue mapping block numbers to tries to gc - StateCache lendingstate.Database // State database to reuse between imports (contains state cache) *lendingstate.TradingStateDB + Triegc *prque.Prque[int64, common.Hash] // Priority queue mapping block numbers to tries to gc + StateCache lendingstate.Database // State database to reuse between imports (contains state cache) *lendingstate.TradingStateDB orderNonce map[common.Address]*big.Int @@ -61,7 +61,7 @@ func (l *Lending) Stop() error { func New(XDCx *XDCx.XDCX) *Lending { lending := &Lending{ orderNonce: make(map[common.Address]*big.Int), - Triegc: prque.New(nil), + Triegc: prque.New[int64, common.Hash](nil), lendingItemHistory: lru.NewCache[common.Hash, map[common.Hash]lendingstate.LendingItemHistoryItem](defaultCacheLimit), lendingTradeHistory: lru.NewCache[common.Hash, map[common.Hash]lendingstate.LendingTradeHistoryItem](defaultCacheLimit), } @@ -682,7 +682,7 @@ func (l *Lending) HasLendingState(block *types.Block, author common.Address) boo return err == nil } -func (l *Lending) GetTriegc() *prque.Prque { +func (l *Lending) GetTriegc() *prque.Prque[int64, common.Hash] { return l.Triegc } diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index 883d210735ce..ae3cd798da00 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -21,6 +21,7 @@ import ( "time" "github.com/XinFinOrg/XDPoSChain/common/mclock" + "golang.org/x/exp/constraints" ) // LazyQueue is a priority queue data structure where priorities can change over @@ -32,31 +33,31 @@ import ( // // If the upper estimate is exceeded then Update should be called for that item. // A global Refresh function should also be called periodically. -type LazyQueue struct { +type LazyQueue[P constraints.Ordered, V any] struct { clock mclock.Clock // Items are stored in one of two internal queues ordered by estimated max // priority until the next and the next-after-next refresh. Update and Refresh // always places items in queue[1]. - queue [2]*sstack - popQueue *sstack + queue [2]*sstack[P, V] + popQueue *sstack[P, V] period time.Duration maxUntil mclock.AbsTime indexOffset int - setIndex SetIndexCallback - priority PriorityCallback - maxPriority MaxPriorityCallback + setIndex SetIndexCallback[V] + priority PriorityCallback[P, V] + maxPriority MaxPriorityCallback[P, V] lastRefresh1, lastRefresh2 mclock.AbsTime } type ( - PriorityCallback func(data interface{}) int64 // actual priority callback - MaxPriorityCallback func(data interface{}, until mclock.AbsTime) int64 // estimated maximum priority callback + PriorityCallback[P constraints.Ordered, V any] func(data V) P // actual priority callback + MaxPriorityCallback[P constraints.Ordered, V any] func(data V, until mclock.AbsTime) P // estimated maximum priority callback ) // NewLazyQueue creates a new lazy queue -func NewLazyQueue(setIndex SetIndexCallback, priority PriorityCallback, maxPriority MaxPriorityCallback, clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue { - q := &LazyQueue{ - popQueue: newSstack(nil, false), +func NewLazyQueue[P constraints.Ordered, V any](setIndex SetIndexCallback[V], priority PriorityCallback[P, V], maxPriority MaxPriorityCallback[P, V], clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue[P, V] { + q := &LazyQueue[P, V]{ + popQueue: newSstack[P, V](nil), setIndex: setIndex, priority: priority, maxPriority: maxPriority, @@ -71,13 +72,13 @@ func NewLazyQueue(setIndex SetIndexCallback, priority PriorityCallback, maxPrior } // Reset clears the contents of the queue -func (q *LazyQueue) Reset() { - q.queue[0] = newSstack(q.setIndex0, false) - q.queue[1] = newSstack(q.setIndex1, false) +func (q *LazyQueue[P, V]) Reset() { + q.queue[0] = newSstack[P, V](q.setIndex0) + q.queue[1] = newSstack[P, V](q.setIndex1) } // Refresh performs queue re-evaluation if necessary -func (q *LazyQueue) Refresh() { +func (q *LazyQueue[P, V]) Refresh() { now := q.clock.Now() for time.Duration(now-q.lastRefresh2) >= q.period*2 { q.refresh(now) @@ -87,10 +88,10 @@ func (q *LazyQueue) Refresh() { } // refresh re-evaluates items in the older queue and swaps the two queues -func (q *LazyQueue) refresh(now mclock.AbsTime) { +func (q *LazyQueue[P, V]) refresh(now mclock.AbsTime) { q.maxUntil = now.Add(q.period) for q.queue[0].Len() != 0 { - q.Push(heap.Pop(q.queue[0]).(*item).value) + q.Push(heap.Pop(q.queue[0]).(*item[P, V]).value) } q.queue[0], q.queue[1] = q.queue[1], q.queue[0] q.indexOffset = 1 - q.indexOffset @@ -98,22 +99,22 @@ func (q *LazyQueue) refresh(now mclock.AbsTime) { } // Push adds an item to the queue -func (q *LazyQueue) Push(data interface{}) { - heap.Push(q.queue[1], &item{data, q.maxPriority(data, q.maxUntil)}) +func (q *LazyQueue[P, V]) Push(data V) { + heap.Push(q.queue[1], &item[P, V]{data, q.maxPriority(data, q.maxUntil)}) } // Update updates the upper priority estimate for the item with the given queue index -func (q *LazyQueue) Update(index int) { +func (q *LazyQueue[P, V]) Update(index int) { q.Push(q.Remove(index)) } // Pop removes and returns the item with the greatest actual priority -func (q *LazyQueue) Pop() (interface{}, int64) { +func (q *LazyQueue[P, V]) Pop() (V, P) { var ( - resData interface{} - resPri int64 + resData V + resPri P ) - q.MultiPop(func(data interface{}, priority int64) bool { + q.MultiPop(func(data V, priority P) bool { resData = data resPri = priority return false @@ -123,7 +124,7 @@ func (q *LazyQueue) Pop() (interface{}, int64) { // peekIndex returns the index of the internal queue where the item with the // highest estimated priority is or -1 if both are empty -func (q *LazyQueue) peekIndex() int { +func (q *LazyQueue[P, V]) peekIndex() int { if q.queue[0].Len() != 0 { if q.queue[1].Len() != 0 && q.queue[1].blocks[0][0].priority > q.queue[0].blocks[0][0].priority { return 1 @@ -139,17 +140,17 @@ func (q *LazyQueue) peekIndex() int { // MultiPop pops multiple items from the queue and is more efficient than calling // Pop multiple times. Popped items are passed to the callback. MultiPop returns // when the callback returns false or there are no more items to pop. -func (q *LazyQueue) MultiPop(callback func(data interface{}, priority int64) bool) { +func (q *LazyQueue[P, V]) MultiPop(callback func(data V, priority P) bool) { nextIndex := q.peekIndex() for nextIndex != -1 { - data := heap.Pop(q.queue[nextIndex]).(*item).value - heap.Push(q.popQueue, &item{data, q.priority(data)}) + data := heap.Pop(q.queue[nextIndex]).(*item[P, V]).value + heap.Push(q.popQueue, &item[P, V]{data, q.priority(data)}) nextIndex = q.peekIndex() for q.popQueue.Len() != 0 && (nextIndex == -1 || q.queue[nextIndex].blocks[0][0].priority < q.popQueue.blocks[0][0].priority) { - i := heap.Pop(q.popQueue).(*item) + i := heap.Pop(q.popQueue).(*item[P, V]) if !callback(i.value, i.priority) { for q.popQueue.Len() != 0 { - q.Push(heap.Pop(q.popQueue).(*item).value) + q.Push(heap.Pop(q.popQueue).(*item[P, V]).value) } return } @@ -159,31 +160,28 @@ func (q *LazyQueue) MultiPop(callback func(data interface{}, priority int64) boo } // PopItem pops the item from the queue only, dropping the associated priority value. -func (q *LazyQueue) PopItem() interface{} { +func (q *LazyQueue[P, V]) PopItem() V { i, _ := q.Pop() return i } // Remove removes the item with the given index. -func (q *LazyQueue) Remove(index int) interface{} { - if index < 0 { - return nil - } - return heap.Remove(q.queue[index&1^q.indexOffset], index>>1).(*item).value +func (q *LazyQueue[P, V]) Remove(index int) V { + return heap.Remove(q.queue[index&1^q.indexOffset], index>>1).(*item[P, V]).value } // Empty checks whether the priority queue is empty. -func (q *LazyQueue) Empty() bool { +func (q *LazyQueue[P, V]) Empty() bool { return q.queue[0].Len() == 0 && q.queue[1].Len() == 0 } // Size returns the number of items in the priority queue. -func (q *LazyQueue) Size() int { +func (q *LazyQueue[P, V]) Size() int { return q.queue[0].Len() + q.queue[1].Len() } // setIndex0 translates internal queue item index to the virtual index space of LazyQueue -func (q *LazyQueue) setIndex0(data interface{}, index int) { +func (q *LazyQueue[P, V]) setIndex0(data V, index int) { if index == -1 { q.setIndex(data, -1) } else { @@ -192,6 +190,6 @@ func (q *LazyQueue) setIndex0(data interface{}, index int) { } // setIndex1 translates internal queue item index to the virtual index space of LazyQueue -func (q *LazyQueue) setIndex1(data interface{}, index int) { +func (q *LazyQueue[P, V]) setIndex1(data V, index int) { q.setIndex(data, index+index+1) } diff --git a/common/prque/prque.go b/common/prque/prque.go index fb02e3418c28..0e8c9f897fad 100755 --- a/common/prque/prque.go +++ b/common/prque/prque.go @@ -19,65 +19,59 @@ package prque import ( "container/heap" + + "golang.org/x/exp/constraints" ) // Priority queue data structure. -type Prque struct { - cont *sstack +type Prque[P constraints.Ordered, V any] struct { + cont *sstack[P, V] } // New creates a new priority queue. -func New(setIndex SetIndexCallback) *Prque { - return &Prque{newSstack(setIndex, false)} -} - -// NewWrapAround creates a new priority queue with wrap-around priority handling. -func NewWrapAround(setIndex SetIndexCallback) *Prque { - return &Prque{newSstack(setIndex, true)} +func New[P constraints.Ordered, V any](setIndex SetIndexCallback[V]) *Prque[P, V] { + return &Prque[P, V]{newSstack[P, V](setIndex)} } // Pushes a value with a given priority into the queue, expanding if necessary. -func (p *Prque) Push(data interface{}, priority int64) { - heap.Push(p.cont, &item{data, priority}) +func (p *Prque[P, V]) Push(data V, priority P) { + heap.Push(p.cont, &item[P, V]{data, priority}) } // Peek returns the value with the greatest priority but does not pop it off. -func (p *Prque) Peek() (interface{}, int64) { +func (p *Prque[P, V]) Peek() (V, P) { item := p.cont.blocks[0][0] return item.value, item.priority } // Pops the value with the greatest priority off the stack and returns it. // Currently no shrinking is done. -func (p *Prque) Pop() (interface{}, int64) { - item := heap.Pop(p.cont).(*item) +func (p *Prque[P, V]) Pop() (V, P) { + item := heap.Pop(p.cont).(*item[P, V]) return item.value, item.priority } // Pops only the item from the queue, dropping the associated priority value. -func (p *Prque) PopItem() interface{} { - return heap.Pop(p.cont).(*item).value +func (p *Prque[P, V]) PopItem() V { + return heap.Pop(p.cont).(*item[P, V]).value } // Remove removes the element with the given index. -func (p *Prque) Remove(i int) interface{} { - if i < 0 { - return nil - } - return heap.Remove(p.cont, i) +func (p *Prque[P, V]) Remove(i int) V { + return heap.Remove(p.cont, i).(*item[P, V]).value } // Checks whether the priority queue is empty. -func (p *Prque) Empty() bool { +func (p *Prque[P, V]) Empty() bool { return p.cont.Len() == 0 } // Returns the number of element in the priority queue. -func (p *Prque) Size() int { +func (p *Prque[P, V]) Size() int { return p.cont.Len() } // Clears the contents of the priority queue. -func (p *Prque) Reset() { - *p = *New(p.cont.setIndex) +func (p *Prque[P, V]) Reset() { + *p = *New[P, V](p.cont.setIndex) } diff --git a/common/prque/prque_test.go b/common/prque/prque_test.go index 1cffcebad437..c4910f205a00 100644 --- a/common/prque/prque_test.go +++ b/common/prque/prque_test.go @@ -21,22 +21,24 @@ func TestPrque(t *testing.T) { for i := 0; i < size; i++ { data[i] = rand.Int() } - queue := New(nil) + queue := New[int, int](nil) + for rep := 0; rep < 2; rep++ { // Fill a priority queue with the above data for i := 0; i < size; i++ { - queue.Push(data[i], int64(prio[i])) + queue.Push(data[i], prio[i]) if queue.Size() != i+1 { t.Errorf("queue size mismatch: have %v, want %v.", queue.Size(), i+1) } } // Create a map the values to the priorities for easier verification - dict := make(map[int64]int) + dict := make(map[int]int) for i := 0; i < size; i++ { - dict[int64(prio[i])] = data[i] + dict[prio[i]] = data[i] } + // Pop out the elements in priority order and verify them - prevPrio := int64(size + 1) + prevPrio := size + 1 for !queue.Empty() { val, prio := queue.Pop() if prio > prevPrio { @@ -59,22 +61,23 @@ func TestReset(t *testing.T) { for i := 0; i < size; i++ { data[i] = rand.Int() } - queue := New(nil) + queue := New[int, int](nil) + for rep := 0; rep < 2; rep++ { // Fill a priority queue with the above data for i := 0; i < size; i++ { - queue.Push(data[i], int64(prio[i])) + queue.Push(data[i], prio[i]) if queue.Size() != i+1 { t.Errorf("queue size mismatch: have %v, want %v.", queue.Size(), i+1) } } // Create a map the values to the priorities for easier verification - dict := make(map[int64]int) + dict := make(map[int]int) for i := 0; i < size; i++ { - dict[int64(prio[i])] = data[i] + dict[prio[i]] = data[i] } // Pop out half the elements in priority order and verify them - prevPrio := int64(size + 1) + prevPrio := size + 1 for i := 0; i < size/2; i++ { val, prio := queue.Pop() if prio > prevPrio { @@ -104,7 +107,7 @@ func BenchmarkPush(b *testing.B) { } // Execute the benchmark b.ResetTimer() - queue := New(nil) + queue := New[int64, int](nil) for i := 0; i < len(data); i++ { queue.Push(data[i], prio[i]) } @@ -118,7 +121,7 @@ func BenchmarkPop(b *testing.B) { data[i] = rand.Int() prio[i] = rand.Int63() } - queue := New(nil) + queue := New[int64, int](nil) for i := 0; i < len(data); i++ { queue.Push(data[i], prio[i]) } diff --git a/common/prque/sstack.go b/common/prque/sstack.go index b06a95413df0..5dcd1d9dd0c4 100755 --- a/common/prque/sstack.go +++ b/common/prque/sstack.go @@ -10,53 +10,50 @@ package prque +import "golang.org/x/exp/constraints" + // The size of a block of data const blockSize = 4096 // A prioritized item in the sorted stack. -// -// Note: priorities can "wrap around" the int64 range, a comes before b if (a.priority - b.priority) > 0. -// The difference between the lowest and highest priorities in the queue at any point should be less than 2^63. -type item struct { - value interface{} - priority int64 +type item[P constraints.Ordered, V any] struct { + value V + priority P } // SetIndexCallback is called when the element is moved to a new index. // Providing SetIndexCallback is optional, it is needed only if the application needs // to delete elements other than the top one. -type SetIndexCallback func(data interface{}, index int) +type SetIndexCallback[V any] func(data V, index int) // Internal sortable stack data structure. Implements the Push and Pop ops for // the stack (heap) functionality and the Len, Less and Swap methods for the // sortability requirements of the heaps. -type sstack struct { - setIndex SetIndexCallback - size int - capacity int - offset int - wrapAround bool +type sstack[P constraints.Ordered, V any] struct { + setIndex SetIndexCallback[V] + size int + capacity int + offset int - blocks [][]*item - active []*item + blocks [][]*item[P, V] + active []*item[P, V] } // Creates a new, empty stack. -func newSstack(setIndex SetIndexCallback, wrapAround bool) *sstack { - result := new(sstack) +func newSstack[P constraints.Ordered, V any](setIndex SetIndexCallback[V]) *sstack[P, V] { + result := new(sstack[P, V]) result.setIndex = setIndex - result.active = make([]*item, blockSize) - result.blocks = [][]*item{result.active} + result.active = make([]*item[P, V], blockSize) + result.blocks = [][]*item[P, V]{result.active} result.capacity = blockSize - result.wrapAround = wrapAround return result } // Pushes a value onto the stack, expanding it if necessary. Required by // heap.Interface. -func (s *sstack) Push(data interface{}) { +func (s *sstack[P, V]) Push(data any) { if s.size == s.capacity { - s.active = make([]*item, blockSize) + s.active = make([]*item[P, V], blockSize) s.blocks = append(s.blocks, s.active) s.capacity += blockSize s.offset = 0 @@ -65,16 +62,16 @@ func (s *sstack) Push(data interface{}) { s.offset = 0 } if s.setIndex != nil { - s.setIndex(data.(*item).value, s.size) + s.setIndex(data.(*item[P, V]).value, s.size) } - s.active[s.offset] = data.(*item) + s.active[s.offset] = data.(*item[P, V]) s.offset++ s.size++ } // Pops a value off the stack and returns it. Currently no shrinking is done. // Required by heap.Interface. -func (s *sstack) Pop() (res interface{}) { +func (s *sstack[P, V]) Pop() (res any) { s.size-- s.offset-- if s.offset < 0 { @@ -83,28 +80,24 @@ func (s *sstack) Pop() (res interface{}) { } res, s.active[s.offset] = s.active[s.offset], nil if s.setIndex != nil { - s.setIndex(res.(*item).value, -1) + s.setIndex(res.(*item[P, V]).value, -1) } return } // Returns the length of the stack. Required by sort.Interface. -func (s *sstack) Len() int { +func (s *sstack[P, V]) Len() int { return s.size } // Compares the priority of two elements of the stack (higher is first). // Required by sort.Interface. -func (s *sstack) Less(i, j int) bool { - a, b := s.blocks[i/blockSize][i%blockSize].priority, s.blocks[j/blockSize][j%blockSize].priority - if s.wrapAround { - return a-b > 0 - } - return a > b +func (s *sstack[P, V]) Less(i, j int) bool { + return s.blocks[i/blockSize][i%blockSize].priority > s.blocks[j/blockSize][j%blockSize].priority } // Swaps two elements in the stack. Required by sort.Interface. -func (s *sstack) Swap(i, j int) { +func (s *sstack[P, V]) Swap(i, j int) { ib, io, jb, jo := i/blockSize, i%blockSize, j/blockSize, j%blockSize a, b := s.blocks[jb][jo], s.blocks[ib][io] if s.setIndex != nil { @@ -115,6 +108,6 @@ func (s *sstack) Swap(i, j int) { } // Resets the stack, effectively clearing its contents. -func (s *sstack) Reset() { - *s = *newSstack(s.setIndex, false) +func (s *sstack[P, V]) Reset() { + *s = *newSstack[P, V](s.setIndex) } diff --git a/common/prque/sstack_test.go b/common/prque/sstack_test.go index bc6298979cbc..edc99955e837 100644 --- a/common/prque/sstack_test.go +++ b/common/prque/sstack_test.go @@ -17,23 +17,23 @@ import ( func TestSstack(t *testing.T) { // Create some initial data size := 16 * blockSize - data := make([]*item, size) + data := make([]*item[int64, int], size) for i := 0; i < size; i++ { - data[i] = &item{rand.Int(), rand.Int63()} + data[i] = &item[int64, int]{rand.Int(), rand.Int63()} } - stack := newSstack(nil, false) + stack := newSstack[int64, int](nil) for rep := 0; rep < 2; rep++ { // Push all the data into the stack, pop out every second - secs := []*item{} + secs := []*item[int64, int]{} for i := 0; i < size; i++ { stack.Push(data[i]) if i%2 == 0 { - secs = append(secs, stack.Pop().(*item)) + secs = append(secs, stack.Pop().(*item[int64, int])) } } - rest := []*item{} + rest := []*item[int64, int]{} for stack.Len() > 0 { - rest = append(rest, stack.Pop().(*item)) + rest = append(rest, stack.Pop().(*item[int64, int])) } // Make sure the contents of the resulting slices are ok for i := 0; i < size; i++ { @@ -50,12 +50,12 @@ func TestSstack(t *testing.T) { func TestSstackSort(t *testing.T) { // Create some initial data size := 16 * blockSize - data := make([]*item, size) + data := make([]*item[int64, int], size) for i := 0; i < size; i++ { - data[i] = &item{rand.Int(), int64(i)} + data[i] = &item[int64, int]{rand.Int(), int64(i)} } // Push all the data into the stack - stack := newSstack(nil, false) + stack := newSstack[int64, int](nil) for _, val := range data { stack.Push(val) } @@ -72,18 +72,18 @@ func TestSstackSort(t *testing.T) { func TestSstackReset(t *testing.T) { // Create some initial data size := 16 * blockSize - data := make([]*item, size) + data := make([]*item[int64, int], size) for i := 0; i < size; i++ { - data[i] = &item{rand.Int(), rand.Int63()} + data[i] = &item[int64, int]{rand.Int(), rand.Int63()} } - stack := newSstack(nil, false) + stack := newSstack[int64, int](nil) for rep := 0; rep < 2; rep++ { // Push all the data into the stack, pop out every second - secs := []*item{} + secs := []*item[int64, int]{} for i := 0; i < size; i++ { stack.Push(data[i]) if i%2 == 0 { - secs = append(secs, stack.Pop().(*item)) + secs = append(secs, stack.Pop().(*item[int64, int])) } } // Reset and verify both pulled and stack contents diff --git a/consensus/XDPoS/utils/types.go b/consensus/XDPoS/utils/types.go index fc4aaf0463aa..55265516f7e2 100644 --- a/consensus/XDPoS/utils/types.go +++ b/consensus/XDPoS/utils/types.go @@ -26,7 +26,7 @@ type TradingService interface { GetEmptyTradingState() (*tradingstate.TradingStateDB, error) HasTradingState(block *types.Block, author common.Address) bool GetStateCache() tradingstate.Database - GetTriegc() *prque.Prque + GetTriegc() *prque.Prque[int64, common.Hash] ApplyOrder(header *types.Header, coinbase common.Address, chain consensus.ChainContext, statedb *state.StateDB, XDCXstatedb *tradingstate.TradingStateDB, orderBook common.Hash, order *tradingstate.OrderItem) ([]map[string]string, []*tradingstate.OrderItem, error) UpdateMediumPriceBeforeEpoch(epochNumber uint64, tradingStateDB *tradingstate.TradingStateDB, statedb *state.StateDB) error IsSDKNode() bool @@ -40,7 +40,7 @@ type LendingService interface { GetLendingState(block *types.Block, author common.Address) (*lendingstate.LendingStateDB, error) HasLendingState(block *types.Block, author common.Address) bool GetStateCache() lendingstate.Database - GetTriegc() *prque.Prque + GetTriegc() *prque.Prque[int64, common.Hash] ApplyOrder(header *types.Header, coinbase common.Address, chain consensus.ChainContext, statedb *state.StateDB, lendingStateDB *lendingstate.LendingStateDB, tradingStateDb *tradingstate.TradingStateDB, lendingOrderBook common.Hash, order *lendingstate.LendingItem) ([]*lendingstate.LendingTrade, []*lendingstate.LendingItem, error) GetCollateralPrices(header *types.Header, chain consensus.ChainContext, statedb *state.StateDB, tradingStateDb *tradingstate.TradingStateDB, collateralToken common.Address, lendingToken common.Address) (*big.Int, *big.Int, error) GetMediumTradePriceBeforeEpoch(chain consensus.ChainContext, statedb *state.StateDB, tradingStateDb *tradingstate.TradingStateDB, baseToken common.Address, quoteToken common.Address) (*big.Int, error) diff --git a/core/blockchain.go b/core/blockchain.go index 3c74fc6f8e84..b6d328cc642b 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -137,8 +137,8 @@ type BlockChain struct { db ethdb.Database // Low level persistent database to store final content in XDCxDb ethdb.XDCxDatabase - triegc *prque.Prque // Priority queue mapping block numbers to tries to gc - gcproc time.Duration // Accumulates canonical block processing for trie dumping + triegc *prque.Prque[int64, common.Hash] // Priority queue mapping block numbers to tries to gc + gcproc time.Duration // Accumulates canonical block processing for trie dumping hc *HeaderChain rmLogsFeed event.Feed @@ -209,7 +209,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par chainConfig: chainConfig, cacheConfig: cacheConfig, db: db, - triegc: prque.New(nil), + triegc: prque.New[int64, common.Hash](nil), stateCache: state.NewDatabase(db), quit: make(chan struct{}), bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit), @@ -975,17 +975,17 @@ func (bc *BlockChain) saveData() { } } for !bc.triegc.Empty() { - triedb.Dereference(bc.triegc.PopItem().(common.Hash)) + triedb.Dereference(bc.triegc.PopItem()) } if tradingTriedb != nil && lendingTriedb != nil { if tradingService.GetTriegc() != nil { for !tradingService.GetTriegc().Empty() { - tradingTriedb.Dereference(tradingService.GetTriegc().PopItem().(common.Hash)) + tradingTriedb.Dereference(tradingService.GetTriegc().PopItem()) } } if lendingService.GetTriegc() != nil { for !lendingService.GetTriegc().Empty() { - lendingTriedb.Dereference(lendingService.GetTriegc().PopItem().(common.Hash)) + lendingTriedb.Dereference(lendingService.GetTriegc().PopItem()) } } } @@ -1328,7 +1328,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. bc.triegc.Push(root, number) break } - triedb.Dereference(root.(common.Hash)) + triedb.Dereference(root) } if tradingService != nil { for !tradingService.GetTriegc().Empty() { @@ -1337,7 +1337,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. tradingService.GetTriegc().Push(tradingRoot, number) break } - tradingTrieDb.Dereference(tradingRoot.(common.Hash)) + tradingTrieDb.Dereference(tradingRoot) } } if lendingService != nil { @@ -1347,7 +1347,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. lendingService.GetTriegc().Push(lendingRoot, number) break } - lendingTrieDb.Dereference(lendingRoot.(common.Hash)) + lendingTrieDb.Dereference(lendingRoot) } } } diff --git a/core/txpool/lending_pool.go b/core/txpool/lending_pool.go index 4a199384cf12..e73d71fc31c5 100644 --- a/core/txpool/lending_pool.go +++ b/core/txpool/lending_pool.go @@ -997,7 +997,7 @@ func (pool *LendingPool) promoteExecutables(accounts []common.Address) { if pending > pool.config.GlobalSlots { pendingBeforeCap := pending // Assemble a spam order to penalize large transactors first - spammers := prque.New(nil) + spammers := prque.New[int64, common.Address](nil) for addr, list := range pool.pending { // Only evict transactions from high rollers if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { @@ -1009,12 +1009,12 @@ func (pool *LendingPool) promoteExecutables(accounts []common.Address) { for pending > pool.config.GlobalSlots && !spammers.Empty() { // Retrieve the next offender if not local address offender, _ := spammers.Pop() - offenders = append(offenders, offender.(common.Address)) + offenders = append(offenders, offender) // Equalize balances until all the same or below threshold if len(offenders) > 1 { // Calculate the equalization threshold for all current offenders - threshold := pool.pending[offender.(common.Address)].Len() + threshold := pool.pending[offender].Len() // Iteratively reduce all offenders until below limit or threshold reached for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { diff --git a/core/txpool/order_pool.go b/core/txpool/order_pool.go index 4857d993886e..247fdf6cef4f 100644 --- a/core/txpool/order_pool.go +++ b/core/txpool/order_pool.go @@ -914,7 +914,7 @@ func (pool *OrderPool) promoteExecutables(accounts []common.Address) { if pending > pool.config.GlobalSlots { pendingBeforeCap := pending // Assemble a spam order to penalize large transactors first - spammers := prque.New(nil) + spammers := prque.New[int64, common.Address](nil) for addr, list := range pool.pending { // Only evict transactions from high rollers if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { @@ -926,12 +926,12 @@ func (pool *OrderPool) promoteExecutables(accounts []common.Address) { for pending > pool.config.GlobalSlots && !spammers.Empty() { // Retrieve the next offender if not local address offender, _ := spammers.Pop() - offenders = append(offenders, offender.(common.Address)) + offenders = append(offenders, offender) // Equalize balances until all the same or below threshold if len(offenders) > 1 { // Calculate the equalization threshold for all current offenders - threshold := pool.pending[offender.(common.Address)].Len() + threshold := pool.pending[offender].Len() // Iteratively reduce all offenders until below limit or threshold reached for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index fc57d9355aa9..fd5f2381699f 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -1535,7 +1535,7 @@ func (pool *TxPool) truncatePending() { pendingBeforeCap := pending // Assemble a spam order to penalize large transactors first - spammers := prque.New(nil) + spammers := prque.New[int64, common.Address](nil) for addr, list := range pool.pending { // Only evict transactions from high rollers if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { @@ -1547,12 +1547,12 @@ func (pool *TxPool) truncatePending() { for pending > pool.config.GlobalSlots && !spammers.Empty() { // Retrieve the next offender if not local address offender, _ := spammers.Pop() - offenders = append(offenders, offender.(common.Address)) + offenders = append(offenders, offender) // Equalize balances until all the same or below threshold if len(offenders) > 1 { // Calculate the equalization threshold for all current offenders - threshold := pool.pending[offender.(common.Address)].Len() + threshold := pool.pending[offender].Len() // Iteratively reduce all offenders until below limit or threshold reached for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index b21460c2efd6..115a780f9210 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -70,7 +70,7 @@ type queue struct { // Headers are "special", they download in batches, supported by a skeleton chain headerHead common.Hash // [eth/62] Hash of the last queued header to verify order headerTaskPool map[uint64]*types.Header // [eth/62] Pending header retrieval tasks, mapping starting indexes to skeleton headers - headerTaskQueue *prque.Prque // [eth/62] Priority queue of the skeleton indexes to fetch the filling headers for + headerTaskQueue *prque.Prque[int64, uint64] // [eth/62] Priority queue of the skeleton indexes to fetch the filling headers for headerPeerMiss map[string]map[uint64]struct{} // [eth/62] Set of per-peer header batches known to be unavailable headerPendPool map[string]*fetchRequest // [eth/62] Currently pending header retrieval operations headerResults []*types.Header // [eth/62] Result cache accumulating the completed headers @@ -79,15 +79,15 @@ type queue struct { headerContCh chan bool // [eth/62] Channel to notify when header download finishes // All data retrievals below are based on an already assembles header chain - blockTaskPool map[common.Hash]*types.Header // [eth/62] Pending block (body) retrieval tasks, mapping hashes to headers - blockTaskQueue *prque.Prque // [eth/62] Priority queue of the headers to fetch the blocks (bodies) for - blockPendPool map[string]*fetchRequest // [eth/62] Currently pending block (body) retrieval operations - blockDonePool map[common.Hash]struct{} // [eth/62] Set of the completed block (body) fetches + blockTaskPool map[common.Hash]*types.Header // [eth/62] Pending block (body) retrieval tasks, mapping hashes to headers + blockTaskQueue *prque.Prque[int64, *types.Header] // [eth/62] Priority queue of the headers to fetch the blocks (bodies) for + blockPendPool map[string]*fetchRequest // [eth/62] Currently pending block (body) retrieval operations + blockDonePool map[common.Hash]struct{} // [eth/62] Set of the completed block (body) fetches - receiptTaskPool map[common.Hash]*types.Header // [eth/63] Pending receipt retrieval tasks, mapping hashes to headers - receiptTaskQueue *prque.Prque // [eth/63] Priority queue of the headers to fetch the receipts for - receiptPendPool map[string]*fetchRequest // [eth/63] Currently pending receipt retrieval operations - receiptDonePool map[common.Hash]struct{} // [eth/63] Set of the completed receipt fetches + receiptTaskPool map[common.Hash]*types.Header // [eth/63] Pending receipt retrieval tasks, mapping hashes to headers + receiptTaskQueue *prque.Prque[int64, *types.Header] // [eth/63] Priority queue of the headers to fetch the receipts for + receiptPendPool map[string]*fetchRequest // [eth/63] Currently pending receipt retrieval operations + receiptDonePool map[common.Hash]struct{} // [eth/63] Set of the completed receipt fetches resultCache []*fetchResult // Downloaded but not yet delivered fetch results resultOffset uint64 // Offset of the first cached fetch result in the block chain @@ -105,11 +105,11 @@ func newQueue() *queue { headerPendPool: make(map[string]*fetchRequest), headerContCh: make(chan bool), blockTaskPool: make(map[common.Hash]*types.Header), - blockTaskQueue: prque.New(nil), + blockTaskQueue: prque.New[int64, *types.Header](nil), blockPendPool: make(map[string]*fetchRequest), blockDonePool: make(map[common.Hash]struct{}), receiptTaskPool: make(map[common.Hash]*types.Header), - receiptTaskQueue: prque.New(nil), + receiptTaskQueue: prque.New[int64, *types.Header](nil), receiptPendPool: make(map[string]*fetchRequest), receiptDonePool: make(map[common.Hash]struct{}), resultCache: make([]*fetchResult, blockCacheItems), @@ -277,7 +277,7 @@ func (q *queue) ScheduleSkeleton(from uint64, skeleton []*types.Header) { } // Shedule all the header retrieval tasks for the skeleton assembly q.headerTaskPool = make(map[uint64]*types.Header) - q.headerTaskQueue = prque.New(nil) + q.headerTaskQueue = prque.New[int64, uint64](nil) q.headerPeerMiss = make(map[string]map[uint64]struct{}) // Reset availability to correct invalid chains q.headerResults = make([]*types.Header, len(skeleton)*MaxHeaderFetch) q.headerProced = 0 @@ -427,12 +427,12 @@ func (q *queue) ReserveHeaders(p *peerConnection, count int) *fetchRequest { for send == 0 && !q.headerTaskQueue.Empty() { from, _ := q.headerTaskQueue.Pop() if q.headerPeerMiss[p.id] != nil { - if _, ok := q.headerPeerMiss[p.id][from.(uint64)]; ok { - skip = append(skip, from.(uint64)) + if _, ok := q.headerPeerMiss[p.id][from]; ok { + skip = append(skip, from) continue } } - send = from.(uint64) + send = from } // Merge all the skipped batches back for _, from := range skip { @@ -484,7 +484,7 @@ func (q *queue) ReserveReceipts(p *peerConnection, count int) (*fetchRequest, bo // Note, this method expects the queue lock to be already held for writing. The // reason the lock is not obtained in here is because the parameters already need // to access the queue, so they already need a lock anyway. -func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque, +func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque[int64, *types.Header], pendPool map[string]*fetchRequest, donePool map[common.Hash]struct{}, isNoop func(*types.Header) bool) (*fetchRequest, bool, error) { // Short circuit if the pool has been depleted, or if the peer's already // downloading something (sanity check not to corrupt state) @@ -503,7 +503,7 @@ func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common progress := false for proc := 0; proc < space && len(send) < count && !taskQueue.Empty(); proc++ { - header := taskQueue.PopItem().(*types.Header) + header := taskQueue.PopItem() hash := header.Hash() // If we're the first to request this task, initialise the result container @@ -586,12 +586,12 @@ func (q *queue) CancelReceipts(request *fetchRequest) { } // Cancel aborts a fetch request, returning all pending hashes to the task queue. -func (q *queue) cancel(request *fetchRequest, taskQueue *prque.Prque, pendPool map[string]*fetchRequest) { +func (q *queue) cancel(request *fetchRequest, taskQueue interface{}, pendPool map[string]*fetchRequest) { if request.From > 0 { - taskQueue.Push(request.From, -int64(request.From)) + taskQueue.(*prque.Prque[int64, uint64]).Push(request.From, -int64(request.From)) } for _, header := range request.Headers { - taskQueue.Push(header, -int64(header.Number.Uint64())) + taskQueue.(*prque.Prque[int64, *types.Header]).Push(header, -int64(header.Number.Uint64())) } delete(pendPool, request.Peer.id) } @@ -650,7 +650,7 @@ func (q *queue) ExpireReceipts(timeout time.Duration) map[string]int { // Note, this method expects the queue lock to be already held. The // reason the lock is not obtained in here is because the parameters already need // to access the queue, so they already need a lock anyway. -func (q *queue) expire(timeout time.Duration, pendPool map[string]*fetchRequest, taskQueue *prque.Prque, timeoutMeter *metrics.Meter) map[string]int { +func (q *queue) expire(timeout time.Duration, pendPool map[string]*fetchRequest, taskQueue interface{}, timeoutMeter *metrics.Meter) map[string]int { // Iterate over the expired requests and return each to the queue expiries := make(map[string]int) for id, request := range pendPool { @@ -660,10 +660,10 @@ func (q *queue) expire(timeout time.Duration, pendPool map[string]*fetchRequest, // Return any non satisfied requests to the pool if request.From > 0 { - taskQueue.Push(request.From, -int64(request.From)) + taskQueue.(*prque.Prque[int64, uint64]).Push(request.From, -int64(request.From)) } for _, header := range request.Headers { - taskQueue.Push(header, -int64(header.Number.Uint64())) + taskQueue.(*prque.Prque[int64, *types.Header]).Push(header, -int64(header.Number.Uint64())) } // Add the peer to the expiry report along the the number of failed requests expiries[id] = len(request.Headers) @@ -804,7 +804,7 @@ func (q *queue) DeliverReceipts(id string, receiptList [][]*types.Receipt) (int, // Note, this method expects the queue lock to be already held for writing. The // reason the lock is not obtained in here is because the parameters already need // to access the queue, so they already need a lock anyway. -func (q *queue) deliver(id string, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque, +func (q *queue) deliver(id string, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque[int64, *types.Header], pendPool map[string]*fetchRequest, donePool map[common.Hash]struct{}, reqTimer *metrics.Timer, results int, reconstruct func(header *types.Header, index int, result *fetchResult) error) (int, error) { diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 259781a6bb11..f8cf67f23cf8 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -131,11 +131,10 @@ type Fetcher struct { completing map[common.Hash]*announce // Blocks with headers, currently body-completing // Block cache - queue *prque.Prque // Queue containing the import operations (block number sorted) - queues map[string]int // Per peer block counts to prevent memory exhaustion - queued map[common.Hash]*inject // Set of already queued blocks (to dedup imports) + queue *prque.Prque[int64, *inject] // Queue containing the import operations (block number sorted) + queues map[string]int // Per peer block counts to prevent memory exhaustion + queued map[common.Hash]*inject // Set of already queued blocks (to dedup imports) knowns *lru.Cache[common.Hash, struct{}] - // Callbacks getBlock blockRetrievalFn // Retrieves a block from the local chain verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work @@ -170,7 +169,7 @@ func New(getBlock blockRetrievalFn, verifyHeader headerVerifierFn, handlePropose fetching: make(map[common.Hash]*announce), fetched: make(map[common.Hash][]*announce), completing: make(map[common.Hash]*announce), - queue: prque.New(nil), + queue: prque.New[int64, *inject](nil), queues: make(map[string]int), queued: make(map[common.Hash]*inject), knowns: lru.NewCache[common.Hash, struct{}](blockLimit), @@ -304,7 +303,7 @@ func (f *Fetcher) loop() { // Import any queued blocks that could potentially fit height := f.chainHeight() for !f.queue.Empty() { - op := f.queue.PopItem().(*inject) + op := f.queue.PopItem() if f.queueChangeHook != nil { f.queueChangeHook(op.block.Hash(), false) } diff --git a/go.mod b/go.mod index 9adb083eca74..83100986b004 100644 --- a/go.mod +++ b/go.mod @@ -53,6 +53,7 @@ require ( github.com/mattn/go-isatty v0.0.17 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/urfave/cli/v2 v2.27.5 + golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) diff --git a/go.sum b/go.sum index e59acf391656..7b0965c69d3c 100644 --- a/go.sum +++ b/go.sum @@ -214,6 +214,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4= +golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/trie/sync.go b/trie/sync.go index 645789f6ea96..021a836f3ad9 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -73,7 +73,7 @@ type Sync struct { database ethdb.KeyValueReader // Persistent database to check for existing entries membatch *syncMemBatch // Memory buffer to avoid frequent database writes requests map[common.Hash]*request // Pending requests pertaining to a key hash - queue *prque.Prque // Priority queue with the pending requests + queue *prque.Prque[int64, any] // Priority queue with the pending requests bloom *SyncBloom // Bloom filter for fast Node existence checks } @@ -83,7 +83,7 @@ func NewSync(root common.Hash, database ethdb.KeyValueReader, callback LeafCallb database: database, membatch: newSyncMemBatch(), requests: make(map[common.Hash]*request), - queue: prque.New(nil), + queue: prque.New[int64, any](nil), // Ugh, can contain both string and hash, whyyy bloom: bloom, } ts.AddSubTrie(root, 0, common.Hash{}, callback) From b58802a4020f042ff15e1d8281638e8790c75608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 22 Feb 2023 13:55:09 +0200 Subject: [PATCH 073/121] common/math: allow HexOrDecimal to accept unquoted decimals too (#26758) --- common/math/big.go | 18 ++++++++++++++++++ common/math/integer.go | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/common/math/big.go b/common/math/big.go index 7254efed4823..d6b2c5097b8f 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -41,6 +41,24 @@ const ( // HexOrDecimal256 marshals big.Int as hex or decimal. type HexOrDecimal256 big.Int +// NewHexOrDecimal256 creates a new HexOrDecimal256 +func NewHexOrDecimal256(x int64) *HexOrDecimal256 { + b := big.NewInt(x) + h := HexOrDecimal256(*b) + return &h +} + +// UnmarshalJSON implements json.Unmarshaler. +// +// It is similar to UnmarshalText, but allows parsing real decimals too, not just +// quoted decimal strings. +func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error { + if len(input) > 0 && input[0] == '"' { + input = input[1 : len(input)-1] + } + return i.UnmarshalText(input) +} + // UnmarshalText implements encoding.TextUnmarshaler. func (i *HexOrDecimal256) UnmarshalText(input []byte) error { bigint, ok := ParseBig256(string(input)) diff --git a/common/math/integer.go b/common/math/integer.go index 17a9fb1375d1..e78949299185 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -41,6 +41,17 @@ const ( // HexOrDecimal64 marshals uint64 as hex or decimal. type HexOrDecimal64 uint64 +// UnmarshalJSON implements json.Unmarshaler. +// +// It is similar to UnmarshalText, but allows parsing real decimals too, not just +// quoted decimal strings. +func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error { + if len(input) > 0 && input[0] == '"' { + input = input[1 : len(input)-1] + } + return i.UnmarshalText(input) +} + // UnmarshalText implements encoding.TextUnmarshaler. func (i *HexOrDecimal64) UnmarshalText(input []byte) error { int, ok := ParseUint64(string(input)) From 12111d30ea4730c7f8826778f225c16933046fd1 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Mon, 3 Apr 2023 01:51:31 -0600 Subject: [PATCH 074/121] common: delete MakeName (#27023) common,p2p: remove unused function MakeName --- common/path.go | 9 --------- p2p/server.go | 1 - 2 files changed, 10 deletions(-) diff --git a/common/path.go b/common/path.go index 69820cfe5dec..c1e382fd29c4 100644 --- a/common/path.go +++ b/common/path.go @@ -17,19 +17,10 @@ package common import ( - "fmt" "os" "path/filepath" - "runtime" ) -// MakeName creates a node name that follows the ethereum convention -// for such names. It adds the operation system name and Go runtime version -// the name. -func MakeName(name, version string) string { - return fmt.Sprintf("%s/v%s/%s/%s", name, version, runtime.GOOS, runtime.Version()) -} - // FileExist checks if a file exists at filePath. func FileExist(filePath string) bool { _, err := os.Stat(filePath) diff --git a/p2p/server.go b/p2p/server.go index 51579ff7c30c..a2cdb1707724 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -81,7 +81,6 @@ type Config struct { DiscoveryV5 bool `toml:",omitempty"` // Name sets the node name of this server. - // Use common.MakeName to create a name that follows existing conventions. Name string `toml:"-"` // BootstrapNodes are used to establish connectivity From 59b14ed2cbd1c6cc612a5b0422678d180ce5df43 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 18 Dec 2024 19:02:48 +0800 Subject: [PATCH 075/121] internal/ethapi: make NewAccount return EIP-55 format (#26973) --- common/types.go | 14 ++++++++++++++ common/types_test.go | 24 ++++++++++++++++++++++++ internal/ethapi/api.go | 10 +++++++--- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/common/types.go b/common/types.go index d32343ccd4bc..5f2f366c99b2 100644 --- a/common/types.go +++ b/common/types.go @@ -19,6 +19,7 @@ package common import ( "bytes" "encoding/hex" + "encoding/json" "fmt" "math/big" "math/rand" @@ -405,3 +406,16 @@ func ExtractAddressFromBytes(bytePenalties []byte) []Address { } return penalties } + +// AddressEIP55 is an alias of Address with a customized json marshaller +type AddressEIP55 Address + +// String returns the hex representation of the address in the manner of EIP55. +func (addr AddressEIP55) String() string { + return Address(addr).Hex() +} + +// MarshalJSON marshals the address in the manner of EIP55. +func (addr AddressEIP55) MarshalJSON() ([]byte, error) { + return json.Marshal(addr.String()) +} diff --git a/common/types_test.go b/common/types_test.go index 598286c08978..3262f549310b 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -371,6 +371,30 @@ func TestStringToBinaryAddress(t *testing.T) { } } +func TestAddressEIP55(t *testing.T) { + addr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed") + addrEIP55 := AddressEIP55(addr) + + if addr.Hex() != addrEIP55.String() { + t.Fatal("AddressEIP55 should match original address hex") + } + + blob, err := addrEIP55.MarshalJSON() + if err != nil { + t.Fatal("Failed to marshal AddressEIP55", err) + } + if strings.Trim(string(blob), "\"") != addr.Hex() { + t.Fatal("Address with checksum is expected") + } + var dec Address + if err := json.Unmarshal(blob, &dec); err != nil { + t.Fatal("Failed to unmarshal AddressEIP55", err) + } + if addr != dec { + t.Fatal("Unexpected address after unmarshal") + } +} + func BenchmarkPrettyDuration(b *testing.B) { var x = PrettyDuration(time.Duration(int64(1203123912312))) b.Logf("Pre %s", time.Duration(x).String()) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index f88c79d4940f..c371f1442594 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -383,12 +383,16 @@ func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (a } // NewAccount will create a new account and returns the address for the new account. -func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { +func (s *PrivateAccountAPI) NewAccount(password string) (common.AddressEIP55, error) { acc, err := fetchKeystore(s.am).NewAccount(password) if err == nil { - return acc.Address, nil + addrEIP55 := common.AddressEIP55(acc.Address) + log.Info("Your new key was generated", "address", addrEIP55.String()) + log.Warn("Please backup your key file!", "path", acc.URL.Path) + log.Warn("Please remember your password!") + return addrEIP55, nil } - return common.Address{}, err + return common.AddressEIP55{}, err } // fetchKeystore retrives the encrypted keystore from the account manager. From f74cccd1cbdaa5deef4ab78c6214a7c2f8631d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felf=C3=B6ldi=20Zsolt?= Date: Wed, 17 May 2023 16:39:33 +0200 Subject: [PATCH 076/121] beacon/types: add beacon chain data types (#27292) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * beacon/types: add beacon chain data types * beacon/merkle: added comments * go.mod: cleanups --------- Co-authored-by: Péter Szilágyi --- beacon/merkle/merkle.go | 67 ++++++++++ beacon/params/params.go | 44 +++++++ beacon/types/committee.go | 214 ++++++++++++++++++++++++++++++++ beacon/types/config.go | 176 ++++++++++++++++++++++++++ beacon/types/gen_header_json.go | 66 ++++++++++ beacon/types/header.go | 121 ++++++++++++++++++ beacon/types/update.go | 118 ++++++++++++++++++ common/types.go | 20 +++ go.mod | 3 + go.sum | 7 ++ 10 files changed, 836 insertions(+) create mode 100644 beacon/merkle/merkle.go create mode 100644 beacon/params/params.go create mode 100644 beacon/types/committee.go create mode 100644 beacon/types/config.go create mode 100644 beacon/types/gen_header_json.go create mode 100644 beacon/types/header.go create mode 100644 beacon/types/update.go diff --git a/beacon/merkle/merkle.go b/beacon/merkle/merkle.go new file mode 100644 index 000000000000..d1c18a2cf151 --- /dev/null +++ b/beacon/merkle/merkle.go @@ -0,0 +1,67 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package merkle implements proof verifications in binary merkle trees. +package merkle + +import ( + "crypto/sha256" + "errors" + "reflect" + + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" +) + +// Value represents either a 32 byte leaf value or hash node in a binary merkle tree/partial proof. +type Value [32]byte + +// Values represent a series of merkle tree leaves/nodes. +type Values []Value + +var valueT = reflect.TypeOf(Value{}) + +// UnmarshalJSON parses a merkle value in hex syntax. +func (m *Value) UnmarshalJSON(input []byte) error { + return hexutil.UnmarshalFixedJSON(valueT, input, m[:]) +} + +// VerifyProof verifies a Merkle proof branch for a single value in a +// binary Merkle tree (index is a generalized tree index). +func VerifyProof(root common.Hash, index uint64, branch Values, value Value) error { + hasher := sha256.New() + for _, sibling := range branch { + hasher.Reset() + if index&1 == 0 { + hasher.Write(value[:]) + hasher.Write(sibling[:]) + } else { + hasher.Write(sibling[:]) + hasher.Write(value[:]) + } + hasher.Sum(value[:0]) + if index >>= 1; index == 0 { + return errors.New("branch has extra items") + } + } + if index != 1 { + return errors.New("branch is missing items") + } + if common.Hash(value) != root { + return errors.New("root mismatch") + } + return nil +} diff --git a/beacon/params/params.go b/beacon/params/params.go new file mode 100644 index 000000000000..ee9feb1acbea --- /dev/null +++ b/beacon/params/params.go @@ -0,0 +1,44 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package params + +const ( + EpochLength = 32 + SyncPeriodLength = 8192 + + BLSSignatureSize = 96 + BLSPubkeySize = 48 + + SyncCommitteeSize = 512 + SyncCommitteeBitmaskSize = SyncCommitteeSize / 8 + SyncCommitteeSupermajority = (SyncCommitteeSize*2 + 2) / 3 +) + +const ( + StateIndexGenesisTime = 32 + StateIndexGenesisValidators = 33 + StateIndexForkVersion = 141 + StateIndexLatestHeader = 36 + StateIndexBlockRoots = 37 + StateIndexStateRoots = 38 + StateIndexHistoricRoots = 39 + StateIndexFinalBlock = 105 + StateIndexSyncCommittee = 54 + StateIndexNextSyncCommittee = 55 + StateIndexExecPayload = 56 + StateIndexExecHead = 908 +) diff --git a/beacon/types/committee.go b/beacon/types/committee.go new file mode 100644 index 000000000000..80af480d2262 --- /dev/null +++ b/beacon/types/committee.go @@ -0,0 +1,214 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "crypto/sha256" + "encoding/json" + "fmt" + "math/bits" + + "github.com/XinFinOrg/XDPoSChain/beacon/params" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" + bls "github.com/protolambda/bls12-381-util" +) + +// SerializedSyncCommitteeSize is the size of the sync committee plus the +// aggregate public key. +const SerializedSyncCommitteeSize = (params.SyncCommitteeSize + 1) * params.BLSPubkeySize + +// SerializedSyncCommittee is the serialized version of a sync committee +// plus the aggregate public key. +type SerializedSyncCommittee [SerializedSyncCommitteeSize]byte + +// jsonSyncCommittee is the JSON representation of a sync committee. +// +// See data structure definition here: +// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#syncaggregate +type jsonSyncCommittee struct { + Pubkeys []hexutil.Bytes `json:"pubkeys"` + Aggregate hexutil.Bytes `json:"aggregate_pubkey"` +} + +// MarshalJSON implements json.Marshaler. +func (s *SerializedSyncCommittee) MarshalJSON() ([]byte, error) { + sc := jsonSyncCommittee{Pubkeys: make([]hexutil.Bytes, params.SyncCommitteeSize)} + for i := range sc.Pubkeys { + sc.Pubkeys[i] = make(hexutil.Bytes, params.BLSPubkeySize) + copy(sc.Pubkeys[i][:], s[i*params.BLSPubkeySize:(i+1)*params.BLSPubkeySize]) + } + sc.Aggregate = make(hexutil.Bytes, params.BLSPubkeySize) + copy(sc.Aggregate[:], s[params.SyncCommitteeSize*params.BLSPubkeySize:]) + return json.Marshal(&sc) +} + +// UnmarshalJSON implements json.Marshaler. +func (s *SerializedSyncCommittee) UnmarshalJSON(input []byte) error { + var sc jsonSyncCommittee + if err := json.Unmarshal(input, &sc); err != nil { + return err + } + if len(sc.Pubkeys) != params.SyncCommitteeSize { + return fmt.Errorf("invalid number of pubkeys %d", len(sc.Pubkeys)) + } + for i, key := range sc.Pubkeys { + if len(key) != params.BLSPubkeySize { + return fmt.Errorf("pubkey %d has invalid size %d", i, len(key)) + } + copy(s[i*params.BLSPubkeySize:], key[:]) + } + if len(sc.Aggregate) != params.BLSPubkeySize { + return fmt.Errorf("invalid aggregate pubkey size %d", len(sc.Aggregate)) + } + copy(s[params.SyncCommitteeSize*params.BLSPubkeySize:], sc.Aggregate[:]) + return nil +} + +// Root calculates the root hash of the binary tree representation of a sync +// committee provided in serialized format. +// +// TODO(zsfelfoldi): Get rid of this when SSZ encoding lands. +func (s *SerializedSyncCommittee) Root() common.Hash { + var ( + hasher = sha256.New() + padding [64 - params.BLSPubkeySize]byte + data [params.SyncCommitteeSize]common.Hash + l = params.SyncCommitteeSize + ) + for i := range data { + hasher.Reset() + hasher.Write(s[i*params.BLSPubkeySize : (i+1)*params.BLSPubkeySize]) + hasher.Write(padding[:]) + hasher.Sum(data[i][:0]) + } + for l > 1 { + for i := 0; i < l/2; i++ { + hasher.Reset() + hasher.Write(data[i*2][:]) + hasher.Write(data[i*2+1][:]) + hasher.Sum(data[i][:0]) + } + l /= 2 + } + hasher.Reset() + hasher.Write(s[SerializedSyncCommitteeSize-params.BLSPubkeySize : SerializedSyncCommitteeSize]) + hasher.Write(padding[:]) + hasher.Sum(data[1][:0]) + hasher.Reset() + hasher.Write(data[0][:]) + hasher.Write(data[1][:]) + hasher.Sum(data[0][:0]) + return data[0] +} + +// Deserialize splits open the pubkeys into proper BLS key types. +func (s *SerializedSyncCommittee) Deserialize() (*SyncCommittee, error) { + sc := new(SyncCommittee) + for i := 0; i <= params.SyncCommitteeSize; i++ { + key := new(bls.Pubkey) + + var bytes [params.BLSPubkeySize]byte + copy(bytes[:], s[i*params.BLSPubkeySize:(i+1)*params.BLSPubkeySize]) + + if err := key.Deserialize(&bytes); err != nil { + return nil, err + } + if i < params.SyncCommitteeSize { + sc.keys[i] = key + } else { + sc.aggregate = key + } + } + return sc, nil +} + +// SyncCommittee is a set of sync committee signer pubkeys and the aggregate key. +// +// See data structure definition here: +// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#syncaggregate +type SyncCommittee struct { + keys [params.SyncCommitteeSize]*bls.Pubkey + aggregate *bls.Pubkey +} + +// VerifySignature returns true if the given sync aggregate is a valid signature +// or the given hash. +func (sc *SyncCommittee) VerifySignature(signingRoot common.Hash, signature *SyncAggregate) bool { + var ( + sig bls.Signature + keys = make([]*bls.Pubkey, 0, params.SyncCommitteeSize) + ) + if err := sig.Deserialize(&signature.Signature); err != nil { + return false + } + for i, key := range sc.keys { + if signature.Signers[i/8]&(byte(1)<<(i%8)) != 0 { + keys = append(keys, key) + } + } + return bls.FastAggregateVerify(keys, signingRoot[:], &sig) +} + +// SyncAggregate represents an aggregated BLS signature with Signers referring +// to a subset of the corresponding sync committee. +// +// See data structure definition here: +// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#syncaggregate +type SyncAggregate struct { + Signers [params.SyncCommitteeBitmaskSize]byte + Signature [params.BLSSignatureSize]byte +} + +type jsonSyncAggregate struct { + Signers hexutil.Bytes `json:"sync_committee_bits"` + Signature hexutil.Bytes `json:"sync_committee_signature"` +} + +// MarshalJSON implements json.Marshaler. +func (s *SyncAggregate) MarshalJSON() ([]byte, error) { + return json.Marshal(&jsonSyncAggregate{ + Signers: s.Signers[:], + Signature: s.Signature[:], + }) +} + +// UnmarshalJSON implements json.Marshaler. +func (s *SyncAggregate) UnmarshalJSON(input []byte) error { + var sc jsonSyncAggregate + if err := json.Unmarshal(input, &sc); err != nil { + return err + } + if len(sc.Signers) != params.SyncCommitteeBitmaskSize { + return fmt.Errorf("invalid signature bitmask size %d", len(sc.Signers)) + } + if len(sc.Signature) != params.BLSSignatureSize { + return fmt.Errorf("invalid signature size %d", len(sc.Signature)) + } + copy(s.Signers[:], sc.Signers) + copy(s.Signature[:], sc.Signature) + return nil +} + +// SignerCount returns the number of signers in the aggregate signature. +func (s *SyncAggregate) SignerCount() int { + var count int + for _, v := range s.Signers { + count += bits.OnesCount8(v) + } + return count +} diff --git a/beacon/types/config.go b/beacon/types/config.go new file mode 100644 index 000000000000..abe2b8f60193 --- /dev/null +++ b/beacon/types/config.go @@ -0,0 +1,176 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "crypto/sha256" + "fmt" + "os" + "sort" + "strconv" + "strings" + + "github.com/XinFinOrg/XDPoSChain/beacon/merkle" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" + "github.com/go-yaml/yaml" +) + +// syncCommitteeDomain specifies the signatures specific use to avoid clashes +// across signing different data structures. +const syncCommitteeDomain = 7 + +// Fork describes a single beacon chain fork and also stores the calculated +// signature domain used after this fork. +type Fork struct { + // Name of the fork in the chain config (config.yaml) file{ + Name string + + // Epoch when given fork version is activated + Epoch uint64 + + // Fork version, see https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types + Version []byte + + // calculated by computeDomain, based on fork version and genesis validators root + domain merkle.Value +} + +// computeDomain returns the signature domain based on the given fork version +// and genesis validator set root. +func (f *Fork) computeDomain(genesisValidatorsRoot common.Hash) { + var ( + hasher = sha256.New() + forkVersion32 merkle.Value + forkDataRoot merkle.Value + ) + copy(forkVersion32[:], f.Version) + hasher.Write(forkVersion32[:]) + hasher.Write(genesisValidatorsRoot[:]) + hasher.Sum(forkDataRoot[:0]) + + f.domain[0] = syncCommitteeDomain + copy(f.domain[4:], forkDataRoot[:28]) +} + +// Forks is the list of all beacon chain forks in the chain configuration. +type Forks []*Fork + +// domain returns the signature domain for the given epoch (assumes that domains +// have already been calculated). +func (f Forks) domain(epoch uint64) (merkle.Value, error) { + for i := len(f) - 1; i >= 0; i-- { + if epoch >= f[i].Epoch { + return f[i].domain, nil + } + } + return merkle.Value{}, fmt.Errorf("unknown fork for epoch %d", epoch) +} + +// SigningRoot calculates the signing root of the given header. +func (f Forks) SigningRoot(header Header) (common.Hash, error) { + domain, err := f.domain(header.Epoch()) + if err != nil { + return common.Hash{}, err + } + var ( + signingRoot common.Hash + headerHash = header.Hash() + hasher = sha256.New() + ) + hasher.Write(headerHash[:]) + hasher.Write(domain[:]) + hasher.Sum(signingRoot[:0]) + + return signingRoot, nil +} + +func (f Forks) Len() int { return len(f) } +func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f Forks) Less(i, j int) bool { return f[i].Epoch < f[j].Epoch } + +// ChainConfig contains the beacon chain configuration. +type ChainConfig struct { + GenesisTime uint64 // Unix timestamp of slot 0 + GenesisValidatorsRoot common.Hash // Root hash of the genesis validator set, used for signature domain calculation + Forks Forks +} + +// AddFork adds a new item to the list of forks. +func (c *ChainConfig) AddFork(name string, epoch uint64, version []byte) *ChainConfig { + fork := &Fork{ + Name: name, + Epoch: epoch, + Version: version, + } + fork.computeDomain(c.GenesisValidatorsRoot) + + c.Forks = append(c.Forks, fork) + sort.Sort(c.Forks) + + return c +} + +// LoadForks parses the beacon chain configuration file (config.yaml) and extracts +// the list of forks. +func (c *ChainConfig) LoadForks(path string) error { + file, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read beacon chain config file: %v", err) + } + config := make(map[string]string) + if err := yaml.Unmarshal(file, &config); err != nil { + return fmt.Errorf("failed to parse beacon chain config file: %v", err) + } + var ( + versions = make(map[string][]byte) + epochs = make(map[string]uint64) + ) + epochs["GENESIS"] = 0 + + for key, value := range config { + if strings.HasSuffix(key, "_FORK_VERSION") { + name := key[:len(key)-len("_FORK_VERSION")] + if v, err := hexutil.Decode(value); err == nil { + versions[name] = v + } else { + return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", value, err) + } + } + if strings.HasSuffix(key, "_FORK_EPOCH") { + name := key[:len(key)-len("_FORK_EPOCH")] + if v, err := strconv.ParseUint(value, 10, 64); err == nil { + epochs[name] = v + } else { + return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", value, err) + } + } + } + for name, epoch := range epochs { + if version, ok := versions[name]; ok { + delete(versions, name) + c.AddFork(name, epoch, version) + } else { + return fmt.Errorf("fork id missing for %q in beacon chain config file", name) + } + } + for name := range versions { + return fmt.Errorf("epoch number missing for fork %q in beacon chain config file", name) + } + sort.Sort(c.Forks) + return nil +} diff --git a/beacon/types/gen_header_json.go b/beacon/types/gen_header_json.go new file mode 100644 index 000000000000..f15881c53fce --- /dev/null +++ b/beacon/types/gen_header_json.go @@ -0,0 +1,66 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package types + +import ( + "encoding/json" + "errors" + + "github.com/XinFinOrg/XDPoSChain/common" +) + +var _ = (*headerMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (h Header) MarshalJSON() ([]byte, error) { + type Header struct { + Slot common.Decimal `gencodec:"required" json:"slot"` + ProposerIndex common.Decimal `gencodec:"required" json:"proposer_index"` + ParentRoot common.Hash `gencodec:"required" json:"parent_root"` + StateRoot common.Hash `gencodec:"required" json:"state_root"` + BodyRoot common.Hash `gencodec:"required" json:"body_root"` + } + var enc Header + enc.Slot = common.Decimal(h.Slot) + enc.ProposerIndex = common.Decimal(h.ProposerIndex) + enc.ParentRoot = h.ParentRoot + enc.StateRoot = h.StateRoot + enc.BodyRoot = h.BodyRoot + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (h *Header) UnmarshalJSON(input []byte) error { + type Header struct { + Slot *common.Decimal `gencodec:"required" json:"slot"` + ProposerIndex *common.Decimal `gencodec:"required" json:"proposer_index"` + ParentRoot *common.Hash `gencodec:"required" json:"parent_root"` + StateRoot *common.Hash `gencodec:"required" json:"state_root"` + BodyRoot *common.Hash `gencodec:"required" json:"body_root"` + } + var dec Header + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.Slot == nil { + return errors.New("missing required field 'slot' for Header") + } + h.Slot = uint64(*dec.Slot) + if dec.ProposerIndex == nil { + return errors.New("missing required field 'proposer_index' for Header") + } + h.ProposerIndex = uint64(*dec.ProposerIndex) + if dec.ParentRoot == nil { + return errors.New("missing required field 'parent_root' for Header") + } + h.ParentRoot = *dec.ParentRoot + if dec.StateRoot == nil { + return errors.New("missing required field 'state_root' for Header") + } + h.StateRoot = *dec.StateRoot + if dec.BodyRoot == nil { + return errors.New("missing required field 'body_root' for Header") + } + h.BodyRoot = *dec.BodyRoot + return nil +} diff --git a/beacon/types/header.go b/beacon/types/header.go new file mode 100644 index 000000000000..c4a21598b590 --- /dev/null +++ b/beacon/types/header.go @@ -0,0 +1,121 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package types implements a few types of the beacon chain for light client usage. +package types + +import ( + "crypto/sha256" + "encoding/binary" + + "github.com/XinFinOrg/XDPoSChain/beacon/merkle" + "github.com/XinFinOrg/XDPoSChain/beacon/params" + "github.com/XinFinOrg/XDPoSChain/common" +) + +//go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go + +const ( + headerIndexSlot = 8 + headerIndexProposerIndex = 9 + headerIndexParentRoot = 10 + headerIndexStateRoot = 11 + headerIndexBodyRoot = 12 +) + +// Header defines a beacon header. +// +// See data structure definition here: +// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader +type Header struct { + // Monotonically increasing slot number for the beacon block (may be gapped) + Slot uint64 `gencodec:"required" json:"slot"` + + // Index into the validator table who created the beacon block + ProposerIndex uint64 `gencodec:"required" json:"proposer_index"` + + // SSZ hash of the parent beacon header + ParentRoot common.Hash `gencodec:"required" json:"parent_root"` + + // SSZ hash of the beacon state (https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#beacon-state) + StateRoot common.Hash `gencodec:"required" json:"state_root"` + + // SSZ hash of the beacon block body (https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#beaconblockbody) + BodyRoot common.Hash `gencodec:"required" json:"body_root"` +} + +// headerMarshaling is a field type overrides for gencodec. +type headerMarshaling struct { + Slot common.Decimal + ProposerIndex common.Decimal +} + +// Hash calculates the block root of the header. +// +// TODO(zsfelfoldi): Remove this when an SSZ encoder lands. +func (h *Header) Hash() common.Hash { + var values [16]merkle.Value // values corresponding to indices 8 to 15 of the beacon header tree + binary.LittleEndian.PutUint64(values[headerIndexSlot][:8], h.Slot) + binary.LittleEndian.PutUint64(values[headerIndexProposerIndex][:8], h.ProposerIndex) + values[headerIndexParentRoot] = merkle.Value(h.ParentRoot) + values[headerIndexStateRoot] = merkle.Value(h.StateRoot) + values[headerIndexBodyRoot] = merkle.Value(h.BodyRoot) + hasher := sha256.New() + for i := 7; i > 0; i-- { + hasher.Reset() + hasher.Write(values[i*2][:]) + hasher.Write(values[i*2+1][:]) + hasher.Sum(values[i][:0]) + } + return common.Hash(values[1]) +} + +// Epoch returns the epoch the header belongs to. +func (h *Header) Epoch() uint64 { + return h.Slot / params.EpochLength +} + +// SyncPeriod returns the sync period the header belongs to. +func (h *Header) SyncPeriod() uint64 { + return SyncPeriod(h.Slot) +} + +// SyncPeriodStart returns the first slot of the given period. +func SyncPeriodStart(period uint64) uint64 { + return period * params.SyncPeriodLength +} + +// SyncPeriod returns the sync period that the given slot belongs to. +func SyncPeriod(slot uint64) uint64 { + return slot / params.SyncPeriodLength +} + +// SignedHeader represents a beacon header signed by a sync committee. +// +// This structure is created from either an optimistic update or an instant update: +// - https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate +// - https://github.com/zsfelfoldi/beacon-APIs/blob/instant_update/apis/beacon/light_client/instant_update.yaml +type SignedHeader struct { + // Beacon header being signed + Header Header + + // Sync committee BLS signature aggregate + Signature SyncAggregate + + // Slot in which the signature has been created (newer than Header.Slot, + // determines the signing sync committee) + SignatureSlot uint64 +} diff --git a/beacon/types/update.go b/beacon/types/update.go new file mode 100644 index 000000000000..697ffedf534e --- /dev/null +++ b/beacon/types/update.go @@ -0,0 +1,118 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "errors" + "fmt" + + "github.com/XinFinOrg/XDPoSChain/beacon/merkle" + "github.com/XinFinOrg/XDPoSChain/beacon/params" + "github.com/XinFinOrg/XDPoSChain/common" +) + +// LightClientUpdate is a proof of the next sync committee root based on a header +// signed by the sync committee of the given period. Optionally, the update can +// prove quasi-finality by the signed header referring to a previous, finalized +// header from the same period, and the finalized header referring to the next +// sync committee root. +// +// See data structure definition here: +// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientupdate +type LightClientUpdate struct { + AttestedHeader SignedHeader // Arbitrary header out of the period signed by the sync committee + NextSyncCommitteeRoot common.Hash // Sync committee of the next period advertised in the current one + NextSyncCommitteeBranch merkle.Values // Proof for the next period's sync committee + + FinalizedHeader *Header `rlp:"nil"` // Optional header to announce a point of finality + FinalityBranch merkle.Values // Proof for the announced finality + + score *UpdateScore // Weight of the update to compare between competing ones +} + +// Validate verifies the validity of the update. +func (update *LightClientUpdate) Validate() error { + period := update.AttestedHeader.Header.SyncPeriod() + if SyncPeriod(update.AttestedHeader.SignatureSlot) != period { + return errors.New("signature slot and signed header are from different periods") + } + if update.FinalizedHeader != nil { + if update.FinalizedHeader.SyncPeriod() != period { + return errors.New("finalized header is from different period") + } + if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexFinalBlock, update.FinalityBranch, merkle.Value(update.FinalizedHeader.Hash())); err != nil { + return fmt.Errorf("invalid finalized header proof: %w", err) + } + } + if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexNextSyncCommittee, update.NextSyncCommitteeBranch, merkle.Value(update.NextSyncCommitteeRoot)); err != nil { + return fmt.Errorf("invalid next sync committee proof: %w", err) + } + return nil +} + +// Score returns the UpdateScore describing the proof strength of the update +// Note: thread safety can be ensured by always calling Score on a newly received +// or decoded update before making it potentially available for other threads +func (update *LightClientUpdate) Score() UpdateScore { + if update.score == nil { + update.score = &UpdateScore{ + SignerCount: uint32(update.AttestedHeader.Signature.SignerCount()), + SubPeriodIndex: uint32(update.AttestedHeader.Header.Slot & 0x1fff), + FinalizedHeader: update.FinalizedHeader != nil, + } + } + return *update.score +} + +// UpdateScore allows the comparison between updates at the same period in order +// to find the best update chain that provides the strongest proof of being canonical. +// +// UpdateScores have a tightly packed binary encoding format for efficient p2p +// protocol transmission. Each UpdateScore is encoded in 3 bytes. +// When interpreted as a 24 bit little indian unsigned integer: +// - the lowest 10 bits contain the number of signers in the header signature aggregate +// - the next 13 bits contain the "sub-period index" which is he signed header's +// slot modulo params.SyncPeriodLength (which is correlated with the risk of the chain being +// re-orged before the previous period boundary in case of non-finalized updates) +// - the highest bit is set when the update is finalized (meaning that the finality +// header referenced by the signed header is in the same period as the signed +// header, making reorgs before the period boundary impossible +type UpdateScore struct { + SignerCount uint32 // number of signers in the header signature aggregate + SubPeriodIndex uint32 // signed header's slot modulo params.SyncPeriodLength + FinalizedHeader bool // update is considered finalized if has finalized header from the same period and 2/3 signatures +} + +// finalized returns true if the update has a header signed by at least 2/3 of +// the committee, referring to a finalized header that refers to the next sync +// committee. This condition is a close approximation of the actual finality +// condition that can only be verified by full beacon nodes. +func (u *UpdateScore) finalized() bool { + return u.FinalizedHeader && u.SignerCount >= params.SyncCommitteeSupermajority +} + +// BetterThan returns true if update u is considered better than w. +func (u UpdateScore) BetterThan(w UpdateScore) bool { + var ( + uFinalized = u.finalized() + wFinalized = w.finalized() + ) + if uFinalized != wFinalized { + return uFinalized + } + return u.SignerCount > w.SignerCount +} diff --git a/common/types.go b/common/types.go index 5f2f366c99b2..5f9f58b18e94 100644 --- a/common/types.go +++ b/common/types.go @@ -24,6 +24,7 @@ import ( "math/big" "math/rand" "reflect" + "strconv" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "golang.org/x/crypto/sha3" @@ -419,3 +420,22 @@ func (addr AddressEIP55) String() string { func (addr AddressEIP55) MarshalJSON() ([]byte, error) { return json.Marshal(addr.String()) } + +type Decimal uint64 + +func isString(input []byte) bool { + return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' +} + +// UnmarshalJSON parses a hash in hex syntax. +func (d *Decimal) UnmarshalJSON(input []byte) error { + if !isString(input) { + return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))} + } + if i, err := strconv.ParseInt(string(input[1:len(input)-1]), 10, 64); err == nil { + *d = Decimal(i) + return nil + } else { + return err + } +} diff --git a/go.mod b/go.mod index 83100986b004..fcbe37d9a954 100644 --- a/go.mod +++ b/go.mod @@ -68,14 +68,17 @@ require ( github.com/dlclark/regexp2 v1.10.0 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-yaml/yaml v2.1.0+incompatible // indirect github.com/google/uuid v1.3.0 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect + github.com/kilic/bls12-381 v0.1.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 7b0965c69d3c..73c7510dc470 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -107,6 +109,8 @@ github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4d github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/karalabe/hid v1.0.0 h1:+/CIMNXhSU/zIJgnIvBD2nKHxS/bnRHhhs9xBryLpPo= github.com/karalabe/hid v1.0.0/go.mod h1:Vr51f8rUOLYrfrWDFlV12GGQgM5AT8sVh+2fY4MPeu8= +github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= +github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -171,6 +175,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/prometheus v1.7.2-0.20170814170113-3101606756c5 h1:K2PKeDFZidfjUWpXk05Gbxhwm8Rnz1l4O+u/bbbcCvc= github.com/prometheus/prometheus v1.7.2-0.20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= +github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 h1:cZC+usqsYgHtlBaGulVnZ1hfKAi8iWtujBnRLQE698c= +github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= @@ -249,6 +255,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 441f8ed70c54d10767741af999c2df116c490d66 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 11:01:21 +0800 Subject: [PATCH 077/121] common: add variable MaxHash (#28306) --- common/types.go | 3 +++ core/state_processor_test.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/types.go b/common/types.go index 5f9f58b18e94..60977e848670 100644 --- a/common/types.go +++ b/common/types.go @@ -54,6 +54,9 @@ const ( ) var ( + // MaxHash represents the maximum possible hash value. + MaxHash = HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + BlockSignersBinary = Address{19: 0x89} // xdc0000000000000000000000000000000000000089 MasternodeVotingSMCBinary = Address{19: 0x88} // xdc0000000000000000000000000000000000000088 RandomizeSMCBinary = Address{19: 0x90} // xdc0000000000000000000000000000000000000090 diff --git a/core/state_processor_test.go b/core/state_processor_test.go index cce40167528d..6de370ec980f 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -90,7 +90,7 @@ func TestStateProcessorErrors(t *testing.T) { blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) ) defer blockchain.Stop() - bigNumber := new(big.Int).SetBytes(common.FromHex("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) + bigNumber := new(big.Int).SetBytes(common.MaxHash.Bytes()) tooBigNumber := new(big.Int).Set(bigNumber) tooBigNumber.Add(tooBigNumber, common.Big1) for i, tt := range []struct { From 4cc2b2ea5fee86c483bf3265b4d6404739df14d5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 11:57:47 +0800 Subject: [PATCH 078/121] tests/fuzzers: move fuzzers into native packages (#28467) --- common/bitutil/compress_test.go | 61 ++++++-- core/types/rlp_fuzzer_test.go | 147 ++++++++++++++++++ .../vm/contracts_fuzz_test.go | 29 +++- .../vm/runtime/runtime_fuzz_test.go | 6 +- tests/fuzzers/bitutil/compress_test.go | 68 -------- tests/fuzzers/rlp/rlp_fuzzer.go | 143 ----------------- tests/fuzzers/secp256k1/secp_test.go | 3 +- trie/trie_test.go | 65 ++++++-- 8 files changed, 275 insertions(+), 247 deletions(-) create mode 100644 core/types/rlp_fuzzer_test.go rename tests/fuzzers/rlp/rlp_test.go => core/vm/contracts_fuzz_test.go (57%) rename tests/fuzzers/runtime/runtime_test.go => core/vm/runtime/runtime_fuzz_test.go (87%) delete mode 100644 tests/fuzzers/bitutil/compress_test.go delete mode 100644 tests/fuzzers/rlp/rlp_fuzzer.go diff --git a/common/bitutil/compress_test.go b/common/bitutil/compress_test.go index 19a3324e8ba9..84f624f46c64 100644 --- a/common/bitutil/compress_test.go +++ b/common/bitutil/compress_test.go @@ -18,6 +18,7 @@ package bitutil import ( "bytes" + "fmt" "math/rand" "testing" @@ -48,19 +49,23 @@ func TestEncodingCycle(t *testing.T) { "0xdf7070533534333636313639343638373532313536346c1bc333393438373130707063363430353639343638373532313536346c1bc333393438336336346c65fe", } for i, tt := range tests { - data := hexutil.MustDecode(tt) - - proc, err := bitsetDecodeBytes(bitsetEncodeBytes(data), len(data)) - if err != nil { - t.Errorf("test %d: failed to decompress compressed data: %v", i, err) - continue - } - if !bytes.Equal(data, proc) { - t.Errorf("test %d: compress/decompress mismatch: have %x, want %x", i, proc, data) + if err := testEncodingCycle(hexutil.MustDecode(tt)); err != nil { + t.Errorf("test %d: %v", i, err) } } } +func testEncodingCycle(data []byte) error { + proc, err := bitsetDecodeBytes(bitsetEncodeBytes(data), len(data)) + if err != nil { + return fmt.Errorf("failed to decompress compressed data: %v", err) + } + if !bytes.Equal(data, proc) { + return fmt.Errorf("compress/decompress mismatch: have %x, want %x", proc, data) + } + return nil +} + // Tests that data bitset decoding and rencoding works and is bijective. func TestDecodingCycle(t *testing.T) { tests := []struct { @@ -179,3 +184,41 @@ func benchmarkEncoding(b *testing.B, bytes int, fill float64) { bitsetDecodeBytes(bitsetEncodeBytes(data), len(data)) } } + +func FuzzEncoder(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + if err := testEncodingCycle(data); err != nil { + t.Fatal(err) + } + }) +} + +func FuzzDecoder(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + fuzzDecode(data) + }) +} + +// fuzzDecode implements a go-fuzz fuzzer method to test the bit decoding and +// reencoding algorithm. +func fuzzDecode(data []byte) { + blob, err := DecompressBytes(data, 1024) + if err != nil { + return + } + // re-compress it (it's OK if the re-compressed differs from the + // original - the first input may not have been compressed at all) + comp := CompressBytes(blob) + if len(comp) > len(blob) { + // After compression, it must be smaller or equal + panic("bad compression") + } + // But decompressing it once again should work + decomp, err := DecompressBytes(data, 1024) + if err != nil { + panic(err) + } + if !bytes.Equal(decomp, blob) { + panic("content mismatch") + } +} diff --git a/core/types/rlp_fuzzer_test.go b/core/types/rlp_fuzzer_test.go new file mode 100644 index 000000000000..64fc43965620 --- /dev/null +++ b/core/types/rlp_fuzzer_test.go @@ -0,0 +1,147 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "bytes" + "fmt" + "math/big" + "testing" + + "github.com/XinFinOrg/XDPoSChain/rlp" + "github.com/holiman/uint256" +) + +func decodeEncode(input []byte, val interface{}) error { + if err := rlp.DecodeBytes(input, val); err != nil { + // not valid rlp, nothing to do + return nil + } + // If it _were_ valid rlp, we can encode it again + output, err := rlp.EncodeToBytes(val) + if err != nil { + return err + } + if !bytes.Equal(input, output) { + return fmt.Errorf("encode-decode is not equal, \ninput : %x\noutput: %x", input, output) + } + return nil +} + +func FuzzRLP(f *testing.F) { + f.Fuzz(fuzzRlp) +} + +func fuzzRlp(t *testing.T, input []byte) { + if len(input) == 0 || len(input) > 500*1024 { + return + } + rlp.Split(input) + if elems, _, err := rlp.SplitList(input); err == nil { + rlp.CountValues(elems) + } + rlp.NewStream(bytes.NewReader(input), 0).Decode(new(interface{})) + if err := decodeEncode(input, new(interface{})); err != nil { + t.Fatal(err) + } + { + var v struct { + Int uint + String string + Bytes []byte + } + if err := decodeEncode(input, &v); err != nil { + t.Fatal(err) + } + } + { + type Types struct { + Bool bool + Raw rlp.RawValue + Slice []*Types + Iface []interface{} + } + var v Types + if err := decodeEncode(input, &v); err != nil { + t.Fatal(err) + } + } + { + type AllTypes struct { + Int uint + String string + Bytes []byte + Bool bool + Raw rlp.RawValue + Slice []*AllTypes + Array [3]*AllTypes + Iface []interface{} + } + var v AllTypes + if err := decodeEncode(input, &v); err != nil { + t.Fatal(err) + } + } + { + if err := decodeEncode(input, [10]byte{}); err != nil { + t.Fatal(err) + } + } + { + var v struct { + Byte [10]byte + Rool [10]bool + } + if err := decodeEncode(input, &v); err != nil { + t.Fatal(err) + } + } + { + var h Header + if err := decodeEncode(input, &h); err != nil { + t.Fatal(err) + } + var b Block + if err := decodeEncode(input, &b); err != nil { + t.Fatal(err) + } + var tx Transaction + if err := decodeEncode(input, &tx); err != nil { + t.Fatal(err) + } + var txs Transactions + if err := decodeEncode(input, &txs); err != nil { + t.Fatal(err) + } + var rs Receipts + if err := decodeEncode(input, &rs); err != nil { + t.Fatal(err) + } + } + { + var v struct { + AnIntPtr *big.Int + AnInt big.Int + AnU256Ptr *uint256.Int + AnU256 uint256.Int + NotAnU256 [4]uint64 + } + if err := decodeEncode(input, &v); err != nil { + t.Fatal(err) + } + } +} diff --git a/tests/fuzzers/rlp/rlp_test.go b/core/vm/contracts_fuzz_test.go similarity index 57% rename from tests/fuzzers/rlp/rlp_test.go rename to core/vm/contracts_fuzz_test.go index 377b3961bf14..adf77bfe9ca4 100644 --- a/tests/fuzzers/rlp/rlp_test.go +++ b/core/vm/contracts_fuzz_test.go @@ -14,12 +14,31 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package rlp +package vm -import "testing" +import ( + "testing" -func Fuzz(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzz(data) + "github.com/XinFinOrg/XDPoSChain/common" +) + +func FuzzPrecompiledContracts(f *testing.F) { + // Create list of addresses + var addrs []common.Address + for k := range allPrecompiles { + addrs = append(addrs, k) + } + f.Fuzz(func(t *testing.T, addr uint8, input []byte) { + a := addrs[int(addr)%len(addrs)] + p := allPrecompiles[a] + gas := p.RequiredGas(input) + if gas > 10_000_000 { + return + } + inWant := string(input) + RunPrecompiledContract(nil, p, input, gas) + if inHave := string(input); inWant != inHave { + t.Errorf("Precompiled %v modified input data", a) + } }) } diff --git a/tests/fuzzers/runtime/runtime_test.go b/core/vm/runtime/runtime_fuzz_test.go similarity index 87% rename from tests/fuzzers/runtime/runtime_test.go rename to core/vm/runtime/runtime_fuzz_test.go index 97d7cdc71fb9..8a4d31d81983 100644 --- a/tests/fuzzers/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_fuzz_test.go @@ -18,13 +18,11 @@ package runtime import ( "testing" - - "github.com/XinFinOrg/XDPoSChain/core/vm/runtime" ) -func Fuzz(f *testing.F) { +func FuzzVmRuntime(f *testing.F) { f.Fuzz(func(t *testing.T, code, input []byte) { - runtime.Execute(code, input, &runtime.Config{ + Execute(code, input, &Config{ GasLimit: 12000000, }) }) diff --git a/tests/fuzzers/bitutil/compress_test.go b/tests/fuzzers/bitutil/compress_test.go deleted file mode 100644 index 0c6ce21c9d35..000000000000 --- a/tests/fuzzers/bitutil/compress_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package bitutil - -import ( - "bytes" - "testing" - - "github.com/XinFinOrg/XDPoSChain/common/bitutil" -) - -func FuzzEncoder(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzzEncode(data) - }) -} -func FuzzDecoder(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzzDecode(data) - }) -} - -// fuzzEncode implements a go-fuzz fuzzer method to test the bitset encoding and -// decoding algorithm. -func fuzzEncode(data []byte) { - proc, _ := bitutil.DecompressBytes(bitutil.CompressBytes(data), len(data)) - if !bytes.Equal(data, proc) { - panic("content mismatch") - } -} - -// fuzzDecode implements a go-fuzz fuzzer method to test the bit decoding and -// reencoding algorithm. -func fuzzDecode(data []byte) { - blob, err := bitutil.DecompressBytes(data, 1024) - if err != nil { - return - } - // re-compress it (it's OK if the re-compressed differs from the - // original - the first input may not have been compressed at all) - comp := bitutil.CompressBytes(blob) - if len(comp) > len(blob) { - // After compression, it must be smaller or equal - panic("bad compression") - } - // But decompressing it once again should work - decomp, err := bitutil.DecompressBytes(data, 1024) - if err != nil { - panic(err) - } - if !bytes.Equal(decomp, blob) { - panic("content mismatch") - } -} diff --git a/tests/fuzzers/rlp/rlp_fuzzer.go b/tests/fuzzers/rlp/rlp_fuzzer.go deleted file mode 100644 index 1ffd845ba055..000000000000 --- a/tests/fuzzers/rlp/rlp_fuzzer.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rlp - -import ( - "bytes" - "fmt" - "math/big" - - "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/rlp" - "github.com/holiman/uint256" -) - -func decodeEncode(input []byte, val interface{}, i int) { - if err := rlp.DecodeBytes(input, val); err == nil { - output, err := rlp.EncodeToBytes(val) - if err != nil { - panic(err) - } - if !bytes.Equal(input, output) { - panic(fmt.Sprintf("case %d: encode-decode is not equal, \ninput : %x\noutput: %x", i, input, output)) - } - } -} - -func fuzz(input []byte) int { - if len(input) == 0 { - return 0 - } - if len(input) > 500*1024 { - return 0 - } - - var i int - { - rlp.Split(input) - } - { - if elems, _, err := rlp.SplitList(input); err == nil { - rlp.CountValues(elems) - } - } - - { - rlp.NewStream(bytes.NewReader(input), 0).Decode(new(interface{})) - } - - { - decodeEncode(input, new(interface{}), i) - i++ - } - { - var v struct { - Int uint - String string - Bytes []byte - } - decodeEncode(input, &v, i) - i++ - } - - { - type Types struct { - Bool bool - Raw rlp.RawValue - Slice []*Types - Iface []interface{} - } - var v Types - decodeEncode(input, &v, i) - i++ - } - { - type AllTypes struct { - Int uint - String string - Bytes []byte - Bool bool - Raw rlp.RawValue - Slice []*AllTypes - Array [3]*AllTypes - Iface []interface{} - } - var v AllTypes - decodeEncode(input, &v, i) - i++ - } - { - decodeEncode(input, [10]byte{}, i) - i++ - } - { - var v struct { - Byte [10]byte - Rool [10]bool - } - decodeEncode(input, &v, i) - i++ - } - { - var h types.Header - decodeEncode(input, &h, i) - i++ - var b types.Block - decodeEncode(input, &b, i) - i++ - var t types.Transaction - decodeEncode(input, &t, i) - i++ - var txs types.Transactions - decodeEncode(input, &txs, i) - i++ - var rs types.Receipts - decodeEncode(input, &rs, i) - } - { - i++ - var v struct { - AnIntPtr *big.Int - AnInt big.Int - AnU256Ptr *uint256.Int - AnU256 uint256.Int - NotAnU256 [4]uint64 - } - decodeEncode(input, &v, i) - } - return 1 -} diff --git a/tests/fuzzers/secp256k1/secp_test.go b/tests/fuzzers/secp256k1/secp_test.go index 59bfe07cc20a..e8b655669c53 100644 --- a/tests/fuzzers/secp256k1/secp_test.go +++ b/tests/fuzzers/secp256k1/secp_test.go @@ -35,7 +35,7 @@ func Fuzz(f *testing.F) { }) } -func fuzz(dataP1, dataP2 []byte) int { +func fuzz(dataP1, dataP2 []byte) { var ( curveA = secp256k1.S256() curveB = btcec.S256() @@ -50,5 +50,4 @@ func fuzz(dataP1, dataP2 []byte) int { fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2) panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY)) } - return 0 } diff --git a/trie/trie_test.go b/trie/trie_test.go index 9311cbae6400..b8ed49364535 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -21,6 +21,7 @@ import ( "encoding/binary" "errors" "fmt" + "io" "math/big" "math/rand" "os" @@ -346,8 +347,9 @@ func TestRandomCases(t *testing.T) { {op: 1, key: common.Hex2Bytes("980c393656413a15c8da01978ed9f89feb80b502f58f2d640e3a2f5f7a99a7018f1b573befd92053ac6f78fca4a87268"), value: common.Hex2Bytes("")}, // step 24 {op: 1, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")}, // step 25 } - runRandTest(rt) - + if err := runRandTest(rt); err != nil { + t.Fatal(err) + } } // randTest performs random trie operations. @@ -373,36 +375,53 @@ const ( ) func (randTest) Generate(r *rand.Rand, size int) reflect.Value { + var finishedFn = func() bool { + size-- + return size > 0 + } + return reflect.ValueOf(generateSteps(finishedFn, r)) +} + +func generateSteps(finished func() bool, r io.Reader) randTest { var allKeys [][]byte + var one = []byte{0} genKey := func() []byte { - if len(allKeys) < 2 || r.Intn(100) < 10 { + r.Read(one) + if len(allKeys) < 2 || one[0]%100 > 90 { // new key - key := make([]byte, r.Intn(50)) + size := one[0] % 50 + key := make([]byte, size) r.Read(key) allKeys = append(allKeys, key) return key } // use existing key - return allKeys[r.Intn(len(allKeys))] + idx := int(one[0]) % len(allKeys) + return allKeys[idx] } - var steps randTest - for i := 0; i < size; i++ { - step := randTestStep{op: r.Intn(opMax)} + for !finished() { + r.Read(one) + step := randTestStep{op: int(one[0]) % opMax} switch step.op { case opUpdate: step.key = genKey() step.value = make([]byte, 8) - binary.BigEndian.PutUint64(step.value, uint64(i)) + binary.BigEndian.PutUint64(step.value, uint64(len(steps))) case opGet, opDelete: step.key = genKey() } steps = append(steps, step) } - return reflect.ValueOf(steps) + return steps } -func runRandTest(rt randTest) bool { +// runRandTestBool coerces error to boolean, for use in quick.Check +func runRandTestBool(rt randTest) bool { + return runRandTest(rt) == nil +} + +func runRandTest(rt randTest) error { triedb := NewDatabase(memorydb.New()) tr, _ := New(common.Hash{}, triedb) @@ -432,12 +451,12 @@ func runRandTest(rt randTest) bool { hash, err := tr.Commit(nil) if err != nil { rt[i].err = err - return false + return err } newtr, err := New(hash, triedb) if err != nil { rt[i].err = err - return false + return err } tr = newtr case opItercheckhash: @@ -452,14 +471,14 @@ func runRandTest(rt randTest) bool { } // Abort the test on error. if rt[i].err != nil { - return false + return rt[i].err } } - return true + return nil } func TestRandom(t *testing.T) { - if err := quick.Check(runRandTest, nil); err != nil { + if err := quick.Check(runRandTestBool, nil); err != nil { if cerr, ok := err.(*quick.CheckError); ok { t.Fatalf("random test iteration %d failed: %s", cerr.Count, spew.Sdump(cerr.In)) } @@ -854,3 +873,17 @@ func TestDecodeNode(t *testing.T) { decodeNode(hash, elems) } } + +func FuzzTrie(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + var steps = 500 + var input = bytes.NewReader(data) + var finishedFn = func() bool { + steps-- + return steps < 0 || input.Len() == 0 + } + if err := runRandTest(generateSteps(finishedFn, input)); err != nil { + t.Fatal(err) + } + }) +} From ff13d16fe53ebbe8bcaeaf6e4905bdcd7cfe3656 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 12:43:49 +0800 Subject: [PATCH 079/121] core/vm: make structlog/json-log stack hex again (#28628) --- common/hexutil/json.go | 45 ++++++++++++++++++++++++++++ common/hexutil/json_test.go | 60 +++++++++++++++++++++++++++++++++++++ core/vm/gen_structlog.go | 16 +++++++--- core/vm/logger.go | 1 + 4 files changed, 118 insertions(+), 4 deletions(-) diff --git a/common/hexutil/json.go b/common/hexutil/json.go index 2a1b06146ad7..8e04dcf327ce 100644 --- a/common/hexutil/json.go +++ b/common/hexutil/json.go @@ -23,6 +23,8 @@ import ( "math/big" "reflect" "strconv" + + "github.com/holiman/uint256" ) var ( @@ -30,6 +32,7 @@ var ( bigT = reflect.TypeOf((*Big)(nil)) uintT = reflect.TypeOf(Uint(0)) uint64T = reflect.TypeOf(Uint64(0)) + u256T = reflect.TypeOf((*uint256.Int)(nil)) ) // Bytes marshals/unmarshals as a JSON string with 0x prefix. @@ -195,6 +198,48 @@ func (b *Big) String() string { return EncodeBig(b.ToInt()) } +// U256 marshals/unmarshals as a JSON string with 0x prefix. +// The zero value marshals as "0x0". +type U256 uint256.Int + +// MarshalText implements encoding.TextMarshaler +func (b U256) MarshalText() ([]byte, error) { + u256 := (*uint256.Int)(&b) + return []byte(u256.Hex()), nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (b *U256) UnmarshalJSON(input []byte) error { + // The uint256.Int.UnmarshalJSON method accepts "dec", "0xhex"; we must be + // more strict, hence we check string and invoke SetFromHex directly. + if !isString(input) { + return errNonString(u256T) + } + // The hex decoder needs to accept empty string ("") as '0', which uint256.Int + // would reject. + if len(input) == 2 { + (*uint256.Int)(b).Clear() + return nil + } + err := (*uint256.Int)(b).SetFromHex(string(input[1 : len(input)-1])) + if err != nil { + return &json.UnmarshalTypeError{Value: err.Error(), Type: u256T} + } + return nil +} + +// UnmarshalText implements encoding.TextUnmarshaler +func (b *U256) UnmarshalText(input []byte) error { + // The uint256.Int.UnmarshalText method accepts "dec", "0xhex"; we must be + // more strict, hence we check string and invoke SetFromHex directly. + return (*uint256.Int)(b).SetFromHex(string(input)) +} + +// String returns the hex encoding of b. +func (b *U256) String() string { + return (*uint256.Int)(b).Hex() +} + // Uint64 marshals/unmarshals as a JSON string with 0x prefix. // The zero value marshals as "0x0". type Uint64 uint64 diff --git a/common/hexutil/json_test.go b/common/hexutil/json_test.go index ed7d6fad1a8e..7cca300951cd 100644 --- a/common/hexutil/json_test.go +++ b/common/hexutil/json_test.go @@ -23,6 +23,8 @@ import ( "errors" "math/big" "testing" + + "github.com/holiman/uint256" ) func checkError(t *testing.T, input string, got, want error) bool { @@ -176,6 +178,64 @@ func TestUnmarshalBig(t *testing.T) { } } +var unmarshalU256Tests = []unmarshalTest{ + // invalid encoding + {input: "", wantErr: errJSONEOF}, + {input: "null", wantErr: errNonString(u256T)}, + {input: "10", wantErr: errNonString(u256T)}, + {input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, u256T)}, + {input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, u256T)}, + {input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, u256T)}, + {input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, u256T)}, + {input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, u256T)}, + { + input: `"0x10000000000000000000000000000000000000000000000000000000000000000"`, + wantErr: wrapTypeError(ErrBig256Range, u256T), + }, + + // valid encoding + {input: `""`, want: big.NewInt(0)}, + {input: `"0x0"`, want: big.NewInt(0)}, + {input: `"0x2"`, want: big.NewInt(0x2)}, + {input: `"0x2F2"`, want: big.NewInt(0x2f2)}, + {input: `"0X2F2"`, want: big.NewInt(0x2f2)}, + {input: `"0x1122aaff"`, want: big.NewInt(0x1122aaff)}, + {input: `"0xbBb"`, want: big.NewInt(0xbbb)}, + {input: `"0xfffffffff"`, want: big.NewInt(0xfffffffff)}, + { + input: `"0x112233445566778899aabbccddeeff"`, + want: referenceBig("112233445566778899aabbccddeeff"), + }, + { + input: `"0xffffffffffffffffffffffffffffffffffff"`, + want: referenceBig("ffffffffffffffffffffffffffffffffffff"), + }, + { + input: `"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`, + want: referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + }, +} + +func TestUnmarshalU256(t *testing.T) { + for _, test := range unmarshalU256Tests { + var v U256 + err := json.Unmarshal([]byte(test.input), &v) + if !checkError(t, test.input, err, test.wantErr) { + continue + } + if test.want == nil { + continue + } + want := new(uint256.Int) + want.SetFromBig(test.want.(*big.Int)) + have := (*uint256.Int)(&v) + if want.Cmp(have) != 0 { + t.Errorf("input %s: value mismatch: have %x, want %x", test.input, have, want) + continue + } + } +} + func BenchmarkUnmarshalBig(b *testing.B) { input := []byte(`"0x123456789abcdef123456789abcdef"`) for i := 0; i < b.N; i++ { diff --git a/core/vm/gen_structlog.go b/core/vm/gen_structlog.go index 1230944d57f3..a14635876ef5 100644 --- a/core/vm/gen_structlog.go +++ b/core/vm/gen_structlog.go @@ -22,7 +22,7 @@ func (s StructLog) MarshalJSON() ([]byte, error) { GasCost math.HexOrDecimal64 `json:"gasCost"` Memory hexutil.Bytes `json:"memory"` MemorySize int `json:"memSize"` - Stack []uint256.Int `json:"stack"` + Stack []hexutil.U256 `json:"stack"` ReturnData hexutil.Bytes `json:"returnData"` Storage map[common.Hash]common.Hash `json:"-"` Depth int `json:"depth"` @@ -38,7 +38,12 @@ func (s StructLog) MarshalJSON() ([]byte, error) { enc.GasCost = math.HexOrDecimal64(s.GasCost) enc.Memory = s.Memory enc.MemorySize = s.MemorySize - enc.Stack = s.Stack + if s.Stack != nil { + enc.Stack = make([]hexutil.U256, len(s.Stack)) + for k, v := range s.Stack { + enc.Stack[k] = hexutil.U256(v) + } + } enc.ReturnData = s.ReturnData enc.Storage = s.Storage enc.Depth = s.Depth @@ -58,7 +63,7 @@ func (s *StructLog) UnmarshalJSON(input []byte) error { GasCost *math.HexOrDecimal64 `json:"gasCost"` Memory *hexutil.Bytes `json:"memory"` MemorySize *int `json:"memSize"` - Stack []uint256.Int `json:"stack"` + Stack []hexutil.U256 `json:"stack"` ReturnData *hexutil.Bytes `json:"returnData"` Storage map[common.Hash]common.Hash `json:"-"` Depth *int `json:"depth"` @@ -88,7 +93,10 @@ func (s *StructLog) UnmarshalJSON(input []byte) error { s.MemorySize = *dec.MemorySize } if dec.Stack != nil { - s.Stack = dec.Stack + s.Stack = make([]uint256.Int, len(dec.Stack)) + for k, v := range dec.Stack { + s.Stack[k] = uint256.Int(v) + } } if dec.ReturnData != nil { s.ReturnData = *dec.ReturnData diff --git a/core/vm/logger.go b/core/vm/logger.go index ce014b17fc1e..24178f54ff22 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -81,6 +81,7 @@ type structLogMarshaling struct { GasCost math.HexOrDecimal64 Memory hexutil.Bytes ReturnData hexutil.Bytes + Stack []hexutil.U256 OpName string `json:"opName"` // adds call to OpName() in MarshalJSON ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON } From f2cd7c082bfc9a219a9be0cc9c72f71ab4259c1b Mon Sep 17 00:00:00 2001 From: Aaron Chen Date: Tue, 12 Mar 2024 20:05:31 +0800 Subject: [PATCH 080/121] common/math: copy result in Exp (#29233) common/math: does not change base parameter --- common/math/big.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/math/big.go b/common/math/big.go index d6b2c5097b8f..41bfa29aa0bc 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -189,7 +189,7 @@ func ReadBits(bigint *big.Int, buf []byte) { } } -// U256 encodes as a 256 bit two's complement number. This operation is destructive. +// U256 encodes x as a 256 bit two's complement number. This operation is destructive. func U256(x *big.Int) *big.Int { return x.And(x, tt256m1) } @@ -220,14 +220,15 @@ func S256(x *big.Int) *big.Int { // // Courtesy @karalabe and @chfast func Exp(base, exponent *big.Int) *big.Int { + copyBase := new(big.Int).Set(base) result := big.NewInt(1) for _, word := range exponent.Bits() { for i := 0; i < wordBits; i++ { if word&1 == 1 { - U256(result.Mul(result, base)) + U256(result.Mul(result, copyBase)) } - U256(base.Mul(base, base)) + U256(copyBase.Mul(copyBase, copyBase)) word >>= 1 } } From 009542a92e069d76fb97dd9a7faab16cc41a8c2a Mon Sep 17 00:00:00 2001 From: Justin Dhillon Date: Tue, 12 Mar 2024 23:54:40 -0700 Subject: [PATCH 081/121] accounts/usbwallet, common/bitutil: fix broken links in docs (#29078) fixes some links in documentation --- accounts/usbwallet/ledger.go | 2 +- common/bitutil/bitutil.go | 2 +- common/bitutil/bitutil_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index f9d06aa032dc..005a02278358 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -16,7 +16,7 @@ // This file contains the implementation for interacting with the Ledger hardware // wallets. The wire protocol spec can be found in the Ledger Blue GitHub repo: -// https://raw.githubusercontent.com/LedgerHQ/blue-app-eth/master/doc/ethapp.asc +// https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc package usbwallet diff --git a/common/bitutil/bitutil.go b/common/bitutil/bitutil.go index cd3e72169fc5..a18a6d18eed8 100644 --- a/common/bitutil/bitutil.go +++ b/common/bitutil/bitutil.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Adapted from: https://golang.org/src/crypto/cipher/xor.go +// Adapted from: https://go.dev/src/crypto/subtle/xor_generic.go // Package bitutil implements fast bitwise operations. package bitutil diff --git a/common/bitutil/bitutil_test.go b/common/bitutil/bitutil_test.go index 307bf731f765..12f3fe24a6c9 100644 --- a/common/bitutil/bitutil_test.go +++ b/common/bitutil/bitutil_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Adapted from: https://golang.org/src/crypto/cipher/xor_test.go +// Adapted from: https://go.dev/src/crypto/subtle/xor_test.go package bitutil From 57eb92da1c154cdacf2710c5f1ae868249bcee09 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 13:23:40 +0800 Subject: [PATCH 082/121] common/prque: remove dependency on golang.org/exp (#29314) --- common/prque/lazyqueue.go | 10 +++++----- common/prque/prque.go | 7 +++---- common/prque/sstack.go | 8 ++++---- go.mod | 5 ++--- go.sum | 2 -- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/common/prque/lazyqueue.go b/common/prque/lazyqueue.go index ae3cd798da00..02619543c2aa 100644 --- a/common/prque/lazyqueue.go +++ b/common/prque/lazyqueue.go @@ -17,11 +17,11 @@ package prque import ( + "cmp" "container/heap" "time" "github.com/XinFinOrg/XDPoSChain/common/mclock" - "golang.org/x/exp/constraints" ) // LazyQueue is a priority queue data structure where priorities can change over @@ -33,7 +33,7 @@ import ( // // If the upper estimate is exceeded then Update should be called for that item. // A global Refresh function should also be called periodically. -type LazyQueue[P constraints.Ordered, V any] struct { +type LazyQueue[P cmp.Ordered, V any] struct { clock mclock.Clock // Items are stored in one of two internal queues ordered by estimated max // priority until the next and the next-after-next refresh. Update and Refresh @@ -50,12 +50,12 @@ type LazyQueue[P constraints.Ordered, V any] struct { } type ( - PriorityCallback[P constraints.Ordered, V any] func(data V) P // actual priority callback - MaxPriorityCallback[P constraints.Ordered, V any] func(data V, until mclock.AbsTime) P // estimated maximum priority callback + PriorityCallback[P cmp.Ordered, V any] func(data V) P // actual priority callback + MaxPriorityCallback[P cmp.Ordered, V any] func(data V, until mclock.AbsTime) P // estimated maximum priority callback ) // NewLazyQueue creates a new lazy queue -func NewLazyQueue[P constraints.Ordered, V any](setIndex SetIndexCallback[V], priority PriorityCallback[P, V], maxPriority MaxPriorityCallback[P, V], clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue[P, V] { +func NewLazyQueue[P cmp.Ordered, V any](setIndex SetIndexCallback[V], priority PriorityCallback[P, V], maxPriority MaxPriorityCallback[P, V], clock mclock.Clock, refreshPeriod time.Duration) *LazyQueue[P, V] { q := &LazyQueue[P, V]{ popQueue: newSstack[P, V](nil), setIndex: setIndex, diff --git a/common/prque/prque.go b/common/prque/prque.go index 0e8c9f897fad..ec8351020a10 100755 --- a/common/prque/prque.go +++ b/common/prque/prque.go @@ -18,18 +18,17 @@ package prque import ( + "cmp" "container/heap" - - "golang.org/x/exp/constraints" ) // Priority queue data structure. -type Prque[P constraints.Ordered, V any] struct { +type Prque[P cmp.Ordered, V any] struct { cont *sstack[P, V] } // New creates a new priority queue. -func New[P constraints.Ordered, V any](setIndex SetIndexCallback[V]) *Prque[P, V] { +func New[P cmp.Ordered, V any](setIndex SetIndexCallback[V]) *Prque[P, V] { return &Prque[P, V]{newSstack[P, V](setIndex)} } diff --git a/common/prque/sstack.go b/common/prque/sstack.go index 5dcd1d9dd0c4..ee6d7c0c3ac5 100755 --- a/common/prque/sstack.go +++ b/common/prque/sstack.go @@ -10,13 +10,13 @@ package prque -import "golang.org/x/exp/constraints" +import "cmp" // The size of a block of data const blockSize = 4096 // A prioritized item in the sorted stack. -type item[P constraints.Ordered, V any] struct { +type item[P cmp.Ordered, V any] struct { value V priority P } @@ -29,7 +29,7 @@ type SetIndexCallback[V any] func(data V, index int) // Internal sortable stack data structure. Implements the Push and Pop ops for // the stack (heap) functionality and the Len, Less and Swap methods for the // sortability requirements of the heaps. -type sstack[P constraints.Ordered, V any] struct { +type sstack[P cmp.Ordered, V any] struct { setIndex SetIndexCallback[V] size int capacity int @@ -40,7 +40,7 @@ type sstack[P constraints.Ordered, V any] struct { } // Creates a new, empty stack. -func newSstack[P constraints.Ordered, V any](setIndex SetIndexCallback[V]) *sstack[P, V] { +func newSstack[P cmp.Ordered, V any](setIndex SetIndexCallback[V]) *sstack[P, V] { result := new(sstack[P, V]) result.setIndex = setIndex result.active = make([]*item[P, V], blockSize) diff --git a/go.mod b/go.mod index fcbe37d9a954..57fa810ed42d 100644 --- a/go.mod +++ b/go.mod @@ -47,13 +47,14 @@ require ( github.com/deckarep/golang-set v1.8.0 github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/ethereum/c-kzg-4844 v0.4.0 + github.com/go-yaml/yaml v2.1.0+incompatible github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c github.com/kylelemons/godebug v1.1.0 github.com/mattn/go-isatty v0.0.17 + github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/urfave/cli/v2 v2.27.5 - golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -68,7 +69,6 @@ require ( github.com/dlclark/regexp2 v1.10.0 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-yaml/yaml v2.1.0+incompatible // indirect github.com/google/uuid v1.3.0 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/kilic/bls12-381 v0.1.0 // indirect @@ -78,7 +78,6 @@ require ( github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 73c7510dc470..eefee5f64b33 100644 --- a/go.sum +++ b/go.sum @@ -220,8 +220,6 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4= -golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= From 62afcf6b85499ff96762f5eacae70676cd466f06 Mon Sep 17 00:00:00 2001 From: georgehao Date: Sat, 6 Apr 2024 17:09:30 +0800 Subject: [PATCH 083/121] common/prque: fix godoc comments (#29460) Co-authored-by: Felix Lange --- common/prque/prque.go | 14 +++++++------- common/prque/sstack.go | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/common/prque/prque.go b/common/prque/prque.go index ec8351020a10..cb0d9f35801a 100755 --- a/common/prque/prque.go +++ b/common/prque/prque.go @@ -22,7 +22,7 @@ import ( "container/heap" ) -// Priority queue data structure. +// Prque is a priority queue data structure. type Prque[P cmp.Ordered, V any] struct { cont *sstack[P, V] } @@ -32,7 +32,7 @@ func New[P cmp.Ordered, V any](setIndex SetIndexCallback[V]) *Prque[P, V] { return &Prque[P, V]{newSstack[P, V](setIndex)} } -// Pushes a value with a given priority into the queue, expanding if necessary. +// Push a value with a given priority into the queue, expanding if necessary. func (p *Prque[P, V]) Push(data V, priority P) { heap.Push(p.cont, &item[P, V]{data, priority}) } @@ -43,14 +43,14 @@ func (p *Prque[P, V]) Peek() (V, P) { return item.value, item.priority } -// Pops the value with the greatest priority off the stack and returns it. +// Pop the value with the greatest priority off the stack and returns it. // Currently no shrinking is done. func (p *Prque[P, V]) Pop() (V, P) { item := heap.Pop(p.cont).(*item[P, V]) return item.value, item.priority } -// Pops only the item from the queue, dropping the associated priority value. +// PopItem pops only the item from the queue, dropping the associated priority value. func (p *Prque[P, V]) PopItem() V { return heap.Pop(p.cont).(*item[P, V]).value } @@ -60,17 +60,17 @@ func (p *Prque[P, V]) Remove(i int) V { return heap.Remove(p.cont, i).(*item[P, V]).value } -// Checks whether the priority queue is empty. +// Empty checks whether the priority queue is empty. func (p *Prque[P, V]) Empty() bool { return p.cont.Len() == 0 } -// Returns the number of element in the priority queue. +// Size returns the number of element in the priority queue. func (p *Prque[P, V]) Size() int { return p.cont.Len() } -// Clears the contents of the priority queue. +// Reset clears the contents of the priority queue. func (p *Prque[P, V]) Reset() { *p = *New[P, V](p.cont.setIndex) } diff --git a/common/prque/sstack.go b/common/prque/sstack.go index ee6d7c0c3ac5..6865a51e2366 100755 --- a/common/prque/sstack.go +++ b/common/prque/sstack.go @@ -49,7 +49,7 @@ func newSstack[P cmp.Ordered, V any](setIndex SetIndexCallback[V]) *sstack[P, V] return result } -// Pushes a value onto the stack, expanding it if necessary. Required by +// Push a value onto the stack, expanding it if necessary. Required by // heap.Interface. func (s *sstack[P, V]) Push(data any) { if s.size == s.capacity { @@ -69,7 +69,7 @@ func (s *sstack[P, V]) Push(data any) { s.size++ } -// Pops a value off the stack and returns it. Currently no shrinking is done. +// Pop a value off the stack and returns it. Currently no shrinking is done. // Required by heap.Interface. func (s *sstack[P, V]) Pop() (res any) { s.size-- @@ -85,18 +85,18 @@ func (s *sstack[P, V]) Pop() (res any) { return } -// Returns the length of the stack. Required by sort.Interface. +// Len returns the length of the stack. Required by sort.Interface. func (s *sstack[P, V]) Len() int { return s.size } -// Compares the priority of two elements of the stack (higher is first). +// Less compares the priority of two elements of the stack (higher is first). // Required by sort.Interface. func (s *sstack[P, V]) Less(i, j int) bool { return s.blocks[i/blockSize][i%blockSize].priority > s.blocks[j/blockSize][j%blockSize].priority } -// Swaps two elements in the stack. Required by sort.Interface. +// Swap two elements in the stack. Required by sort.Interface. func (s *sstack[P, V]) Swap(i, j int) { ib, io, jb, jo := i/blockSize, i%blockSize, j/blockSize, j%blockSize a, b := s.blocks[jb][jo], s.blocks[ib][io] @@ -107,7 +107,7 @@ func (s *sstack[P, V]) Swap(i, j int) { s.blocks[ib][io], s.blocks[jb][jo] = a, b } -// Resets the stack, effectively clearing its contents. +// Reset the stack, effectively clearing its contents. func (s *sstack[P, V]) Reset() { *s = *newSstack[P, V](s.setIndex) } From b274a273b899528ac5cef9f7e8057e899bca379d Mon Sep 17 00:00:00 2001 From: tianyeyouyou <150894831+tianyeyouyou@users.noreply.github.com> Date: Fri, 31 May 2024 15:25:49 +0800 Subject: [PATCH 084/121] common/math: rename variable name `int` to `n` (#29890) * chore: rename variable name `int` to `in` * chore: rename variable name `int` to `n` --- common/math/big_test.go | 4 ++-- common/math/integer.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/math/big_test.go b/common/math/big_test.go index 8ae7578319a7..db69d6014c0a 100644 --- a/common/math/big_test.go +++ b/common/math/big_test.go @@ -180,9 +180,9 @@ func BenchmarkByteAtOld(b *testing.B) { func TestReadBits(t *testing.T) { check := func(input string) { want, _ := hex.DecodeString(input) - int, _ := new(big.Int).SetString(input, 16) + n, _ := new(big.Int).SetString(input, 16) buf := make([]byte, len(want)) - ReadBits(int, buf) + ReadBits(n, buf) if !bytes.Equal(buf, want) { t.Errorf("have: %x\nwant: %x", buf, want) } diff --git a/common/math/integer.go b/common/math/integer.go index e78949299185..7f8ded447c8d 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -54,11 +54,11 @@ func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error { // UnmarshalText implements encoding.TextUnmarshaler. func (i *HexOrDecimal64) UnmarshalText(input []byte) error { - int, ok := ParseUint64(string(input)) + n, ok := ParseUint64(string(input)) if !ok { return fmt.Errorf("invalid hex or decimal integer %q", input) } - *i = HexOrDecimal64(int) + *i = HexOrDecimal64(n) return nil } From 6fda80ade8c9d282d4cf7cd198287943089ab348 Mon Sep 17 00:00:00 2001 From: Dean Eigenmann <7621705+decanus@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:53:00 +0200 Subject: [PATCH 085/121] common/math: fix out of bounds access in json unmarshalling (#30014) Co-authored-by: Martin Holst Swende --- common/math/big.go | 2 +- common/math/integer.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/math/big.go b/common/math/big.go index 41bfa29aa0bc..6fd2b4b6ae6e 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -53,7 +53,7 @@ func NewHexOrDecimal256(x int64) *HexOrDecimal256 { // It is similar to UnmarshalText, but allows parsing real decimals too, not just // quoted decimal strings. func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error { - if len(input) > 0 && input[0] == '"' { + if len(input) > 1 && input[0] == '"' { input = input[1 : len(input)-1] } return i.UnmarshalText(input) diff --git a/common/math/integer.go b/common/math/integer.go index 7f8ded447c8d..b0a67c31859c 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -46,7 +46,7 @@ type HexOrDecimal64 uint64 // It is similar to UnmarshalText, but allows parsing real decimals too, not just // quoted decimal strings. func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error { - if len(input) > 0 && input[0] == '"' { + if len(input) > 1 && input[0] == '"' { input = input[1 : len(input)-1] } return i.UnmarshalText(input) From dff8e500855e5ad1e1f9b3ceee92145a2dee8cb1 Mon Sep 17 00:00:00 2001 From: Halimao <1065621723@qq.com> Date: Wed, 19 Jun 2024 17:06:52 +0800 Subject: [PATCH 086/121] common: using `ParseUint` instead of `ParseInt` (#30020) Since Decimal is defined as unsiged `uint64`, we should use `strconv.ParseUint` instead of `strconv.ParseInt` during unmarshalling. --------- Co-authored-by: Martin Holst Swende --- common/types.go | 2 +- common/types_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/common/types.go b/common/types.go index 60977e848670..c33539135577 100644 --- a/common/types.go +++ b/common/types.go @@ -435,7 +435,7 @@ func (d *Decimal) UnmarshalJSON(input []byte) error { if !isString(input) { return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))} } - if i, err := strconv.ParseInt(string(input[1:len(input)-1]), 10, 64); err == nil { + if i, err := strconv.ParseUint(string(input[1:len(input)-1]), 10, 64); err == nil { *d = Decimal(i) return nil } else { diff --git a/common/types_test.go b/common/types_test.go index 3262f549310b..1faf10197705 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/json" "fmt" + "math" "math/big" "strings" "testing" @@ -405,3 +406,29 @@ func BenchmarkPrettyDuration(b *testing.B) { } b.Logf("Post %s", a) } + +func TestDecimalUnmarshalJSON(t *testing.T) { + // These should error + for _, tc := range []string{``, `"`, `""`, `"-1"`} { + if err := new(Decimal).UnmarshalJSON([]byte(tc)); err == nil { + t.Errorf("input %s should cause error", tc) + } + } + // These should succeed + for _, tc := range []struct { + input string + want uint64 + }{ + {`"0"`, 0}, + {`"9223372036854775807"`, math.MaxInt64}, + {`"18446744073709551615"`, math.MaxUint64}, + } { + have := new(Decimal) + if err := have.UnmarshalJSON([]byte(tc.input)); err != nil { + t.Errorf("input %q triggered error: %v", tc.input, err) + } + if uint64(*have) != tc.want { + t.Errorf("input %q, have %d want %d", tc.input, *have, tc.want) + } + } +} From 6ec35b9644c4aec4344522954bdd368b7224eb85 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 14:18:38 +0800 Subject: [PATCH 087/121] all: get rid of custom MaxUint64 and MaxUint64 (#30636) --- XDCx/tradingstate/statedb_test.go | 7 ++-- accounts/abi/bind/backends/simulated.go | 3 +- common/math/big.go | 35 ------------------- common/math/big_test.go | 45 ------------------------- common/math/integer.go | 16 --------- common/math/integer_test.go | 9 ++--- core/vm/common.go | 3 +- core/vm/contracts.go | 5 +-- internal/ethapi/api.go | 5 +-- internal/ethapi/transaction_args.go | 5 +-- les/odr_test.go | 5 +-- light/odr_test.go | 10 +++--- rlp/decode_test.go | 3 +- rpc/types_test.go | 2 +- 14 files changed, 33 insertions(+), 120 deletions(-) diff --git a/XDCx/tradingstate/statedb_test.go b/XDCx/tradingstate/statedb_test.go index 2979ca64188c..188dae651c9b 100644 --- a/XDCx/tradingstate/statedb_test.go +++ b/XDCx/tradingstate/statedb_test.go @@ -18,11 +18,12 @@ package tradingstate import ( "fmt" - "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/common/math" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" + "math" "math/big" "testing" + + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" ) func TestEchangeStates(t *testing.T) { diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index d0c7562e155c..caa243258437 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + gomath "math" "math/big" "os" "sync" @@ -476,7 +477,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.Cal // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, b.config, vm.Config{NoBaseFee: true}) - gaspool := new(core.GasPool).AddGas(math.MaxUint64) + gaspool := new(core.GasPool).AddGas(gomath.MaxUint64) owner := common.Address{} return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) } diff --git a/common/math/big.go b/common/math/big.go index 6fd2b4b6ae6e..5f401182a711 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -199,38 +199,3 @@ func U256(x *big.Int) *big.Int { func U256Bytes(n *big.Int) []byte { return PaddedBigBytes(U256(n), 32) } - -// S256 interprets x as a two's complement number. -// x must not exceed 256 bits (the result is undefined if it does) and is not modified. -// -// S256(0) = 0 -// S256(1) = 1 -// S256(2**255) = -2**255 -// S256(2**256-1) = -1 -func S256(x *big.Int) *big.Int { - if x.Cmp(tt255) < 0 { - return x - } - return new(big.Int).Sub(x, tt256) -} - -// Exp implements exponentiation by squaring. -// Exp returns a newly-allocated big integer and does not change -// base or exponent. The result is truncated to 256 bits. -// -// Courtesy @karalabe and @chfast -func Exp(base, exponent *big.Int) *big.Int { - copyBase := new(big.Int).Set(base) - result := big.NewInt(1) - - for _, word := range exponent.Bits() { - for i := 0; i < wordBits; i++ { - if word&1 == 1 { - U256(result.Mul(result, copyBase)) - } - U256(copyBase.Mul(copyBase, copyBase)) - word >>= 1 - } - } - return result -} diff --git a/common/math/big_test.go b/common/math/big_test.go index db69d6014c0a..102f18f0c659 100644 --- a/common/math/big_test.go +++ b/common/math/big_test.go @@ -278,48 +278,3 @@ func TestLittleEndianByteAt(t *testing.T) { } } } - -func TestS256(t *testing.T) { - tests := []struct{ x, y *big.Int }{ - {x: big.NewInt(0), y: big.NewInt(0)}, - {x: big.NewInt(1), y: big.NewInt(1)}, - {x: big.NewInt(2), y: big.NewInt(2)}, - { - x: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), - y: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), - }, - { - x: BigPow(2, 255), - y: new(big.Int).Neg(BigPow(2, 255)), - }, - { - x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1)), - y: big.NewInt(-1), - }, - { - x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2)), - y: big.NewInt(-2), - }, - } - for _, test := range tests { - if y := S256(test.x); y.Cmp(test.y) != 0 { - t.Errorf("S256(%x) = %x, want %x", test.x, y, test.y) - } - } -} - -func TestExp(t *testing.T) { - tests := []struct{ base, exponent, result *big.Int }{ - {base: big.NewInt(0), exponent: big.NewInt(0), result: big.NewInt(1)}, - {base: big.NewInt(1), exponent: big.NewInt(0), result: big.NewInt(1)}, - {base: big.NewInt(1), exponent: big.NewInt(1), result: big.NewInt(1)}, - {base: big.NewInt(1), exponent: big.NewInt(2), result: big.NewInt(1)}, - {base: big.NewInt(3), exponent: big.NewInt(144), result: MustParseBig256("507528786056415600719754159741696356908742250191663887263627442114881")}, - {base: big.NewInt(2), exponent: big.NewInt(255), result: MustParseBig256("57896044618658097711785492504343953926634992332820282019728792003956564819968")}, - } - for _, test := range tests { - if result := Exp(test.base, test.exponent); result.Cmp(test.result) != 0 { - t.Errorf("Exp(%d, %d) = %d, want %d", test.base, test.exponent, result, test.result) - } - } -} diff --git a/common/math/integer.go b/common/math/integer.go index b0a67c31859c..25ced8705300 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -22,22 +22,6 @@ import ( "strconv" ) -const ( - // Integer limit values. - MaxInt8 = 1<<7 - 1 - MinInt8 = -1 << 7 - MaxInt16 = 1<<15 - 1 - MinInt16 = -1 << 15 - MaxInt32 = 1<<31 - 1 - MinInt32 = -1 << 31 - MaxInt64 = 1<<63 - 1 - MinInt64 = -1 << 63 - MaxUint8 = 1<<8 - 1 - MaxUint16 = 1<<16 - 1 - MaxUint32 = 1<<32 - 1 - MaxUint64 = 1<<64 - 1 -) - // HexOrDecimal64 marshals uint64 as hex or decimal. type HexOrDecimal64 uint64 diff --git a/common/math/integer_test.go b/common/math/integer_test.go index b31c7c26c262..4643a43f20f3 100644 --- a/common/math/integer_test.go +++ b/common/math/integer_test.go @@ -17,6 +17,7 @@ package math import ( + "math" "testing" ) @@ -36,8 +37,8 @@ func TestOverflow(t *testing.T) { op operation }{ // add operations - {MaxUint64, 1, true, add}, - {MaxUint64 - 1, 1, false, add}, + {math.MaxUint64, 1, true, add}, + {math.MaxUint64 - 1, 1, false, add}, // sub operations {0, 1, true, sub}, @@ -46,8 +47,8 @@ func TestOverflow(t *testing.T) { // mul operations {0, 0, false, mul}, {10, 10, false, mul}, - {MaxUint64, 2, true, mul}, - {MaxUint64, 1, false, mul}, + {math.MaxUint64, 2, true, mul}, + {math.MaxUint64, 1, false, mul}, } { var overflows bool switch test.op { diff --git a/core/vm/common.go b/core/vm/common.go index bb11f4a393e5..d3cbbe97cb57 100644 --- a/core/vm/common.go +++ b/core/vm/common.go @@ -17,8 +17,9 @@ package vm import ( + "math" + "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/holiman/uint256" ) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 7da6949ded53..9f17ba33109d 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -20,6 +20,7 @@ import ( "crypto/sha256" "encoding/binary" "errors" + gomath "math" "math/big" "github.com/XinFinOrg/XDPoSChain/common" @@ -364,7 +365,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { // 2. Different divisor (`GQUADDIVISOR`) (3) gas.Div(gas, big3) if gas.BitLen() > 64 { - return math.MaxUint64 + return gomath.MaxUint64 } // 3. Minimum price of 200 gas if gas.Uint64() < 200 { @@ -377,7 +378,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { gas.Div(gas, big20) if gas.BitLen() > 64 { - return math.MaxUint64 + return gomath.MaxUint64 } return gas.Uint64() } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index c371f1442594..eb8b709aa0ef 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -24,6 +24,7 @@ import ( "math/big" "strings" "time" + gomath "math" "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate" @@ -415,7 +416,7 @@ func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (commo // the given password for duration seconds. If duration is nil it will use a // default of 300 seconds. It returns an indication if the account was unlocked. func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *uint64) (bool, error) { - const max = uint64(time.Duration(math.MaxInt64) / time.Second) + const max = uint64(time.Duration(gomath.MaxInt64) / time.Second) var d time.Duration if duration == nil { d = 300 * time.Second @@ -1389,7 +1390,7 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash }() // Execute the message. - gp := new(core.GasPool).AddGas(math.MaxUint64) + gp := new(core.GasPool).AddGas(gomath.MaxUint64) owner := common.Address{} result, err := core.ApplyMessage(evm, msg, gp, owner) if err := vmError(); err != nil { diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 2202fe580e78..0bdf9903e572 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -21,6 +21,7 @@ import ( "context" "errors" "fmt" + gomath "math" "math/big" "github.com/XinFinOrg/XDPoSChain/common" @@ -99,7 +100,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas if skipGasEstimation { // Skip gas usage estimation if a precise gas limit is not critical, e.g., in non-transaction calls. gas := hexutil.Uint64(b.RPCGasCap()) if gas == 0 { - gas = hexutil.Uint64(math.MaxUint64 / 2) + gas = hexutil.Uint64(gomath.MaxUint64 / 2) } args.Gas = &gas } else { // Estimate the gas usage otherwise. @@ -245,7 +246,7 @@ func (args *TransactionArgs) ToMessage(b Backend, number *big.Int, globalGasCap gas = uint64(*args.Gas) } if gas == 0 { - gas = math.MaxUint64 / 2 + gas = gomath.MaxUint64 / 2 } if globalGasCap != 0 && globalGasCap < gas { log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap) diff --git a/les/odr_test.go b/les/odr_test.go index 706853d504b2..ccff6c8ab840 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -19,6 +19,7 @@ package les import ( "bytes" "context" + gomath "math" "math/big" "testing" "time" @@ -140,7 +141,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai vmenv := vm.NewEVM(context, txContext, statedb, nil, config, vm.Config{NoBaseFee: true}) //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) - gp := new(core.GasPool).AddGas(math.MaxUint64) + gp := new(core.GasPool).AddGas(gomath.MaxUint64) owner := common.Address{} result, _ := core.ApplyMessage(vmenv, msg, gp, owner) res = append(res, result.Return()...) @@ -158,7 +159,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai context := core.NewEVMBlockContext(header, lc, nil) txContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(context, txContext, statedb, nil, config, vm.Config{NoBaseFee: true}) - gp := new(core.GasPool).AddGas(math.MaxUint64) + gp := new(core.GasPool).AddGas(gomath.MaxUint64) owner := common.Address{} result, _ := core.ApplyMessage(vmenv, msg, gp, owner) if statedb.Error() == nil { diff --git a/light/odr_test.go b/light/odr_test.go index 79d3241c2048..80e42ac2eeb4 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -20,17 +20,17 @@ import ( "bytes" "context" "errors" + gomath "math" "math/big" "testing" "time" - "github.com/XinFinOrg/XDPoSChain/consensus" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/math" + "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" @@ -44,7 +44,7 @@ import ( var ( testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) - testBankFunds = big.NewInt(math.MaxInt64) + testBankFunds = big.NewInt(gomath.MaxInt64) acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") @@ -189,7 +189,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(header, chain, nil) vmenv := vm.NewEVM(context, txContext, st, nil, config, vm.Config{NoBaseFee: true}) - gp := new(core.GasPool).AddGas(math.MaxUint64) + gp := new(core.GasPool).AddGas(gomath.MaxUint64) owner := common.Address{} result, _ := core.ApplyMessage(vmenv, msg, gp, owner) res = append(res, result.Return()...) diff --git a/rlp/decode_test.go b/rlp/decode_test.go index 38cca38aa548..8cd40c44cc89 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "io" + gomath "math" "math/big" "reflect" "strings" @@ -556,7 +557,7 @@ var decodeTests = []decodeTest{ // uint256 {input: "80", ptr: new(*uint256.Int), value: uint256.NewInt(0)}, {input: "01", ptr: new(*uint256.Int), value: uint256.NewInt(1)}, - {input: "88FFFFFFFFFFFFFFFF", ptr: new(*uint256.Int), value: uint256.NewInt(math.MaxUint64)}, + {input: "88FFFFFFFFFFFFFFFF", ptr: new(*uint256.Int), value: uint256.NewInt(gomath.MaxUint64)}, {input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*uint256.Int), value: veryBigInt256}, {input: "10", ptr: new(uint256.Int), value: *uint256.NewInt(16)}, // non-pointer also works diff --git a/rpc/types_test.go b/rpc/types_test.go index eec0819d048c..47ab5f8aff77 100644 --- a/rpc/types_test.go +++ b/rpc/types_test.go @@ -18,10 +18,10 @@ package rpc import ( "encoding/json" + "math" "testing" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/common/math" ) func TestBlockNumberJSONUnmarshal(t *testing.T) { From 156de2bf90523a45bd9a8ec7f5aa60ccf254ff19 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 14:32:38 +0800 Subject: [PATCH 088/121] common/math: delete some further dead code (#30639) --- common/math/big.go | 41 ------------------- common/math/big_test.go | 91 ----------------------------------------- 2 files changed, 132 deletions(-) diff --git a/common/math/big.go b/common/math/big.go index 5f401182a711..5f59195e3d7e 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -23,12 +23,9 @@ import ( ) var ( - tt255 = BigPow(2, 255) tt256 = BigPow(2, 256) tt256m1 = new(big.Int).Sub(tt256, big.NewInt(1)) MaxBig256 = new(big.Int).Set(tt256m1) - tt63 = BigPow(2, 63) - MaxBig63 = new(big.Int).Sub(tt63, big.NewInt(1)) ) const ( @@ -127,16 +124,6 @@ func BigMin(x, y *big.Int) *big.Int { return x } -// FirstBitSet returns the index of the first 1 bit in v, counting from LSB. -func FirstBitSet(v *big.Int) int { - for i := 0; i < v.BitLen(); i++ { - if v.Bit(i) > 0 { - return i - } - } - return v.BitLen() -} - // PaddedBigBytes encodes a big integer as a big-endian byte slice. The length // of the slice is at least n bytes. func PaddedBigBytes(bigint *big.Int, n int) []byte { @@ -148,34 +135,6 @@ func PaddedBigBytes(bigint *big.Int, n int) []byte { return ret } -// bigEndianByteAt returns the byte at position n, -// in Big-Endian encoding -// So n==0 returns the least significant byte -func bigEndianByteAt(bigint *big.Int, n int) byte { - words := bigint.Bits() - // Check word-bucket the byte will reside in - i := n / wordBytes - if i >= len(words) { - return byte(0) - } - word := words[i] - // Offset of the byte - shift := 8 * uint(n%wordBytes) - - return byte(word >> shift) -} - -// Byte returns the byte at position n, -// with the supplied padlength in Little-Endian encoding. -// n==0 returns the MSB -// Example: bigint '5', padlength 32, n=31 => 5 -func Byte(bigint *big.Int, padlength, n int) byte { - if n >= padlength { - return byte(0) - } - return bigEndianByteAt(bigint, padlength-1-n) -} - // ReadBits encodes the absolute value of bigint as big-endian bytes. Callers must ensure // that buf has enough space. If buf is too short the result will be incomplete. func ReadBits(bigint *big.Int, buf []byte) { diff --git a/common/math/big_test.go b/common/math/big_test.go index 102f18f0c659..92a322e29d66 100644 --- a/common/math/big_test.go +++ b/common/math/big_test.go @@ -21,8 +21,6 @@ import ( "encoding/hex" "math/big" "testing" - - "github.com/XinFinOrg/XDPoSChain/common" ) func TestHexOrDecimal256(t *testing.T) { @@ -100,23 +98,6 @@ func TestBigMin(t *testing.T) { } } -func TestFirstBigSet(t *testing.T) { - tests := []struct { - num *big.Int - ix int - }{ - {big.NewInt(0), 0}, - {big.NewInt(1), 0}, - {big.NewInt(2), 1}, - {big.NewInt(0x100), 8}, - } - for _, test := range tests { - if ix := FirstBitSet(test.num); ix != test.ix { - t.Errorf("FirstBitSet(b%b) = %d, want %d", test.num, ix, test.ix) - } - } -} - func TestPaddedBigBytes(t *testing.T) { tests := []struct { num *big.Int @@ -156,20 +137,6 @@ func BenchmarkPaddedBigBytesSmallOnePadding(b *testing.B) { } } -func BenchmarkByteAtBrandNew(b *testing.B) { - bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") - for i := 0; i < b.N; i++ { - bigEndianByteAt(bigint, 15) - } -} - -func BenchmarkByteAt(b *testing.B) { - bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") - for i := 0; i < b.N; i++ { - bigEndianByteAt(bigint, 15) - } -} - func BenchmarkByteAtOld(b *testing.B) { bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") for i := 0; i < b.N; i++ { @@ -220,61 +187,3 @@ func TestU256Bytes(t *testing.T) { t.Errorf("expected %x got %x", ubytes, unsigned) } } - -func TestBigEndianByteAt(t *testing.T) { - tests := []struct { - x string - y int - exp byte - }{ - {"00", 0, 0x00}, - {"01", 1, 0x00}, - {"00", 1, 0x00}, - {"01", 0, 0x01}, - {"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x30}, - {"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x20}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0xAB}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 500, 0x00}, - } - for _, test := range tests { - v := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) - actual := bigEndianByteAt(v, test.y) - if actual != test.exp { - t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) - } - } -} - -func TestLittleEndianByteAt(t *testing.T) { - tests := []struct { - x string - y int - exp byte - }{ - {"00", 0, 0x00}, - {"01", 1, 0x00}, - {"00", 1, 0x00}, - {"01", 0, 0x00}, - {"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x00}, - {"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x00}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0x00}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 0, 0xAB}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 1, 0xCD}, - {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 0, 0x00}, - {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 1, 0xCD}, - {"0000000000000000000000000000000000000000000000000000000000102030", 31, 0x30}, - {"0000000000000000000000000000000000000000000000000000000000102030", 30, 0x20}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32, 0x0}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31, 0xFF}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0xFFFF, 0x0}, - } - for _, test := range tests { - v := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) - actual := Byte(v, 32, test.y) - if actual != test.exp { - t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) - } - } -} From 6e33633d287dd750dab66b64d083644bcaa27922 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 19 Dec 2024 15:38:22 +0800 Subject: [PATCH 089/121] common: drop BigMin and BigMax, they pollute our dep graph (#30645) --- accounts/abi/bind/backends/simulated.go | 5 ++++- common/math/big.go | 16 ------------- common/math/big_test.go | 30 ------------------------- consensus/ethash/consensus.go | 4 +++- core/state_transition.go | 6 +++-- core/types/transaction.go | 16 +++++++++---- core/vm/contracts.go | 22 ++++++++++++------ internal/ethapi/api.go | 13 ++++++----- internal/ethapi/transaction_args.go | 12 +++++----- tests/state_test_util.go | 6 +++-- 10 files changed, 57 insertions(+), 73 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index caa243258437..694a3e51832b 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -449,7 +449,10 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.Cal // Backfill the legacy gasPrice for EVM execution, unless we're all zeroes call.GasPrice = new(big.Int) if call.GasFeeCap.BitLen() > 0 || call.GasTipCap.BitLen() > 0 { - call.GasPrice = math.BigMin(new(big.Int).Add(call.GasTipCap, head.BaseFee), call.GasFeeCap) + call.GasPrice = new(big.Int).Add(call.GasTipCap, head.BaseFee) + if call.GasPrice.Cmp(call.GasFeeCap) > 0 { + call.GasPrice.Set(call.GasFeeCap) + } } } } diff --git a/common/math/big.go b/common/math/big.go index 5f59195e3d7e..78e3c8255d97 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -108,22 +108,6 @@ func BigPow(a, b int64) *big.Int { return r.Exp(r, big.NewInt(b), nil) } -// BigMax returns the larger of x or y. -func BigMax(x, y *big.Int) *big.Int { - if x.Cmp(y) < 0 { - return y - } - return x -} - -// BigMin returns the smaller of x or y. -func BigMin(x, y *big.Int) *big.Int { - if x.Cmp(y) > 0 { - return y - } - return x -} - // PaddedBigBytes encodes a big integer as a big-endian byte slice. The length // of the slice is at least n bytes. func PaddedBigBytes(bigint *big.Int, n int) []byte { diff --git a/common/math/big_test.go b/common/math/big_test.go index 92a322e29d66..6f701b621a7a 100644 --- a/common/math/big_test.go +++ b/common/math/big_test.go @@ -68,36 +68,6 @@ func TestMustParseBig256(t *testing.T) { MustParseBig256("ggg") } -func TestBigMax(t *testing.T) { - a := big.NewInt(10) - b := big.NewInt(5) - - max1 := BigMax(a, b) - if max1 != a { - t.Errorf("Expected %d got %d", a, max1) - } - - max2 := BigMax(b, a) - if max2 != a { - t.Errorf("Expected %d got %d", a, max2) - } -} - -func TestBigMin(t *testing.T) { - a := big.NewInt(10) - b := big.NewInt(5) - - min1 := BigMin(a, b) - if min1 != b { - t.Errorf("Expected %d got %d", b, min1) - } - - min2 := BigMin(b, a) - if min2 != b { - t.Errorf("Expected %d got %d", b, min2) - } -} - func TestPaddedBigBytes(t *testing.T) { tests := []struct { num *big.Int diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 92806693aeb4..e6ecc9f7ab64 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -458,7 +458,9 @@ func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int { expDiff := periodCount.Sub(periodCount, big2) expDiff.Exp(big2, expDiff, nil) diff.Add(diff, expDiff) - diff = math.BigMax(diff, params.MinimumDifficulty) + if diff.Cmp(params.MinimumDifficulty) < 0 { + diff = params.MinimumDifficulty + } } return diff } diff --git a/core/state_transition.go b/core/state_transition.go index e18064501041..24375cf8ff96 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -23,7 +23,6 @@ import ( "math/big" "github.com/XinFinOrg/XDPoSChain/common" - cmath "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -397,7 +396,10 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, } else { effectiveTip := st.gasPrice if st.evm.ChainConfig().IsEIP1559(st.evm.Context.BlockNumber) { - effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee)) + effectiveTip = new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee) + if effectiveTip.Cmp(st.gasTipCap) > 0 { + effectiveTip = st.gasTipCap + } } st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)) } diff --git a/core/types/transaction.go b/core/types/transaction.go index dca1ef50a5bf..3054534e558d 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -28,7 +28,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" - "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/rlp" ) @@ -364,10 +363,16 @@ func (tx *Transaction) EffectiveGasTip(baseFee *big.Int) (*big.Int, error) { } var err error gasFeeCap := tx.GasFeeCap() - if gasFeeCap.Cmp(baseFee) == -1 { + if gasFeeCap.Cmp(baseFee) < 0 { err = ErrGasFeeCapTooLow } - return math.BigMin(tx.GasTipCap(), gasFeeCap.Sub(gasFeeCap, baseFee)), err + gasFeeCap = gasFeeCap.Sub(gasFeeCap, baseFee) + + gasTipCap := tx.GasTipCap() + if gasTipCap.Cmp(gasFeeCap) < 0 { + return gasTipCap, err + } + return gasFeeCap, err } // EffectiveGasTipValue is identical to EffectiveGasTip, but does not return an @@ -453,7 +458,10 @@ func (tx *Transaction) AsMessage(s Signer, balanceFee, blockNumber, baseFee *big } } else if baseFee != nil { // If baseFee provided, set gasPrice to effectiveGasPrice. - msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.gasTipCap, baseFee), msg.gasFeeCap) + msg.gasPrice = msg.gasPrice.Add(msg.gasTipCap, baseFee) + if msg.gasPrice.Cmp(msg.gasFeeCap) > 0 { + msg.gasPrice.Set(msg.gasFeeCap) + } } var err error diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 9f17ba33109d..98e1fdc43666 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -20,11 +20,10 @@ import ( "crypto/sha256" "encoding/binary" "errors" - gomath "math" + "math" "math/big" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/core/vm/privacy" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto/blake2b" @@ -347,7 +346,12 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { } adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) // Calculate the gas cost of the operation - gas := new(big.Int).Set(math.BigMax(modLen, baseLen)) + gas := new(big.Int) + if modLen.Cmp(baseLen) < 0 { + gas.Set(baseLen) + } else { + gas.Set(modLen) + } if c.eip2565 { // EIP-2565 has three changes // 1. Different multComplexity (inlined here) @@ -361,11 +365,13 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { gas = gas.Div(gas, big8) gas.Mul(gas, gas) - gas.Mul(gas, math.BigMax(adjExpLen, big1)) + if adjExpLen.Cmp(big1) > 0 { + gas.Mul(gas, adjExpLen) + } // 2. Different divisor (`GQUADDIVISOR`) (3) gas.Div(gas, big3) if gas.BitLen() > 64 { - return gomath.MaxUint64 + return math.MaxUint64 } // 3. Minimum price of 200 gas if gas.Uint64() < 200 { @@ -374,11 +380,13 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { return gas.Uint64() } gas = modexpMultComplexity(gas) - gas.Mul(gas, math.BigMax(adjExpLen, big1)) + if adjExpLen.Cmp(big1) > 0 { + gas.Mul(gas, adjExpLen) + } gas.Div(gas, big20) if gas.BitLen() > 64 { - return gomath.MaxUint64 + return math.MaxUint64 } return gas.Uint64() } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index eb8b709aa0ef..5c9c55562b01 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -21,10 +21,10 @@ import ( "context" "errors" "fmt" + "math" "math/big" "strings" "time" - gomath "math" "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate" @@ -34,7 +34,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/keystore" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" - "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/common/sort" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" @@ -416,7 +415,7 @@ func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (commo // the given password for duration seconds. If duration is nil it will use a // default of 300 seconds. It returns an indication if the account was unlocked. func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *uint64) (bool, error) { - const max = uint64(time.Duration(gomath.MaxInt64) / time.Second) + const max = uint64(time.Duration(math.MaxInt64) / time.Second) var d time.Duration if duration == nil { d = 300 * time.Second @@ -1390,7 +1389,7 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash }() // Execute the message. - gp := new(core.GasPool).AddGas(gomath.MaxUint64) + gp := new(core.GasPool).AddGas(math.MaxUint64) owner := common.Address{} result, err := core.ApplyMessage(evm, msg, gp, owner) if err := vmError(); err != nil { @@ -1954,7 +1953,11 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber // if the transaction has been mined, compute the effective gas price if baseFee != nil && blockHash != (common.Hash{}) { // price = min(tip, gasFeeCap - baseFee) + baseFee - price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap()) + price := new(big.Int).Add(tx.GasTipCap(), baseFee) + txGasFeeCap := tx.GasFeeCap() + if price.Cmp(txGasFeeCap) > 0 { + price = txGasFeeCap + } result.GasPrice = (*hexutil.Big)(price) } else { result.GasPrice = (*hexutil.Big)(tx.GasFeeCap()) diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 0bdf9903e572..68807629a20d 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -21,12 +21,11 @@ import ( "context" "errors" "fmt" - gomath "math" + "math" "math/big" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" - "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/rpc" @@ -100,7 +99,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas if skipGasEstimation { // Skip gas usage estimation if a precise gas limit is not critical, e.g., in non-transaction calls. gas := hexutil.Uint64(b.RPCGasCap()) if gas == 0 { - gas = hexutil.Uint64(gomath.MaxUint64 / 2) + gas = hexutil.Uint64(math.MaxUint64 / 2) } args.Gas = &gas } else { // Estimate the gas usage otherwise. @@ -246,7 +245,7 @@ func (args *TransactionArgs) ToMessage(b Backend, number *big.Int, globalGasCap gas = uint64(*args.Gas) } if gas == 0 { - gas = gomath.MaxUint64 / 2 + gas = math.MaxUint64 / 2 } if globalGasCap != 0 && globalGasCap < gas { log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap) @@ -287,7 +286,10 @@ func (args *TransactionArgs) ToMessage(b Backend, number *big.Int, globalGasCap // Backfill the legacy gasPrice for EVM execution, unless we're all zeroes gasPrice = new(big.Int) if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 { - gasPrice = math.BigMin(new(big.Int).Add(gasTipCap, baseFee), gasFeeCap) + gasPrice = gasPrice.Add(gasTipCap, baseFee) + if gasPrice.Cmp(gasFeeCap) > 0 { + gasPrice = gasFeeCap + } } } } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 6f9ace8ec3ef..74f5fc33c47a 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -275,8 +275,10 @@ func (tx *stTransaction) toMessage(ps stPostState, number *big.Int, baseFee *big if tx.MaxPriorityFeePerGas == nil { tx.MaxPriorityFeePerGas = tx.MaxFeePerGas } - gasPrice = math.BigMin(new(big.Int).Add(tx.MaxPriorityFeePerGas, baseFee), - tx.MaxFeePerGas) + gasPrice = new(big.Int).Add(tx.MaxPriorityFeePerGas, baseFee) + if gasPrice.Cmp(tx.MaxFeePerGas) > 0 { + gasPrice.Set(tx.MaxFeePerGas) + } } if gasPrice == nil { return nil, errors.New("no gas price provided") From 1c555b2defdeb420f83361a73ddb6f5fdd45e0ee Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 23 Dec 2024 19:28:54 +0800 Subject: [PATCH 090/121] core, light: get rid of the dual mutexes (#18436) --- core/blockchain.go | 45 ++++++++++++++++++++-------------------- core/blockchain_test.go | 11 +++++----- light/lightchain.go | 26 +++++++++-------------- light/lightchain_test.go | 7 ++++--- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index b6d328cc642b..6496abd2f9fa 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -149,7 +149,6 @@ type BlockChain struct { scope event.SubscriptionScope genesisBlock *types.Block - mu sync.RWMutex // global mutex for locking chain operations chainmu sync.RWMutex // blockchain insertion lock procmu sync.RWMutex // block processor lock @@ -411,8 +410,8 @@ func (bc *BlockChain) loadLastState() error { func (bc *BlockChain) SetHead(head uint64) error { log.Warn("Rewinding blockchain", "target", head) - bc.mu.Lock() - defer bc.mu.Unlock() + bc.chainmu.Lock() + defer bc.chainmu.Unlock() // Rewind the header chain, deleting all block bodies until then delFn := func(hash common.Hash, num uint64) { @@ -476,10 +475,10 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { return err } // If all checks out, manually set the head block - bc.mu.Lock() + bc.chainmu.Lock() bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) - bc.mu.Unlock() + bc.chainmu.Unlock() log.Info("Committed new head block", "number", block.Number(), "hash", hash) return nil @@ -598,8 +597,8 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { if err := bc.SetHead(0); err != nil { return err } - bc.mu.Lock() - defer bc.mu.Unlock() + bc.chainmu.Lock() + defer bc.chainmu.Unlock() // Prepare the genesis block and reinitialise the chain if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { @@ -672,8 +671,8 @@ func (bc *BlockChain) Export(w io.Writer) error { // ExportN writes a subset of the active chain to the given writer. func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { - bc.mu.RLock() - defer bc.mu.RUnlock() + bc.chainmu.RLock() + defer bc.chainmu.RUnlock() if first > last { return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) @@ -690,7 +689,6 @@ func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { return err } } - return nil } @@ -1053,8 +1051,8 @@ const ( // Rollback is designed to remove a chain of links from the database that aren't // certain enough to be valid. func (bc *BlockChain) Rollback(chain []common.Hash) { - bc.mu.Lock() - defer bc.mu.Unlock() + bc.chainmu.Lock() + defer bc.chainmu.Unlock() for i := len(chain) - 1; i >= 0; i-- { hash := chain[i] @@ -1146,7 +1144,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ } // Update the head fast sync block if better - bc.mu.Lock() + bc.chainmu.Lock() head := blockChain[len(blockChain)-1] if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case currentFastBlock := bc.CurrentFastBlock() @@ -1158,7 +1156,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ headFastBlockGauge.Update(int64(head.NumberU64())) } } - bc.mu.Unlock() + bc.chainmu.Unlock() log.Info("Imported new block receipts", "count", stats.processed, @@ -1188,6 +1186,15 @@ func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (e // WriteBlockWithState writes the block and all associated state to the database. func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB, tradingState *tradingstate.TradingStateDB, lendingState *lendingstate.LendingStateDB) (status WriteStatus, err error) { + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + + return bc.writeBlockWithState(block, receipts, state, tradingState, lendingState) +} + +// writeBlockWithState writes the block and all associated state to the database, +// but is expects the chain mutex to be held. +func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB, tradingState *tradingstate.TradingStateDB, lendingState *lendingstate.LendingStateDB) (status WriteStatus, err error) { bc.wg.Add(1) defer bc.wg.Done() @@ -1197,9 +1204,6 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. return NonStatTy, consensus.ErrUnknownAncestor } // Make sure no inconsistent state is leaked during insertion - bc.mu.Lock() - defer bc.mu.Unlock() - currentBlock := bc.CurrentBlock() localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) externTd := new(big.Int).Add(block.Difficulty(), ptd) @@ -1710,7 +1714,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] proctime := time.Since(bstart) // Write the block to the chain and get the status. - status, err := bc.WriteBlockWithState(block, receipts, statedb, tradingState, lendingState) + status, err := bc.writeBlockWithState(block, receipts, statedb, tradingState, lendingState) t3 := time.Now() if err != nil { return i, events, coalescedLogs, err @@ -2061,7 +2065,7 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L if bc.HasBlockAndFullState(block.Hash(), block.NumberU64()) { return events, coalescedLogs, nil } - status, err := bc.WriteBlockWithState(block, result.receipts, result.state, result.tradingState, result.lendingState) + status, err := bc.writeBlockWithState(block, result.receipts, result.state, result.tradingState, result.lendingState) if err != nil { return events, coalescedLogs, err @@ -2425,9 +2429,6 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i defer bc.wg.Done() whFunc := func(header *types.Header) error { - bc.mu.Lock() - defer bc.mu.Unlock() - _, err := bc.hc.WriteHeader(header) return err } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index de15d9ca6c5a..41283aa592aa 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -25,10 +25,9 @@ import ( "testing" "time" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" @@ -129,11 +128,11 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { blockchain.reportBlock(block, receipts, err) return err } - blockchain.mu.Lock() + blockchain.chainmu.Lock() WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash()))) rawdb.WriteBlock(blockchain.db, block) statedb.Commit(true) - blockchain.mu.Unlock() + blockchain.chainmu.Unlock() } return nil } @@ -147,10 +146,10 @@ func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error return err } // Manually insert the header into the database, but don't reorganise (allows subsequent testing) - blockchain.mu.Lock() + blockchain.chainmu.Lock() WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash))) rawdb.WriteHeader(blockchain.db, header) - blockchain.mu.Unlock() + blockchain.chainmu.Unlock() } return nil } diff --git a/light/lightchain.go b/light/lightchain.go index 9cbf95ddf9c6..7664750615a7 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -56,7 +56,6 @@ type LightChain struct { scope event.SubscriptionScope genesisBlock *types.Block - mu sync.RWMutex chainmu sync.RWMutex bodyCache *lru.Cache[common.Hash, *types.Body] @@ -159,8 +158,8 @@ func (lc *LightChain) loadLastState() error { // SetHead rewinds the local chain to a new head. Everything above the new // head will be deleted and the new one set. func (lc *LightChain) SetHead(head uint64) { - lc.mu.Lock() - defer lc.mu.Unlock() + lc.chainmu.Lock() + defer lc.chainmu.Unlock() lc.hc.SetHead(head, nil) lc.loadLastState() @@ -182,8 +181,8 @@ func (lc *LightChain) ResetWithGenesisBlock(genesis *types.Block) { // Dump the entire block chain and purge the caches lc.SetHead(0) - lc.mu.Lock() - defer lc.mu.Unlock() + lc.chainmu.Lock() + defer lc.chainmu.Unlock() // Prepare the genesis block and reinitialise the chain if err := core.WriteTd(lc.chainDb, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { @@ -297,8 +296,8 @@ func (lc *LightChain) Stop() { // Rollback is designed to remove a chain of links from the database that aren't // certain enough to be valid. func (lc *LightChain) Rollback(chain []common.Hash) { - lc.mu.Lock() - defer lc.mu.Unlock() + lc.chainmu.Lock() + defer lc.chainmu.Unlock() for i := len(chain) - 1; i >= 0; i-- { hash := chain[i] @@ -344,19 +343,13 @@ func (lc *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i // Make sure only one thread manipulates the chain at once lc.chainmu.Lock() - defer func() { - lc.chainmu.Unlock() - time.Sleep(time.Millisecond * 10) // ugly hack; do not hog chain lock in case syncing is CPU-limited by validation - }() + defer lc.chainmu.Unlock() lc.wg.Add(1) defer lc.wg.Done() var events []interface{} whFunc := func(header *types.Header) error { - lc.mu.Lock() - defer lc.mu.Unlock() - status, err := lc.hc.WriteHeader(header) switch status { @@ -450,11 +443,12 @@ func (lc *LightChain) SyncCht(ctx context.Context) bool { num := chtCount*CHTFrequencyClient - 1 header, err := GetHeaderByNumber(ctx, lc.odr, num) if header != nil && err == nil { - lc.mu.Lock() + lc.chainmu.Lock() + defer lc.chainmu.Unlock() + if lc.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() { lc.hc.SetCurrentHeader(header) } - lc.mu.Unlock() return true } } diff --git a/light/lightchain_test.go b/light/lightchain_test.go index 7d762e2e3f73..4733810e94d9 100644 --- a/light/lightchain_test.go +++ b/light/lightchain_test.go @@ -18,10 +18,11 @@ package light import ( "context" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" "math/big" "testing" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" + "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" @@ -122,10 +123,10 @@ func testHeaderChainImport(chain []*types.Header, lightchain *LightChain) error return err } // Manually insert the header into the database, but don't reorganize (allows subsequent testing) - lightchain.mu.Lock() + lightchain.chainmu.Lock() core.WriteTd(lightchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, lightchain.GetTdByHash(header.ParentHash))) rawdb.WriteHeader(lightchain.chainDb, header) - lightchain.mu.Unlock() + lightchain.chainmu.Unlock() } return nil } From d7e0e9d734a519835d2a461daf997ba09859045d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 24 Dec 2024 15:09:18 +0800 Subject: [PATCH 091/121] core: write chain data in atomic way (#20287) --- core/blockchain.go | 302 ++++++++++++++++++------------- core/database_util.go | 5 - core/database_util_test.go | 4 +- core/headerchain.go | 159 +++++++++------- core/rawdb/accessors_chain.go | 130 ++++++++++++- core/rawdb/accessors_indexes.go | 56 ++++++ core/rawdb/accessors_metadata.go | 34 ++++ core/rawdb/schema.go | 33 ++++ light/lightchain.go | 28 ++- light/txpool.go | 5 +- 10 files changed, 548 insertions(+), 208 deletions(-) create mode 100644 core/rawdb/accessors_indexes.go create mode 100644 core/rawdb/accessors_metadata.go diff --git a/core/blockchain.go b/core/blockchain.go index 6496abd2f9fa..480fa606017b 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -413,12 +413,69 @@ func (bc *BlockChain) SetHead(head uint64) error { bc.chainmu.Lock() defer bc.chainmu.Unlock() + updateFn := func(db ethdb.KeyValueWriter, header *types.Header) { + // Rewind the block chain, ensuring we don't end up with a stateless head block + if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() < currentBlock.NumberU64() { + newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) + if newHeadBlock == nil { + newHeadBlock = bc.genesisBlock + } else { + if _, err := state.New(newHeadBlock.Root(), bc.stateCache); err != nil { + // Rewound state missing, rolled back to before pivot, reset to genesis + newHeadBlock = bc.genesisBlock + } + } + rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash()) + + // Degrade the chain markers if they are explicitly reverted. + // In theory we should update all in-memory markers in the + // last step, however the direction of SetHead is from high + // to low, so it's safe the update in-memory markers directly. + bc.currentBlock.Store(newHeadBlock) + headBlockGauge.Update(int64(newHeadBlock.NumberU64())) + } + + // Rewind the fast block in a simpleton way to the target head + if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() { + newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) + // If either blocks reached nil, reset to the genesis state + if newHeadFastBlock == nil { + newHeadFastBlock = bc.genesisBlock + } + rawdb.WriteHeadFastBlockHash(db, newHeadFastBlock.Hash()) + + // Degrade the chain markers if they are explicitly reverted. + // In theory we should update all in-memory markers in the + // last step, however the direction of SetHead is from high + // to low, so it's safe the update in-memory markers directly. + bc.currentFastBlock.Store(newHeadFastBlock) + headFastBlockGauge.Update(int64(newHeadFastBlock.NumberU64())) + } + } + // Rewind the header chain, deleting all block bodies until then - delFn := func(hash common.Hash, num uint64) { - DeleteBody(bc.db, hash, num) + delFn := func(db ethdb.KeyValueWriter, hash common.Hash, num uint64) { + // Ignore the error here since light client won't hit this path + frozen, _ := bc.db.Ancients() + if num+1 <= frozen { + // Truncate all relative data(header, total difficulty, body, receipt + // and canonical hash) from ancient store. + if err := bc.db.TruncateAncients(num + 1); err != nil { + log.Crit("Failed to truncate ancient data", "number", num, "err", err) + } + + // Remove the hash <-> number mapping from the active store. + rawdb.DeleteHeaderNumber(db, hash) + } else { + // Remove relative body and receipts from the active store. + // The header, total difficulty and canonical hash will be + // removed in the hc.SetHead function. + rawdb.DeleteBody(db, hash, num) + rawdb.DeleteReceipts(db, hash, num) + } + // Todo(rjl493456442) txlookup, bloombits, etc } - bc.hc.SetHead(head, delFn) - currentHeader := bc.hc.CurrentHeader() + bc.hc.SetHead(head, updateFn, delFn) // Clear out any stale content from the caches bc.bodyCache.Purge() @@ -428,38 +485,6 @@ func (bc *BlockChain) SetHead(head uint64) error { bc.futureBlocks.Purge() bc.blocksHashCache.Purge() - // Rewind the block chain, ensuring we don't end up with a stateless head block - if currentBlock := bc.CurrentBlock(); currentBlock != nil && currentHeader.Number.Uint64() < currentBlock.NumberU64() { - bc.currentBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64())) - headBlockGauge.Update(int64(currentHeader.Number.Uint64())) - } - if currentBlock := bc.CurrentBlock(); currentBlock != nil { - if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil { - // Rewound state missing, rolled back to before pivot, reset to genesis - bc.currentBlock.Store(bc.genesisBlock) - headBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) - } - } - // Rewind the fast block in a simpleton way to the target head - if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && currentHeader.Number.Uint64() < currentFastBlock.NumberU64() { - bc.currentFastBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64())) - headFastBlockGauge.Update(int64(currentHeader.Number.Uint64())) - } - // If either blocks reached nil, reset to the genesis state - if currentBlock := bc.CurrentBlock(); currentBlock == nil { - bc.currentBlock.Store(bc.genesisBlock) - headBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) - } - if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock == nil { - bc.currentFastBlock.Store(bc.genesisBlock) - headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) - } - currentBlock := bc.CurrentBlock() - currentFastBlock := bc.CurrentFastBlock() - rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash()) - if err := WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash()); err != nil { - log.Crit("Failed to reset head fast block", "err", err) - } return bc.loadLastState() } @@ -601,20 +626,22 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { defer bc.chainmu.Unlock() // Prepare the genesis block and reinitialise the chain - if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { - log.Crit("Failed to write genesis block TD", "err", err) + batch := bc.db.NewBatch() + rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()) + rawdb.WriteBlock(batch, genesis) + if err := batch.Write(); err != nil { + log.Crit("Failed to write genesis block", "err", err) } - rawdb.WriteBlock(bc.db, genesis) + bc.writeHeadBlock(genesis, false) + + // Last update all in-memory chain markers bc.genesisBlock = genesis - bc.insert(bc.genesisBlock, false) bc.currentBlock.Store(bc.genesisBlock) headBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) - bc.hc.SetGenesis(bc.genesisBlock.Header()) bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) bc.currentFastBlock.Store(bc.genesisBlock) headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) - return nil } @@ -692,27 +719,45 @@ func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { return nil } -// insert injects a new head block into the current block chain. This method +// writeHeadBlock injects a new head block into the current block chain. This method // assumes that the block is indeed a true head. It will also reset the head // header and the head fast sync block to this very same block if they are older // or if they are on a different side chain. // // Note, this function assumes that the `mu` mutex is held! -func (bc *BlockChain) insert(block *types.Block, writeBlock bool) { - +func (bc *BlockChain) writeHeadBlock(block *types.Block, writeBlock bool) { blockHash := block.Hash() blockNumberU64 := block.NumberU64() // If the block is on a side chain or an unknown one, force other heads onto it too - updateHeads := GetCanonicalHash(bc.db, blockNumberU64) != blockHash + updateHeads := rawdb.ReadCanonicalHash(bc.db, blockNumberU64) != blockHash // Add the block to the canonical chain number scheme and mark as the head - rawdb.WriteCanonicalHash(bc.db, blockHash, blockNumberU64) - rawdb.WriteHeadBlockHash(bc.db, blockHash) + batch := bc.db.NewBatch() + rawdb.WriteCanonicalHash(batch, blockHash, blockNumberU64) + rawdb.WriteTxLookupEntries(batch, block) + rawdb.WriteHeadBlockHash(batch, blockHash) if writeBlock { - rawdb.WriteBlock(bc.db, block) + rawdb.WriteBlock(batch, block) + } + + // If the block is better than our head or is on a different chain, force update heads + if updateHeads { + rawdb.WriteHeadHeaderHash(batch, blockHash) + rawdb.WriteHeadFastBlockHash(batch, blockHash) + } + + // Flush the whole batch into the disk, exit the node if failed + if err := batch.Write(); err != nil { + log.Crit("Failed to update chain indexes and markers", "err", err) } + // Update all in-memory chain markers in the last step + if updateHeads { + bc.hc.SetCurrentHeader(block.Header()) + bc.currentFastBlock.Store(block) + headFastBlockGauge.Update(int64(blockNumberU64)) + } bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) @@ -723,17 +768,6 @@ func (bc *BlockChain) insert(block *types.Block, writeBlock bool) { engine.CacheNoneTIPSigningTxs(block.Header(), block.Transactions(), bc.GetReceiptsByHash(blockHash)) } } - - // If the block is better than our head or is on a different chain, force update heads - if updateHeads { - bc.hc.SetCurrentHeader(block.Header()) - - if err := WriteHeadFastBlockHash(bc.db, blockHash); err != nil { - log.Crit("Failed to insert head fast block hash", "err", err) - } - bc.currentFastBlock.Store(block) - headFastBlockGauge.Update(int64(block.NumberU64())) - } } // Genesis retrieves the chain's genesis block. @@ -1054,26 +1088,37 @@ func (bc *BlockChain) Rollback(chain []common.Hash) { bc.chainmu.Lock() defer bc.chainmu.Unlock() + batch := bc.db.NewBatch() for i := len(chain) - 1; i >= 0; i-- { hash := chain[i] + // Degrade the chain markers if they are explicitly reverted. + // In theory we should update all in-memory markers in the + // last step, however the direction of rollback is from high + // to low, so it's safe the update in-memory markers directly. currentHeader := bc.hc.CurrentHeader() if currentHeader.Hash() == hash { - bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) + newHeadHeader := bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1) + rawdb.WriteHeadHeaderHash(batch, currentHeader.ParentHash) + bc.hc.SetCurrentHeader(newHeadHeader) } if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash { newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1) + rawdb.WriteHeadFastBlockHash(batch, currentFastBlock.ParentHash()) bc.currentFastBlock.Store(newFastBlock) - WriteHeadFastBlockHash(bc.db, newFastBlock.Hash()) headFastBlockGauge.Update(int64(newFastBlock.NumberU64())) } if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash { newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1) + rawdb.WriteHeadBlockHash(batch, currentBlock.ParentHash()) bc.currentBlock.Store(newBlock) headBlockGauge.Update(int64(newBlock.NumberU64())) - rawdb.WriteHeadBlockHash(bc.db, newBlock.Hash()) } } + if err := batch.Write(); err != nil { + log.Crit("Failed to rollback chain markers", "err", err) + } + // TODO: Truncate ancient data which exceeds the current header. } // InsertReceiptChain attempts to complete an already existing header chain with @@ -1126,8 +1171,10 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ if err := WriteTxLookupEntries(batch, block); err != nil { return i, fmt.Errorf("failed to write lookup metadata: %v", err) } - stats.processed++ + // Write everything belongs to the blocks into the database. So that + // we can ensure all components of body is completed(body, receipts, + // tx indexes) if batch.ValueSize() >= ethdb.IdealBatchSize { if err := batch.Write(); err != nil { return 0, err @@ -1135,7 +1182,11 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ bytes += batch.ValueSize() batch.Reset() } + stats.processed++ } + // Write everything belongs to the blocks into the database. So that + // we can ensure all components of body is completed(body, receipts, + // tx indexes) if batch.ValueSize() > 0 { bytes += batch.ValueSize() if err := batch.Write(); err != nil { @@ -1177,10 +1228,12 @@ func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (e bc.wg.Add(1) defer bc.wg.Done() - if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), td); err != nil { - return err + batch := bc.db.NewBatch() + rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td) + rawdb.WriteBlock(batch, block) + if err := batch.Write(); err != nil { + log.Crit("Failed to write block into disk", "err", err) } - rawdb.WriteBlock(bc.db, block) return nil } @@ -1208,17 +1261,25 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) externTd := new(big.Int).Add(block.Difficulty(), ptd) - // Irrelevant of the canonical status, write the block itself to the database - if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil { - return NonStatTy, err - } - // Write other block data using a batch. - batch := bc.db.NewBatch() - rawdb.WriteBlock(batch, block) + // Irrelevant of the canonical status, write the block itself to the database. + // + // Note all the components of block(td, hash->number map, header, body, receipts) + // should be written atomically. BlockBatch is used for containing all components. + blockBatch := bc.db.NewBatch() + rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd) + rawdb.WriteBlock(blockBatch, block) + rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts) + rawdb.WritePreimages(blockBatch, state.Preimages()) + if err := blockBatch.Write(); err != nil { + log.Crit("Failed to write block into disk", "err", err) + } + // Commit all cached state changes into underlying memory database. root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) if err != nil { return NonStatTy, err } + triedb := bc.stateCache.TrieDB() + tradingRoot := common.Hash{} if tradingState != nil { tradingRoot, err = tradingState.Commit() @@ -1233,6 +1294,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. return NonStatTy, err } } + engine, _ := bc.Engine().(*XDPoS.XDPoS) var tradingTrieDb *trie.Database var tradingService utils.TradingService @@ -1248,7 +1310,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. lendingTrieDb = lendingService.GetStateCache().TrieDB() } } - triedb := bc.stateCache.TrieDB() + // If we're running an archive node, always flush if bc.cacheConfig.Disabled { if err := triedb.Commit(root, false); err != nil { @@ -1356,9 +1418,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. } } } - if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil { - return NonStatTy, err - } + // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf @@ -1368,24 +1428,6 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // Split same-difficulty blocks by number reorg = block.NumberU64() > currentBlock.NumberU64() } - - // This is the ETH fix. We shall ultimately have this workflow, - // but due to below code has diverged significantly between ETH and XDC, and current issue we have, - // it's best to have it in a different PR with more investigations. - // if reorg { - // // Write the positional metadata for transaction and receipt lookups - // if err := WriteTxLookupEntries(batch, block); err != nil { - // return NonStatTy, err - // } - // // Write hash preimages - // if err := WritePreimages(bc.db, block.NumberU64(), state.Preimages()); err != nil { - // return NonStatTy, err - // } - // } - // if err := batch.Write(); err != nil { - // return NonStatTy, err - // } - if reorg { // Reorganise the chain if the parent is not the head block if block.ParentHash() != currentBlock.Hash() { @@ -1393,26 +1435,15 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. return NonStatTy, err } } - // Write the positional metadata for transaction and receipt lookups - if err := WriteTxLookupEntries(batch, block); err != nil { - return NonStatTy, err - } - // Write hash preimages - if err := WritePreimages(bc.db, block.NumberU64(), state.Preimages()); err != nil { - return NonStatTy, err - } status = CanonStatTy } else { status = SideStatTy } - if err := batch.Write(); err != nil { - return NonStatTy, err - } // Set new head. if status == CanonStatTy { // WriteBlock has already been called, no need to write again - bc.insert(block, false) + bc.writeHeadBlock(block, false) // prepare set of masternodes for the next epoch if bc.chainConfig.XDPoS != nil && ((block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap)) { err := bc.UpdateM1() @@ -2181,15 +2212,16 @@ func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log { return logs } -// reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them -// to be part of the new canonical chain and accumulates potential missing transactions and post an -// event about them +// reorg takes two blocks, an old chain and a new chain and will reconstruct the +// blocks and inserts them to be part of the new canonical chain and accumulates +// potential missing transactions and post an event about them. func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { var ( newChain types.Blocks oldChain types.Blocks commonBlock *types.Block deletedTxs types.Transactions + addedTxs types.Transactions deletedLogs []*types.Log ) log.Warn("Reorg", "oldBlock hash", oldBlock.Hash().Hex(), "number", oldBlock.NumberU64(), "newBlock hash", newBlock.Hash().Hex(), "number", newBlock.NumberU64()) @@ -2238,6 +2270,7 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { return errors.New("invalid new chain") } } + // Ensure XDPoS engine committed block will be not reverted if xdpos, ok := bc.Engine().(*XDPoS.XDPoS); ok { latestCommittedBlock := xdpos.EngineV2.GetLatestCommittedBlockInfo() @@ -2263,6 +2296,7 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } } } + // Ensure the user sees large reorgs if len(oldChain) > 0 && len(newChain) > 0 { logFn := log.Warn @@ -2277,16 +2311,16 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } else { log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) } - // Insert the new chain, taking care of the proper incremental order - var addedTxs types.Transactions + + // Insert the new chain(except the head block(reverse order)), + // taking care of the proper incremental order. for i := len(newChain) - 1; i >= 0; i-- { // insert the block in the canonical way, re-writing history - bc.insert(newChain[i], true) - // write lookup entries for hash based transaction/receipt searches - if err := WriteTxLookupEntries(bc.db, newChain[i]); err != nil { - return err - } + bc.writeHeadBlock(newChain[i], true) + + // Collect the new added transactions. addedTxs = append(addedTxs, newChain[i].Transactions()...) + // prepare set of masternodes for the next epoch if bc.chainConfig.XDPoS != nil && ((newChain[i].NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap)) { err := bc.UpdateM1() @@ -2295,20 +2329,36 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } } } - // calculate the difference between deleted and added transactions - diff := types.TxDifference(deletedTxs, addedTxs) - // When transactions get deleted from the database that means the - // receipts that were created in the fork must also be deleted - for _, tx := range diff { - DeleteTxLookupEntry(bc.db, tx.Hash()) + + // Delete useless indexes right now which includes the non-canonical + // transaction indexes, canonical chain indexes which above the head. + indexesBatch := bc.db.NewBatch() + for _, tx := range types.TxDifference(deletedTxs, addedTxs) { + rawdb.DeleteTxLookupEntry(indexesBatch, tx.Hash()) + } + // Delete any canonical number assignments above the new head + number := bc.CurrentBlock().NumberU64() + for i := number + 1; ; i++ { + hash := rawdb.ReadCanonicalHash(bc.db, i) + if hash == (common.Hash{}) { + break + } + rawdb.DeleteCanonicalHash(indexesBatch, i) + } + if err := indexesBatch.Write(); err != nil { + log.Crit("Failed to delete useless indexes", "err", err) } + // If any logs need to be fired, do it now. In theory we could avoid creating + // this goroutine if there are no events to fire, but realistcally that only + // ever happens if we're reorging empty blocks, which will only happen on idle + // networks where performance is not an issue either way. if len(deletedLogs) > 0 { go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs}) } if len(oldChain) > 0 { go func() { - for _, block := range oldChain { - bc.chainSideFeed.Send(ChainSideEvent{Block: block}) + for i := len(oldChain) - 1; i >= 0; i-- { + bc.chainSideFeed.Send(ChainSideEvent{Block: oldChain[i]}) } }() } diff --git a/core/database_util.go b/core/database_util.go index e65ac0ff8e2c..d25e06ac3a6f 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -487,11 +487,6 @@ func DeleteBlockReceipts(db DatabaseDeleter, hash common.Hash, number uint64) { db.Delete(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)) } -// DeleteTxLookupEntry removes all transaction data associated with a hash. -func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) { - db.Delete(append(lookupPrefix, hash.Bytes()...)) -} - // PreimageTable returns a Database instance with the key prefix for preimage entries. func PreimageTable(db ethdb.Database) ethdb.Database { return rawdb.NewTable(db, preimagePrefix) diff --git a/core/database_util_test.go b/core/database_util_test.go index 1f29908b963f..0c1494ba527e 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -24,8 +24,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/types" - "golang.org/x/crypto/sha3" "github.com/XinFinOrg/XDPoSChain/rlp" + "golang.org/x/crypto/sha3" ) // Tests block header storage and retrieval operations. @@ -304,7 +304,7 @@ func TestLookupStorage(t *testing.T) { } // Delete the transactions and check purge for i, tx := range txs { - DeleteTxLookupEntry(db, tx.Hash()) + rawdb.DeleteTxLookupEntry(db, tx.Hash()) if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil { t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn) } diff --git a/core/headerchain.go b/core/headerchain.go index 51a876d2ecac..633803f2faab 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -45,6 +45,14 @@ const ( // HeaderChain implements the basic block header chain logic that is shared by // core.BlockChain and light.LightChain. It is not usable in itself, only as // a part of either structure. +// +// HeaderChain is responsible for maintaining the header chain including the +// header query and updating. +// +// The components maintained by headerchain includes: (1) total difficult +// (2) header (3) block hash -> number mapping (4) canonical number -> hash mapping +// and (5) head header flag. +// // It is not thread safe either, the encapsulating chain structures should do // the necessary mutex locking/unlocking. type HeaderChain struct { @@ -66,11 +74,8 @@ type HeaderChain struct { engine consensus.Engine } -// NewHeaderChain creates a new HeaderChain structure. -// -// getValidator should return the parent's validator -// procInterrupt points to the parent's interrupt semaphore -// wg points to the parent's shutdown wait group +// NewHeaderChain creates a new HeaderChain structure. ProcInterrupt points +// to the parent's interrupt semaphore. func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) { // Seed a fast but crypto originating random generator seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64)) @@ -143,41 +148,54 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er externTd := new(big.Int).Add(header.Difficulty, ptd) // Irrelevant of the canonical status, write the td and header to the database - if err := hc.WriteTd(hash, number, externTd); err != nil { - log.Crit("Failed to write header total difficulty", "err", err) + // + // Note all the components of header(td, hash->number index and header) should + // be written atomically. + headerBatch := hc.chainDb.NewBatch() + rawdb.WriteTd(headerBatch, hash, number, externTd) + rawdb.WriteHeader(headerBatch, header) + if err := headerBatch.Write(); err != nil { + log.Crit("Failed to write header into disk", "err", err) } - rawdb.WriteHeader(hc.chainDb, header) // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) { + // If the header can be added into canonical chain, adjust the + // header chain markers(canonical indexes and head header flag). + // + // Note all markers should be written atomically. + // Delete any canonical number assignments above the new head + markerBatch := hc.chainDb.NewBatch() for i := number + 1; ; i++ { - hash := GetCanonicalHash(hc.chainDb, i) + hash := rawdb.ReadCanonicalHash(hc.chainDb, i) if hash == (common.Hash{}) { break } - DeleteCanonicalHash(hc.chainDb, i) + rawdb.DeleteCanonicalHash(markerBatch, i) } + // Overwrite any stale canonical number assignments var ( headHash = header.ParentHash headNumber = header.Number.Uint64() - 1 headHeader = hc.GetHeader(headHash, headNumber) ) - for GetCanonicalHash(hc.chainDb, headNumber) != headHash { - rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber) + for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash { + rawdb.WriteCanonicalHash(markerBatch, headHash, headNumber) headHash = headHeader.ParentHash headNumber = headHeader.Number.Uint64() - 1 headHeader = hc.GetHeader(headHash, headNumber) } // Extend the canonical chain with the new header - rawdb.WriteCanonicalHash(hc.chainDb, hash, number) - if err := WriteHeadHeaderHash(hc.chainDb, hash); err != nil { - log.Crit("Failed to insert head header hash", "err", err) + rawdb.WriteCanonicalHash(markerBatch, hash, number) + rawdb.WriteHeadHeaderHash(markerBatch, hash) + if err := markerBatch.Write(); err != nil { + log.Crit("Failed to write header markers into disk", "err", err) } - + // Last step update all in-memory head header markers hc.currentHeaderHash = hash hc.currentHeader.Store(types.CopyHeader(header)) headHeaderGauge.Update(header.Number.Int64()) @@ -186,10 +204,9 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er } else { status = SideStatTy } - + hc.tdCache.Add(hash, externTd) hc.headerCache.Add(hash, header) hc.numberCache.Add(hash, number) - return } @@ -328,16 +345,6 @@ func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int { return hc.GetTd(hash, hc.GetBlockNumber(hash)) } -// WriteTd stores a block's total difficulty into the database, also caching it -// along the way. -func (hc *HeaderChain) WriteTd(hash common.Hash, number uint64, td *big.Int) error { - if err := WriteTd(hc.chainDb, hash, number, td); err != nil { - return err - } - hc.tdCache.Add(hash, new(big.Int).Set(td)) - return nil -} - // GetHeader retrieves a block header from the database by hash and number, // caching it if found. func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header { @@ -361,12 +368,13 @@ func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header { } // HasHeader checks if a block header is present in the database or not. +// In theory, if header is present in the database, all relative components +// like td and hash->number should be present too. func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool { if hc.numberCache.Contains(hash) || hc.headerCache.Contains(hash) { return true } - ok, _ := hc.chainDb.Has(headerKey(hash, number)) - return ok + return rawdb.HasHeader(hc.chainDb, hash, number) } // GetHeaderByNumber retrieves a block header from the database by number, @@ -390,58 +398,79 @@ func (hc *HeaderChain) CurrentHeader() *types.Header { return hc.currentHeader.Load().(*types.Header) } -// SetCurrentHeader sets the current head header of the canonical chain. +// SetCurrentHeader sets the in-memory head header marker of the canonical chan +// as the given header. func (hc *HeaderChain) SetCurrentHeader(head *types.Header) { - if err := WriteHeadHeaderHash(hc.chainDb, head.Hash()); err != nil { - log.Crit("Failed to insert head header hash", "err", err) - } - hc.currentHeader.Store(head) hc.currentHeaderHash = head.Hash() headHeaderGauge.Update(head.Number.Int64()) } -// DeleteCallback is a callback function that is called by SetHead before -// each header is deleted. -type DeleteCallback func(common.Hash, uint64) - -// SetHead rewinds the local chain to a new head. Everything above the new head -// will be deleted and the new one set. -func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) { - height := uint64(0) +type ( + // UpdateHeadBlocksCallback is a callback function that is called by SetHead + // before head header is updated. + UpdateHeadBlocksCallback func(ethdb.KeyValueWriter, *types.Header) - if hdr := hc.CurrentHeader(); hdr != nil { - height = hdr.Number.Uint64() - } + // DeleteBlockContentCallback is a callback function that is called by SetHead + // before each header is deleted. + DeleteBlockContentCallback func(ethdb.KeyValueWriter, common.Hash, uint64) +) +// SetHead rewinds the local chain to a new head. In the case of headers, everything +// above the new head will be deleted and the new one set. In the case of blocks +// though, the head may be further rewound if block bodies are missing (non-archive +// nodes after a fast sync). +func (hc *HeaderChain) SetHead(head uint64, updateFn UpdateHeadBlocksCallback, delFn DeleteBlockContentCallback) { + var ( + parentHash common.Hash + batch = hc.chainDb.NewBatch() + ) for hdr := hc.CurrentHeader(); hdr != nil && hdr.Number.Uint64() > head; hdr = hc.CurrentHeader() { - hash := hdr.Hash() - num := hdr.Number.Uint64() + hash, num := hdr.Hash(), hdr.Number.Uint64() + + // Rewind block chain to new head. + parent := hc.GetHeader(hdr.ParentHash, num-1) + if parent == nil { + parent = hc.genesisHeader + } + parentHash = hdr.ParentHash + // Notably, since geth has the possibility for setting the head to a low + // height which is even lower than ancient head. + // In order to ensure that the head is always no higher than the data in + // the database(ancient store or active store), we need to update head + // first then remove the relative data from the database. + // + // Update head first(head fast block, head full block) before deleting the data. + markerBatch := hc.chainDb.NewBatch() + if updateFn != nil { + updateFn(markerBatch, parent) + } + // Update head header then. + rawdb.WriteHeadHeaderHash(markerBatch, parentHash) + if err := markerBatch.Write(); err != nil { + log.Crit("Failed to update chain markers", "error", err) + } + hc.currentHeader.Store(parent) + hc.currentHeaderHash = parentHash + headHeaderGauge.Update(parent.Number.Int64()) + + // Remove the relative data from the database. if delFn != nil { - delFn(hash, num) + delFn(batch, hash, num) } - DeleteHeader(hc.chainDb, hash, num) - DeleteTd(hc.chainDb, hash, num) - hc.currentHeader.Store(hc.GetHeader(hdr.ParentHash, hdr.Number.Uint64()-1)) + // Rewind header chain to new head. + rawdb.DeleteHeader(batch, hash, num) + rawdb.DeleteTd(batch, hash, num) + rawdb.DeleteCanonicalHash(batch, num) } - // Roll back the canonical chain numbering - for i := height; i > head; i-- { - DeleteCanonicalHash(hc.chainDb, i) + // Flush all accumulated deletions. + if err := batch.Write(); err != nil { + log.Crit("Failed to rewind block", "error", err) } // Clear out any stale content from the caches hc.headerCache.Purge() hc.tdCache.Purge() hc.numberCache.Purge() - - if hc.CurrentHeader() == nil { - hc.currentHeader.Store(hc.genesisHeader) - } - hc.currentHeaderHash = hc.CurrentHeader().Hash() - headHeaderGauge.Update(hc.CurrentHeader().Number.Int64()) - - if err := WriteHeadHeaderHash(hc.chainDb, hc.currentHeaderHash); err != nil { - log.Crit("Failed to reset head header hash", "err", err) - } } // SetGenesis sets a new genesis block header for the chain diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 7073e8431a60..b8cb9cbd7650 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -24,12 +24,32 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rlp" ) +// ReadCanonicalHash retrieves the hash assigned to a canonical block number. +func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash { + data, _ := db.Ancient(freezerHashTable, number) + if len(data) == 0 { + data, _ = db.Get(headerHashKey(number)) + // In the background freezer is moving data from leveldb to flatten files. + // So during the first check for ancient db, the data is not yet in there, + // but when we reach into leveldb, the data was already moved. That would + // result in a not found error. + if len(data) == 0 { + data, _ = db.Ancient(freezerHashTable, number) + } + } + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + // WriteCanonicalHash stores the hash assigned to a canonical block number. func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { @@ -37,6 +57,13 @@ func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64 } } +// DeleteCanonicalHash removes the number to hash canonical mapping. +func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) { + if err := db.Delete(headerHashKey(number)); err != nil { + log.Crit("Failed to delete number to hash mapping", "err", err) + } +} + // ReadHeaderNumber returns the header number assigned to a hash. func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 { data, _ := db.Get(headerNumberKey(hash)) @@ -56,6 +83,20 @@ func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) } } +// DeleteHeaderNumber removes hash->number mapping. +func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Delete(headerNumberKey(hash)); err != nil { + log.Crit("Failed to delete hash to number mapping", "err", err) + } +} + +// WriteHeadHeaderHash stores the hash of the current canonical head header. +func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last header's hash", "err", err) + } +} + // WriteHeadBlockHash stores the head block's hash. func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { if err := db.Put(headBlockKey, hash.Bytes()); err != nil { @@ -63,10 +104,47 @@ func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { } } +// WriteHeadFastBlockHash stores the hash of the current fast-sync head block. +func WriteHeadFastBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last fast block's hash", "err", err) + } +} + // ReadHeaderRLP retrieves a block header in its raw RLP database encoding. func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { - data, _ := db.Get(headerKey(number, hash)) - return data + // First try to look up the data in ancient database. Extra hash + // comparison is necessary since ancient database only maintains + // the canonical data. + data, _ := db.Ancient(freezerHeaderTable, number) + if len(data) > 0 && crypto.Keccak256Hash(data) == hash { + return data + } + // Then try to look up the data in leveldb. + data, _ = db.Get(headerKey(number, hash)) + if len(data) > 0 { + return data + } + // In the background freezer is moving data from leveldb to flatten files. + // So during the first check for ancient db, the data is not yet in there, + // but when we reach into leveldb, the data was already moved. That would + // result in a not found error. + data, _ = db.Ancient(freezerHeaderTable, number) + if len(data) > 0 && crypto.Keccak256Hash(data) == hash { + return data + } + return nil // Can't find the data anywhere. +} + +// HasHeader verifies the existence of a block header corresponding to the hash. +func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { + if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash { + return true + } + if has, err := db.Has(headerKey(number, hash)); !has || err != nil { + return false + } + return true } // ReadHeader retrieves the block header corresponding to the hash. @@ -104,6 +182,22 @@ func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { } } +// DeleteHeader removes all block header data associated with a hash. +func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + deleteHeaderWithoutNumber(db, hash, number) + if err := db.Delete(headerNumberKey(hash)); err != nil { + log.Crit("Failed to delete hash to number mapping", "err", err) + } +} + +// deleteHeaderWithoutNumber removes only the block header but does not remove +// the hash to number mapping. +func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(headerKey(number, hash)); err != nil { + log.Crit("Failed to delete header", "err", err) + } +} + // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { // First try to look up the data in ancient database. Extra hash @@ -165,6 +259,31 @@ func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *t WriteBodyRLP(db, hash, number, data) } +// DeleteBody removes all block body data associated with a hash. +func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(blockBodyKey(number, hash)); err != nil { + log.Crit("Failed to delete block body", "err", err) + } +} + +// WriteTd stores the total difficulty of a block into the database. +func WriteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64, td *big.Int) { + data, err := rlp.EncodeToBytes(td) + if err != nil { + log.Crit("Failed to RLP encode block total difficulty", "err", err) + } + if err := db.Put(headerTDKey(number, hash), data); err != nil { + log.Crit("Failed to store block total difficulty", "err", err) + } +} + +// DeleteTd removes all block total difficulty data associated with a hash. +func DeleteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(headerTDKey(number, hash)); err != nil { + log.Crit("Failed to delete block total difficulty", "err", err) + } +} + // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding. func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { // First try to look up the data in ancient database. Extra hash @@ -270,6 +389,13 @@ func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rec } } +// DeleteReceipts removes all receipt data associated with a block hash. +func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { + log.Crit("Failed to delete block receipts", "err", err) + } +} + // storedReceiptRLP is the storage encoding of a receipt. // Re-definition in core/types/receipt.go. type storedReceiptRLP struct { diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go new file mode 100644 index 000000000000..edb263325705 --- /dev/null +++ b/core/rawdb/accessors_indexes.go @@ -0,0 +1,56 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/ethdb" + "github.com/XinFinOrg/XDPoSChain/log" + "github.com/XinFinOrg/XDPoSChain/rlp" +) + +type TxLookupEntry struct { + BlockHash common.Hash + BlockIndex uint64 + Index uint64 +} + +// WriteTxLookupEntries stores a positional metadata for every transaction from +// a block, enabling hash based transaction and receipt lookups. +func WriteTxLookupEntries(db ethdb.KeyValueWriter, block *types.Block) { + // Iterate over each transaction and encode its metadata + for i, tx := range block.Transactions() { + entry := TxLookupEntry{ + BlockHash: block.Hash(), + BlockIndex: block.NumberU64(), + Index: uint64(i), + } + data, err := rlp.EncodeToBytes(entry) + if err != nil { + log.Crit("Failed to RLP encode TxLookupEntry", "err", err) + } + if err := db.Put(txLookupKey(tx.Hash()), data); err != nil { + log.Crit("Failed to store tx lookup entry", "err", err) + } + } +} + +// DeleteTxLookupEntry removes all transaction data associated with a hash. +func DeleteTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash) { + db.Delete(txLookupKey(hash)) +} diff --git a/core/rawdb/accessors_metadata.go b/core/rawdb/accessors_metadata.go new file mode 100644 index 000000000000..a56ab22d7b4c --- /dev/null +++ b/core/rawdb/accessors_metadata.go @@ -0,0 +1,34 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/ethdb" + "github.com/XinFinOrg/XDPoSChain/log" +) + +// WritePreimages writes the provided set of preimages to the database. +func WritePreimages(db ethdb.KeyValueWriter, preimages map[common.Hash][]byte) { + for hash, preimage := range preimages { + if err := db.Put(preimageKey(hash), preimage); err != nil { + log.Crit("Failed to store trie preimage", "err", err) + } + } + preimageCounter.Inc(int64(len(preimages))) + preimageHitCounter.Inc(int64(len(preimages))) +} diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 26d098347e74..a0a1852c7550 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -21,23 +21,41 @@ import ( "encoding/binary" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/metrics" ) // The fields below define the low level database schema prefixing. var ( + // headHeaderKey tracks the latest known header's hash. + headHeaderKey = []byte("LastHeader") + // headBlockKey tracks the latest known full block's hash. headBlockKey = []byte("LastBlock") + // headFastBlockKey tracks the latest known incomplete block's hash during fast sync. + headFastBlockKey = []byte("LastFast") + // Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes). headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header + headerTDSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian) blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts + + txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata + + preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage + + preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) + preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) ) const ( + // freezerHeaderTable indicates the name of the freezer header table. + freezerHeaderTable = "headers" + // freezerHashTable indicates the name of the freezer canonical hash table. freezerHashTable = "hashes" @@ -60,6 +78,11 @@ func headerKey(number uint64, hash common.Hash) []byte { return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...) } +// headerTDKey = headerPrefix + num (uint64 big endian) + hash + headerTDSuffix +func headerTDKey(number uint64, hash common.Hash) []byte { + return append(headerKey(number, hash), headerTDSuffix...) +} + // headerHashKey = headerPrefix + num (uint64 big endian) + headerHashSuffix func headerHashKey(number uint64) []byte { return append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...) @@ -79,3 +102,13 @@ func blockBodyKey(number uint64, hash common.Hash) []byte { func blockReceiptsKey(number uint64, hash common.Hash) []byte { return append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...) } + +// txLookupKey = txLookupPrefix + hash +func txLookupKey(hash common.Hash) []byte { + return append(txLookupPrefix, hash.Bytes()...) +} + +// preimageKey = preimagePrefix + hash +func preimageKey(hash common.Hash) []byte { + return append(preimagePrefix, hash.Bytes()...) +} diff --git a/light/lightchain.go b/light/lightchain.go index 7664750615a7..4b90cf3cca7a 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -146,7 +146,6 @@ func (lc *LightChain) loadLastState() error { lc.hc.SetCurrentHeader(header) } } - // Issue a status log and return header := lc.hc.CurrentHeader() headerTd := lc.GetTd(header.Hash(), header.Number.Uint64()) @@ -161,7 +160,7 @@ func (lc *LightChain) SetHead(head uint64) { lc.chainmu.Lock() defer lc.chainmu.Unlock() - lc.hc.SetHead(head, nil) + lc.hc.SetHead(head, nil, nil) lc.loadLastState() } @@ -185,10 +184,13 @@ func (lc *LightChain) ResetWithGenesisBlock(genesis *types.Block) { defer lc.chainmu.Unlock() // Prepare the genesis block and reinitialise the chain - if err := core.WriteTd(lc.chainDb, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { - log.Crit("Failed to write genesis block TD", "err", err) + batch := lc.chainDb.NewBatch() + rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()) + rawdb.WriteBlock(batch, genesis) + rawdb.WriteHeadHeaderHash(batch, genesis.Hash()) + if err := batch.Write(); err != nil { + log.Crit("Failed to reset genesis block", "err", err) } - rawdb.WriteBlock(lc.chainDb, genesis) lc.genesisBlock = genesis lc.hc.SetGenesis(lc.genesisBlock.Header()) lc.hc.SetCurrentHeader(lc.genesisBlock.Header()) @@ -299,13 +301,22 @@ func (lc *LightChain) Rollback(chain []common.Hash) { lc.chainmu.Lock() defer lc.chainmu.Unlock() + batch := lc.chainDb.NewBatch() for i := len(chain) - 1; i >= 0; i-- { hash := chain[i] + // Degrade the chain markers if they are explicitly reverted. + // In theory we should update all in-memory markers in the + // last step, however the direction of rollback is from high + // to low, so it's safe the update in-memory markers directly. if head := lc.hc.CurrentHeader(); head.Hash() == hash { + rawdb.WriteHeadHeaderHash(batch, head.ParentHash) lc.hc.SetCurrentHeader(lc.GetHeader(head.ParentHash, head.Number.Uint64()-1)) } } + if err := batch.Write(); err != nil { + log.Crit("Failed to rollback light chain", "error", err) + } } // postChainEvents iterates over the events generated by a chain insertion and @@ -441,12 +452,15 @@ func (lc *LightChain) SyncCht(ctx context.Context) bool { chtCount, _, _ := lc.odr.ChtIndexer().Sections() if headNum+1 < chtCount*CHTFrequencyClient { num := chtCount*CHTFrequencyClient - 1 - header, err := GetHeaderByNumber(ctx, lc.odr, num) - if header != nil && err == nil { + // Retrieve the latest useful header and update to it + if header, err := GetHeaderByNumber(ctx, lc.odr, num); header != nil && err == nil { lc.chainmu.Lock() defer lc.chainmu.Unlock() + // Ensure the chain didn't move past the latest block while retrieving it if lc.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() { + log.Info("Updated latest header based on CHT", "number", header.Number, "hash", header.Hash()) + rawdb.WriteHeadHeaderHash(lc.chainDb, header.Hash()) lc.hc.SetCurrentHeader(header) } return true diff --git a/light/txpool.go b/light/txpool.go index a1d9190a3874..7a7bf619d7f3 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -25,6 +25,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -205,15 +206,17 @@ func (p *TxPool) checkMinedTxs(ctx context.Context, hash common.Hash, number uin // rollbackTxs marks the transactions contained in recently rolled back blocks // as rolled back. It also removes any positional lookup entries. func (p *TxPool) rollbackTxs(hash common.Hash, txc txStateChanges) { + batch := p.chainDb.NewBatch() if list, ok := p.mined[hash]; ok { for _, tx := range list { txHash := tx.Hash() - core.DeleteTxLookupEntry(p.chainDb, txHash) + rawdb.DeleteTxLookupEntry(batch, txHash) p.pending[txHash] = tx txc.setState(txHash, false) } delete(p.mined, hash) } + batch.Write() } // reorgOnNewHead sets a new head header, processing (and rolling back if necessary) From 2d5dc550d0c4daa648446c9de1b2dc797624116d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 24 Dec 2024 17:36:11 +0800 Subject: [PATCH 092/121] core/rawdb: rename WriteTxLookupEntries to WriteTxLookupEntriesByBlock (#21480) --- core/blockchain.go | 2 +- core/rawdb/accessors_indexes.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 480fa606017b..d38b3eec6ace 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -735,7 +735,7 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block, writeBlock bool) { // Add the block to the canonical chain number scheme and mark as the head batch := bc.db.NewBatch() rawdb.WriteCanonicalHash(batch, blockHash, blockNumberU64) - rawdb.WriteTxLookupEntries(batch, block) + rawdb.WriteTxLookupEntriesByBlock(batch, block) rawdb.WriteHeadBlockHash(batch, blockHash) if writeBlock { rawdb.WriteBlock(batch, block) diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index edb263325705..7f9409875193 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -30,9 +30,9 @@ type TxLookupEntry struct { Index uint64 } -// WriteTxLookupEntries stores a positional metadata for every transaction from +// WriteTxLookupEntriesByBlock stores a positional metadata for every transaction from // a block, enabling hash based transaction and receipt lookups. -func WriteTxLookupEntries(db ethdb.KeyValueWriter, block *types.Block) { +func WriteTxLookupEntriesByBlock(db ethdb.KeyValueWriter, block *types.Block) { // Iterate over each transaction and encode its metadata for i, tx := range block.Transactions() { entry := TxLookupEntry{ From 2baadc6e8768607c4b33cdeb510c882575e3e98b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 24 Dec 2024 23:30:33 +0800 Subject: [PATCH 093/121] core: improve shutdown synchronization in BlockChain (#22853) --- core/blockchain.go | 179 +++++++++++++++++++++++++++------------- core/blockchain_test.go | 4 +- internal/syncx/mutex.go | 64 ++++++++++++++ 3 files changed, 189 insertions(+), 58 deletions(-) create mode 100644 internal/syncx/mutex.go diff --git a/core/blockchain.go b/core/blockchain.go index d38b3eec6ace..be6281b6cabe 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -48,6 +48,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/ethclient" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/event" + "github.com/XinFinOrg/XDPoSChain/internal/syncx" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/metrics" "github.com/XinFinOrg/XDPoSChain/params" @@ -81,6 +82,9 @@ var ( blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil) blockReorgDropMeter = metrics.NewRegisteredMeter("chain/reorg/drop", nil) + errInsertionInterrupted = errors.New("insertion is interrupted") + errChainStopped = errors.New("blockchain is stopped") + CheckpointCh = make(chan int) ) @@ -149,8 +153,11 @@ type BlockChain struct { scope event.SubscriptionScope genesisBlock *types.Block - chainmu sync.RWMutex // blockchain insertion lock - procmu sync.RWMutex // block processor lock + // This mutex synchronizes chain write operations. + // Readers don't need to take it, they can just read the database. + chainmu *syncx.ClosableMutex + + procmu sync.RWMutex // block processor lock currentBlock atomic.Value // Current head of the block chain currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!) @@ -169,10 +176,10 @@ type BlockChain struct { // future blocks are blocks added for later processing futureBlocks *lru.Cache[common.Hash, *types.Block] - wg sync.WaitGroup // chain processing wait group for shutting down - quit chan struct{} // shutdown signal, closed in Stop. - running int32 // 0 if chain is running, 1 when stopped - procInterrupt int32 // interrupt signaler for block processing + wg sync.WaitGroup + quit chan struct{} // shutdown signal, closed in Stop. + running int32 // 0 if chain is running, 1 when stopped + procInterrupt int32 // interrupt signaler for block processing engine consensus.Engine processor Processor // block processor interface @@ -211,6 +218,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par triegc: prque.New[int64, common.Hash](nil), stateCache: state.NewDatabase(db), quit: make(chan struct{}), + chainmu: syncx.NewClosableMutex(), bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit), bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit), receiptsCache: lru.NewCache[common.Hash, types.Receipts](receiptsCacheLimit), @@ -261,8 +269,11 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par } } } - // Take ownership of this particular state - go bc.update() + + // Start future block processor. + bc.wg.Add(1) + go bc.futureBlocksLoop() + return bc, nil } @@ -410,7 +421,9 @@ func (bc *BlockChain) loadLastState() error { func (bc *BlockChain) SetHead(head uint64) error { log.Warn("Rewinding blockchain", "target", head) - bc.chainmu.Lock() + if !bc.chainmu.TryLock() { + return errChainStopped + } defer bc.chainmu.Unlock() updateFn := func(db ethdb.KeyValueWriter, header *types.Header) { @@ -499,8 +512,11 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil { return err } - // If all checks out, manually set the head block - bc.chainmu.Lock() + + // If all checks out, manually set the head block. + if !bc.chainmu.TryLock() { + return errChainStopped + } bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) bc.chainmu.Unlock() @@ -622,7 +638,9 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { if err := bc.SetHead(0); err != nil { return err } - bc.chainmu.Lock() + if !bc.chainmu.TryLock() { + return errChainStopped + } defer bc.chainmu.Unlock() // Prepare the genesis block and reinitialise the chain @@ -698,8 +716,10 @@ func (bc *BlockChain) Export(w io.Writer) error { // ExportN writes a subset of the active chain to the given writer. func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { - bc.chainmu.RLock() - defer bc.chainmu.RUnlock() + if !bc.chainmu.TryLock() { + return errChainStopped + } + defer bc.chainmu.Unlock() if first > last { return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) @@ -1033,15 +1053,38 @@ func (bc *BlockChain) Stop() { if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { return } - // Unsubscribe all subscriptions registered from blockchain + + // Unsubscribe all subscriptions registered from blockchain. bc.scope.Close() + + // Signal shutdown to all goroutines. close(bc.quit) - atomic.StoreInt32(&bc.procInterrupt, 1) + bc.StopInsert() + + // Now wait for all chain modifications to end and persistent goroutines to exit. + // + // Note: Close waits for the mutex to become available, i.e. any running chain + // modification will have exited when Close returns. Since we also called StopInsert, + // the mutex should become available quickly. It cannot be taken again after Close has + // returned. + bc.chainmu.Close() bc.wg.Wait() bc.saveData() log.Info("Blockchain manager stopped") } +// StopInsert interrupts all insertion methods, causing them to return +// errInsertionInterrupted as soon as possible. Insertion is permanently disabled after +// calling this method. +func (bc *BlockChain) StopInsert() { + atomic.StoreInt32(&bc.procInterrupt, 1) +} + +// insertStopped returns true after StopInsert has been called. +func (bc *BlockChain) insertStopped() bool { + return atomic.LoadInt32(&bc.procInterrupt) == 1 +} + func (bc *BlockChain) procFutureBlocks() { blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) for _, hash := range bc.futureBlocks.Keys() { @@ -1085,7 +1128,9 @@ const ( // Rollback is designed to remove a chain of links from the database that aren't // certain enough to be valid. func (bc *BlockChain) Rollback(chain []common.Hash) { - bc.chainmu.Lock() + if !bc.chainmu.TryLock() { + return + } defer bc.chainmu.Unlock() batch := bc.db.NewBatch() @@ -1124,6 +1169,8 @@ func (bc *BlockChain) Rollback(chain []common.Hash) { // InsertReceiptChain attempts to complete an already existing header chain with // transaction and receipt data. func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { + // We don't require the chainMu here since we want to maximize the + // concurrency of header insertion and receipt insertion. bc.wg.Add(1) defer bc.wg.Done() @@ -1195,7 +1242,9 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ } // Update the head fast sync block if better - bc.chainmu.Lock() + if !bc.chainmu.TryLock() { + return 0, errChainStopped + } head := blockChain[len(blockChain)-1] if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case currentFastBlock := bc.CurrentFastBlock() @@ -1221,12 +1270,13 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ var lastWrite uint64 -// WriteBlockWithoutState writes only the block and its metadata to the database, +// writeBlockWithoutState writes only the block and its metadata to the database, // but does not write any state. This is used to construct competing side forks // up to the point where they exceed the canonical total difficulty. -func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (err error) { - bc.wg.Add(1) - defer bc.wg.Done() +func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (err error) { + if bc.insertStopped() { + return errInsertionInterrupted + } batch := bc.db.NewBatch() rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td) @@ -1239,17 +1289,19 @@ func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (e // WriteBlockWithState writes the block and all associated state to the database. func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB, tradingState *tradingstate.TradingStateDB, lendingState *lendingstate.LendingStateDB) (status WriteStatus, err error) { - bc.chainmu.Lock() + if !bc.chainmu.TryLock() { + return NonStatTy, errInsertionInterrupted + } defer bc.chainmu.Unlock() - return bc.writeBlockWithState(block, receipts, state, tradingState, lendingState) } // writeBlockWithState writes the block and all associated state to the database, // but is expects the chain mutex to be held. func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB, tradingState *tradingstate.TradingStateDB, lendingState *lendingstate.LendingStateDB) (status WriteStatus, err error) { - bc.wg.Add(1) - defer bc.wg.Done() + if bc.insertStopped() { + return NonStatTy, errInsertionInterrupted + } // Calculate the total difficulty of the block ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) @@ -1470,38 +1522,51 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // // After insertion is done, all accumulated events will be fired. func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { - n, events, logs, err := bc.insertChain(chain, true) - bc.PostChainEvents(events, logs) - return n, err -} - -// insertChain will execute the actual chain insertion and event aggregation. The -// only reason this method exists as a separate one is to make locking cleaner -// with deferred statements. -func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []interface{}, []*types.Log, error) { // Sanity check that we have something meaningful to import if len(chain) == 0 { - return 0, nil, nil, nil + return 0, nil } - engine, _ := bc.Engine().(*XDPoS.XDPoS) // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { - if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { + block, prev := chain[i], chain[i-1] + if block.NumberU64() != chain[i-1].NumberU64()+1 || block.ParentHash() != chain[i-1].Hash() { // Chain broke ancestry, log a messge (programming error) and skip insertion - log.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(), - "parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash()) + log.Error("Non contiguous block insert", + "number", block.Number(), + "hash", block.Hash(), + "parent", block.ParentHash(), + "prevnumber", prev.Number(), + "prevhash", prev.Hash()) - return 0, nil, nil, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, chain[i-1].NumberU64(), - chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4]) + return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, prev.NumberU64(), + prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4]) } } - // Pre-checks passed, start the full block imports - bc.wg.Add(1) - defer bc.wg.Done() - bc.chainmu.Lock() + // Pre-check passed, start the full block imports. + if !bc.chainmu.TryLock() { + return 0, errChainStopped + } defer bc.chainmu.Unlock() + n, events, logs, err := bc.insertChain(chain, true) + bc.PostChainEvents(events, logs) + return n, err +} + +// insertChain is the internal implementation of InsertChain, which assumes that +// 1) chains are contiguous, and 2) The chain mutex is held. +// +// This method is split out so that import batches that require re-injecting +// historical blocks can do so without releasing the lock, which could lead to +// racey behaviour. If a sidechain import is in progress, and the historic state +// is imported, but then new canon-head is added before the actual sidechain +// completes, then the historic state could be pruned again +func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []interface{}, []*types.Log, error) { + // If the chain is terminating, don't even bother starting up. + if bc.insertStopped() { + return 0, nil, nil, nil + } // A queued approach to delivering events. This is generally // faster than direct delivery and requires much less mutex @@ -1578,7 +1643,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) externTd := new(big.Int).Add(bc.GetTd(block.ParentHash(), block.NumberU64()-1), block.Difficulty()) if localTd.Cmp(externTd) > 0 { - if err = bc.WriteBlockWithoutState(block, externTd); err != nil { + if err = bc.writeBlockWithoutState(block, externTd); err != nil { return i, events, coalescedLogs, err } continue @@ -1596,10 +1661,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] } log.Debug("Number block need calculated again", "number", block.NumberU64(), "hash", block.Hash().Hex(), "winners", len(winner)) // Import all the pruned blocks to make the state available - bc.chainmu.Unlock() // During reorg, we use verifySeals=false _, evs, logs, err := bc.insertChain(winner, false) - bc.chainmu.Lock() events, coalescedLogs = evs, logs if err != nil { @@ -1628,6 +1691,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] var tradingService utils.TradingService var lendingService utils.LendingService isSDKNode := false + engine, _ := bc.Engine().(*XDPoS.XDPoS) if bc.Config().IsTIPXDCXReceiver(block.Number()) && bc.chainConfig.XDPoS != nil && engine != nil && block.NumberU64() > bc.chainConfig.XDPoS.Epoch { author, err := bc.Engine().Author(block.Header()) // Ignore error, we're past header validation if err != nil { @@ -2091,7 +2155,9 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L bc.wg.Add(1) defer bc.wg.Done() // Write the block to the chain and get the status. - bc.chainmu.Lock() + if !bc.chainmu.TryLock() { + return nil, nil, errChainStopped + } defer bc.chainmu.Unlock() if bc.HasBlockAndFullState(block.Hash(), block.NumberU64()) { return events, coalescedLogs, nil @@ -2387,7 +2453,10 @@ func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) { } } -func (bc *BlockChain) update() { +// futureBlocksLoop processes the 'future block' queue. +func (bc *BlockChain) futureBlocksLoop() { + defer bc.wg.Done() + futureTimer := time.NewTicker(10 * time.Millisecond) defer futureTimer.Stop() for { @@ -2471,13 +2540,11 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i return i, err } - // Make sure only one thread manipulates the chain at once - bc.chainmu.Lock() + if !bc.chainmu.TryLock() { + return 0, errChainStopped + } defer bc.chainmu.Unlock() - bc.wg.Add(1) - defer bc.wg.Done() - whFunc := func(header *types.Header) error { _, err := bc.hc.WriteHeader(header) return err diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 41283aa592aa..31ba9bb4a701 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -128,7 +128,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { blockchain.reportBlock(block, receipts, err) return err } - blockchain.chainmu.Lock() + blockchain.chainmu.MustLock() WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash()))) rawdb.WriteBlock(blockchain.db, block) statedb.Commit(true) @@ -146,7 +146,7 @@ func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error return err } // Manually insert the header into the database, but don't reorganise (allows subsequent testing) - blockchain.chainmu.Lock() + blockchain.chainmu.MustLock() WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash))) rawdb.WriteHeader(blockchain.db, header) blockchain.chainmu.Unlock() diff --git a/internal/syncx/mutex.go b/internal/syncx/mutex.go new file mode 100644 index 000000000000..96a21986c60c --- /dev/null +++ b/internal/syncx/mutex.go @@ -0,0 +1,64 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package syncx contains exotic synchronization primitives. +package syncx + +// ClosableMutex is a mutex that can also be closed. +// Once closed, it can never be taken again. +type ClosableMutex struct { + ch chan struct{} +} + +func NewClosableMutex() *ClosableMutex { + ch := make(chan struct{}, 1) + ch <- struct{}{} + return &ClosableMutex{ch} +} + +// TryLock attempts to lock cm. +// If the mutex is closed, TryLock returns false. +func (cm *ClosableMutex) TryLock() bool { + _, ok := <-cm.ch + return ok +} + +// MustLock locks cm. +// If the mutex is closed, MustLock panics. +func (cm *ClosableMutex) MustLock() { + _, ok := <-cm.ch + if !ok { + panic("mutex closed") + } +} + +// Unlock unlocks cm. +func (cm *ClosableMutex) Unlock() { + select { + case cm.ch <- struct{}{}: + default: + panic("Unlock of already-unlocked ClosableMutex") + } +} + +// Close locks the mutex, then closes it. +func (cm *ClosableMutex) Close() { + _, ok := <-cm.ch + if !ok { + panic("Close of already-closed ClosableMutex") + } + close(cm.ch) +} From d03859d49e8297aed73958d9ec0a60aebf97d694 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 25 Dec 2024 11:02:44 +0800 Subject: [PATCH 094/121] core: update the fast block on chain import at the end of the fast sync phase (#23576) --- core/blockchain.go | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index be6281b6cabe..9fd7582960a8 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -749,11 +749,10 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block, writeBlock bool) { blockHash := block.Hash() blockNumberU64 := block.NumberU64() - // If the block is on a side chain or an unknown one, force other heads onto it too - updateHeads := rawdb.ReadCanonicalHash(bc.db, blockNumberU64) != blockHash - // Add the block to the canonical chain number scheme and mark as the head batch := bc.db.NewBatch() + rawdb.WriteHeadHeaderHash(batch, blockHash) + rawdb.WriteHeadFastBlockHash(batch, blockHash) rawdb.WriteCanonicalHash(batch, blockHash, blockNumberU64) rawdb.WriteTxLookupEntriesByBlock(batch, block) rawdb.WriteHeadBlockHash(batch, blockHash) @@ -761,23 +760,17 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block, writeBlock bool) { rawdb.WriteBlock(batch, block) } - // If the block is better than our head or is on a different chain, force update heads - if updateHeads { - rawdb.WriteHeadHeaderHash(batch, blockHash) - rawdb.WriteHeadFastBlockHash(batch, blockHash) - } - // Flush the whole batch into the disk, exit the node if failed if err := batch.Write(); err != nil { log.Crit("Failed to update chain indexes and markers", "err", err) } // Update all in-memory chain markers in the last step - if updateHeads { - bc.hc.SetCurrentHeader(block.Header()) - bc.currentFastBlock.Store(block) - headFastBlockGauge.Update(int64(blockNumberU64)) - } + bc.hc.SetCurrentHeader(block.Header()) + + bc.currentFastBlock.Store(block) + headFastBlockGauge.Update(int64(blockNumberU64)) + bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) From c8c39efb630a9b4c573722b7101f97268e4a4b29 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 25 Dec 2024 11:33:56 +0800 Subject: [PATCH 095/121] core: remove unnecessary log copy (#27475) --- core/blockchain.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 9fd7582960a8..66b6fdcddc67 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2263,9 +2263,10 @@ func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log { var logs []*types.Log for _, receipt := range receipts { for _, log := range receipt.Logs { - l := *log - l.Removed = removed - logs = append(logs, &l) + if removed { + log.Removed = true + } + logs = append(logs, log) } } return logs From f8decab0611bda001b8462568f17d671ea369470 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Sun, 29 Dec 2024 21:47:14 -0800 Subject: [PATCH 096/121] code refactor for performance (#782) Co-authored-by: liam.lai --- .github/workflows/deploy_rpc_image.yml | 7 +- .../XDPoS/engines/engine_v2/epochSwitch.go | 6 +- consensus/XDPoS/engines/engine_v2/timeout.go | 69 +++++++++++-------- consensus/XDPoS/engines/engine_v2/utils.go | 8 +-- params/config.go | 6 ++ params/config_test.go | 19 +++++ 6 files changed, 74 insertions(+), 41 deletions(-) diff --git a/.github/workflows/deploy_rpc_image.yml b/.github/workflows/deploy_rpc_image.yml index ebac65d963a5..088d809aeee8 100644 --- a/.github/workflows/deploy_rpc_image.yml +++ b/.github/workflows/deploy_rpc_image.yml @@ -6,19 +6,19 @@ on: network: type: choice description: 'devnet, testnet, or mainnet' - options: + options: - devnet - testnet - mainnet rpc_image: description: 'full image name' - + jobs: ansible: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + - name: Update RPC nodes image uses: dawidd6/action-ansible-playbook@v2 with: @@ -38,4 +38,3 @@ jobs: - name: Send deployment notification run: | curl --location --request POST "66.94.98.186:8080/deploy?environment=${{inputs.network}}&service=xdc_rpc&version=${{inputs.rpc_image}}" - \ No newline at end of file diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index 40a684e335e3..9928b88fb25a 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -98,7 +98,7 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types // IsEpochSwitchAtRound() is used by miner to check whether it mines a block in the same epoch with parent func (x *XDPoS_v2) isEpochSwitchAtRound(round types.Round, parentHeader *types.Header) (bool, uint64, error) { - epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch + epochNum := x.config.V2.SwitchEpoch + uint64(round)/x.config.Epoch // if parent is last v1 block and this is first v2 block, this is treated as epoch switch if parentHeader.Number.Cmp(x.config.V2.SwitchBlock) == 0 { return true, epochNum, nil @@ -127,7 +127,7 @@ func (x *XDPoS_v2) GetCurrentEpochSwitchBlock(chain consensus.ChainReader, block } currentCheckpointNumber := epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() - epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch + epochNum := x.config.V2.SwitchEpoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch return currentCheckpointNumber, epochNum, nil } @@ -145,7 +145,7 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) { } parentRound := quorumCert.ProposedBlockInfo.Round epochStartRound := round - round%types.Round(x.config.Epoch) - epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(round)/x.config.Epoch + epochNum := x.config.V2.SwitchEpoch + uint64(round)/x.config.Epoch // if parent is last v1 block and this is first v2 block, this is treated as epoch switch if quorumCert.ProposedBlockInfo.Number.Cmp(x.config.V2.SwitchBlock) == 0 { log.Info("[IsEpochSwitch] true, parent equals V2.SwitchBlock", "round", round, "number", header.Number.Uint64(), "hash", header.Hash()) diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index 875dd22c9c99..169e1db7bab0 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -79,6 +79,43 @@ func (x *XDPoS_v2) onTimeoutPoolThresholdReached(blockChainReader consensus.Chai return nil } +func (x *XDPoS_v2) getTCEpochInfo(chain consensus.ChainReader, timeoutCert *types.TimeoutCert) (*types.EpochSwitchInfo, error) { + + epochSwitchInfo, err := x.getEpochSwitchInfo(chain, (chain.CurrentHeader()), (chain.CurrentHeader()).Hash()) + if err != nil { + log.Error("[getTCEpochInfo] Error when getting epoch switch info", "error", err) + return nil, fmt.Errorf("fail on getTCEpochInfo due to failure in getting epoch switch info, %s", err) + } + + epochRound := epochSwitchInfo.EpochSwitchBlockInfo.Round + tempTCEpoch := x.config.V2.SwitchEpoch + uint64(epochRound)/x.config.Epoch + + epochBlockInfo := &types.BlockInfo{ + Hash: epochSwitchInfo.EpochSwitchBlockInfo.Hash, + Round: epochRound, + Number: epochSwitchInfo.EpochSwitchBlockInfo.Number, + } + log.Info("[getTCEpochInfo] Init epochInfo", "number", epochBlockInfo.Number, "round", epochRound, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch) + for epochBlockInfo.Round > timeoutCert.Round { + tempTCEpoch-- + epochBlockInfo, err = x.GetBlockByEpochNumber(chain, tempTCEpoch) + if err != nil { + log.Error("[getTCEpochInfo] Error when getting epoch block info by tc round", "error", err) + return nil, fmt.Errorf("fail on getTCEpochInfo due to failure in getting epoch block info tc round, %s", err) + } + log.Debug("[getTCEpochInfo] Loop to get right epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch) + } + tcEpoch := tempTCEpoch + log.Info("[getTCEpochInfo] Final TC epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tcEpoch) + + epochInfo, err := x.getEpochSwitchInfo(chain, nil, epochBlockInfo.Hash) + if err != nil { + log.Error("[getTCEpochInfo] Error when getting epoch switch info", "error", err) + return nil, fmt.Errorf("fail on getTCEpochInfo due to failure in getting epoch switch info, %s", err) + } + return epochInfo, nil +} + func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.TimeoutCert) error { /* 1. Get epoch master node list by gapNumber @@ -110,37 +147,9 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time } } - epochSwitchInfo, err := x.getEpochSwitchInfo(chain, (chain.CurrentHeader()), (chain.CurrentHeader()).Hash()) + epochInfo, err := x.getTCEpochInfo(chain, timeoutCert) if err != nil { - log.Error("[verifyTC] Error when getting epoch switch info", "error", err) - return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err) - } - - epochRound := epochSwitchInfo.EpochSwitchBlockInfo.Round - tempTCEpoch := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochRound)/x.config.Epoch - - epochBlockInfo := &types.BlockInfo{ - Hash: epochSwitchInfo.EpochSwitchBlockInfo.Hash, - Round: epochRound, - Number: epochSwitchInfo.EpochSwitchBlockInfo.Number, - } - log.Info("[verifyTC] Init epochInfo", "number", epochBlockInfo.Number, "round", epochRound, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch) - for epochBlockInfo.Round > timeoutCert.Round { - tempTCEpoch-- - epochBlockInfo, err = x.GetBlockByEpochNumber(chain, tempTCEpoch) - if err != nil { - log.Error("[verifyTC] Error when getting epoch block info by tc round", "error", err) - return fmt.Errorf("fail on verifyTC due to failure in getting epoch block info tc round, %s", err) - } - log.Debug("[verifyTC] Loop to get right epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tempTCEpoch) - } - tcEpoch := tempTCEpoch - log.Info("[verifyTC] Final TC epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutCert.Round, "tcEpoch", tcEpoch) - - epochInfo, err := x.getEpochSwitchInfo(chain, nil, epochBlockInfo.Hash) - if err != nil { - log.Error("[verifyTC] Error when getting epoch switch info", "error", err) - return fmt.Errorf("fail on verifyTC due to failure in getting epoch switch info, %s", err) + return err } certThreshold := x.config.V2.Config(uint64(timeoutCert.Round)).CertThreshold diff --git a/consensus/XDPoS/engines/engine_v2/utils.go b/consensus/XDPoS/engines/engine_v2/utils.go index 49d79177e8c1..0a0f2ad7a68f 100644 --- a/consensus/XDPoS/engines/engine_v2/utils.go +++ b/consensus/XDPoS/engines/engine_v2/utils.go @@ -296,7 +296,7 @@ func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpoc if err != nil { return nil, err } - epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch + epochNum := x.config.V2.SwitchEpoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch // if current epoch is this epoch, we early return the result if targetEpochNum == epochNum { return epochSwitchInfo.EpochSwitchBlockInfo, nil @@ -304,11 +304,11 @@ func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpoc if targetEpochNum > epochNum { return nil, errors.New("input epoch number > current epoch number") } - if targetEpochNum < x.config.V2.SwitchBlock.Uint64()/x.config.Epoch { + if targetEpochNum < x.config.V2.SwitchEpoch { return nil, errors.New("input epoch number < v2 begin epoch number") } // the block's round should be in [estRound,estRound+Epoch-1] - estRound := types.Round((targetEpochNum - x.config.V2.SwitchBlock.Uint64()/x.config.Epoch) * x.config.Epoch) + estRound := types.Round((targetEpochNum - x.config.V2.SwitchEpoch) * x.config.Epoch) // check the round2epochBlockInfo cache blockInfo := x.getBlockByEpochNumberInCache(chain, estRound) if blockInfo != nil { @@ -330,7 +330,7 @@ func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpoc return nil, err } for _, info := range epochSwitchInfos { - epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(info.EpochSwitchBlockInfo.Round)/x.config.Epoch + epochNum := x.config.V2.SwitchEpoch + uint64(info.EpochSwitchBlockInfo.Round)/x.config.Epoch if epochNum == targetEpochNum { return info.EpochSwitchBlockInfo, nil } diff --git a/params/config.go b/params/config.go index ba9b45212a7a..6630f9b197b6 100644 --- a/params/config.go +++ b/params/config.go @@ -180,6 +180,7 @@ var ( Gap: 450, FoudationWalletAddr: common.HexToAddress("xdc92a289fe95a85c53b8d0d113cbaef0c1ec98ac65"), V2: &V2{ + SwitchEpoch: common.TIPV2SwitchBlock.Uint64() / 900, SwitchBlock: common.TIPV2SwitchBlock, CurrentConfig: MainnetV2Configs[0], AllConfigs: MainnetV2Configs, @@ -222,6 +223,7 @@ var ( Gap: 450, FoudationWalletAddr: common.HexToAddress("xdc746249c61f5832c5eed53172776b460491bdcd5c"), V2: &V2{ + SwitchEpoch: common.TIPV2SwitchBlock.Uint64() / 900, SwitchBlock: common.TIPV2SwitchBlock, CurrentConfig: TestnetV2Configs[0], AllConfigs: TestnetV2Configs, @@ -246,6 +248,7 @@ var ( Gap: 450, FoudationWalletAddr: common.HexToAddress("0x746249c61f5832c5eed53172776b460491bdcd5c"), V2: &V2{ + SwitchEpoch: common.TIPV2SwitchBlock.Uint64() / 900, SwitchBlock: common.TIPV2SwitchBlock, CurrentConfig: DevnetV2Configs[0], AllConfigs: DevnetV2Configs, @@ -269,6 +272,7 @@ var ( Period: 15, Epoch: 900, V2: &V2{ + SwitchEpoch: 9999999999 / 900, SwitchBlock: big.NewInt(9999999999), CurrentConfig: MainnetV2Configs[0], AllConfigs: MainnetV2Configs, @@ -355,6 +359,7 @@ var ( FoudationWalletAddr: common.HexToAddress("0x0000000000000000000000000000000000000068"), Reward: 250, V2: &V2{ + SwitchEpoch: 1, SwitchBlock: big.NewInt(900), CurrentConfig: UnitTestV2Configs[0], AllConfigs: UnitTestV2Configs, @@ -451,6 +456,7 @@ type XDPoSConfig struct { type V2 struct { lock sync.RWMutex // Protects the signer fields + SwitchEpoch uint64 SwitchBlock *big.Int `json:"switchBlock"` CurrentConfig *V2Config `json:"config"` AllConfigs map[uint64]*V2Config `json:"allConfigs"` diff --git a/params/config_test.go b/params/config_test.go index 3b18db4b5977..bd4113e135f1 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -117,3 +117,22 @@ func TestBuildConfigIndex(t *testing.T) { expected := []uint64{900, 10, 0} assert.Equal(t, expected, index) } + +// Test switch epoch is switchblock divide into epoch per block +func TestSwitchEpoch(t *testing.T) { + config := XDCMainnetChainConfig.XDPoS + epoch := config.Epoch + assert.Equal(t, config.V2.SwitchEpoch, config.V2.SwitchBlock.Uint64()/epoch) + + config = TestnetChainConfig.XDPoS + epoch = config.Epoch + assert.Equal(t, config.V2.SwitchEpoch, config.V2.SwitchBlock.Uint64()/epoch) + + config = DevnetChainConfig.XDPoS + epoch = config.Epoch + assert.Equal(t, config.V2.SwitchEpoch, config.V2.SwitchBlock.Uint64()/epoch) + + config = TestXDPoSMockChainConfig.XDPoS + epoch = config.Epoch + assert.Equal(t, config.V2.SwitchEpoch, config.V2.SwitchBlock.Uint64()/epoch) +} From 6307460603097ebb0d7243be7713c4d5cbfaadc3 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Sun, 29 Dec 2024 21:50:28 -0800 Subject: [PATCH 097/121] update bootnode list (#783) Co-authored-by: liam.lai --- cicd/mainnet/bootnodes.list | 39 +++++++++++++++++++------------------ cicd/testnet/bootnodes.list | 9 --------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/cicd/mainnet/bootnodes.list b/cicd/mainnet/bootnodes.list index f720193cfa98..4527bbbf5db1 100644 --- a/cicd/mainnet/bootnodes.list +++ b/cicd/mainnet/bootnodes.list @@ -1,31 +1,20 @@ -enode://11299e930438a12a7171d540e7ed594172babd7856aa518c4ca0a25564d6cf7fe4abaf74a68fd626118c205095f5aa40badf5f16f9651e1743383040f74323ca@154.53.57.144:30303 -enode://4ebfb7b3dd8d335fb5160410b9d4b494224caf7e2b5a2630f000a69b9edc83382b7c45536981a60e217876a1f553ed351846f14623e969df0796fb2d5d55b947@209.126.1.10:30303 -enode://ad638c179f9f72565bd78db98aa68d3c33b3a476421faeb07e185b18fa95d5999e72c15b9811526a65c0cf27573d25dc1905a5bf09d7de634b5fc5ef1cd661de@209.126.11.108:30303 -enode://1e331800102e30f83418b5b6eb59a7e325aaa05f9efb9756e6c6ba1624c8e17ba1dd4334a32c87f9022afe2bb3a53410d9f96a0b4ae3aecd574b08785d5f6014@209.126.2.33:30303 -enode://70e471eb021a3bca37407fabe461873380f100823a1ad610d564dd11514e7db2a9c79a74456adda3e3a48f6364ee08f390e3e0df9288eaceae1fc2d084647c92@209.126.0.250:30303 -enode://4406a66a21b7c242c4fa9605301e889419e4c0d4f503baed88b24f7521dc783a9259f9fb23ca4748cbad8d48cf59164419438b317a889488cc7bcf0d44023296@161.97.164.153:30303 -enode://021fb5b586c865f31db4fc82c9aa9e21110328fe88e1e99a65ca87031bcd6544785c68d47efe15e106c71b0066509d94a1379fb2a95ecdebab77d518b222422f@161.97.131.6:30303 -enode://25ce413f1f20ec9099d7c93ea583c749454f0523e906a4d2ad835fbd12eaf296976bd89a3ff1ab7a34d7afe25cc61572a4da5cd6f72c0551240c590f5a1affa2@161.97.131.145:30303 -enode://25faf1b866535701790398623ac86705a91dff419a6e460eaf80325220dc2525c97bbf0812085fd8dc9745d1d2a7ff024b7b36aa27f6e4fcb7a10ac508e3078a@161.97.172.27:30303 -enode://fc0caeb94dc942f06c56885e07206a0431f6f1045a46de6f7c65a93826220c84f1b72894ffae9091e2e05472f7926b59ed159ffc145ac0225dfb2ac1325b3629@161.97.128.201:30303 -enode://6358dd8ba702f8666259d07513f760d897739956e7b8ee4da29cc2461020f04c1d80f3d17becf69f1f0b9bfe5ed83754a5ebbad5a193e9d56266c668cf0ab4ba@161.97.129.254:30303 -enode://c5ab74d3cc2a7f68cf16b421ec0c19d1de2aa10de20d6fd4b6589174b216c81e930a7d395cd64099218838f7adb2fd9302a9b5d0650123930ce3ec553369e32b@212.38.189.120:30303 -enode://7698c7dd2f5ca348c2237bc62751c3bd8432d89cf082233540d9512a4d49b6d90fea395f0a2d79ccb90ef663c1cb9baa5204a494b904acb91fb42d7ef2991c1b@212.38.189.121:30303 -enode://7698c7dd2f5ca348c2237bc62751c3bd8432d89cf082233540d9512a4d49b6d90fea395f0a2d79ccb90ef663c1cb9baa5204a494b904acb91fb42d7ef2991c1b@212.38.189.122:30303 -enode://7923727ebf54d1fc9d9fef1508df7235b123b7d74a7dbd900f78ce169e5e3f30171291f22e7c9ea7c66e97ea405f75ad460073434e6f282b0c902fd0eb99047f@23.111.13.177:30303 -enode://c225c4954add10563b34f230ef9ae076760fb3cb347f15b2629ca94054b2c7b92593ae198830beb601a5515ca464af709229c7cbbaa0512bca4d3ef113ac8241@103.101.130.85:30303 -enode://c225c4954add10563b34f230ef9ae076760fb3cb347f15b2629ca94054b2c7b92593ae198830beb601a5515ca464af709229c7cbbaa0512bca4d3ef113ac8241@103.101.130.199:30303 -enode://f9b52fa47ef04a94d71b0e9723df4a453f42cb359573175acdc2eb693c36cd64c0afb697a04ad2c61d74bd3e60fb84d3077e3ce92d5bcaa642177064e77f4587@103.101.129.198:30303 -enode://c225c4954add10563b34f230ef9ae076760fb3cb347f15b2629ca94054b2c7b92593ae198830beb601a5515ca464af709229c7cbbaa0512bca4d3ef113ac8241@103.101.130.199:30303 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@154.53.42.5:30303 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@194.146.12.183:30303 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@194.146.12.181:30303 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@154.53.56.28:30303 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@144.126.150.58:30303 +enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@194.146.12.182:30303 +enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@78.129.229.96:30301 +enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@5.152.223.199:30301 +enode://560113969268e30a430991e36fcb1a6ea8a2bc16f23bc1dabffd6f8c17649237d58d8cf554e9ce882184abdc9b3a607230123e2bcf819d4ed01ec02acee1c4c2@78.159.100.155:30303 +enode://a86d3268c060323572bfeb6df76081e4668ec44cc60ff028c1685a9a683c5d6497c987b5dfade81323d08875066218a1877484396e11f400ce1c2c9bd343c935@78.159.100.155:30304 +enode://b69648bc931e60ab59057af72f411567444725a165c8798ffdb420de3be2636c5823f69f8ea76895422d5797af439c97221daa153785ad4bc2e7a6719a6116ae@78.159.100.155:30305 +enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@107.191.46.179:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@107.191.63.81:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@108.61.208.82:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@137.220.52.242:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@137.220.53.156:30301 +enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@139.180.167.226:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@139.180.188.238:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@139.180.207.188:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@149.248.57.56:30301 @@ -34,3 +23,15 @@ enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@155.138.132.39:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@155.138.135.5:30301 enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@155.138.136.247:30301 +enode://07257a47f5609c284e43b6c08d54fa2bd1ef524e39d552da928938b9e86c1944aec5d4c7e46919b6953fe4ecd8b4847c6aa0e2303fdc417cb3439abd03706311@209.126.9.230:30303 +enode://3dc8823dba75781aad99534ff7ff0460d95120644421c3874d3759a25eb4c84ad1e7aa3129110901f1dd42d6c19cc02a7757c152c5d433ceb8e47c621d02e15e@144.126.146.184:30303 +enode://fc7d703932a2f53e203c6263462af69bfca3520c5130748f54f3ce85196f895f6be43e618544e66b511f78e926dcfe7e842e0b94937cdadb9d6e9f328a34796f@66.94.122.169:30303 +enode://8d6ecd0fcc842a3553847b7f66cdee2c008e295ba657ed63da4b8e6da303c6bb308b6e9a8d9c0d0cc357c690033696e5c8222f726a3f39338101ef9b1f4026f1@66.94.122.172:30303 +enode://f1bb123968485d1acb3d3b19230742e7018c91419d2acd5fb391d5150310c6b6a686de287394dd28087ba5e6019a8ccc494a4d8eddf21e8324e794173d7d9f35@66.94.100.116:30303 +enode://25bd979e84e09401b3dcbf506f859fb979ca5dd1d1687d500a5fa5798308119f4cbe49cd26136d6a480f855b5b3f99a26f696c01fff45630aba5aea24b958469@66.94.100.115:30303 +enode://a49ba70cb4991fc3dbb15f0133684c3501a46004a0d4f3abfa1137c5a1c50f5942b2b8bc9c9fa6649621275df3532681f1167c06ea2e1ab0cd6f71e33cf97d9b@86.48.31.135:30303 +enode://5de7e18451f56ae6506d28a85b0d274b03dec7028bdfaf9407816765d38352c654a35b4b260c710de0f2e33bd9df63420ec448d4b87d46b81a05729c9d1df350@66.94.122.40:30303 +enode://4515870a9dd133c3cbbcb194e0f73853fae510217dd35bb0ffe6793f9b21945e0a280708273e7f5b30330b6737858bedabbc6eebcf68d38089eb11e4fb6930d8@161.97.156.58:30303 +enode://1686e2536b5c27a443575e0e94daee0736d6a043e806bfe889b979003c43a6017f00aa2b4e5b820afbd02822f1918e07ce15b050ae55202355c1d803ed372b0c@161.97.175.15:30303 +enode://ad187cfa297ccd540b6afc1fbc4e5d552c27eadd788084b5667cd57b558109f338b9403f880d96d6efed65fbd741521ec81c77c01b0b7bce5dbafe30043369fd@194.233.74.229:30303 +enode://3dc8823dba75781aad99534ff7ff0460d95120644421c3874d3759a25eb4c84ad1e7aa3129110901f1dd42d6c19cc02a7757c152c5d433ceb8e47c621d02e15e@144.126.146.184:30303 \ No newline at end of file diff --git a/cicd/testnet/bootnodes.list b/cicd/testnet/bootnodes.list index 9fca6cadab7c..c2af1034635b 100644 --- a/cicd/testnet/bootnodes.list +++ b/cicd/testnet/bootnodes.list @@ -1,12 +1,3 @@ -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@188.227.164.51:30301 -enode://278a1ac8aab1381b460788dcf4dcaffd58252f0f4c57d95e4c68b4b2bbf0b0fee83b5c140b3e6eb3af8b8369e76fa6996ccc667f65f9ce35c1d14fbffbfdfd52@95.179.217.201:30301 -enode://518a2b963f0e41ef6520973766a8caad9b13c4261c50a73eedfeaa3ebf3cce623dadc132d8d42ec41a50195c925ca55abd4e2a96258f9d335e3f625e6c2df789@149.28.167.190:30301 -enode://63f5a65ffce84b7123562b8bc871ae63db6dadded14df1dae6ad09b4a30e722a72e522d99aaf0bbad19380a0dd3abe94768ed03a8f68204b5dee6ae16ddb4d83@194.233.77.19:30301 -enode://87497c34ce0102e888040d6ec530e73c33bb0330770105797cf5667f465115d49d53cb583a8b4e34ff14048448c63f03fbd1c269897d7b99716dcdb942b6d707@144.91.108.231:30301 -enode://8c372fc5859e69a49037768f2ece54f14d1d159ec3181d06d7b58f1a54dac4f2f13623f1377a7e506e48e5f33b1752a9726a44b33fdb158ce7d6d5a57c055f65@207.244.240.232:30301 -enode://bed408a65f2894b09ac11ec03eee6b4b1af279e27c81fbe942aa6300ebe5d734913c0c7b30cdbcf98dfebd7a46bf9c79cfc1a8878e20240b5da872dc358be571@66.94.121.62:30301 -enode://dd8973429effba6d6f8edd27efad8544553bb39c82c6350c09e82cd3cfdcdecaf6d0ce9820ed97482aedd0b9236e88d362ca031a65dcbdac52aa292e693723e3@144.126.150.69:30301 -enode://fb5616c009265a162c08fb3984192ffc4df18946dc4d591ba5480011169e6f3f324685b5e102e8123d32e27cd968220d6400b9f1f0a6d1611c130079cd1e71bb@161.97.93.168:30301 enode://75e95709fd89a6314b0d5363226e3e46c56d98c6ddd3ec3cbdffcb65fdfedc8cbad870e2af1382b97e5986c1465cdb00e621cc01e1910f622ba20ed2359a02a0@213.136.89.186:30304 enode://34ba74c6a0ef379040243e19c5f673b29155ec5928a5300f1cdfd2215983b7720d52585acb16f7199cc5abdd9ff3657305e901e097f951e35740b0a80fce3e18@185.217.126.17:30304 enode://d7c070939155be296a8b254d43a0927e6c6777f1352239499fab867af455b9c671bddd5f9ae359ddcd6af9a368746e2f993416bafff2d03a4d974d888daaf020@38.242.244.116:30304 From ac3b44eebf259a10e42165d8966958e1262806e0 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Mon, 30 Dec 2024 18:31:31 -0800 Subject: [PATCH 098/121] remove devnet ecs terraform (#786) Co-authored-by: liam.lai --- .github/workflows/ci.yml | 78 ++----------- cicd/devnet/terraform/.env | 13 --- cicd/devnet/terraform/iam.tf | 28 ----- cicd/devnet/terraform/main.tf | 63 ----------- .../module/region/container-definition.tpl | 44 -------- cicd/devnet/terraform/module/region/ecs.tf | 96 ---------------- cicd/devnet/terraform/module/region/efs.tf | 67 ----------- cicd/devnet/terraform/module/region/main.tf | 102 ----------------- cicd/devnet/terraform/module/region/rpc.tf | 104 ------------------ .../terraform/module/region/variables.tf | 31 ------ cicd/devnet/terraform/s3.tf | 13 --- cicd/devnet/terraform/variables.tf | 39 ------- 12 files changed, 10 insertions(+), 668 deletions(-) delete mode 100644 cicd/devnet/terraform/.env delete mode 100644 cicd/devnet/terraform/iam.tf delete mode 100644 cicd/devnet/terraform/main.tf delete mode 100644 cicd/devnet/terraform/module/region/container-definition.tpl delete mode 100644 cicd/devnet/terraform/module/region/ecs.tf delete mode 100644 cicd/devnet/terraform/module/region/efs.tf delete mode 100644 cicd/devnet/terraform/module/region/main.tf delete mode 100644 cicd/devnet/terraform/module/region/rpc.tf delete mode 100644 cicd/devnet/terraform/module/region/variables.tf delete mode 100644 cicd/devnet/terraform/s3.tf delete mode 100644 cicd/devnet/terraform/variables.tf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3306363dd0fd..b6b7db7ffe5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,23 +100,6 @@ jobs: echo "image_name=$image_name" echo "image_name=$image_name" >> "$GITHUB_OUTPUT" - devnet_terraform_apply: - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') - needs: devnet_build_push - environment: devnet - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - steps: - - uses: actions/checkout@v4 - - name: Terraform Apply - run: | - git_hash=$(git rev-parse --short "$GITHUB_SHA") - cd cicd/devnet/terraform - terraform init ${{ env.tf_init_cli_options }} - terraform apply -var "docker_tag=dev-upgrade-${git_hash}" ${{ env.tf_apply_cli_options }} - rpcnode_terraform_apply: runs-on: ubuntu-latest if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') @@ -143,54 +126,13 @@ jobs: --extra-vars network=ec2_rpcs --extra-vars rpc_image=${{ needs.devnet_build_push.outputs.output1 }} - devnet_dev-upgrade_node: - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') - needs: rpcnode_terraform_apply - environment: devnet - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - steps: - - uses: actions/checkout@v4 - - name: ECS Update - run: | - aws ecs update-service --region ap-southeast-1 --cluster devnet-xdcnode-cluster --service ecs-service-rpc1 --force-new-deployment --no-cli-pager | head -n 10; - - testnet_dev-upgrade_node: - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') - needs: rpcnode_terraform_apply - environment: testnet - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - steps: - - uses: actions/checkout@v4 - - name: ECS Update - run: | - aws ecs update-service --region ap-southeast-1 --cluster testnet-xdcnode-cluster --service ecs-service-testnet-rpc1 --force-new-deployment --no-cli-pager | head -n 10; - - mainnet_dev-upgrade_node: - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') - needs: rpcnode_terraform_apply - environment: mainnet - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - steps: - - uses: actions/checkout@v4 - - name: ECS Update - run: | - aws ecs update-service --region ap-southeast-1 --cluster mainnet-xdcnode-cluster --service ecs-service-mainnet-rpc1 --force-new-deployment --no-cli-pager | head -n 10; - - devnet_send_notification: - runs-on: ubuntu-latest - needs: devnet_terraform_apply - if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') - steps: - - uses: actions/checkout@v4 - - name: Send deployment notification - run: | - curl --location --request POST "66.94.98.186:8080/deploy?environment=devnet&service=xdc&version=${GITHUB_SHA}" + # TODO Uncomment until new devnet + # devnet_send_notification: + # runs-on: ubuntu-latest + # needs: devnet_terraform_apply + # if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') + # steps: + # - uses: actions/checkout@v4 + # - name: Send deployment notification + # run: | + # curl --location --request POST "66.94.98.186:8080/deploy?environment=devnet&service=xdc&version=${GITHUB_SHA}" diff --git a/cicd/devnet/terraform/.env b/cicd/devnet/terraform/.env deleted file mode 100644 index 626762d2e6e3..000000000000 --- a/cicd/devnet/terraform/.env +++ /dev/null @@ -1,13 +0,0 @@ -log_level=2 - -# Ohio -us_east_2_start=11 -us_east_2_end=36 - -# Ireland -eu_west_1_start=37 -eu_west_1_end=62 - -# Sydney -ap_southeast_2_start=73 -ap_southeast_2_end=73 \ No newline at end of file diff --git a/cicd/devnet/terraform/iam.tf b/cicd/devnet/terraform/iam.tf deleted file mode 100644 index 5a9e984a3826..000000000000 --- a/cicd/devnet/terraform/iam.tf +++ /dev/null @@ -1,28 +0,0 @@ -# IAM policies -data "aws_iam_policy_document" "xdc_ecs_tasks_execution_role" { - statement { - actions = ["sts:AssumeRole"] - - principals { - type = "Service" - identifiers = ["ecs-tasks.amazonaws.com"] - } - } -} - -# Create the role -resource "aws_iam_role" "devnet_xdc_ecs_tasks_execution_role" { - name = "devnet-xdc-ecs-task-execution-role" - assume_role_policy = "${data.aws_iam_policy_document.xdc_ecs_tasks_execution_role.json}" -} - -# Attached the AWS managed policies to the new role -resource "aws_iam_role_policy_attachment" "devnet_xdc_ecs_tasks_execution_role" { - for_each = toset([ - "arn:aws:iam::aws:policy/AmazonElasticFileSystemClientFullAccess", - "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", - "arn:aws:iam::aws:policy/AmazonElasticFileSystemsUtils" - ]) - role = aws_iam_role.devnet_xdc_ecs_tasks_execution_role.name - policy_arn = each.value -} diff --git a/cicd/devnet/terraform/main.tf b/cicd/devnet/terraform/main.tf deleted file mode 100644 index fc998b799ce7..000000000000 --- a/cicd/devnet/terraform/main.tf +++ /dev/null @@ -1,63 +0,0 @@ -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - } - } -} - -# Default -provider "aws" { - region = "us-east-1" -} - -provider "aws" { - alias = "us-east-2" - region = "us-east-2" -} - -module "us-east-2" { - source = "./module/region" - region = "us-east-2" - devnetNodeKeys = local.devnetNodeKeys["us-east-2"] - logLevel = local.logLevel - devnet_xdc_ecs_tasks_execution_role_arn = aws_iam_role.devnet_xdc_ecs_tasks_execution_role.arn - docker_tag = var.docker_tag - providers = { - aws = aws.us-east-2 - } -} - -provider "aws" { - alias = "eu-west-1" - region = "eu-west-1" -} - -module "eu-west-1" { - source = "./module/region" - region = "eu-west-1" - devnetNodeKeys = local.devnetNodeKeys["eu-west-1"] - logLevel = local.logLevel - devnet_xdc_ecs_tasks_execution_role_arn = aws_iam_role.devnet_xdc_ecs_tasks_execution_role.arn - docker_tag = var.docker_tag - providers = { - aws = aws.eu-west-1 - } -} - -provider "aws" { - alias = "ap-southeast-2" - region = "ap-southeast-2" -} - -module "ap-southeast-2" { - source = "./module/region" - region = "ap-southeast-2" - devnetNodeKeys = local.devnetNodeKeys["ap-southeast-2"] - logLevel = local.logLevel - devnet_xdc_ecs_tasks_execution_role_arn = aws_iam_role.devnet_xdc_ecs_tasks_execution_role.arn - docker_tag = var.docker_tag - providers = { - aws = aws.ap-southeast-2 - } -} diff --git a/cicd/devnet/terraform/module/region/container-definition.tpl b/cicd/devnet/terraform/module/region/container-definition.tpl deleted file mode 100644 index 008e98522ac1..000000000000 --- a/cicd/devnet/terraform/module/region/container-definition.tpl +++ /dev/null @@ -1,44 +0,0 @@ -[ - { - "name": "tfXdcNode", - "image": "xinfinorg/${image_environment}:${image_tag}", - "environment": [ - {"name": "PRIVATE_KEY", "value": "${private_key}"}, - {"name": "LOG_LEVEL", "value": "${log_level}"}, - {"name": "NODE_NAME", "value": "${node_name}"}, - {"name": "NETWORK", "value": "${chain_network}"} - ], - "essential": true, - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-group": "${cloudwatch_group}", - "awslogs-region": "${cloudwatch_region}", - "awslogs-stream-prefix": "ecs" - } - }, - "portMappings": [ - { - "hostPort": 8555, - "protocol": "tcp", - "containerPort": 8555 - }, - { - "hostPort": 8545, - "protocol": "tcp", - "containerPort": 8545 - }, - { - "hostPort": 30303, - "protocol": "tcp", - "containerPort": 30303 - } - ], - "mountPoints": [ - { - "containerPath": "/work/xdcchain", - "sourceVolume": "efs" - } - ] - } -] \ No newline at end of file diff --git a/cicd/devnet/terraform/module/region/ecs.tf b/cicd/devnet/terraform/module/region/ecs.tf deleted file mode 100644 index bd7a88b17aea..000000000000 --- a/cicd/devnet/terraform/module/region/ecs.tf +++ /dev/null @@ -1,96 +0,0 @@ -data template_file devnet_container_definition { - for_each = var.devnetNodeKeys - template = "${file("${path.module}/container-definition.tpl")}" - - vars = { - image_environment = "${lookup(each.value, "imageEnvironment", "devnet")}" - image_tag = "${lookup(each.value, "imageTag", var.docker_tag)}" - node_name = "${each.key}" - private_key = "${each.value.pk}" - cloudwatch_group = "tf-${each.key}" - cloudwatch_region = "${var.region}" - log_level = "${lookup(each.value, "logLevel", "${var.logLevel}")}" - chain_network = "devnet" - } -} - -resource "aws_ecs_task_definition" "devnet_task_definition_group" { - for_each = var.devnetNodeKeys - - family = "devnet-${each.key}" - requires_compatibilities = ["FARGATE"] - network_mode = "awsvpc" - container_definitions = data.template_file.devnet_container_definition[each.key].rendered - execution_role_arn = var.devnet_xdc_ecs_tasks_execution_role_arn - task_role_arn = var.devnet_xdc_ecs_tasks_execution_role_arn - - # New nodes will consume a lot more CPU usage than existing nodes. - # This is due to sync is resource heavy. Recommending set to below if doing sync: - # CPU = 2048, Memory = 4096 - # Please set it back to cpu 256 and memory of 2048 after sync is done to save the cost - # cpu = 256 - # memory = 2048 - cpu = 1024 - memory = 4096 - volume { - name = "efs" - - efs_volume_configuration { - file_system_id = aws_efs_file_system.devnet_efs[each.key].id - root_directory = "/" - transit_encryption = "ENABLED" - authorization_config { - access_point_id = aws_efs_access_point.devnet_efs_access_point[each.key].id - iam = "DISABLED" - } - } - } - - tags = { - Name = "TfDevnetEcs-${each.key}" - } -} - -data "aws_ecs_task_definition" "devnet_ecs_task_definition" { - for_each = var.devnetNodeKeys - task_definition = aws_ecs_task_definition.devnet_task_definition_group[each.key].family -} - -# ECS cluster -resource "aws_ecs_cluster" "devnet_ecs_cluster" { - name = "devnet-xdcnode-cluster" - tags = { - Name = "TfDevnetEcsCluster" - } -} - - -resource "aws_ecs_service" "devnet_ecs_service" { - for_each = var.enableFixedIp ? {} : var.devnetNodeKeys - name = "ecs-service-${each.key}" - cluster = aws_ecs_cluster.devnet_ecs_cluster.id - task_definition = "${aws_ecs_task_definition.devnet_task_definition_group[each.key].family}:${max(aws_ecs_task_definition.devnet_task_definition_group[each.key].revision, data.aws_ecs_task_definition.devnet_ecs_task_definition[each.key].revision)}" - launch_type = "FARGATE" - scheduling_strategy = "REPLICA" - desired_count = 1 - force_new_deployment = true - deployment_minimum_healthy_percent = 0 - deployment_maximum_percent = 100 - - network_configuration { - subnets = [aws_subnet.devnet_subnet.id] - assign_public_ip = true - security_groups = [ - aws_default_security_group.devnet_xdcnode_security_group.id - ] - } - - deployment_circuit_breaker { - enable = true - rollback = false - } - - tags = { - Name = "TfDevnetEcsService-${each.key}" - } -} \ No newline at end of file diff --git a/cicd/devnet/terraform/module/region/efs.tf b/cicd/devnet/terraform/module/region/efs.tf deleted file mode 100644 index d03adc85b77c..000000000000 --- a/cicd/devnet/terraform/module/region/efs.tf +++ /dev/null @@ -1,67 +0,0 @@ - -# EFS -resource "aws_security_group" "devnet_efs_security_group" { - name = "TfDevnetEfsSecurityGroup" - description = "Allow HTTP in and out of devnet EFS" - vpc_id = aws_vpc.devnet_vpc.id - - ingress { - from_port = 2049 - to_port = 2049 - protocol = "TCP" - security_groups = [aws_default_security_group.devnet_xdcnode_security_group.id] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - tags = { - Name = "TfDevnetEfs" - } -} - -resource "aws_efs_file_system" "devnet_efs" { - for_each = var.devnetNodeKeys - creation_token = "efs-${each.key}" - performance_mode = "generalPurpose" - throughput_mode = "bursting" - encrypted = "true" - lifecycle_policy { - transition_to_ia = "AFTER_30_DAYS" - } - tags = { - Name = "TfDevnetEfs${each.key}" - } - } - -resource "aws_efs_mount_target" "devnet_efs_efs_mount_target" { - for_each = var.devnetNodeKeys - file_system_id = aws_efs_file_system.devnet_efs[each.key].id - subnet_id = aws_subnet.devnet_subnet.id - security_groups = [aws_security_group.devnet_efs_security_group.id] -} - -resource "aws_efs_access_point" "devnet_efs_access_point" { - for_each = var.devnetNodeKeys - file_system_id = aws_efs_file_system.devnet_efs[each.key].id - root_directory { - path = "/${each.key}/database" - creation_info { - owner_gid = 1001 - owner_uid = 1001 - permissions = 777 - } - } - posix_user { - gid = 1001 - uid = 1001 - secondary_gids = [0] - } - - tags = { - Name = "TfDevnetEfsAccessPoint${each.key}" - } -} \ No newline at end of file diff --git a/cicd/devnet/terraform/module/region/main.tf b/cicd/devnet/terraform/module/region/main.tf deleted file mode 100644 index 10fc5b08e603..000000000000 --- a/cicd/devnet/terraform/module/region/main.tf +++ /dev/null @@ -1,102 +0,0 @@ -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - } - } -} - -resource "aws_vpc" "devnet_vpc" { - cidr_block = "10.0.0.0/16" - instance_tenancy = "default" - enable_dns_hostnames = true - - tags = { - Name = "TfDevnetVpc" - } -} - -resource "aws_subnet" "devnet_subnet" { - vpc_id = aws_vpc.devnet_vpc.id - cidr_block = "10.0.0.0/20" - map_public_ip_on_launch = true - - tags = { - Name = "TfDevnetVpcSubnet" - } -} - -resource "aws_internet_gateway" "devnet_gatewat" { - vpc_id = aws_vpc.devnet_vpc.id - - tags = { - Name = "TfDevnetGateway" - } -} - -resource "aws_route_table" "devnet_route_table" { - vpc_id = aws_vpc.devnet_vpc.id - - route { - cidr_block = "0.0.0.0/0" - gateway_id = aws_internet_gateway.devnet_gatewat.id - } - - tags = { - Name = "TfDevnetVpcRoutingTable" - } -} - -resource "aws_route_table_association" "devnet_route_table_association" { - subnet_id = aws_subnet.devnet_subnet.id - route_table_id = aws_route_table.devnet_route_table.id -} - -resource "aws_default_security_group" "devnet_xdcnode_security_group" { - vpc_id = aws_vpc.devnet_vpc.id - - ingress { - description = "listener port" - from_port = 30303 - to_port = 30303 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - description = "discovery port" - from_port = 30303 - to_port = 30303 - protocol = "udp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - description = "rpc port" - from_port = 8545 - to_port = 8545 - protocol = "tcp" - cidr_blocks = ["10.0.0.0/16"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - tags = { - Name = "TfDevnetNode" - } -} - -# Logs -resource "aws_cloudwatch_log_group" "devnet_cloud_watch_group" { - for_each = var.devnetNodeKeys - - name = "tf-${each.key}" - retention_in_days = 14 # Logs are only kept for 14 days - tags = { - Name = "TfDevnetCloudWatchGroup${each.key}" - } -} \ No newline at end of file diff --git a/cicd/devnet/terraform/module/region/rpc.tf b/cicd/devnet/terraform/module/region/rpc.tf deleted file mode 100644 index 2ba07813c11f..000000000000 --- a/cicd/devnet/terraform/module/region/rpc.tf +++ /dev/null @@ -1,104 +0,0 @@ -# Allocate an Elastic IP for the NLB -resource "aws_eip" "nlb_eip" { - domain = "vpc" -} - - -# Create a Network Load Balancer -resource "aws_lb" "rpc_node_nlb" { - count = var.enableFixedIp ? 1 : 0 - name = "rpc-node-nlb" - load_balancer_type = "network" - - enable_deletion_protection = false - - subnet_mapping { - subnet_id = aws_subnet.devnet_subnet.id - allocation_id = aws_eip.nlb_eip.id - } -} - -# Listener and Target Group for the rpc node container -resource "aws_lb_target_group" "rpc_node_tg_8545" { - count = var.enableFixedIp ? 1 : 0 - name = "rpc-node-tg" - port = 8545 - protocol = "TCP" - vpc_id = aws_vpc.devnet_vpc.id - target_type = "ip" -} - -resource "aws_lb_listener" "rpc_node_listener_8545" { - count = var.enableFixedIp ? 1 : 0 - load_balancer_arn = aws_lb.rpc_node_nlb[0].arn - port = 8545 - protocol = "TCP" - - default_action { - type = "forward" - target_group_arn = aws_lb_target_group.rpc_node_tg_8545[0].arn - } -} - -resource "aws_ecs_service" "devnet_rpc_node_ecs_service" { - for_each = var.enableFixedIp ? var.devnetNodeKeys : {} - name = "ecs-service-${each.key}" - cluster = aws_ecs_cluster.devnet_ecs_cluster.id - task_definition = "${aws_ecs_task_definition.devnet_task_definition_group[each.key].family}:${max(aws_ecs_task_definition.devnet_task_definition_group[each.key].revision, data.aws_ecs_task_definition.devnet_ecs_task_definition[each.key].revision)}" - launch_type = "FARGATE" - scheduling_strategy = "REPLICA" - desired_count = 1 - force_new_deployment = true - deployment_minimum_healthy_percent = 0 - deployment_maximum_percent = 100 - - network_configuration { - subnets = [aws_subnet.devnet_subnet.id] - assign_public_ip = true - security_groups = [ - aws_default_security_group.devnet_xdcnode_security_group.id - ] - } - - deployment_circuit_breaker { - enable = true - rollback = false - } - - load_balancer { - target_group_arn = aws_lb_target_group.rpc_node_tg_8545[0].arn - container_name = "tfXdcNode" - container_port = 8545 - } - - depends_on = [ - aws_lb_listener.rpc_node_listener_8545 - ] - - tags = { - Name = "TfDevnetRpcNodeEcsService-${each.key}" - } -} - -# Target Group for port 30303 -resource "aws_lb_target_group" "rpc_node_tg_30303" { - count = var.enableFixedIp ? 1 : 0 - name = "rpc-node-tg-30303" - port = 30303 - protocol = "TCP" - vpc_id = aws_vpc.devnet_vpc.id - target_type = "ip" -} - -# Listener for port 30303 -resource "aws_lb_listener" "rpc_node_listener_30303" { - count = var.enableFixedIp ? 1 : 0 - load_balancer_arn = aws_lb.rpc_node_nlb[0].arn - port = 30303 - protocol = "TCP" - - default_action { - type = "forward" - target_group_arn = aws_lb_target_group.rpc_node_tg_30303[0].arn - } -} \ No newline at end of file diff --git a/cicd/devnet/terraform/module/region/variables.tf b/cicd/devnet/terraform/module/region/variables.tf deleted file mode 100644 index 00dcd2277cf4..000000000000 --- a/cicd/devnet/terraform/module/region/variables.tf +++ /dev/null @@ -1,31 +0,0 @@ -variable "region" { - description = "AWS region" - type = string -} - -variable "devnetNodeKeys" { - description = "each miner's key" - type = map -} - -variable "logLevel" { - description = "containers log level" - type = string -} - -variable "devnet_xdc_ecs_tasks_execution_role_arn" { - description = "aws iam role resource arn" - type = string -} - -variable "enableFixedIp" { - description = "a flag to indicate whether fixed ip should be associated to the nodes. This is used for RPC node" - type = bool - default = false -} - -variable docker_tag { - type = string - default = "latest" - description = "description" -} diff --git a/cicd/devnet/terraform/s3.tf b/cicd/devnet/terraform/s3.tf deleted file mode 100644 index cd30e5ce324a..000000000000 --- a/cicd/devnet/terraform/s3.tf +++ /dev/null @@ -1,13 +0,0 @@ -terraform { - backend "s3" { - bucket = "tf-xinfin-bucket" // This name need to be updated to be the same as local.s3BucketName. We can't use variable here. - key = "tf/terraform_devnet.tfstate" - region = "us-east-1" - encrypt = true - } -} - -data "aws_s3_object" "devnet_xdc_node_config" { - bucket = "tf-xinfin-bucket" - key = "node-config.json" -} diff --git a/cicd/devnet/terraform/variables.tf b/cicd/devnet/terraform/variables.tf deleted file mode 100644 index 12285d8ca76e..000000000000 --- a/cicd/devnet/terraform/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -variable docker_tag { - type = string - default = "latest" - description = "description" -} - -locals { - predefinedNodesConfig = jsondecode(data.aws_s3_object.devnet_xdc_node_config.body) - envs = { for tuple in regexall("(.*)=(.*)", file(".env")) : tuple[0] => tuple[1] } - logLevel = local.envs["log_level"] - - regions = [ - { - "name": "us-east-2", // Ohio - "start": local.envs["us_east_2_start"], - "end": local.envs["us_east_2_end"], - }, - { - "name": "eu-west-1", // Ireland - "start": local.envs["eu_west_1_start"], - "end": local.envs["eu_west_1_end"], - }, - { - "name": "ap-southeast-2", // Sydney - "start": local.envs["ap_southeast_2_start"], - "end": local.envs["ap_southeast_2_end"], - } - ] - - keyNames = { - for r in local.regions : - r.name => [for i in range(r.start, r.end+1) : "xdc${i}"] - } - - devnetNodeKeys = { - for r in local.regions : - r.name => { for i in local.keyNames[r.name]: i => local.predefinedNodesConfig[i] } - } -} From dd0fb11fa344136c8ec3df186f8334a5c9fceb31 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Mon, 30 Dec 2024 18:31:47 -0800 Subject: [PATCH 099/121] reduce gas limit for devnet to 50M (#785) Co-authored-by: liam.lai --- cicd/devnet/start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cicd/devnet/start.sh b/cicd/devnet/start.sh index 8e52b1c92380..19250b52fcde 100755 --- a/cicd/devnet/start.sh +++ b/cicd/devnet/start.sh @@ -86,7 +86,7 @@ XDC --ethstats ${netstats} --gcmode archive \ --http-port $rpc_port \ --http-api db,eth,debug,net,shh,txpool,personal,web3,XDPoS \ --http-vhosts "*" --unlock "${wallet}" --password /work/.pwd --mine \ ---miner-gasprice "1" --miner-gaslimit "420000000" --verbosity ${log_level} \ +--miner-gasprice "1" --miner-gaslimit "50000000" --verbosity ${log_level} \ --debugdatadir /work/xdcchain \ --store-reward \ --ws --ws-addr=0.0.0.0 --ws-port $ws_port \ From 44ac46f676c0c22967cdb088853dc389779f1a97 Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Wed, 26 Jun 2024 11:52:06 +0400 Subject: [PATCH 100/121] add local xdpos function add readme changes to support xdpos2 protocol from block 0 --- cicd/Dockerfile | 9 +- cicd/entry.sh | 2 +- cicd/local/README.md | 10 ++ cicd/local/start.sh | 83 +++++++++ cmd/puppeth/wizard_genesis.go | 12 +- common/constants/constants.go.local | 158 ++++++++++++++++++ consensus/XDPoS/engines/engine_v2/engine.go | 13 +- .../XDPoS/engines/engine_v2/epochSwitch.go | 20 +++ consensus/XDPoS/engines/engine_v2/snapshot.go | 4 + consensus/XDPoS/engines/engine_v2/timeout.go | 8 + consensus/XDPoS/engines/engine_v2/vote.go | 4 + eth/hooks/engine_v2_hooks.go | 9 + 12 files changed, 322 insertions(+), 10 deletions(-) create mode 100644 cicd/local/README.md create mode 100755 cicd/local/start.sh create mode 100644 common/constants/constants.go.local diff --git a/cicd/Dockerfile b/cicd/Dockerfile index 055492e548bd..c9f7de7cf6a2 100644 --- a/cicd/Dockerfile +++ b/cicd/Dockerfile @@ -5,11 +5,14 @@ RUN apk add make build-base linux-headers COPY . /builder RUN cd /builder && make && mv /builder/build/bin/XDC /builder/build/bin/XDC-mainnet +RUN mv /builder/common/constants/constants.go.testnet /builder/common/constants.go +RUN cd /builder && make && mv /builder/build/bin/XDC /builder/build/bin/XDC-testnet + RUN mv /builder/common/constants/constants.go.devnet /builder/common/constants.go RUN cd /builder && make && mv /builder/build/bin/XDC /builder/build/bin/XDC-devnet -RUN mv /builder/common/constants/constants.go.testnet /builder/common/constants.go -RUN cd /builder && make && mv /builder/build/bin/XDC /builder/build/bin/XDC-testnet +RUN mv /builder/common/constants/constants.go.local /builder/common/constants.go +RUN cd /builder && make && mv /builder/build/bin/XDC /builder/build/bin/XDC-local # The runtime image FROM alpine:3 @@ -18,11 +21,13 @@ WORKDIR /work RUN apk add --no-cache bash curl +COPY --from=builder /builder/build/bin/XDC-local /usr/bin COPY --from=builder /builder/build/bin/XDC-devnet /usr/bin COPY --from=builder /builder/build/bin/XDC-testnet /usr/bin COPY --from=builder /builder/build/bin/XDC-mainnet /usr/bin # # Copy over files +ADD cicd/local /work/local ADD cicd/devnet /work/devnet ADD cicd/testnet /work/testnet ADD cicd/mainnet /work/mainnet diff --git a/cicd/entry.sh b/cicd/entry.sh index 777bd58692e6..e7518fe9f603 100755 --- a/cicd/entry.sh +++ b/cicd/entry.sh @@ -1,7 +1,7 @@ #!/bin/bash if test -z "$NETWORK" then - echo "NETWORK env Must be set, mainnet/testnet/devnet" + echo "NETWORK env Must be set, mainnet/testnet/devnet/local" exit 1 fi diff --git a/cicd/local/README.md b/cicd/local/README.md new file mode 100644 index 000000000000..83d8dad0b179 --- /dev/null +++ b/cicd/local/README.md @@ -0,0 +1,10 @@ +To set up local xdpos you need pass env NETWORK=local and inject 2 files when starting the container +1. genesis.json - deploy to path "/work/genesis.json" in the container. + - Creating genesis.json using puppeth + 1. "make puppeth" from base repo directory + 2. run the binary (genesis wizard) "./build/bin/puppeth" + 3. the output genesis.json will be in your ~/.puppeth directory + +2. bootnodes.list - deploy to path "/work/bootnodes.list" in the container. + - check example bootnode format in cicd/devnet or cicd/testnet + - REQUIRES newline at the end of the file, or the last line won't read diff --git a/cicd/local/start.sh b/cicd/local/start.sh new file mode 100755 index 000000000000..cfd877de4066 --- /dev/null +++ b/cicd/local/start.sh @@ -0,0 +1,83 @@ +#!/bin/bash +if [ ! -d /work/xdcchain/XDC/chaindata ] +then + if test -z "$PRIVATE_KEY" + then + echo "PRIVATE_KEY environment variable has not been set." + exit 1 + fi + echo $PRIVATE_KEY >> /tmp/key + wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -F '[{}]' '{print $2}') + XDC --datadir /work/xdcchain init /work/genesis.json +else + wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -F '[{}]' '{print $2}') +fi + +input="/work/bootnodes.list" +bootnodes="" +while IFS= read -r line +do + if [ -z "${bootnodes}" ] + then + bootnodes=$line + else + bootnodes="${bootnodes},$line" + fi +done < "$input" + +log_level=3 +if test -z "$LOG_LEVEL" +then + echo "Log level not set, default to verbosity of $log_level" +else + echo "Log level found, set to $LOG_LEVEL" + log_level=$LOG_LEVEL +fi + +port=30303 +if test -z "$PORT" +then + echo "PORT not set, default to $port" +else + echo "PORT found, set to $PORT" + port=$PORT +fi + +rpc_port=8545 +if test -z "$RPC_PORT" +then + echo "RPC_PORT not set, default to $rpc_port" +else + echo "RPC_PORT found, set to $RPC_PORT" + rpc_port=$RPC_PORT +fi + +ws_port=8555 +if test -z "$WS_PORT" +then + echo "WS_PORT not set, default to $ws_port" +else + echo "WS_PORT found, set to $WS_PORT" + ws_port=$WS_PORT +fi + +netstats="${NODE_NAME}-${wallet}:xinfin_xdpos_hybrid_network_stats@devnetstats.apothem.network:2000" + + +echo "Running a node with wallet: ${wallet}" +echo "Starting nodes with $bootnodes ..." + +# Note: --gcmode=archive means node will store all historical data. This will lead to high memory usage. But sync mode require archive to sync +# https://github.com/XinFinOrg/XDPoSChain/issues/268 + +XDC --ethstats ${netstats} --gcmode archive \ +--bootnodes ${bootnodes} --syncmode full \ +--datadir /work/xdcchain --networkid 551 \ +-port $port --rpc --rpccorsdomain "*" --rpcaddr 0.0.0.0 \ +--rpcport $rpc_port \ +--rpcapi db,eth,debug,net,shh,txpool,personal,web3,XDPoS \ +--rpcvhosts "*" --unlock "${wallet}" --password /work/.pwd --mine \ +--gasprice "1" --targetgaslimit "420000000" --verbosity ${log_level} \ +--debugdatadir /work/xdcchain \ +--ws --wsaddr=0.0.0.0 --wsport $ws_port \ +--wsorigins "*" 2>&1 >>/work/xdcchain/xdc.log | tee -a /work/xdcchain/xdc.log diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index d7a8f93cec02..af52abc8e459 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -51,11 +51,11 @@ func (w *wizard) makeGenesis() { Difficulty: big.NewInt(524288), Alloc: make(core.GenesisAlloc), Config: ¶ms.ChainConfig{ - HomesteadBlock: big.NewInt(1), - EIP150Block: big.NewInt(2), - EIP155Block: big.NewInt(3), - EIP158Block: big.NewInt(3), - ByzantiumBlock: big.NewInt(4), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), }, } // Figure out which consensus engine to choose @@ -147,7 +147,7 @@ func (w *wizard) makeGenesis() { fmt.Println() fmt.Printf("Proportion of total masternodes v2 vote collection to generate a QC (float value), should be two thirds of masternodes? (default = %f)\n", 0.667) genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = w.readDefaultFloat(0.667) - + genesis.Config.XDPoS.V2.CurrentConfig.MaxMasternodes = 108 genesis.Config.XDPoS.V2.AllConfigs[0] = genesis.Config.XDPoS.V2.CurrentConfig fmt.Println() diff --git a/common/constants/constants.go.local b/common/constants/constants.go.local new file mode 100644 index 000000000000..6c5114313728 --- /dev/null +++ b/common/constants/constants.go.local @@ -0,0 +1,158 @@ +package common + +import ( + "math/big" +) + +const ( + RewardMasterPercent = 90 + RewardVoterPercent = 0 + RewardFoundationPercent = 10 + HexSignMethod = "e341eaa4" + HexSetSecret = "34d38600" + HexSetOpening = "e11f5ba2" + EpocBlockSecret = 800 + EpocBlockOpening = 850 + EpocBlockRandomize = 900 + MaxMasternodes = 18 + MaxMasternodesV2 = 108 // Last v1 masternodes + LimitPenaltyEpoch = 4 + LimitPenaltyEpochV2 = 0 + BlocksPerYearTest = uint64(200000) + BlocksPerYear = uint64(15768000) + LimitThresholdNonceInQueue = 10 + DefaultMinGasPrice = 250000000 + MergeSignRange = 15 + RangeReturnSigner = 150 + MinimunMinerBlockPerEpoch = 1 + + OneYear = uint64(365 * 86400) + LiquidateLendingTradeBlock = uint64(100) +) + +var Rewound = uint64(0) + +var TIP2019Block = big.NewInt(0) +var TIPSigning = big.NewInt(0) +var TIPRandomize = big.NewInt(0) + +var TIPV2SwitchBlock = big.NewInt(0) + +var TIPIncreaseMasternodes = big.NewInt(0) // Upgrade MN Count at Block. +var TIPNoHalvingMNReward = big.NewInt(0) // hardfork no halving masternodes reward +var BlackListHFNumber = uint64(0) +var TIPXDCX = big.NewInt(0) +var TIPXDCXLending = big.NewInt(0) +var TIPXDCXCancellationFee = big.NewInt(0) +var TIPXDCXCancellationFeeTestnet = big.NewInt(0) +var TIPXDCXMinerDisable = big.NewInt(0) +var TIPXDCXReceiverDisable = big.NewInt(0) +var BerlinBlock = big.NewInt(0) +var LondonBlock = big.NewInt(0) +var MergeBlock = big.NewInt(0) +var ShanghaiBlock = big.NewInt(0) +var Eip1559Block = big.NewInt(9999999999) + +var TIPXDCXTestnet = big.NewInt(0) +var IsTestnet bool = false +var Enable0xPrefix bool = true +var StoreRewardFolder string +var RollbackHash Hash +var BasePrice = big.NewInt(1000000000000000000) // 1 +var RelayerLockedFund = big.NewInt(20000) // 20000 XDC +var RelayerFee = big.NewInt(1000000000000000) // 0.001 +var XDCXBaseFee = big.NewInt(10000) // 1 / XDCXBaseFee +var RelayerCancelFee = big.NewInt(100000000000000) // 0.0001 +var XDCXBaseCancelFee = new(big.Int).Mul(XDCXBaseFee, big.NewInt(10)) // 1/ (XDCXBaseFee *10) +var RelayerLendingFee = big.NewInt(10000000000000000) // 0.01 +var RelayerLendingCancelFee = big.NewInt(1000000000000000) // 0.001 +var BaseLendingInterest = big.NewInt(100000000) // 1e8 + +var MinGasPrice = big.NewInt(DefaultMinGasPrice) +var RelayerRegistrationSMC = "0x16c63b79f9C8784168103C0b74E6A59EC2de4a02" +var RelayerRegistrationSMCTestnet = "0xA1996F69f47ba14Cb7f661010A7C31974277958c" +var LendingRegistrationSMC = "0x7d761afd7ff65a79e4173897594a194e3c506e57" +var LendingRegistrationSMCTestnet = "0x28d7fC2Cf5c18203aaCD7459EFC6Af0643C97bE8" +var TRC21IssuerSMCTestNet = HexToAddress("0x0E2C88753131CE01c7551B726b28BFD04e44003F") +var TRC21IssuerSMC = HexToAddress("0x8c0faeb5C6bEd2129b8674F262Fd45c4e9468bee") +var XDCXListingSMC = HexToAddress("0xDE34dD0f536170993E8CFF639DdFfCF1A85D3E53") +var XDCXListingSMCTestNet = HexToAddress("0x14B2Bf043b9c31827A472CE4F94294fE9a6277e0") +var TRC21GasPriceBefore = big.NewInt(2500) +var TRC21GasPrice = big.NewInt(250000000) +var RateTopUp = big.NewInt(90) // 90% +var BaseTopUp = big.NewInt(100) +var BaseRecall = big.NewInt(100) +var TIPTRC21Fee = big.NewInt(13523400) +var TIPTRC21FeeTestnet = big.NewInt(225000) +var BlockNumberGas50x = big.NewInt(11818181) +var LimitTimeFinality = uint64(30) // limit in 30 block + +var IgnoreSignerCheckBlockArray = map[uint64]bool{ + uint64(1032300): true, + uint64(1033200): true, + uint64(27307800): true, + uint64(28270800): true, +} +var Blacklist = map[Address]bool{ + HexToAddress("0x5248bfb72fd4f234e062d3e9bb76f08643004fcd"): true, + HexToAddress("0x5ac26105b35ea8935be382863a70281ec7a985e9"): true, + HexToAddress("0x09c4f991a41e7ca0645d7dfbfee160b55e562ea4"): true, + HexToAddress("0xb3157bbc5b401a45d6f60b106728bb82ebaa585b"): true, + HexToAddress("0x741277a8952128d5c2ffe0550f5001e4c8247674"): true, + HexToAddress("0x10ba49c1caa97d74b22b3e74493032b180cebe01"): true, + HexToAddress("0x07048d51d9e6179578a6e3b9ee28cdc183b865e4"): true, + HexToAddress("0x4b899001d73c7b4ec404a771d37d9be13b8983de"): true, + HexToAddress("0x85cb320a9007f26b7652c19a2a65db1da2d0016f"): true, + HexToAddress("0x06869dbd0e3a2ea37ddef832e20fa005c6f0ca39"): true, + HexToAddress("0x82e48bc7e2c93d89125428578fb405947764ad7c"): true, + HexToAddress("0x1f9a78534d61732367cbb43fc6c89266af67c989"): true, + HexToAddress("0x7c3b1fa91df55ff7af0cad9e0399384dc5c6641b"): true, + HexToAddress("0x5888dc1ceb0ff632713486b9418e59743af0fd20"): true, + HexToAddress("0xa512fa1c735fc3cc635624d591dd9ea1ce339ca5"): true, + HexToAddress("0x0832517654c7b7e36b1ef45d76de70326b09e2c7"): true, + HexToAddress("0xca14e3c4c78bafb60819a78ff6e6f0f709d2aea7"): true, + HexToAddress("0x652ce195a23035114849f7642b0e06647d13e57a"): true, + HexToAddress("0x29a79f00f16900999d61b6e171e44596af4fb5ae"): true, + HexToAddress("0xf9fd1c2b0af0d91b0b6754e55639e3f8478dd04a"): true, + HexToAddress("0xb835710c9901d5fe940ef1b99ed918902e293e35"): true, + HexToAddress("0x04dd29ce5c253377a9a3796103ea0d9a9e514153"): true, + HexToAddress("0x2b4b56846eaf05c1fd762b5e1ac802efd0ab871c"): true, + HexToAddress("0x1d1f909f6600b23ce05004f5500ab98564717996"): true, + HexToAddress("0x0dfdcebf80006dc9ab7aae8c216b51c6b6759e86"): true, + HexToAddress("0x2b373890a28e5e46197fbc04f303bbfdd344056f"): true, + HexToAddress("0xa8a3ef3dc5d8e36aee76f3671ec501ec31e28254"): true, + HexToAddress("0x4f3d18136fe2b5665c29bdaf74591fc6625ef427"): true, + HexToAddress("0x175d728b0e0f1facb5822a2e0c03bde93596e324"): true, + HexToAddress("0xd575c2611984fcd79513b80ab94f59dc5bab4916"): true, + HexToAddress("0x0579337873c97c4ba051310236ea847f5be41bc0"): true, + HexToAddress("0xed12a519cc15b286920fc15fd86106b3e6a16218"): true, + HexToAddress("0x492d26d852a0a0a2982bb40ec86fe394488c419e"): true, + HexToAddress("0xce5c7635d02dc4e1d6b46c256cae6323be294a32"): true, + HexToAddress("0x8b94db158b5e78a6c032c7e7c9423dec62c8b11c"): true, + HexToAddress("0x0e7c48c085b6b0aa7ca6e4cbcc8b9a92dc270eb4"): true, + HexToAddress("0x206e6508462033ef8425edc6c10789d241d49acb"): true, + HexToAddress("0x7710e7b7682f26cb5a1202e1cff094fbf7777758"): true, + HexToAddress("0xcb06f949313b46bbf53b8e6b2868a0c260ff9385"): true, + HexToAddress("0xf884e43533f61dc2997c0e19a6eff33481920c00"): true, + HexToAddress("0x8b635ef2e4c8fe21fc2bda027eb5f371d6aa2fc1"): true, + HexToAddress("0x10f01a27cf9b29d02ce53497312b96037357a361"): true, + HexToAddress("0x693dd49b0ed70f162d733cf20b6c43dc2a2b4d95"): true, + HexToAddress("0xe0bec72d1c2a7a7fb0532cdfac44ebab9f6f41ee"): true, + HexToAddress("0xc8793633a537938cb49cdbbffd45428f10e45b64"): true, + HexToAddress("0x0d07a6cbbe9fa5c4f154e5623bfe47fb4d857d8e"): true, + HexToAddress("0xd4080b289da95f70a586610c38268d8d4cf1e4c4"): true, + HexToAddress("0x8bcfb0caf41f0aa1b548cae76dcdd02e33866a1b"): true, + HexToAddress("0xabfef22b92366d3074676e77ea911ccaabfb64c1"): true, + HexToAddress("0xcc4df7a32faf3efba32c9688def5ccf9fefe443d"): true, + HexToAddress("0x7ec1e48a582475f5f2b7448a86c4ea7a26ea36f8"): true, + HexToAddress("0xe3de67289080f63b0c2612844256a25bb99ac0ad"): true, + HexToAddress("0x3ba623300cf9e48729039b3c9e0dee9b785d636e"): true, + HexToAddress("0x402f2cfc9c8942f5e7a12c70c625d07a5d52fe29"): true, + HexToAddress("0xd62358d42afbde095a4ca868581d85f9adcc3d61"): true, + HexToAddress("0x3969f86acb733526cd61e3c6e3b4660589f32bc6"): true, + HexToAddress("0x67615413d7cdadb2c435a946aec713a9a9794d39"): true, + HexToAddress("0xfe685f43acc62f92ab01a8da80d76455d39d3cb3"): true, + HexToAddress("0x3538a544021c07869c16b764424c5987409cba48"): true, + HexToAddress("0xe187cf86c2274b1f16e8225a7da9a75aba4f1f5f"): true, + HexToAddress("0x0000000000000000000000000000000000000011"): true, +} diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index bcbf4651cb9f..298b18114388 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -191,7 +191,10 @@ func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) er Signatures: nil, GapNumber: header.Number.Uint64() - x.config.Gap, } - + // prevent overflow + if header.Number.Uint64() < x.config.Gap { + quorumCert.GapNumber = 0 + } // can not call processQC because round is equal to default x.currentRound = 1 x.highestQuorumCert = quorumCert @@ -210,6 +213,10 @@ func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) er // Initial first v2 snapshot lastGapNum := x.config.V2.SwitchBlock.Uint64() - x.config.Gap + // prevent overflow + if x.config.V2.SwitchBlock.Uint64() < x.config.Gap { + lastGapNum = 0 + } lastGapHeader := chain.GetHeaderByNumber(lastGapNum) snap, _ := loadSnapshot(x.db, lastGapHeader.Hash()) @@ -846,6 +853,10 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert * } epochSwitchNumber := epochInfo.EpochSwitchBlockInfo.Number.Uint64() gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch - x.config.Gap + // prevent overflow + if epochSwitchNumber-epochSwitchNumber%x.config.Epoch < x.config.Gap { + gapNumber = 0 + } if gapNumber != quorumCert.GapNumber { log.Error("[verifyQC] QC gap number mismatch", "epochSwitchNumber", epochSwitchNumber, "BlockNum", quorumCert.ProposedBlockInfo.Number, "BlockInfoHash", quorumCert.ProposedBlockInfo.Hash, "Gap", quorumCert.GapNumber, "GapShouldBe", gapNumber) return fmt.Errorf("gap number mismatch QC Gap %d, shouldBe %d", quorumCert.GapNumber, gapNumber) diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index 9928b88fb25a..5f9892e985ed 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -49,6 +49,26 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types } if isEpochSwitch { log.Debug("[getEpochSwitchInfo] header is epoch switch", "hash", hash.Hex(), "number", h.Number.Uint64()) + if h.Number.Uint64() == 0 { + log.Warn("[getEpochSwitchInfo] block 0, init epoch differently") + // handle genesis block differently as follows + masternodes := common.ExtractAddressFromBytes(h.Extra[32 : len(h.Extra)-65]) + penalties := []common.Address{} + standbynodes := []common.Address{} + epochSwitchInfo := &types.EpochSwitchInfo{ + Penalties: penalties, + Standbynodes: standbynodes, + Masternodes: masternodes, + MasternodesLen: len(masternodes), + EpochSwitchBlockInfo: &types.BlockInfo{ + Hash: hash, + Number: h.Number, + Round: 0, + }, + } + x.epochSwitches.Add(hash, epochSwitchInfo) + return epochSwitchInfo, nil + } quorumCert, round, masternodes, err := x.getExtraFields(h) if err != nil { log.Error("[getEpochSwitchInfo] get extra field", "err", err, "number", h.Number.Uint64()) diff --git a/consensus/XDPoS/engines/engine_v2/snapshot.go b/consensus/XDPoS/engines/engine_v2/snapshot.go index de4fb76d82bf..f0ce71a2d434 100644 --- a/consensus/XDPoS/engines/engine_v2/snapshot.go +++ b/consensus/XDPoS/engines/engine_v2/snapshot.go @@ -78,6 +78,10 @@ func (x *XDPoS_v2) getSnapshot(chain consensus.ChainReader, number uint64, isGap gapBlockNum = number } else { gapBlockNum = number - number%x.config.Epoch - x.config.Gap + //prevent overflow + if number-number%x.config.Epoch < x.config.Gap { + gapBlockNum = 0 + } } gapBlockHash := chain.GetHeaderByNumber(gapBlockNum).Hash() diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index 169e1db7bab0..ff689f45ef0c 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -231,6 +231,10 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error { // Notice this +1 is because we expect a block whos is the child of currentHeader currentNumber := currentBlockHeader.Number.Uint64() + 1 gapNumber = currentNumber - currentNumber%x.config.Epoch - x.config.Gap + // prevent overflow + if currentNumber-currentNumber%x.config.Epoch < x.config.Gap { + gapNumber = 0 + } log.Debug("[sendTimeout] is epoch switch when sending out timeout message", "currentNumber", currentNumber, "gapNumber", gapNumber) } else { epochSwitchInfo, err := x.getEpochSwitchInfo(chain, currentBlockHeader, currentBlockHeader.Hash()) @@ -239,6 +243,10 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error { return err } gapNumber = epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() - epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()%x.config.Epoch - x.config.Gap + // prevent overflow + if epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()-epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()%x.config.Epoch < x.config.Gap { + gapNumber = 0 + } log.Debug("[sendTimeout] non-epoch-switch block found its epoch block and calculated the gapNumber", "epochSwitchInfo.EpochSwitchBlockInfo.Number", epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64(), "gapNumber", gapNumber) } diff --git a/consensus/XDPoS/engines/engine_v2/vote.go b/consensus/XDPoS/engines/engine_v2/vote.go index f31e95c86284..675b0ca2c9ae 100644 --- a/consensus/XDPoS/engines/engine_v2/vote.go +++ b/consensus/XDPoS/engines/engine_v2/vote.go @@ -30,6 +30,10 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *types. } epochSwitchNumber := epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch - x.config.Gap + // prevent overflow + if epochSwitchNumber-epochSwitchNumber%x.config.Epoch < x.config.Gap { + gapNumber = 0 + } signedHash, err := x.signSignature(types.VoteSigHash(&types.VoteForSign{ ProposedBlockInfo: blockInfo, GapNumber: gapNumber, diff --git a/eth/hooks/engine_v2_hooks.go b/eth/hooks/engine_v2_hooks.go index bd5b0ffdd1df..e549802a100e 100644 --- a/eth/hooks/engine_v2_hooks.go +++ b/eth/hooks/engine_v2_hooks.go @@ -222,6 +222,11 @@ func GetSigningTxCount(c *XDPoS.XDPoS, chain consensus.ChainReader, header *type signers := make(map[common.Address]*contracts.RewardLog) mapBlkHash := map[uint64]common.Hash{} + // prevent overflow + if number == 0 { + return signers, nil + } + data := make(map[common.Hash][]common.Address) epochCount := 0 var masternodes []common.Address @@ -256,6 +261,10 @@ func GetSigningTxCount(c *XDPoS.XDPoS, chain consensus.ChainReader, header *type from := *tx.From() data[blkHash] = append(data[blkHash], from) } + // prevent overflow + if i == 0 { + return signers, nil + } } for i := startBlockNumber; i <= endBlockNumber; i++ { From 4859d5e7db63aeac6a3e18aa1f0d505d0ae18e70 Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Wed, 18 Dec 2024 14:36:23 +0700 Subject: [PATCH 101/121] new constants and genesis.json --- cicd/devnet/bootnodes.list | 4 +- cicd/devnet/genesis.json | 273 +++++++++++++++++++++------ cicd/entry.sh | 2 +- common/constants/constants.go.devnet | 36 ++-- 4 files changed, 232 insertions(+), 83 deletions(-) diff --git a/cicd/devnet/bootnodes.list b/cicd/devnet/bootnodes.list index 618052572b94..edffbabcf4a3 100644 --- a/cicd/devnet/bootnodes.list +++ b/cicd/devnet/bootnodes.list @@ -1,2 +1,2 @@ -enode://00d49d72a48164681906ad61924568da0d3049937efdbaed0b7533e34a99f55814f1839d909cdc82f78e04a36ac04737d80b41b22905c7d6cac3c80bb5cdbbc4@66.94.98.186:30301 -enode://d6793b02a478f13ed6d01c30778935f6f8f7461a75aebedcb310def4ed9b066f995a0dca046d0c7ea7f5ffdd8e3f1f53c6b6dce909d1693650504921aad62f1a@194.163.167.177:30301 +enode://c7a38ecc7fd5849eaefb3e928f882ab2f1260d5591bd1fef1db39c8ae0d9fe21d86e2d4efee6def0f4f16d0b6103f86f92f7e910295b849266fef83f05768596@10.244.1.77:30301 +enode://9160713d41656154ce3fdaa9d0f9799dd8546652b1784edecf82ce7a5b54a977f897ea617a9b3b4db513dc6b0dc98c1c3ad8a1914075ab87ded4e367c89dcd3b@10.244.2.53:30301 diff --git a/cicd/devnet/genesis.json b/cicd/devnet/genesis.json index 4ea005d6ea7e..b92159f33089 100644 --- a/cicd/devnet/genesis.json +++ b/cicd/devnet/genesis.json @@ -1,24 +1,47 @@ { "config": { "chainId": 551, - "homesteadBlock": 1, - "eip150Block": 2, + "homesteadBlock": 0, + "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 3, - "eip158Block": 3, - "byzantiumBlock": 4, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, "XDPoS": { "period": 2, "epoch": 900, - "reward": 5000, + "reward": 10, "rewardCheckpoint": 900, "gap": 450, - "foudationWalletAddr": "0x746249c61f5832c5eed53172776b460491bdcd5c" + "foudationWalletAddr": "0xde5b54e8e7b585153add32f472e8d545e5d42a82", + "SkipV1Validation": false, + "v2": { + "switchBlock": 0, + "config": { + "maxMasternodes": 108, + "switchRound": 0, + "minePeriod": 2, + "timeoutSyncThreshold": 3, + "timeoutPeriod": 10, + "certificateThreshold": 0.667 + }, + "allConfigs": { + "0": { + "maxMasternodes": 108, + "switchRound": 0, + "minePeriod": 2, + "timeoutSyncThreshold": 3, + "timeoutPeriod": 10, + "certificateThreshold": 0.667 + } + }, + "SkipV2Validation": false + } } }, "nonce": "0x0", - "timestamp": "0x60c1b36a", - "extraData": "0x000000000000000000000000000000000000000000000000000000000000000037224936d88724f1de8686e52071d515b1af0eab52e78df27ca83be8716a77882da63a8dac227dac888c073313b36cf03cf1f739f39443551ff12bbe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x6771d3f2", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000311bdf9066246e68559816e7f636435867f824ef442a44a6fc20f5b8dfa8b304d7137581f7e6bef347318441696e9ae962633c16e04d53935272639d537fc89618edae86950e12687a612e15c4786b8473898cc3c5beca5841306b26fdb4e30411392a6a74826141342a4dc33a1045cefa4182b6212ec0317bc30fbeb7208192d1474b5f87ffbc056de43c11888c073313b36cf03cf1f739f39443551ff12bbe8d993351c0e2db739f9bcbfdeda94d73b50b16d3a242960b7ca1937e826bda6c397df74d9f9ab01aa89af636787499e81362e815e36f28763eac120babebf5a6cbe6113780cbe489e3eb0db882381aebaf81190100d82f41ad2c95898195c7a47dc59115bb5ec85408683795da2f604a5c0464868eabfcb6da489a1b4304f49aafaec938c7adc48539470624e1f9c75ce33e568d8fa3ace90497ee0c60dc921eefea93e384a6ccaaf28e33790a2d1b2625bf964dfc087e2622b02b0bb78713e872c02796ef64c8f10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x47b760", "difficulty": "0x1", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -30,43 +53,151 @@ "0000000000000000000000000000000000000001": { "balance": "0x0" }, + "0000000000000000000000000000000000000068": { + "balance": "0xd3c21bcecceda10000000" + }, "0000000000000000000000000000000000000088": { "code": "0x606060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063012679511461019b578063025e7c27146101c957806302aa9be21461022c57806306a49fce1461026e5780630db02622146102d85780630e3e4fb81461030157806315febd68146103715780632a3640b1146103a85780632d15cc041461042a5780632f9c4bba146104b8578063302b687214610522578063326586521461058e5780633477ee2e14610640578063441a3e70146106a357806358e7525f146106cf5780635b860d271461071c5780635b9cd8cc146107695780636dd7d8ea1461082457806372e44a3814610852578063a9a981a31461089f578063a9ff959e146108c8578063ae6e43f5146108f1578063b642facd1461092a578063c45607df146109a3578063d09f1ab4146109f0578063d161c76714610a19578063d51b9e9314610a42578063d55b7dff14610a93578063ef18374a14610abc578063f2ee3c7d14610ae5578063f5c9512514610b1e578063f8ac9dd514610b4c575b600080fd5b6101c7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b75565b005b34156101d457600080fd5b6101ea60048080359060200190919050506111fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561023757600080fd5b61026c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061123b565b005b341561027957600080fd5b610281611796565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102c45780820151818401526020810190506102a9565b505050509050019250505060405180910390f35b34156102e357600080fd5b6102eb61182a565b6040518082815260200191505060405180910390f35b341561030c57600080fd5b610357600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611830565b604051808215151515815260200191505060405180910390f35b341561037c57600080fd5b610392600480803590602001909190505061185f565b6040518082815260200191505060405180910390f35b34156103b357600080fd5b6103e8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506118bb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561043557600080fd5b610461600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611909565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156104a4578082015181840152602081019050610489565b505050509050019250505060405180910390f35b34156104c357600080fd5b6104cb6119dc565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561050e5780820151818401526020810190506104f3565b505050509050019250505060405180910390f35b341561052d57600080fd5b610578600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611a79565b6040518082815260200191505060405180910390f35b341561059957600080fd5b6105c5600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611b03565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156106055780820151818401526020810190506105ea565b50505050905090810190601f1680156106325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561064b57600080fd5b6106616004808035906020019091905050611da2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156106ae57600080fd5b6106cd6004808035906020019091908035906020019091905050611de1565b005b34156106da57600080fd5b610706600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061208d565b6040518082815260200191505060405180910390f35b341561072757600080fd5b610753600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506120d9565b6040518082815260200191505060405180910390f35b341561077457600080fd5b6107a9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506121a1565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156107e95780820151818401526020810190506107ce565b50505050905090810190601f1680156108165780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610850600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061226a565b005b341561085d57600080fd5b610889600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612653565b6040518082815260200191505060405180910390f35b34156108aa57600080fd5b6108b261266b565b6040518082815260200191505060405180910390f35b34156108d357600080fd5b6108db612671565b6040518082815260200191505060405180910390f35b34156108fc57600080fd5b610928600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612677565b005b341561093557600080fd5b610961600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612c36565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156109ae57600080fd5b6109da600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612ca2565b6040518082815260200191505060405180910390f35b34156109fb57600080fd5b610a03612cee565b6040518082815260200191505060405180910390f35b3415610a2457600080fd5b610a2c612cf4565b6040518082815260200191505060405180910390f35b3415610a4d57600080fd5b610a79600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612cfa565b604051808215151515815260200191505060405180910390f35b3415610a9e57600080fd5b610aa6612d53565b6040518082815260200191505060405180910390f35b3415610ac757600080fd5b610acf612d59565b6040518082815260200191505060405180910390f35b3415610af057600080fd5b610b1c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612d63565b005b3415610b2957600080fd5b610b4a600480803590602001908201803590602001919091929050506134f1565b005b3415610b5757600080fd5b610b5f6135f0565b6040518082815260200191505060405180910390f35b6000600b543410151515610b8857600080fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050141580610c1c57506000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050115b1515610c2757600080fd5b81600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff16151515610c8457600080fd5b610cd934600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546135f690919063ffffffff16565b915060088054806001018281610cef919061362d565b9160005260206000209001600085909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506060604051908101604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160011515815260200183815250600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160010155905050610eb834600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546135f690919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f5160016009546135f690919063ffffffff16565b6009819055506000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905014156110185760078054806001018281610fb6919061362d565b9160005260206000209001600033909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600a600081548092919060010191905055505b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806001018281611069919061362d565b9160005260206000209001600085909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806001018281611109919061362d565b9160005260206000209001600033909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550507f7635f1d87b47fba9f2b09e56eb4be75cca030e0cb179c1602ac9261d39a8f5c1338434604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b60078181548110151561120b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000828280600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156112cd57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561140657600b546113f882600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461361490919063ffffffff16565b1015151561140557600080fd5b5b61145b84600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015461361490919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555061153384600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461361490919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506115cb43600f546135f690919063ffffffff16565b9250611632846000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000016000868152602001908152602001600020546135f690919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000016000858152602001908152602001600020819055506000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010180548060010182816116db9190613659565b9160005260206000209001600085909190915055507faa0e554f781c3c3b2be110a0557f260f11af9a8aa2c64bc1e7a31dbb21e32fa2338686604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a15050505050565b61179e613685565b600880548060200260200160405190810160405280929190818152602001828054801561182057602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116117d6575b5050505050905090565b600a5481565b60056020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000016000838152602001908152602001600020549050919050565b6006602052816000526040600020818154811015156118d657fe5b90600052602060002090016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611911613685565b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156119d057602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611986575b50505050509050919050565b6119e4613699565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101805480602002602001604051908101604052809291908181526020018280548015611a6f57602002820191906000526020600020905b815481526020019060010190808311611a5b575b5050505050905090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b611b0b6136ad565b611b1482612cfa565b15611c655760036000611b2684612c36565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600160036000611b6f86612c36565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905003815481101515611bba57fe5b90600052602060002090018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c595780601f10611c2e57610100808354040283529160200191611c59565b820191906000526020600020905b815481529060010190602001808311611c3c57829003601f168201915b50505050509050611d9d565b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905003815481101515611cf657fe5b90600052602060002090018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d955780601f10611d6a57610100808354040283529160200191611d95565b820191906000526020600020905b815481529060010190602001808311611d7857829003601f168201915b505050505090505b919050565b600881815481101515611db157fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282600082111515611df457600080fd5b814310151515611e0357600080fd5b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600084815260200190815260200160002054111515611e6457600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010182815481101515611eb357fe5b906000526020600020900154141515611ecb57600080fd5b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008681526020019081526020016000205492506000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000016000868152602001908152602001600020600090556000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010184815481101515611fc457fe5b9060005260206000209001600090553373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050151561201357600080fd5b7ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568338685604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a15050505050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050919050565b60008082600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff16151561213857600080fd5b61214184612c36565b915061214b612d59565b6064600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540281151561219757fe5b0492505050919050565b6003602052816000526040600020818154811015156121bc57fe5b9060005260206000209001600091509150508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156122625780601f1061223757610100808354040283529160200191612262565b820191906000526020600020905b81548152906001019060200180831161224557829003601f168201915b505050505081565b600c54341015151561227b57600080fd5b80600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff1615156122d757600080fd5b61232c34600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546135f690919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561249b57600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480600101828161244b919061362d565b9160005260206000209001600033909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b61252d34600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546135f690919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f66a9138482c99e9baf08860110ef332cc0c23b4a199a53593d8db0fc8f96fbfc338334604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a15050565b60046020528060005260406000206000915090505481565b60095481565b600f5481565b6000806000833373ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561271957600080fd5b84600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff16151561277557600080fd5b6000600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548160ff0219169083151502179055506127e6600160095461361490919063ffffffff16565b600981905550600094505b6008805490508510156128bb578573ffffffffffffffffffffffffffffffffffffffff1660088681548110151561282457fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156128ae5760088581548110151561287b57fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556128bb565b84806001019550506127f1565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054935061299284600160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015461361490919063ffffffff16565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612a7243600e546135f690919063ffffffff16565b9250612ad9846000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000016000868152602001908152602001600020546135f690919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000016000858152602001908152602001600020819055506000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018054806001018281612b829190613659565b9160005260206000209001600085909190915055507f4edf3e325d0063213a39f9085522994a1c44bea5f39e7d63ef61260a1e58c6d33387604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1505050505050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b600d5481565b600e5481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff169050919050565b600b5481565b6000600a54905090565b600080612d6e613685565b600080600033600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff161515612dcf57600080fd5b87600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff161515612e2b57600080fd5b612e3433612c36565b9750612e3f89612c36565b9650600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515612ed757600080fd5b6001600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550604b612fc4612d59565b6064600460008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540281151561301057fe5b041015156134e65760016008805490500360405180591061302e5750595b9080825280602002602001820160405250955060009450600093505b600880549050841015613357578673ffffffffffffffffffffffffffffffffffffffff166130b160088681548110151561308057fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612c36565b73ffffffffffffffffffffffffffffffffffffffff16141561334a576130e3600160095461361490919063ffffffff16565b6009819055506008848154811015156130f857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868680600101975081518110151561313857fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060088481548110151561318357fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600160006008868154811015156131c457fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549060ff021916905560018201600090555050600360008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006132bb91906136c1565b600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061330691906136e2565b600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600090555b838060010194505061304a565b600092505b600780549050831015613439578673ffffffffffffffffffffffffffffffffffffffff1660078481548110151561338f57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561342c576007838154811015156133e657fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600a6000815480929190600190039190505550613439565b828060010193505061335c565b7fe18d61a5bf4aa2ab40afc88aa9039d27ae17ff4ec1c65f5f414df6f02ce8b35e8787604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156134d15780820151818401526020810190506134b6565b50505050905001935050505060405180910390a15b505050505050505050565b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060010182816135429190613703565b91600052602060002090016000848490919290919250919061356592919061372f565b50507f949360d814b28a3b393a68909efe1fee120ee09cac30f360a0f80ab5415a611a338383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437820191505094505050505060405180910390a15050565b600c5481565b600080828401905083811015151561360a57fe5b8091505092915050565b600082821115151561362257fe5b818303905092915050565b8154818355818115116136545781836000526020600020918201910161365391906137af565b5b505050565b8154818355818115116136805781836000526020600020918201910161367f91906137af565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b50805460008255906000526020600020908101906136df91906137d4565b50565b508054600082559060005260206000209081019061370091906137af565b50565b81548183558181151161372a5781836000526020600020918201910161372991906137d4565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061377057803560ff191683800117855561379e565b8280016001018555821561379e579182015b8281111561379d578235825591602001919060010190613782565b5b5090506137ab91906137af565b5090565b6137d191905b808211156137cd5760008160009055506001016137b5565b5090565b90565b6137fd91905b808211156137f957600081816137f09190613800565b506001016137da565b5090565b90565b50805460018160011615610100020316600290046000825580601f106138265750613845565b601f01602090049060005260206000209081019061384491906137af565b5b505600a165627a7a72305820f5bbb127b52ce86c873faef85cff176563476a5e49a3d88eaa9a06a8f432c9080029", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000009": "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000012", + "0x0000000000000000000000000000000000000000000000000000000000000009": "0x0000000000000000000000000000000000000000000000000000000000000012", "0x000000000000000000000000000000000000000000000000000000000000000a": "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000000000000000000000000000000000000000000b": "0x000000000000000000000000000000000000000000084595161401484a000000", "0x000000000000000000000000000000000000000000000000000000000000000c": "0x00000000000000000000000000000000000000000000054b40b1f852bda00000", "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000000012", "0x000000000000000000000000000000000000000000000000000000000000000e": "0x000000000000000000000000000000000000000000000000000000000013c680", "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000000069780", - "0x0cca6b5183395dc86a20cb86687ed86453de376e4e17bed8966e42a889c8725d": "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x334b7f9d5f3d799751f76e65d323e6c91276efb6e64b0446a088d2fcf516b440": "0x000000000000000000000000000000000000000000084595161401484a000000", - "0x3657f70c5cac69bc1db087212204978b5e36fb39f142fc384dfbf897f13145e3": "0x000000000000000000000000a12a44433e64b76a9e388d87af02ce80580cf1f8", - "0x395dbd86e0de75e9c4a1fb35427f914ce460476379d076bd1b537fb4a716bab0": "0x000000000000000000000000000000000000000000084595161401484a000000", - "0x555ff3aa35f12513cb7de85980072f5394cf6321406b8b9b091f8a2974b83943": "0x00000000000000000000000037224936d88724f1de8686e52071d515b1af0eab", - "0x555ff3aa35f12513cb7de85980072f5394cf6321406b8b9b091f8a2974b83944": "0x00000000000000000000000052e78df27ca83be8716a77882da63a8dac227dac", - "0x555ff3aa35f12513cb7de85980072f5394cf6321406b8b9b091f8a2974b83945": "0x000000000000000000000000888c073313b36cf03cf1f739f39443551ff12bbe", - "0x6723efa5b718fd93a9c3fe445b0ce1acaeb21b7b0687a7a4586def1f3c294770": "0x000000000000000000000000000000000000000000084595161401484a000000", - "0x832066899179d47432d68c70d433422b9ba89f4037ef6cf4bc0b29aac1db8ae5": "0x000000000000000000000001a12a44433e64b76a9e388d87af02ce80580cf1f8", - "0x832066899179d47432d68c70d433422b9ba89f4037ef6cf4bc0b29aac1db8ae6": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x030c4482e31df0bec3a61ba9044822c841d3be0a21a4a43d22ffabb19a238030": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x03857c1c3036c8068aecc274ccdef26c09d6bc8d7323c3b0af04944281aea3c5": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x04606a03b4103377c3cc40f7d070c9672b8c34f833337c95acd6cc3b9ef873be": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x04606a03b4103377c3cc40f7d070c9672b8c34f833337c95acd6cc3b9ef873bf": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0x0f0a4bf138332e4dee2840995f18ef3f4e7ce9800a43298cd303f652f37e2760": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x0f77b98b641f695810840536460aceac3aa93db4b69360cb1e825fc50a01cbf8": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x125b08b20a070fdff51220f22ab5783fe8553385c29d73595065987e274ae2ba": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x125b08b20a070fdff51220f22ab5783fe8553385c29d73595065987e274ae2bb": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0x141b2f299c67c202a3f56d8c761ef8412df00a99dc4d7df7132fea8b618710fb": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x15e82e9588701aace370d9b0ae88a15878117328c72679be3a43f1fde5480b52": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x19474e4e22de9b7e74a0e935e50e07474f1922fca9ca508d627a1753b89a04c0": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x1a53676945466c0303c4763ecd9fe35b640c62214817fc1cd445cd2df311d75e": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x1acfc824f6e62266e1ddfd5296eb428cb6235e11eb419042440ee2cd234f5064": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x206df8c61c26c41c2f5d8628f9b0af634f51cea5204c2860beac8743b789d8f9": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x213528a16906ba2c7ae2d13a88332596a8f7dba04445edce4dd35851adc6270b": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x217e08ed8a88d1aa61780ebbfa2433d8ee93fe281a28caa61609ffd7feb6ff48": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x217e08ed8a88d1aa61780ebbfa2433d8ee93fe281a28caa61609ffd7feb6ff49": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0x2bbcd29309cdf0c2e0fb87eb0912eda2715ff0d0800356af3b13b1877fc96294": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x2ea8dbac375e20907f0f6064477fb65f425b25387bc4af4a9fa0d909542ad6ec": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x2f46cce9be56b195a997053b94333e3e8608e77a9049008a7867ece9434d7490": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x32f30f989a9121096e27b0ceff2143dfd8ad0a279e39b2dbdd4720d758b1235e": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x334998a4166b71bbee90c9a5395d45b437458344b336983ce195ac15c4cabf41": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x37bbbe931ce8669c7360584cc0c8719480098d88b382fa5147ab6070f6a995e9": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x383c8c93b8864dd3dd80dcce451bff3ccecfe0ef316daeffc3429e8c734ca219": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x424c760de55550140740213338215fb5e72732d77ff28c6fcdce25cc0da4b4df": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x42b4293dae5548c9e2c405a2d603c1b7c254591f10e1a19d475c9573a806ddbf": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x4315dd31061c8b8e85c5b7d9df3c6dda7f6e48ad32c7bd25549115df18f68eb7": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x433573bf8c109958dcd2a79e075574b3fa76ee1309194d6985ec9eb993cfc4a8": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x433573bf8c109958dcd2a79e075574b3fa76ee1309194d6985ec9eb993cfc4a9": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0x471f33d3408681a476d422388b3e426fc8fd1f4db2b3cf07127fc0430da13d5a": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x48ddfeab6816c7d8ea504eaceba35584eed68f73e8bca46561c49f828945d870": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x4bcc08cdec386d590e3c1b686244142bf6e504749f55207aea8cba6292b4a05c": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930991": "0x000000000000000000000000311bdf9066246e68559816e7f636435867f824ef", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930992": "0x000000000000000000000000442a44a6fc20f5b8dfa8b304d7137581f7e6bef3", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930993": "0x00000000000000000000000047318441696e9ae962633c16e04d53935272639d", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930994": "0x000000000000000000000000537fc89618edae86950e12687a612e15c4786b84", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930995": "0x00000000000000000000000073898cc3c5beca5841306b26fdb4e30411392a6a", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930996": "0x00000000000000000000000074826141342a4dc33a1045cefa4182b6212ec031", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930997": "0x0000000000000000000000007bc30fbeb7208192d1474b5f87ffbc056de43c11", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930998": "0x000000000000000000000000888c073313b36cf03cf1f739f39443551ff12bbe", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab930999": "0x0000000000000000000000008d993351c0e2db739f9bcbfdeda94d73b50b16d3", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab93099a": "0x000000000000000000000000a242960b7ca1937e826bda6c397df74d9f9ab01a", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab93099b": "0x000000000000000000000000a89af636787499e81362e815e36f28763eac120b", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab93099c": "0x000000000000000000000000abebf5a6cbe6113780cbe489e3eb0db882381aeb", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab93099d": "0x000000000000000000000000af81190100d82f41ad2c95898195c7a47dc59115", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab93099e": "0x000000000000000000000000bb5ec85408683795da2f604a5c0464868eabfcb6", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab93099f": "0x000000000000000000000000da489a1b4304f49aafaec938c7adc48539470624", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab9309a0": "0x000000000000000000000000e1f9c75ce33e568d8fa3ace90497ee0c60dc921e", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab9309a1": "0x000000000000000000000000efea93e384a6ccaaf28e33790a2d1b2625bf964d", + "0x4d08b2b0194071b50be4200cf623b02a2489a2090e82dca38562a22eab9309a2": "0x000000000000000000000000fc087e2622b02b0bb78713e872c02796ef64c8f1", + "0x4df12e1188de9c93b847240eddba997020037c5f8010088c71c6f497ea6865ab": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x5479b436a6706e20dbebc992f8b75e09f5ef33b9bfc92f6eb52af893bc9f3ef5": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x5a72b959cac93391bff267c6c91f4da4895e3f8769bb512241703807da099182": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x6528b6895a372dd9abf5c9b1e2d763877056e06dcadeefb947482c05a58f1a46": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x6528b6895a372dd9abf5c9b1e2d763877056e06dcadeefb947482c05a58f1a47": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0x690ae50193386ef0c1f3aecb62d156ec48e51576b8faca760d2e782148d2685a": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x69dc30401af3a46fb5caf938fefd3bb163e08eed5018359c7ce99b0a6ac5bcad": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x6f24e27f6bf706ecff22e1cc7232c2b995103d66093d2976eeaa6ced126c7cf3": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x724b5bbb48fc97209628eb6b34adb8dd3cd583180ac721afdf706c4c57bbc253": "0x0000000000000000000000000000000000000000000000000000000000000012", + "0x76dfe65765497bb6461c122d3715541832ddc6bed4af9859d0afcafd98e85d3d": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x78131ffee5eb0b7466641acad70a5e37f247a658acd6910a0e0159013272500f": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x78131ffee5eb0b7466641acad70a5e37f247a658acd6910a0e01590132725010": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0x7860877d0fdf5b8349b69cf151013101002a515fc77b7d9ac9deea724189b49d": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x78f000d26dc5cb7bb6625ad3bbdeb559c2237595558ca062c170e72b826dcaa8": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0x7c5e55320fbb9389307827678ad755ae9bbff14bc2f0b7311e273ea6f816b5e6": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x850302252de9a45ae306fefaef8c0b466423440d4916233feb535a91f5c13884": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x850302252de9a45ae306fefaef8c0b466423440d4916233feb535a91f5c13885": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0x8f6c89a2950c399a6bd26ec8e4f8342cef555205270052553492ac8caab48637": "0x0000000000000000000000000000000000000000000000000000000000000001", "0x92174186dda351528a078fccba50a5ff5332041fd6f861d5ba9f30d9e7416b01": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x9d721527fb4f716033fd64eb5c53e9ebfdcbded3e02421855e691c06bc3d0cda": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688": "0x000000000000000000000000a12a44433e64b76a9e388d87af02ce80580cf1f8", - "0xadf2e2b096791f125211938ba4199c02152b91d8761229ae36342002e463de86": "0x000000000000000000000001a12a44433e64b76a9e388d87af02ce80580cf1f8", - "0xadf2e2b096791f125211938ba4199c02152b91d8761229ae36342002e463de87": "0x000000000000000000000000000000000000000000084595161401484a000000", - "0xbe5c577780cc5cb207d59bca6035e982dd13627ef17edb6a67300e707c7ab194": "0x000000000000000000000001a12a44433e64b76a9e388d87af02ce80580cf1f8", - "0xbe5c577780cc5cb207d59bca6035e982dd13627ef17edb6a67300e707c7ab195": "0x000000000000000000000000000000000000000000084595161401484a000000", - "0xd6e5468fdf7c0709dc80d32848fc6c62d31a193138d0962e6edc92694d422212": "0x000000000000000000000000a12a44433e64b76a9e388d87af02ce80580cf1f8", - "0xdbb72142c0e7c59d0ee1992f539a9bc4a22703f549c839728ce22c2c8ee01113": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xe810e986b7d9bc3e7cd3c6ce464ba1fc6c80bec03a51e6e041228d5df84e0121": "0x000000000000000000000000a12a44433e64b76a9e388d87af02ce80580cf1f8", - "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3": "0x00000000000000000000000037224936d88724f1de8686e52071d515b1af0eab", - "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee4": "0x00000000000000000000000052e78df27ca83be8716a77882da63a8dac227dac", - "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee5": "0x000000000000000000000000888c073313b36cf03cf1f739f39443551ff12bbe" + "0x927695b4feff242034e5b416f50ee8f8804c7c79d682e9b504e1d7ad0376d415": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x9428e90ccbc254697b04337e1bfa9ed42a163a0530cac6ed589ff0e86db639ff": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x979ead4e6ad3f623d00d4c31505cce1a654a543281a073df41b8429781a4700a": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0x979ead4e6ad3f623d00d4c31505cce1a654a543281a073df41b8429781a4700b": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xa0654653e606a2b16e75ace42178d92a333f7bd8fd554600cd8c0dda8959a747": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xa0654653e606a2b16e75ace42178d92a333f7bd8fd554600cd8c0dda8959a748": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xa16feed71a191c25a16b840899c1130128bae680b9fb5afedfad18ee25baa3cc": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xa16feed71a191c25a16b840899c1130128bae680b9fb5afedfad18ee25baa3cd": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xa40e19ad57e57cf5498a358191ef21a46727990f0833f60ef287bb2512f473b2": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xadd3379ca12eb6e907655b06c632df1dfb1d3810478f04657d0eb1f2514ada7d": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0xb07bd76227cbb5a5e93cd5635ab731faceb120715f763221afde9bf9c66d93e1": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xb7a1ebae33d313df562db52e6a17cc25a4fc71072bc8f38e28cca51dca772d2f": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xb7a1ebae33d313df562db52e6a17cc25a4fc71072bc8f38e28cca51dca772d30": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xbd072001a6fd52f3f36f5c32bd3ba9c4ffd3e427ab5661fb687b4b37342e32da": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xbe19bdb2daf84051554e5f7b28c240f2394dfdc01ed9931b1d2270301ce6197a": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xbe5c577780cc5cb207d59bca6035e982dd13627ef17edb6a67300e707c7ab194": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xbe5c577780cc5cb207d59bca6035e982dd13627ef17edb6a67300e707c7ab195": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xd6b02d8d4bab22276f46bd01c273377c92e6ebf28cab145c363c2ad13651ab01": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xd6b02d8d4bab22276f46bd01c273377c92e6ebf28cab145c363c2ad13651ab02": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xd6e5468fdf7c0709dc80d32848fc6c62d31a193138d0962e6edc92694d422212": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xd71673afb2d4fa2bfb83c3892943b95ad4701e2fd78801199c07446743897d39": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xd71673afb2d4fa2bfb83c3892943b95ad4701e2fd78801199c07446743897d3a": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xd9c5f37af5366d29a8e3839d99c1dbe7d1b1e3f1e2f5a3ac117401809b0d2501": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xd9c5f37af5366d29a8e3839d99c1dbe7d1b1e3f1e2f5a3ac117401809b0d2502": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xd9cfd15c4a9619e16321f9e4042a566871512a8c0375122ca56a91ed5dfaa5e2": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xd9cfd15c4a9619e16321f9e4042a566871512a8c0375122ca56a91ed5dfaa5e3": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xd9d4d93f562d5dc8184de584a08046769c25c10f1cebee1617c95d9212c093ec": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0xe0d37705568ac8274db84c0b672ef9a5b02459e4607af2736a98b235c5342cf9": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xe20533b9acd093b6b21eda56a3ad045315f0999f910d7ccada9ec110917d3dc2": "0x000000000000000000000000000000000000000000084595161401484a000000", + "0xe6920aeacdafc0d4f7573369e69a8a79eaee08f9d9f620e22831ee53d8de618c": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xe6a03f7a1a989ef0b5a97e8964334cc7ddb72a67de4c24b5f891847210a9db11": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xe6a03f7a1a989ef0b5a97e8964334cc7ddb72a67de4c24b5f891847210a9db12": "0x000000000000000000000000000000000000000000000a968163f0a57b400000", + "0xea2b7d5c8733427922e04399ac310174bb0431233be39c6a708646879c299ed9": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3": "0x000000000000000000000000311bdf9066246e68559816e7f636435867f824ef", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee4": "0x000000000000000000000000442a44a6fc20f5b8dfa8b304d7137581f7e6bef3", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee5": "0x00000000000000000000000047318441696e9ae962633c16e04d53935272639d", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee6": "0x000000000000000000000000537fc89618edae86950e12687a612e15c4786b84", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee7": "0x00000000000000000000000073898cc3c5beca5841306b26fdb4e30411392a6a", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee8": "0x00000000000000000000000074826141342a4dc33a1045cefa4182b6212ec031", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee9": "0x0000000000000000000000007bc30fbeb7208192d1474b5f87ffbc056de43c11", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636eea": "0x000000000000000000000000888c073313b36cf03cf1f739f39443551ff12bbe", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636eeb": "0x0000000000000000000000008d993351c0e2db739f9bcbfdeda94d73b50b16d3", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636eec": "0x000000000000000000000000a242960b7ca1937e826bda6c397df74d9f9ab01a", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636eed": "0x000000000000000000000000a89af636787499e81362e815e36f28763eac120b", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636eee": "0x000000000000000000000000abebf5a6cbe6113780cbe489e3eb0db882381aeb", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636eef": "0x000000000000000000000000af81190100d82f41ad2c95898195c7a47dc59115", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ef0": "0x000000000000000000000000bb5ec85408683795da2f604a5c0464868eabfcb6", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ef1": "0x000000000000000000000000da489a1b4304f49aafaec938c7adc48539470624", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ef2": "0x000000000000000000000000e1f9c75ce33e568d8fa3ace90497ee0c60dc921e", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ef3": "0x000000000000000000000000efea93e384a6ccaaf28e33790a2d1b2625bf964d", + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ef4": "0x000000000000000000000000fc087e2622b02b0bb78713e872c02796ef64c8f1", + "0xf511943a3baf5478bbcb2a8fc05b1bd215ad2612dcea88999bb647d8a1bc497b": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xf6c2c7fc452bd777ae6315a05df702a9c84c84319642f738c02d7265e7b03519": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xf7c5c70c003782446997bfaca3df73d3f4529e5610bd8f00aa705bd9f2b7bea5": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xfb99b5de22d1e4ca0e5857616be3d3df0df3f371c6dae7e7c3df24980cae362b": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xfd6dda287eb8b2e65f6136280e7f54c250f820b79064da60c2f09859788892b6": "0x000000000000000000000000de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xfdc6e9ef6103a34656ae73183b1f07e0d09db52b8500c3d560707c8f426d61b7": "0x000000000000000000000001de5b54e8e7b585153add32f472e8d545e5d42a82", + "0xfdc6e9ef6103a34656ae73183b1f07e0d09db52b8500c3d560707c8f426d61b8": "0x000000000000000000000000000000000000000000000a968163f0a57b400000" }, - "balance": "0x18d0bf423c03d8de000000" + "balance": "0xbe951906eba2aa800000" }, "0000000000000000000000000000000000000089": { "code": "0x6060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663e341eaa4811461005b578063e7ec6aef14610076578063f4145a83146100df575b600080fd5b341561006657600080fd5b610074600435602435610104565b005b341561008157600080fd5b61008c600435610227565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156100cb5780820151838201526020016100b3565b505050509050019250505060405180910390f35b34156100ea57600080fd5b6100f26102ac565b60405190815260200160405180910390f35b438290101561011257600080fd5b600280546101289184910263ffffffff6102b216565b43111561013457600080fd5b600082815260016020819052604090912080549091810161015583826102c8565b5060009182526020808320919091018390558282528190526040902080546001810161018183826102c8565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff8116919091179091557f62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f5490838360405173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091526040808301919091526060909101905180910390a15050565b61022f6102f1565b600082815260208181526040918290208054909290918281020190519081016040528092919081815260200182805480156102a057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610275575b50505050509050919050565b60025481565b6000828201838110156102c157fe5b9392505050565b8154818355818115116102ec576000838152602090206102ec918101908301610303565b505050565b60206040519081016040526000815290565b61032191905b8082111561031d5760008155600101610309565b5090565b905600a165627a7a72305820a8ceddaea8e4ae00991e2ae81c8c88e160dd8770f255523282c24c2df4c30ec70029", @@ -80,50 +211,68 @@ "balance": "0x0" }, "0000000000000000000000000000000000000099": { - "balance": "0x0" + "balance": "0x92e8434aaaf80e1800000" }, - "03c0d9bc556be68870b96976e81d32ebb49d335d": { + "311bdf9066246e68559816e7f636435867f824ef": { "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "065551f0dcac6f00cae11192d462db709be3758c": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "442a44a6fc20f5b8dfa8b304d7137581f7e6bef3": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "38b20a2594939531373efcd2e6aa54d03fc534be": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "47318441696e9ae962633c16e04d53935272639d": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "42e694adfd403152cd9cad82a62fb6cd403f150a": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "537fc89618edae86950e12687a612e15c4786b84": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "4398241671b3dd484fe3213a4fb7511f30e7d7c0": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "73898cc3c5beca5841306b26fdb4e30411392a6a": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "4e37f91e3bc69725326af96facf85c14128b07ed": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "74826141342a4dc33a1045cefa4182b6212ec031": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "664c4a7b15d91b07c468162f535909114c038b91": { - "balance": "0x7912752226cec5131e000000" + "7bc30fbeb7208192d1474b5f87ffbc056de43c11": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "746249c61f5832c5eed53172776b460491bdcd5c": { - "balance": "0x0" + "888c073313b36cf03cf1f739f39443551ff12bbe": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "a12a44433e64b76a9e388d87af02ce80580cf1f8": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "8d993351c0e2db739f9bcbfdeda94d73b50b16d3": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "7aa125338be075260e77c6a66a56c90a5dec4c58": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "a242960b7ca1937e826bda6c397df74d9f9ab01a": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "9a3787688fd210ec8f8d0224c6c50b8178d75bc0": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "a89af636787499e81362e815e36f28763eac120b": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "a65010026b83368ca05df6e8b467985d6de3eac5": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "abebf5a6cbe6113780cbe489e3eb0db882381aeb": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" }, - "03c0d9bc556BE68870B96976e81D32ebb49d335D": { - "balance": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "af81190100d82f41ad2c95898195c7a47dc59115": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + }, + "bb5ec85408683795da2f604a5c0464868eabfcb6": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + }, + "da489a1b4304f49aafaec938c7adc48539470624": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + }, + "de5b54e8e7b585153add32f472e8d545e5d42a82": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + }, + "e1f9c75ce33e568d8fa3ace90497ee0c60dc921e": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + }, + "efea93e384a6ccaaf28e33790a2d1b2625bf964d": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + }, + "fc087e2622b02b0bb78713e872c02796ef64c8f1": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" } - }, "number": "0x0", "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas": null } \ No newline at end of file diff --git a/cicd/entry.sh b/cicd/entry.sh index e7518fe9f603..0cd11b4ea474 100755 --- a/cicd/entry.sh +++ b/cicd/entry.sh @@ -7,7 +7,7 @@ fi echo "Select to run $NETWORK..." ln -s /usr/bin/XDC-$NETWORK /usr/bin/XDC -cp /work/$NETWORK/* /work +cp -n /work/$NETWORK/* /work echo "Start Node..." /work/start.sh \ No newline at end of file diff --git a/common/constants/constants.go.devnet b/common/constants/constants.go.devnet index 81e8c0487cd2..712bfac8c57e 100644 --- a/common/constants/constants.go.devnet +++ b/common/constants/constants.go.devnet @@ -32,26 +32,26 @@ const ( var Rewound = uint64(0) -var TIP2019Block = big.NewInt(1) -var TIPSigning = big.NewInt(225000) -var TIPRandomize = big.NewInt(225000) +var TIP2019Block = big.NewInt(0) +var TIPSigning = big.NewInt(0) +var TIPRandomize = big.NewInt(0) -var TIPV2SwitchBlock = big.NewInt(7074000) +var TIPV2SwitchBlock = big.NewInt(0) -var TIPIncreaseMasternodes = big.NewInt(225000) // Upgrade MN Count at Block. -var TIPNoHalvingMNReward = big.NewInt(429987) // hardfork no halving masternodes reward -var BlackListHFNumber = uint64(225000) -var TIPXDCX = big.NewInt(225000) -var TIPXDCXLending = big.NewInt(225000) -var TIPXDCXCancellationFee = big.NewInt(225000) -var TIPXDCXCancellationFeeTestnet = big.NewInt(225000) -var TIPXDCXMinerDisable = big.NewInt(15894900) -var TIPXDCXReceiverDisable = big.NewInt(18018000) -var BerlinBlock = big.NewInt(16832700) -var LondonBlock = big.NewInt(16832700) -var MergeBlock = big.NewInt(16832700) -var ShanghaiBlock = big.NewInt(16832700) -var Eip1559Block = big.NewInt(23035500) +var TIPIncreaseMasternodes = big.NewInt(0) // Upgrade MN Count at Block. +var TIPNoHalvingMNReward = big.NewInt(0) // hardfork no halving masternodes reward +var BlackListHFNumber = uint64(0) +var TIPXDCX = big.NewInt(0) +var TIPXDCXLending = big.NewInt(0) +var TIPXDCXCancellationFee = big.NewInt(0) +var TIPXDCXCancellationFeeTestnet = big.NewInt(0) +var TIPXDCXMinerDisable = big.NewInt(0) +var TIPXDCXReceiverDisable = big.NewInt(0) +var BerlinBlock = big.NewInt(0) +var LondonBlock = big.NewInt(0) +var MergeBlock = big.NewInt(0) +var ShanghaiBlock = big.NewInt(0) +var Eip1559Block = big.NewInt(0) var TIPXDCXTestnet = big.NewInt(0) var IsTestnet bool = false From 654be4d8746724e13bd49aba154bab588b6f696d Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Mon, 30 Dec 2024 17:10:27 -0500 Subject: [PATCH 102/121] add cicd --- .github/workflows/ci.yml | 55 ++++++++++++++++++++++++++++ common/constants/constants.go.devnet | 2 +- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6b7db7ffe5b..7ca0550c3db1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,6 +100,61 @@ jobs: echo "image_name=$image_name" echo "image_name=$image_name" >> "$GITHUB_OUTPUT" + devnet_k8_apply: + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') + needs: devnet_build_push + steps: + - uses: actions/checkout@v4 + - name: Set up kubectl + uses: azure/setup-kubectl@v4 + with: + version: 'v1.19.11' + - name: Decode and configure kubeconfig + run: | + mkdir -p $HOME/.kube + echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config + chmod 600 $HOME/.kube/config + git_hash=$(git rev-parse --short "$GITHUB_SHA") + kubectl set image deployment/devnet1 devnet1=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet2 devnet2=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet3 devnet3=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet4 devnet4=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet5 devnet5=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet6 devnet6=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet7 devnet7=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet8 devnet8=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet9 devnet9=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet10 devnet10=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet11 devnet11=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet12 devnet12=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet13 devnet13=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet14 devnet14=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet15 devnet15=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet16 devnet16=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet17 devnet17=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet18 devnet18=xinfinorg/devnet:dev-upgrade-${git_hash} + + rpc_k8_apply: + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') + needs: devnet_build_push + steps: + - uses: actions/checkout@v4 + - name: Set up kubectl + uses: azure/setup-kubectl@v4 + with: + version: 'v1.19.11' + - name: Decode and configure kubeconfig + run: | + mkdir -p $HOME/.kube + echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config + chmod 600 $HOME/.kube/config + git_hash=$(git rev-parse --short "$GITHUB_SHA") + kubectl set image deployment/devnetrpc devnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/testnetrpc testnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/mainnetrpc mainnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} + rpcnode_terraform_apply: runs-on: ubuntu-latest if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') diff --git a/common/constants/constants.go.devnet b/common/constants/constants.go.devnet index 712bfac8c57e..a71257ae6fc1 100644 --- a/common/constants/constants.go.devnet +++ b/common/constants/constants.go.devnet @@ -36,7 +36,7 @@ var TIP2019Block = big.NewInt(0) var TIPSigning = big.NewInt(0) var TIPRandomize = big.NewInt(0) -var TIPV2SwitchBlock = big.NewInt(0) +var TIPV2SwitchBlock = big.NewInt(1800) var TIPIncreaseMasternodes = big.NewInt(0) // Upgrade MN Count at Block. var TIPNoHalvingMNReward = big.NewInt(0) // hardfork no halving masternodes reward From 0404803366dd1ec0991cfef13dd55ae275a55d4f Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Mon, 30 Dec 2024 20:44:01 -0500 Subject: [PATCH 103/121] optimize shell script --- cicd/local/start.sh | 62 +++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/cicd/local/start.sh b/cicd/local/start.sh index cfd877de4066..30a4ed44642e 100755 --- a/cicd/local/start.sh +++ b/cicd/local/start.sh @@ -1,4 +1,6 @@ #!/bin/bash +set -eo pipefail + if [ ! -d /work/xdcchain/XDC/chaindata ] then if test -z "$PRIVATE_KEY" @@ -25,41 +27,13 @@ do fi done < "$input" -log_level=3 -if test -z "$LOG_LEVEL" -then - echo "Log level not set, default to verbosity of $log_level" -else - echo "Log level found, set to $LOG_LEVEL" - log_level=$LOG_LEVEL -fi +log_level="${LOG_LEVEL:-3}" -port=30303 -if test -z "$PORT" -then - echo "PORT not set, default to $port" -else - echo "PORT found, set to $PORT" - port=$PORT -fi +port="${PORT:-30303}" -rpc_port=8545 -if test -z "$RPC_PORT" -then - echo "RPC_PORT not set, default to $rpc_port" -else - echo "RPC_PORT found, set to $RPC_PORT" - rpc_port=$RPC_PORT -fi +rpc_port="${RPC_PORT:-8545}" -ws_port=8555 -if test -z "$WS_PORT" -then - echo "WS_PORT not set, default to $ws_port" -else - echo "WS_PORT found, set to $WS_PORT" - ws_port=$WS_PORT -fi +ws_port="${WS_PORT:-8555}" netstats="${NODE_NAME}-${wallet}:xinfin_xdpos_hybrid_network_stats@devnetstats.apothem.network:2000" @@ -70,14 +44,24 @@ echo "Starting nodes with $bootnodes ..." # Note: --gcmode=archive means node will store all historical data. This will lead to high memory usage. But sync mode require archive to sync # https://github.com/XinFinOrg/XDPoSChain/issues/268 -XDC --ethstats ${netstats} --gcmode archive \ ---bootnodes ${bootnodes} --syncmode full \ ---datadir /work/xdcchain --networkid 551 \ --port $port --rpc --rpccorsdomain "*" --rpcaddr 0.0.0.0 \ +XDC --ethstats ${netstats} \ +--gcmode archive \ +--bootnodes ${bootnodes} \ +--syncmode full \ +--datadir /work/xdcchain \ +--networkid 551 \ +-port $port \ +--rpc --rpccorsdomain "*" \ +--rpcaddr 0.0.0.0 \ --rpcport $rpc_port \ --rpcapi db,eth,debug,net,shh,txpool,personal,web3,XDPoS \ ---rpcvhosts "*" --unlock "${wallet}" --password /work/.pwd --mine \ ---gasprice "1" --targetgaslimit "420000000" --verbosity ${log_level} \ +--rpcvhosts "*" \ +--unlock "${wallet}" \ +--password /work/.pwd --mine \ +--gasprice "1" --targetgaslimit "420000000" \ +--verbosity ${log_level} \ --debugdatadir /work/xdcchain \ ---ws --wsaddr=0.0.0.0 --wsport $ws_port \ +--ws \ +--wsaddr=0.0.0.0 \ +--wsport $ws_port \ --wsorigins "*" 2>&1 >>/work/xdcchain/xdc.log | tee -a /work/xdcchain/xdc.log From 12488b86ed7f5e61085551da3f7672cfc42458bb Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Wed, 1 Jan 2025 21:51:11 -0500 Subject: [PATCH 104/121] add bootnodes --- cicd/devnet/bootnodes.list | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cicd/devnet/bootnodes.list b/cicd/devnet/bootnodes.list index edffbabcf4a3..d3b1228edd76 100644 --- a/cicd/devnet/bootnodes.list +++ b/cicd/devnet/bootnodes.list @@ -1,2 +1,4 @@ +enode://00d49d72a48164681906ad61924568da0d3049937efdbaed0b7533e34a99f55814f1839d909cdc82f78e04a36ac04737d80b41b22905c7d6cac3c80bb5cdbbc4@66.94.98.186:30301 +enode://d6793b02a478f13ed6d01c30778935f6f8f7461a75aebedcb310def4ed9b066f995a0dca046d0c7ea7f5ffdd8e3f1f53c6b6dce909d1693650504921aad62f1a@194.163.167.177:30301 enode://c7a38ecc7fd5849eaefb3e928f882ab2f1260d5591bd1fef1db39c8ae0d9fe21d86e2d4efee6def0f4f16d0b6103f86f92f7e910295b849266fef83f05768596@10.244.1.77:30301 enode://9160713d41656154ce3fdaa9d0f9799dd8546652b1784edecf82ce7a5b54a977f897ea617a9b3b4db513dc6b0dc98c1c3ad8a1914075ab87ded4e367c89dcd3b@10.244.2.53:30301 From d0566e4165d0113582dcb4d12a9a248824aefa54 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 3 Jan 2025 09:51:44 +0800 Subject: [PATCH 105/121] crypto: update to go version 1.22 (#28946) --- crypto/crypto.go | 15 ++++++-- crypto/ecies/ecies.go | 58 +++++++++++++++++------------- crypto/secp256k1/secp256_test.go | 3 +- crypto/signature_cgo.go | 7 ++-- crypto/signature_nocgo.go | 61 ++++++++++++++++++++++++++------ 5 files changed, 99 insertions(+), 45 deletions(-) diff --git a/crypto/crypto.go b/crypto/crypto.go index 22849aa6ea30..552e93f9cb5f 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -51,6 +51,15 @@ var ( var errInvalidPubkey = errors.New("invalid secp256k1 public key") +// EllipticCurve contains curve operations. +type EllipticCurve interface { + elliptic.Curve + + // Point marshaling/unmarshaing. + Marshal(x, y *big.Int) []byte + Unmarshal(data []byte) (x, y *big.Int) +} + // KeccakState wraps sha3.state. In addition to the usual hash methods, it also supports // Read to get a variable amount of data from the hash state. Read is faster than Sum // because it doesn't copy the internal state, but also modifies the internal state. @@ -148,7 +157,7 @@ func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) { return nil, errors.New("invalid private key, zero or negative") } - priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d) + priv.PublicKey.X, priv.PublicKey.Y = S256().ScalarBaseMult(d) if priv.PublicKey.X == nil { return nil, errors.New("invalid private key") } @@ -165,7 +174,7 @@ func FromECDSA(priv *ecdsa.PrivateKey) []byte { // UnmarshalPubkey converts bytes to a secp256k1 public key. func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { - x, y := elliptic.Unmarshal(S256(), pub) + x, y := S256().Unmarshal(pub) if x == nil { return nil, errInvalidPubkey } @@ -176,7 +185,7 @@ func FromECDSAPub(pub *ecdsa.PublicKey) []byte { if pub == nil || pub.X == nil || pub.Y == nil { return nil } - return elliptic.Marshal(S256(), pub.X, pub.Y) + return S256().Marshal(pub.X, pub.Y) } // HexToECDSA parses a secp256k1 private key. diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index 738bb8f584aa..4a0d03f95839 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -40,6 +40,8 @@ import ( "hash" "io" "math/big" + + "github.com/XinFinOrg/XDPoSChain/crypto" ) var ( @@ -95,15 +97,15 @@ func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey { // Generate an elliptic curve public / private keypair. If params is nil, // the recommended default parameters for the key will be chosen. func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) { - pb, x, y, err := elliptic.GenerateKey(curve, rand) + sk, err := ecdsa.GenerateKey(curve, rand) if err != nil { return } prv = new(PrivateKey) - prv.PublicKey.X = x - prv.PublicKey.Y = y + prv.PublicKey.X = sk.X + prv.PublicKey.Y = sk.Y prv.PublicKey.Curve = curve - prv.D = new(big.Int).SetBytes(pb) + prv.D = new(big.Int).Set(sk.D) if params == nil { params = ParamsFromCurve(curve) } @@ -255,12 +257,15 @@ func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err e d := messageTag(params.Hash, Km, em, s2) - Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y) - ct = make([]byte, len(Rb)+len(em)+len(d)) - copy(ct, Rb) - copy(ct[len(Rb):], em) - copy(ct[len(Rb)+len(em):], d) - return ct, nil + if curve, ok := pub.Curve.(crypto.EllipticCurve); ok { + Rb := curve.Marshal(R.PublicKey.X, R.PublicKey.Y) + ct = make([]byte, len(Rb)+len(em)+len(d)) + copy(ct, Rb) + copy(ct[len(Rb):], em) + copy(ct[len(Rb)+len(em):], d) + return ct, nil + } + return nil, ErrInvalidCurve } // Decrypt decrypts an ECIES ciphertext. @@ -297,21 +302,24 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) { R := new(PublicKey) R.Curve = prv.PublicKey.Curve - R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen]) - if R.X == nil { - return nil, ErrInvalidPublicKey - } - z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen) - if err != nil { - return nil, err - } - Ke, Km := deriveKeys(hash, z, s1, params.KeyLen) + if curve, ok := R.Curve.(crypto.EllipticCurve); ok { + R.X, R.Y = curve.Unmarshal(c[:rLen]) + if R.X == nil { + return nil, ErrInvalidPublicKey + } - d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) - if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { - return nil, ErrInvalidMessage - } + z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen) + if err != nil { + return nil, err + } + Ke, Km := deriveKeys(hash, z, s1, params.KeyLen) - return symDecrypt(params, Ke, c[mStart:mEnd]) -} + d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) + if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { + return nil, ErrInvalidMessage + } + return symDecrypt(params, Ke, c[mStart:mEnd]) + } + return nil, ErrInvalidCurve +} \ No newline at end of file diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index 74408d06d2bf..8bb870fa18bc 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -10,7 +10,6 @@ package secp256k1 import ( "bytes" "crypto/ecdsa" - "crypto/elliptic" "crypto/rand" "encoding/hex" "io" @@ -24,7 +23,7 @@ func generateKeyPair() (pubkey, privkey []byte) { if err != nil { panic(err) } - pubkey = elliptic.Marshal(S256(), key.X, key.Y) + pubkey = S256().Marshal(key.X, key.Y) privkey = make([]byte, 32) blob := key.D.Bytes() diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go index 681165750304..bace593fb507 100644 --- a/crypto/signature_cgo.go +++ b/crypto/signature_cgo.go @@ -21,7 +21,6 @@ package crypto import ( "crypto/ecdsa" - "crypto/elliptic" "errors" "fmt" @@ -40,9 +39,7 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { if err != nil { return nil, err } - - x, y := elliptic.Unmarshal(S256(), s) - return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil + return UnmarshalPubkey(s) } // Sign calculates an ECDSA signature. @@ -84,6 +81,6 @@ func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { } // S256 returns an instance of the secp256k1 curve. -func S256() elliptic.Curve { +func S256() EllipticCurve { return secp256k1.S256() } diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 6d628d758d93..4438c1defda1 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -21,9 +21,9 @@ package crypto import ( "crypto/ecdsa" - "crypto/elliptic" "errors" "fmt" + "math/big" "github.com/btcsuite/btcd/btcec/v2" btc_ecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" @@ -58,7 +58,13 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { if err != nil { return nil, err } - return pub.ToECDSA(), nil + // We need to explicitly set the curve here, because we're wrapping + // the original curve to add (un-)marshalling + return &ecdsa.PublicKey{ + Curve: S256(), + X: pub.X(), + Y: pub.Y(), + }, nil } // Sign calculates an ECDSA signature. @@ -73,7 +79,7 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { if len(hash) != 32 { return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) } - if prv.Curve != btcec.S256() { + if prv.Curve != S256() { return nil, errors.New("private key curve is not secp256k1") } // ecdsa.PrivateKey -> btcec.PrivateKey @@ -82,10 +88,7 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { return nil, errors.New("invalid private key") } defer priv.Zero() - sig, err := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey - if err != nil { - return nil, err - } + sig := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey // Convert to Ethereum signature format with 'recovery id' v at the end. v := sig[0] - 27 copy(sig, sig[1:]) @@ -128,7 +131,13 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) { if err != nil { return nil, err } - return key.ToECDSA(), nil + // We need to explicitly set the curve here, because we're wrapping + // the original curve to add (un-)marshalling + return &ecdsa.PublicKey{ + Curve: S256(), + X: key.X(), + Y: key.Y(), + }, nil } // CompressPubkey encodes a public key to the 33-byte compressed format. The @@ -147,6 +156,38 @@ func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { } // S256 returns an instance of the secp256k1 curve. -func S256() elliptic.Curve { - return btcec.S256() +func S256() EllipticCurve { + return btCurve{btcec.S256()} +} + +type btCurve struct { + *btcec.KoblitzCurve +} + +// Marshall converts a point given as (x, y) into a byte slice. +func (curve btCurve) Marshal(x, y *big.Int) []byte { + byteLen := (curve.Params().BitSize + 7) / 8 + + ret := make([]byte, 1+2*byteLen) + ret[0] = 4 // uncompressed point + + x.FillBytes(ret[1 : 1+byteLen]) + y.FillBytes(ret[1+byteLen : 1+2*byteLen]) + + return ret +} + +// Unmarshal converts a point, serialised by Marshal, into an x, y pair. On +// error, x = nil. +func (curve btCurve) Unmarshal(data []byte) (x, y *big.Int) { + byteLen := (curve.Params().BitSize + 7) / 8 + if len(data) != 1+2*byteLen { + return nil, nil + } + if data[0] != 4 { // uncompressed form + return nil, nil + } + x = new(big.Int).SetBytes(data[1 : 1+byteLen]) + y = new(big.Int).SetBytes(data[1+byteLen:]) + return } From efad15f9f4d5819083241a611a67506b827a70d1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 3 Jan 2025 09:56:02 +0800 Subject: [PATCH 106/121] crypto: use clear from go1.21 (#29307) --- crypto/crypto.go | 4 +--- crypto/secp256k1/scalar_mult_cgo.go | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/crypto/crypto.go b/crypto/crypto.go index 552e93f9cb5f..a5da7111247b 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -287,7 +287,5 @@ func PubkeyToAddress(p ecdsa.PublicKey) common.Address { } func zeroBytes(bytes []byte) { - for i := range bytes { - bytes[i] = 0 - } + clear(bytes) } diff --git a/crypto/secp256k1/scalar_mult_cgo.go b/crypto/secp256k1/scalar_mult_cgo.go index 8afa9d023b07..bdf8eeede7df 100644 --- a/crypto/secp256k1/scalar_mult_cgo.go +++ b/crypto/secp256k1/scalar_mult_cgo.go @@ -44,12 +44,8 @@ func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, // Unpack the result and clear temporaries. x := new(big.Int).SetBytes(point[:32]) y := new(big.Int).SetBytes(point[32:]) - for i := range point { - point[i] = 0 - } - for i := range padded { - scalar[i] = 0 - } + clear(point) + clear(scalar) if res != 1 { return nil, nil } From 136e87fa4c7ef12b8bca8e3cadb75ad0b9d3bb60 Mon Sep 17 00:00:00 2001 From: George Ma <164313692+availhang@users.noreply.github.com> Date: Fri, 22 Mar 2024 20:29:12 +0800 Subject: [PATCH 107/121] crypto: fix docstrings and comments --- crypto/bn256/google/bn256.go | 2 +- crypto/secp256k1/secp256_test.go | 2 +- crypto/signature_nocgo.go | 2 +- crypto/signature_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/bn256/google/bn256.go b/crypto/bn256/google/bn256.go index 93953e23a95f..aca9cf62de1b 100644 --- a/crypto/bn256/google/bn256.go +++ b/crypto/bn256/google/bn256.go @@ -29,7 +29,7 @@ import ( ) // BUG(agl): this implementation is not constant time. -// TODO(agl): keep GF(p²) elements in Mongomery form. +// TODO(agl): keep GF(p²) elements in Montgomery form. // G1 is an abstract cyclic group. The zero value is suitable for use as the // output of an operation, but cannot be used as an input. diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index 8bb870fa18bc..4827cc5b255c 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -48,7 +48,7 @@ func randSig() []byte { } // tests for malleability -// highest bit of signature ECDSA s value must be 0, in the 33th byte +// the highest bit of signature ECDSA s value must be 0, in the 33th byte func compactSigCheck(t *testing.T, sig []byte) { var b = int(sig[32]) if b < 0 { diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 4438c1defda1..5ac3765c7106 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -164,7 +164,7 @@ type btCurve struct { *btcec.KoblitzCurve } -// Marshall converts a point given as (x, y) into a byte slice. +// Marshal converts a point given as (x, y) into a byte slice. func (curve btCurve) Marshal(x, y *big.Int) []byte { byteLen := (curve.Params().BitSize + 7) / 8 diff --git a/crypto/signature_test.go b/crypto/signature_test.go index 3d3331f4d7dc..ce790b1408eb 100644 --- a/crypto/signature_test.go +++ b/crypto/signature_test.go @@ -71,7 +71,7 @@ func TestVerifySignature(t *testing.T) { wrongkey := common.CopyBytes(testpubkey) wrongkey[10]++ if VerifySignature(wrongkey, testmsg, sig) { - t.Errorf("signature valid with with wrong public key") + t.Errorf("signature valid with wrong public key") } } From 104a97354abcaeac8187aba2da5410e14eef3992 Mon Sep 17 00:00:00 2001 From: SuiYuan <165623542+suiyuan1314@users.noreply.github.com> Date: Thu, 30 May 2024 22:24:16 +0800 Subject: [PATCH 108/121] crypto/secp256k1: change receiver variable name to lowercase (#29889) --- crypto/secp256k1/curve.go | 88 +++++++++++++-------------- crypto/secp256k1/scalar_mult_cgo.go | 2 +- crypto/secp256k1/scalar_mult_nocgo.go | 2 +- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go index 9b26ab292859..85ba885d6f5f 100644 --- a/crypto/secp256k1/curve.go +++ b/crypto/secp256k1/curve.go @@ -79,52 +79,52 @@ type BitCurve struct { BitSize int // the size of the underlying field } -func (BitCurve *BitCurve) Params() *elliptic.CurveParams { +func (bitCurve *BitCurve) Params() *elliptic.CurveParams { return &elliptic.CurveParams{ - P: BitCurve.P, - N: BitCurve.N, - B: BitCurve.B, - Gx: BitCurve.Gx, - Gy: BitCurve.Gy, - BitSize: BitCurve.BitSize, + P: bitCurve.P, + N: bitCurve.N, + B: bitCurve.B, + Gx: bitCurve.Gx, + Gy: bitCurve.Gy, + BitSize: bitCurve.BitSize, } } // IsOnCurve returns true if the given (x,y) lies on the BitCurve. -func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { +func (bitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { // y² = x³ + b y2 := new(big.Int).Mul(y, y) //y² - y2.Mod(y2, BitCurve.P) //y²%P + y2.Mod(y2, bitCurve.P) //y²%P x3 := new(big.Int).Mul(x, x) //x² x3.Mul(x3, x) //x³ - x3.Add(x3, BitCurve.B) //x³+B - x3.Mod(x3, BitCurve.P) //(x³+B)%P + x3.Add(x3, bitCurve.B) //x³+B + x3.Mod(x3, bitCurve.P) //(x³+B)%P return x3.Cmp(y2) == 0 } // affineFromJacobian reverses the Jacobian transform. See the comment at the // top of the file. -func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { +func (bitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { if z.Sign() == 0 { return new(big.Int), new(big.Int) } - zinv := new(big.Int).ModInverse(z, BitCurve.P) + zinv := new(big.Int).ModInverse(z, bitCurve.P) zinvsq := new(big.Int).Mul(zinv, zinv) xOut = new(big.Int).Mul(x, zinvsq) - xOut.Mod(xOut, BitCurve.P) + xOut.Mod(xOut, bitCurve.P) zinvsq.Mul(zinvsq, zinv) yOut = new(big.Int).Mul(y, zinvsq) - yOut.Mod(yOut, BitCurve.P) + yOut.Mod(yOut, bitCurve.P) return } // Add returns the sum of (x1,y1) and (x2,y2) -func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { // If one point is at infinity, return the other point. // Adding the point at infinity to any point will preserve the other point. if x1.Sign() == 0 && y1.Sign() == 0 { @@ -135,27 +135,27 @@ func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { } z := new(big.Int).SetInt64(1) if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 { - return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z)) + return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z)) } - return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z)) + return bitCurve.affineFromJacobian(bitCurve.addJacobian(x1, y1, z, x2, y2, z)) } // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and // (x2, y2, z2) and returns their sum, also in Jacobian form. -func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { +func (bitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl z1z1 := new(big.Int).Mul(z1, z1) - z1z1.Mod(z1z1, BitCurve.P) + z1z1.Mod(z1z1, bitCurve.P) z2z2 := new(big.Int).Mul(z2, z2) - z2z2.Mod(z2z2, BitCurve.P) + z2z2.Mod(z2z2, bitCurve.P) u1 := new(big.Int).Mul(x1, z2z2) - u1.Mod(u1, BitCurve.P) + u1.Mod(u1, bitCurve.P) u2 := new(big.Int).Mul(x2, z1z1) - u2.Mod(u2, BitCurve.P) + u2.Mod(u2, bitCurve.P) h := new(big.Int).Sub(u2, u1) if h.Sign() == -1 { - h.Add(h, BitCurve.P) + h.Add(h, bitCurve.P) } i := new(big.Int).Lsh(h, 1) i.Mul(i, i) @@ -163,13 +163,13 @@ func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int s1 := new(big.Int).Mul(y1, z2) s1.Mul(s1, z2z2) - s1.Mod(s1, BitCurve.P) + s1.Mod(s1, bitCurve.P) s2 := new(big.Int).Mul(y2, z1) s2.Mul(s2, z1z1) - s2.Mod(s2, BitCurve.P) + s2.Mod(s2, bitCurve.P) r := new(big.Int).Sub(s2, s1) if r.Sign() == -1 { - r.Add(r, BitCurve.P) + r.Add(r, bitCurve.P) } r.Lsh(r, 1) v := new(big.Int).Mul(u1, i) @@ -179,7 +179,7 @@ func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int x3.Sub(x3, j) x3.Sub(x3, v) x3.Sub(x3, v) - x3.Mod(x3, BitCurve.P) + x3.Mod(x3, bitCurve.P) y3 := new(big.Int).Set(r) v.Sub(v, x3) @@ -187,33 +187,33 @@ func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int s1.Mul(s1, j) s1.Lsh(s1, 1) y3.Sub(y3, s1) - y3.Mod(y3, BitCurve.P) + y3.Mod(y3, bitCurve.P) z3 := new(big.Int).Add(z1, z2) z3.Mul(z3, z3) z3.Sub(z3, z1z1) if z3.Sign() == -1 { - z3.Add(z3, BitCurve.P) + z3.Add(z3, bitCurve.P) } z3.Sub(z3, z2z2) if z3.Sign() == -1 { - z3.Add(z3, BitCurve.P) + z3.Add(z3, bitCurve.P) } z3.Mul(z3, h) - z3.Mod(z3, BitCurve.P) + z3.Mod(z3, bitCurve.P) return x3, y3, z3 } // Double returns 2*(x,y) -func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { z1 := new(big.Int).SetInt64(1) - return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1)) + return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z1)) } // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and // returns its double, also in Jacobian form. -func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { +func (bitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l a := new(big.Int).Mul(x, x) //X1² @@ -231,30 +231,30 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D x3.Sub(f, x3) //F-2*D - x3.Mod(x3, BitCurve.P) + x3.Mod(x3, bitCurve.P) y3 := new(big.Int).Sub(d, x3) //D-X3 y3.Mul(e, y3) //E*(D-X3) y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C - y3.Mod(y3, BitCurve.P) + y3.Mod(y3, bitCurve.P) z3 := new(big.Int).Mul(y, z) //Y1*Z1 z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 - z3.Mod(z3, BitCurve.P) + z3.Mod(z3, bitCurve.P) return x3, y3, z3 } // ScalarBaseMult returns k*G, where G is the base point of the group and k is // an integer in big-endian form. -func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { - return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k) +func (bitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + return bitCurve.ScalarMult(bitCurve.Gx, bitCurve.Gy, k) } // Marshal converts a point into the form specified in section 4.3.6 of ANSI // X9.62. -func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { - byteLen := (BitCurve.BitSize + 7) >> 3 +func (bitCurve *BitCurve) Marshal(x, y *big.Int) []byte { + byteLen := (bitCurve.BitSize + 7) >> 3 ret := make([]byte, 1+2*byteLen) ret[0] = 4 // uncompressed point flag readBits(x, ret[1:1+byteLen]) @@ -264,8 +264,8 @@ func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { // Unmarshal converts a point, serialised by Marshal, into an x, y pair. On // error, x = nil. -func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { - byteLen := (BitCurve.BitSize + 7) >> 3 +func (bitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { + byteLen := (bitCurve.BitSize + 7) >> 3 if len(data) != 1+2*byteLen { return } diff --git a/crypto/secp256k1/scalar_mult_cgo.go b/crypto/secp256k1/scalar_mult_cgo.go index bdf8eeede7df..d11c11faf85b 100644 --- a/crypto/secp256k1/scalar_mult_cgo.go +++ b/crypto/secp256k1/scalar_mult_cgo.go @@ -21,7 +21,7 @@ extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned */ import "C" -func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { // Ensure scalar is exactly 32 bytes. We pad always, even if // scalar is 32 bytes long, to avoid a timing side channel. if len(scalar) > 32 { diff --git a/crypto/secp256k1/scalar_mult_nocgo.go b/crypto/secp256k1/scalar_mult_nocgo.go index 22f53ac6ae65..feb13a8dfd0e 100644 --- a/crypto/secp256k1/scalar_mult_nocgo.go +++ b/crypto/secp256k1/scalar_mult_nocgo.go @@ -9,6 +9,6 @@ package secp256k1 import "math/big" -func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { +func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { panic("ScalarMult is not available when secp256k1 is built without cgo") } From e19093f344ef4324cc11f15cb7db80b8945279be Mon Sep 17 00:00:00 2001 From: zhiqiangxu <652732310@qq.com> Date: Tue, 9 Jul 2024 19:19:25 +0800 Subject: [PATCH 109/121] crypto: remove hardcoded value for secp256k1.N (#30126) --- crypto/crypto.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/crypto.go b/crypto/crypto.go index a5da7111247b..b30137bce534 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -45,7 +45,7 @@ const RecoveryIDOffset = 64 const DigestLength = 32 var ( - secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) + secp256k1N = S256().Params().N secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2)) ) From 15be5ba464f6a2f3e08c87e95c31af277928869a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 3 Jan 2025 10:19:25 +0800 Subject: [PATCH 110/121] crypto: use decred secp256k1 directly (#30595) --- crypto/signature_nocgo.go | 36 ++++++++++++++-------------- go.mod | 3 +-- go.sum | 2 -- tests/fuzzers/secp256k1/secp_test.go | 4 ++-- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 5ac3765c7106..16a785a18600 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -25,8 +25,8 @@ import ( "fmt" "math/big" - "github.com/btcsuite/btcd/btcec/v2" - btc_ecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + decred_ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" ) // Ecrecover returns the uncompressed public key that created the given signature. @@ -39,16 +39,16 @@ func Ecrecover(hash, sig []byte) ([]byte, error) { return bytes, err } -func sigToPub(hash, sig []byte) (*btcec.PublicKey, error) { +func sigToPub(hash, sig []byte) (*secp256k1.PublicKey, error) { if len(sig) != SignatureLength { return nil, errors.New("invalid signature") } - // Convert to btcec input format with 'recovery id' v at the beginning. + // Convert to secp256k1 input format with 'recovery id' v at the beginning. btcsig := make([]byte, SignatureLength) btcsig[0] = sig[RecoveryIDOffset] + 27 copy(btcsig[1:], sig) - pub, _, err := btc_ecdsa.RecoverCompact(btcsig, hash) + pub, _, err := decred_ecdsa.RecoverCompact(btcsig, hash) return pub, err } @@ -82,13 +82,13 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { if prv.Curve != S256() { return nil, errors.New("private key curve is not secp256k1") } - // ecdsa.PrivateKey -> btcec.PrivateKey - var priv btcec.PrivateKey + // ecdsa.PrivateKey -> secp256k1.PrivateKey + var priv secp256k1.PrivateKey if overflow := priv.Key.SetByteSlice(prv.D.Bytes()); overflow || priv.Key.IsZero() { return nil, errors.New("invalid private key") } defer priv.Zero() - sig := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey + sig := decred_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey // Convert to Ethereum signature format with 'recovery id' v at the end. v := sig[0] - 27 copy(sig, sig[1:]) @@ -103,19 +103,19 @@ func VerifySignature(pubkey, hash, signature []byte) bool { if len(signature) != 64 { return false } - var r, s btcec.ModNScalar + var r, s secp256k1.ModNScalar if r.SetByteSlice(signature[:32]) { return false // overflow } if s.SetByteSlice(signature[32:]) { return false } - sig := btc_ecdsa.NewSignature(&r, &s) - key, err := btcec.ParsePubKey(pubkey) + sig := decred_ecdsa.NewSignature(&r, &s) + key, err := secp256k1.ParsePubKey(pubkey) if err != nil { return false } - // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. + // Reject malleable signatures. libsecp256k1 does this check but decred doesn't. if s.IsOverHalfOrder() { return false } @@ -127,7 +127,7 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) { if len(pubkey) != 33 { return nil, errors.New("invalid compressed public key length") } - key, err := btcec.ParsePubKey(pubkey) + key, err := secp256k1.ParsePubKey(pubkey) if err != nil { return nil, err } @@ -148,20 +148,20 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) { // when constructing a PrivateKey. func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { // NOTE: the coordinates may be validated with - // btcec.ParsePubKey(FromECDSAPub(pubkey)) - var x, y btcec.FieldVal + // secp256k1.ParsePubKey(FromECDSAPub(pubkey)) + var x, y secp256k1.FieldVal x.SetByteSlice(pubkey.X.Bytes()) y.SetByteSlice(pubkey.Y.Bytes()) - return btcec.NewPublicKey(&x, &y).SerializeCompressed() + return secp256k1.NewPublicKey(&x, &y).SerializeCompressed() } // S256 returns an instance of the secp256k1 curve. func S256() EllipticCurve { - return btCurve{btcec.S256()} + return btCurve{secp256k1.S256()} } type btCurve struct { - *btcec.KoblitzCurve + *secp256k1.KoblitzCurve } // Marshal converts a point given as (x, y) into a byte slice. diff --git a/go.mod b/go.mod index 57fa810ed42d..3b58b4c90cdc 100644 --- a/go.mod +++ b/go.mod @@ -41,10 +41,10 @@ require ( ) require ( - github.com/btcsuite/btcd/btcec/v2 v2.3.4 github.com/consensys/gnark-crypto v0.10.0 github.com/crate-crypto/go-kzg-4844 v0.7.0 github.com/deckarep/golang-set v1.8.0 + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/ethereum/c-kzg-4844 v0.4.0 github.com/go-yaml/yaml v2.1.0+incompatible @@ -64,7 +64,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect github.com/go-ole/go-ole v1.2.5 // indirect diff --git a/go.sum b/go.sum index eefee5f64b33..baa6733abe5e 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= diff --git a/tests/fuzzers/secp256k1/secp_test.go b/tests/fuzzers/secp256k1/secp_test.go index e8b655669c53..9b7d7491381a 100644 --- a/tests/fuzzers/secp256k1/secp_test.go +++ b/tests/fuzzers/secp256k1/secp_test.go @@ -21,7 +21,7 @@ import ( "testing" "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1" - "github.com/btcsuite/btcd/btcec/v2" + dcred_secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" ) func TestFuzzer(t *testing.T) { @@ -38,7 +38,7 @@ func Fuzz(f *testing.F) { func fuzz(dataP1, dataP2 []byte) { var ( curveA = secp256k1.S256() - curveB = btcec.S256() + curveB = dcred_secp256k1.S256() ) // first point x1, y1 := curveB.ScalarBaseMult(dataP1) From e581093ce18590b8253fca23d59e5f389963411d Mon Sep 17 00:00:00 2001 From: kevaundray Date: Wed, 23 Oct 2024 07:11:25 +0100 Subject: [PATCH 111/121] crypto, tests/fuzzers: add gnark bn254 precompile methods for fuzzing (#30585) Makes the gnark precompile methods more amenable to fuzzing --- crypto/bn256/gnark/g1.go | 51 +++++++++++++++++++++ crypto/bn256/gnark/g2.go | 38 ++++++++++++++++ crypto/bn256/gnark/gt.go | 65 +++++++++++++++++++++++++++ crypto/bn256/gnark/pairing.go | 73 +++++++++++++++++++++++++++++++ tests/fuzzers/bn256/bn256_fuzz.go | 64 ++++++++++++++------------- 5 files changed, 261 insertions(+), 30 deletions(-) create mode 100644 crypto/bn256/gnark/g1.go create mode 100644 crypto/bn256/gnark/g2.go create mode 100644 crypto/bn256/gnark/gt.go create mode 100644 crypto/bn256/gnark/pairing.go diff --git a/crypto/bn256/gnark/g1.go b/crypto/bn256/gnark/g1.go new file mode 100644 index 000000000000..2f933dd53601 --- /dev/null +++ b/crypto/bn256/gnark/g1.go @@ -0,0 +1,51 @@ +package bn256 + +import ( + "math/big" + + "github.com/consensys/gnark-crypto/ecc/bn254" +) + +// G1 is the affine representation of a G1 group element. +// +// Since this code is used for precompiles, using Jacobian +// points are not beneficial because there are no intermediate +// points to allow us to save on inversions. +// +// Note: We also use this struct so that we can conform to the existing API +// that the precompiles want. +type G1 struct { + inner bn254.G1Affine +} + +// Add adds `a` and `b` together, storing the result in `g` +func (g *G1) Add(a, b *G1) { + g.inner.Add(&a.inner, &b.inner) +} + +// ScalarMult computes the scalar multiplication between `a` and +// `scalar`, storing the result in `g` +func (g *G1) ScalarMult(a *G1, scalar *big.Int) { + g.inner.ScalarMultiplication(&a.inner, scalar) +} + +// Unmarshal deserializes `buf` into `g` +// +// Note: whether the deserialization is of a compressed +// or an uncompressed point, is encoded in the bytes. +// +// For our purpose, the point will always be serialized +// as uncompressed, ie 64 bytes. +// +// This method also checks whether the point is on the +// curve and in the prime order subgroup. +func (g *G1) Unmarshal(buf []byte) (int, error) { + return g.inner.SetBytes(buf) +} + +// Marshal serializes the point into a byte slice. +// +// Note: The point is serialized as uncompressed. +func (p *G1) Marshal() []byte { + return p.inner.Marshal() +} diff --git a/crypto/bn256/gnark/g2.go b/crypto/bn256/gnark/g2.go new file mode 100644 index 000000000000..205373a59194 --- /dev/null +++ b/crypto/bn256/gnark/g2.go @@ -0,0 +1,38 @@ +package bn256 + +import ( + "github.com/consensys/gnark-crypto/ecc/bn254" +) + +// G2 is the affine representation of a G2 group element. +// +// Since this code is used for precompiles, using Jacobian +// points are not beneficial because there are no intermediate +// points and G2 in particular is only used for the pairing input. +// +// Note: We also use this struct so that we can conform to the existing API +// that the precompiles want. +type G2 struct { + inner bn254.G2Affine +} + +// Unmarshal deserializes `buf` into `g` +// +// Note: whether the deserialization is of a compressed +// or an uncompressed point, is encoded in the bytes. +// +// For our purpose, the point will always be serialized +// as uncompressed, ie 128 bytes. +// +// This method also checks whether the point is on the +// curve and in the prime order subgroup. +func (g *G2) Unmarshal(buf []byte) (int, error) { + return g.inner.SetBytes(buf) +} + +// Marshal serializes the point into a byte slice. +// +// Note: The point is serialized as uncompressed. +func (g *G2) Marshal() []byte { + return g.inner.Marshal() +} diff --git a/crypto/bn256/gnark/gt.go b/crypto/bn256/gnark/gt.go new file mode 100644 index 000000000000..c30022c5f898 --- /dev/null +++ b/crypto/bn256/gnark/gt.go @@ -0,0 +1,65 @@ +package bn256 + +import ( + "fmt" + "math/big" + + "github.com/consensys/gnark-crypto/ecc/bn254" +) + +// GT is the affine representation of a GT field element. +// +// Note: GT is not explicitly used in mainline code. +// It is needed for fuzzing. +type GT struct { + inner bn254.GT +} + +// Pair compute the optimal Ate pairing between a G1 and +// G2 element. +// +// Note: This method is not explicitly used in mainline code. +// It is needed for fuzzing. It should also be noted, +// that the output of this function may not match other +func Pair(a_ *G1, b_ *G2) *GT { + a := a_.inner + b := b_.inner + + pairingOutput, err := bn254.Pair([]bn254.G1Affine{a}, []bn254.G2Affine{b}) + + if err != nil { + // Since this method is only called during fuzzing, it is okay to panic here. + // We do not return an error to match the interface of the other bn256 libraries. + panic(fmt.Sprintf("gnark/bn254 encountered error: %v", err)) + } + + return >{ + inner: pairingOutput, + } +} + +// Unmarshal deserializes `buf` into `g` +// +// Note: This method is not explicitly used in mainline code. +// It is needed for fuzzing. +func (g *GT) Unmarshal(buf []byte) error { + return g.inner.SetBytes(buf) +} + +// Marshal serializes the point into a byte slice. +// +// Note: This method is not explicitly used in mainline code. +// It is needed for fuzzing. +func (g *GT) Marshal() []byte { + bytes := g.inner.Bytes() + return bytes[:] +} + +// Exp raises `base` to the power of `exponent` +// +// Note: This method is not explicitly used in mainline code. +// It is needed for fuzzing. +func (g *GT) Exp(base GT, exponent *big.Int) *GT { + g.inner.Exp(base.inner, exponent) + return g +} diff --git a/crypto/bn256/gnark/pairing.go b/crypto/bn256/gnark/pairing.go new file mode 100644 index 000000000000..39e8a657f466 --- /dev/null +++ b/crypto/bn256/gnark/pairing.go @@ -0,0 +1,73 @@ +package bn256 + +import ( + "github.com/consensys/gnark-crypto/ecc/bn254" +) + +// Computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1 +// +// To explain why gnark returns a (bool, error): +// +// - If the function `e` does not return a result then internally +// an error is returned. +// - If `e` returns a result, then error will be nil, +// but if this value is not `1` then the boolean value will be false +// +// We therefore check for an error, and return false if its non-nil and +// then return the value of the boolean if not. +func PairingCheck(a_ []*G1, b_ []*G2) bool { + a := getInnerG1s(a_) + b := getInnerG2s(b_) + + // Assume that len(a) == len(b) + // + // The pairing function will return + // false, if this is not the case. + size := len(a) + + // Check if input is empty -- gnark will + // return false on an empty input, however + // the ossified behavior is to return true + // on an empty input, so we add this if statement. + if size == 0 { + return true + } + + ok, err := bn254.PairingCheck(a, b) + if err != nil { + return false + } + return ok +} + +// getInnerG1s gets the inner gnark G1 elements. +// +// These methods are used for two reasons: +// +// - We use a new type `G1`, so we need to convert from +// []*G1 to []*bn254.G1Affine +// - The gnark API accepts slices of values and not slices of +// pointers to values, so we need to return []bn254.G1Affine +// instead of []*bn254.G1Affine. +func getInnerG1s(pointerSlice []*G1) []bn254.G1Affine { + gnarkValues := make([]bn254.G1Affine, 0, len(pointerSlice)) + for _, ptr := range pointerSlice { + if ptr != nil { + gnarkValues = append(gnarkValues, ptr.inner) + } + } + return gnarkValues +} + +// getInnerG2s gets the inner gnark G2 elements. +// +// The rationale for this method is the same as `getInnerG1s`. +func getInnerG2s(pointerSlice []*G2) []bn254.G2Affine { + gnarkValues := make([]bn254.G2Affine, 0, len(pointerSlice)) + for _, ptr := range pointerSlice { + if ptr != nil { + gnarkValues = append(gnarkValues, ptr.inner) + } + } + return gnarkValues +} diff --git a/tests/fuzzers/bn256/bn256_fuzz.go b/tests/fuzzers/bn256/bn256_fuzz.go index 972eaf4b5ebe..02ec37138dfb 100644 --- a/tests/fuzzers/bn256/bn256_fuzz.go +++ b/tests/fuzzers/bn256/bn256_fuzz.go @@ -23,11 +23,11 @@ import ( "math/big" cloudflare "github.com/XinFinOrg/XDPoSChain/crypto/bn256/cloudflare" + gnark "github.com/XinFinOrg/XDPoSChain/crypto/bn256/gnark" google "github.com/XinFinOrg/XDPoSChain/crypto/bn256/google" - "github.com/consensys/gnark-crypto/ecc/bn254" ) -func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1, *bn254.G1Affine) { +func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1, *gnark.G1) { _, xc, err := cloudflare.RandomG1(input) if err != nil { // insufficient input @@ -37,14 +37,14 @@ func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1, *bn254.G1Affine) if _, err := xg.Unmarshal(xc.Marshal()); err != nil { panic(fmt.Sprintf("Could not marshal cloudflare -> google: %v", err)) } - xs := new(bn254.G1Affine) - if err := xs.Unmarshal(xc.Marshal()); err != nil { + xs := new(gnark.G1) + if _, err := xs.Unmarshal(xc.Marshal()); err != nil { panic(fmt.Sprintf("Could not marshal cloudflare -> gnark: %v", err)) } return xc, xg, xs } -func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine) { +func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *gnark.G2) { _, xc, err := cloudflare.RandomG2(input) if err != nil { // insufficient input @@ -54,14 +54,14 @@ func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine) if _, err := xg.Unmarshal(xc.Marshal()); err != nil { panic(fmt.Sprintf("Could not marshal cloudflare -> google: %v", err)) } - xs := new(bn254.G2Affine) - if err := xs.Unmarshal(xc.Marshal()); err != nil { + xs := new(gnark.G2) + if _, err := xs.Unmarshal(xc.Marshal()); err != nil { panic(fmt.Sprintf("Could not marshal cloudflare -> gnark: %v", err)) } return xc, xg, xs } -// fuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries. +// fuzzAdd fuzzes bn256 addition between the Google, Cloudflare and Gnark libraries. func fuzzAdd(data []byte) int { input := bytes.NewReader(data) xc, xg, xs := getG1Points(input) @@ -72,7 +72,7 @@ func fuzzAdd(data []byte) int { if yc == nil { return 0 } - // Ensure both libs can parse the second curve point + // Ensure libs can parse the second curve point // Add the two points and ensure they result in the same output rc := new(cloudflare.G1) rc.Add(xc, yc) @@ -80,9 +80,8 @@ func fuzzAdd(data []byte) int { rg := new(google.G1) rg.Add(xg, yg) - tmpX := new(bn254.G1Jac).FromAffine(xs) - tmpY := new(bn254.G1Jac).FromAffine(ys) - rs := new(bn254.G1Affine).FromJacobian(tmpX.AddAssign(tmpY)) + rs := new(gnark.G1) + rs.Add(xs, ys) if !bytes.Equal(rc.Marshal(), rg.Marshal()) { panic("add mismatch: cloudflare/google") @@ -94,8 +93,8 @@ func fuzzAdd(data []byte) int { return 1 } -// fuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare -// libraries. +// fuzzMul fuzzes bn256 scalar multiplication between the Google, Cloudflare +// and Gnark libraries. func fuzzMul(data []byte) int { input := bytes.NewReader(data) pc, pg, ps := getG1Points(input) @@ -122,15 +121,13 @@ func fuzzMul(data []byte) int { rg := new(google.G1) rg.ScalarMult(pg, new(big.Int).SetBytes(buf)) - rs := new(bn254.G1Jac) - psJac := new(bn254.G1Jac).FromAffine(ps) - rs.ScalarMultiplication(psJac, new(big.Int).SetBytes(buf)) - rsAffine := new(bn254.G1Affine).FromJacobian(rs) + rs := new(gnark.G1) + rs.ScalarMult(ps, new(big.Int).SetBytes(buf)) if !bytes.Equal(rc.Marshal(), rg.Marshal()) { panic("scalar mul mismatch: cloudflare/google") } - if !bytes.Equal(rc.Marshal(), rsAffine.Marshal()) { + if !bytes.Equal(rc.Marshal(), rs.Marshal()) { panic("scalar mul mismatch: cloudflare/gnark") } return 1 @@ -150,17 +147,26 @@ func fuzzPair(data []byte) int { // Pair the two points and ensure they result in the same output clPair := cloudflare.Pair(pc, tc).Marshal() gPair := google.Pair(pg, tg).Marshal() + sPair := gnark.Pair(ps, ts).Marshal() + if !bytes.Equal(clPair, gPair) { panic("pairing mismatch: cloudflare/google") } - cPair, err := bn254.Pair([]bn254.G1Affine{*ps}, []bn254.G2Affine{*ts}) - if err != nil { - panic(fmt.Sprintf("gnark/bn254 encountered error: %v", err)) + + normalizedClPair := normalizeGTToGnark(clPair).Marshal() + if !bytes.Equal(normalizedClPair, sPair) { + panic("pairing mismatch: cloudflare/gnark") } - // gnark uses a different pairing algorithm which might produce - // different but also correct outputs, we need to scale the output by s + return 1 +} +// normalizeGTToGnark scales a Cloudflare/Google GT element by `s` +// so that it can be compared with a gnark GT point. +// +// For the definition of `s` see 3.5 in https://eprint.iacr.org/2015/192.pdf +func normalizeGTToGnark(cloudflareOrGoogleGT []byte) *gnark.GT { + // Compute s = 2*u(6*u^2 + 3*u + 1) u, _ := new(big.Int).SetString("0x44e992b44a6909f1", 0) u_exp2 := new(big.Int).Exp(u, big.NewInt(2), nil) // u^2 u_6_exp2 := new(big.Int).Mul(big.NewInt(6), u_exp2) // 6*u^2 @@ -170,14 +176,12 @@ func fuzzPair(data []byte) int { u_2 := new(big.Int).Mul(big.NewInt(2), u) // 2*u s := u_2.Mul(u_2, inner) // 2*u(6*u^2 + 3*u + 1) - gRes := new(bn254.GT) - if err := gRes.SetBytes(clPair); err != nil { + // Scale the Cloudflare/Google GT element by `s` + gRes := new(gnark.GT) + if err := gRes.Unmarshal(cloudflareOrGoogleGT); err != nil { panic(err) } gRes = gRes.Exp(*gRes, s) - if !bytes.Equal(cPair.Marshal(), gRes.Marshal()) { - panic("pairing mismatch: cloudflare/gnark") - } - return 1 + return gRes } From 9ca3d10001401b02f07004b454cea97dfab2dd78 Mon Sep 17 00:00:00 2001 From: gitglorythegreat Date: Thu, 2 Jan 2025 21:04:06 +0800 Subject: [PATCH 112/121] crypto/bn256: fix MulScalar (#30974) The `a` parameter should be used in the `MulScalar` function. The upstream cloudflare and google repos have already merged fixes. Reference: * https://cs.opensource.google/go/x/crypto/+/8d7daa0c54b357f3071e11eaef7efc4e19a417e2 * https://github.com/cloudflare/bn256/pull/33 --- crypto/bn256/cloudflare/gfp12.go | 4 ++-- crypto/bn256/google/gfp12.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/bn256/cloudflare/gfp12.go b/crypto/bn256/cloudflare/gfp12.go index 93fb368a7bf0..767350701f2d 100644 --- a/crypto/bn256/cloudflare/gfp12.go +++ b/crypto/bn256/cloudflare/gfp12.go @@ -105,8 +105,8 @@ func (e *gfP12) Mul(a, b *gfP12) *gfP12 { } func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { - e.x.Mul(&e.x, b) - e.y.Mul(&e.y, b) + e.x.Mul(&a.x, b) + e.y.Mul(&a.y, b) return e } diff --git a/crypto/bn256/google/gfp12.go b/crypto/bn256/google/gfp12.go index f084eddf2126..2b0151ebcc49 100644 --- a/crypto/bn256/google/gfp12.go +++ b/crypto/bn256/google/gfp12.go @@ -125,8 +125,8 @@ func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 { } func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 { - e.x.Mul(e.x, b, pool) - e.y.Mul(e.y, b, pool) + e.x.Mul(a.x, b, pool) + e.y.Mul(a.y, b, pool) return e } From 7091b934a52ddfc2d57586934f38d02e26f679bd Mon Sep 17 00:00:00 2001 From: Wanwiset Peerapatanapokin Date: Fri, 10 Jan 2025 15:44:00 +0700 Subject: [PATCH 113/121] ignore error and remove old function (#791) --- .github/workflows/ci.yml | 81 ++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ca0550c3db1..19d914017d70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,24 +116,25 @@ jobs: echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config chmod 600 $HOME/.kube/config git_hash=$(git rev-parse --short "$GITHUB_SHA") - kubectl set image deployment/devnet1 devnet1=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet2 devnet2=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet3 devnet3=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet4 devnet4=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet5 devnet5=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet6 devnet6=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet7 devnet7=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet8 devnet8=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet9 devnet9=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet10 devnet10=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet11 devnet11=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet12 devnet12=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet13 devnet13=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet14 devnet14=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet15 devnet15=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet16 devnet16=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet17 devnet17=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/devnet18 devnet18=xinfinorg/devnet:dev-upgrade-${git_hash} + kubectl set image deployment/devnet1 devnet1=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet2 devnet2=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet3 devnet3=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet4 devnet4=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet5 devnet5=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet6 devnet6=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet7 devnet7=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet8 devnet8=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet9 devnet9=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet10 devnet10=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet11 devnet11=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet12 devnet12=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet13 devnet13=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet14 devnet14=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet15 devnet15=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet16 devnet16=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet17 devnet17=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet18 devnet18=xinfinorg/devnet:dev-upgrade-${git_hash} || + echo done rpc_k8_apply: runs-on: ubuntu-latest @@ -151,43 +152,17 @@ jobs: echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config chmod 600 $HOME/.kube/config git_hash=$(git rev-parse --short "$GITHUB_SHA") - kubectl set image deployment/devnetrpc devnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/testnetrpc testnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} - kubectl set image deployment/mainnetrpc mainnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} - - rpcnode_terraform_apply: + kubectl set image deployment/devnetrpc devnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/testnetrpc testnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/mainnetrpc mainnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} || + echo done + + devnet_send_notification: runs-on: ubuntu-latest + needs: devnet_k8_apply if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') - needs: devnet_build_push - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} steps: - uses: actions/checkout@v4 - - name: Terraform Apply + - name: Send deployment notification run: | - cd cicd/terraform - terraform init ${{ env.tf_init_cli_options }} - terraform apply ${{ env.tf_apply_cli_options }} - - - name: Update RPC nodes image - uses: dawidd6/action-ansible-playbook@v2 - with: - playbook: playbooks/update-image.yaml - directory: ./cicd/ansible - key: ${{secrets.SSH_PRIVATE_KEY_DEVNET}} - options: | - --inventory inventory.yaml - --extra-vars network=ec2_rpcs - --extra-vars rpc_image=${{ needs.devnet_build_push.outputs.output1 }} - - # TODO Uncomment until new devnet - # devnet_send_notification: - # runs-on: ubuntu-latest - # needs: devnet_terraform_apply - # if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') - # steps: - # - uses: actions/checkout@v4 - # - name: Send deployment notification - # run: | - # curl --location --request POST "66.94.98.186:8080/deploy?environment=devnet&service=xdc&version=${GITHUB_SHA}" + curl --location --request POST "66.94.98.186:8080/deploy?environment=devnet&service=xdc&version=${GITHUB_SHA}" From baea5d3da7b775acdcd496dc578271bea482584b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Sat, 11 Jan 2025 16:58:59 +0800 Subject: [PATCH 114/121] build: support golangci-lint v1.63.4 --- .gitignore | 1 + .golangci.yml | 79 ++++++++++ Makefile | 18 ++- build/checksums.txt | 126 ++++++++++++++++ build/ci.go | 53 ++++--- go.mod | 2 + internal/build/archive.go | 296 +++++++++++++++++++++++++++++++++++++ internal/build/download.go | 151 +++++++++++++++++++ internal/build/gotool.go | 180 ++++++++++++++++++++++ internal/build/util.go | 39 ++++- 10 files changed, 924 insertions(+), 21 deletions(-) create mode 100644 .golangci.yml create mode 100644 build/checksums.txt create mode 100644 internal/build/archive.go create mode 100644 internal/build/download.go create mode 100644 internal/build/gotool.go diff --git a/.gitignore b/.gitignore index 1a85f2f558a2..3ee7e66bfe84 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build/_vendor/pkg # used by the Makefile /build/_workspace/ +/build/cache/ /build/bin/ /XDC*.zip diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000000..3f8fb3078236 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,79 @@ +# This file configures github.com/golangci/golangci-lint. + +run: + timeout: 20m + tests: true + +linters: + disable-all: true + enable: + - goimports + - gosimple + - govet + - ineffassign + - misspell + - unconvert + - typecheck + - unused + - staticcheck + - bidichk + - durationcheck + - copyloopvar + - whitespace + - revive # only certain checks enabled + - durationcheck + - gocheckcompilerdirectives + - reassign + - mirror + - tenv + ### linters we tried and will not be using: + ### + # - structcheck # lots of false positives + # - errcheck #lot of false positives + # - contextcheck + # - errchkjson # lots of false positives + # - errorlint # this check crashes + # - exhaustive # silly check + # - makezero # false positives + # - nilerr # several intentional + +linters-settings: + gofmt: + simplify: true + revive: + enable-all-rules: false + # here we enable specific useful rules + # see https://golangci-lint.run/usage/linters/#revive for supported rules + rules: + - name: receiver-naming + severity: warning + disabled: false + exclude: [""] + +issues: + # default is true. Enables skipping of directories: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + exclude-dirs-use-default: true + exclude-files: + - core/genesis_alloc.go + exclude-rules: + - path: crypto/bn256/cloudflare/optate.go + linters: + - deadcode + - staticcheck + - path: crypto/bn256/ + linters: + - revive + - path: cmd/utils/flags.go + text: "SA1019: cfg.TxLookupLimit is deprecated: use 'TransactionHistory' instead." + - path: cmd/utils/flags.go + text: "SA1019: ethconfig.Defaults.TxLookupLimit is deprecated: use 'TransactionHistory' instead." + - path: internal/build/pgp.go + text: 'SA1019: "golang.org/x/crypto/openpgp" is deprecated: this package is unmaintained except for security fixes.' + - path: core/vm/contracts.go + text: 'SA1019: "golang.org/x/crypto/ripemd160" is deprecated: RIPEMD-160 is a legacy hash and should not be used for new applications.' + exclude: + - 'SA1019: event.TypeMux is deprecated: use Feed' + - 'SA1019: strings.Title is deprecated' + - 'SA1019: strings.Title has been deprecated since Go 1.18 and an alternative has been available since Go 1.0: The rule Title uses for word boundaries does not handle Unicode punctuation properly. Use golang.org/x/text/cases instead.' + - 'SA1029: should not use built-in type string as key for value' diff --git a/Makefile b/Makefile index 3bd726906ce2..e92835b952a0 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +# This Makefile is meant to be used by people that do not usually work +# with Go source code. If you know what GOPATH is then you probably +# don't need to bother with make. + .PHONY: XDC XDC-cross evm all test clean .PHONY: XDC-linux XDC-linux-386 XDC-linux-amd64 XDC-linux-mips64 XDC-linux-mips64le .PHONY: XDC-darwin XDC-darwin-386 XDC-darwin-amd64 @@ -5,11 +9,12 @@ GOBIN = $(shell pwd)/build/bin GOFMT = gofmt GO ?= 1.22.10 +GORUN = go run GO_PACKAGES = . GO_FILES := $(shell find $(shell go list -f '{{.Dir}}' $(GO_PACKAGES)) -name \*.go) - GIT = git +#? XDC: Build XDC. XDC: go run build/ci.go install ./cmd/XDC @echo "Done building." @@ -41,15 +46,26 @@ puppeth: @echo "Done building." @echo "Run \"$(GOBIN)/puppeth\" to launch puppeth." +#? all: Build all packages and executables. all: go run build/ci.go install +#? test: Run the tests. test: all go run build/ci.go test +#? lint: Run certain pre-selected linters. +lint: ## Run linters. + $(GORUN) build/ci.go lint + +#? clean: Clean go cache, built executables, and the auto generated folder. clean: rm -fr build/_workspace/pkg/ $(GOBIN)/* +#? fmt: Ensure consistent code formatting. +fmt: + gofmt -s -w $(shell find . -name "*.go") + # Cross Compilation Targets (xgo) XDC-cross: XDC-windows-amd64 XDC-darwin-amd64 XDC-linux diff --git a/build/checksums.txt b/build/checksums.txt new file mode 100644 index 000000000000..1484e6499f65 --- /dev/null +++ b/build/checksums.txt @@ -0,0 +1,126 @@ +# This file contains sha256 checksums of optional build dependencies. + +# version:spec-tests 2.1.0 +# https://github.com/ethereum/execution-spec-tests/releases +# https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/ +ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz + +# version:golang 1.22.10 +# https://go.dev/dl/ +1e94fd48be750d1fafb4d9b3b6dd31a6e9d2735d339bf2462bc97b64ca4c1037 go1.22.10.src.tar.gz +dd2c4ac3702658c2c20e3a8b394da1917d86156b2cb4312c9d2f657f80067874 go1.22.10.darwin-amd64.tar.gz +9d37bf96bbdd1669f1ab771c98ac7695f1b49df3c5c2bf10b699950f0fc2f52b go1.22.10.darwin-amd64.pkg +21cf49415ffe0755b45f2b63e75d136528a32f7bb7bdd0166f51d22a03eb0a3f go1.22.10.darwin-arm64.tar.gz +746558a1e677a469b297ed885d94d0cdc3410d2153f49f0109c833f5283e1ad1 go1.22.10.darwin-arm64.pkg +2ae9f00e9621489b75494fa2b8abfc5d09e0cae6effdd4c13867957ad2e4deba go1.22.10.linux-386.tar.gz +736ce492a19d756a92719a6121226087ccd91b652ed5caec40ad6dbfb2252092 go1.22.10.linux-amd64.tar.gz +5213c5e32fde3bd7da65516467b7ffbfe40d2bb5a5f58105e387eef450583eec go1.22.10.linux-arm64.tar.gz +a7bbbc80fe736269820bbdf3555e91ada5d18a5cde2276aac3b559bc1d52fc70 go1.22.10.linux-armv6l.tar.gz +20019b2e60dd0cdf63e4ec26852c1c015c1a27580b32a512b4be33a2539113ae go1.22.10.windows-386.zip +d6f7c00af6d54f09bf5b137cda0b34f75b1ac6fb95abe5a948240110f99d8fad go1.22.10.windows-386.msi +da66f107a0f4959f4615bede230c6bf145a6f01252c6d1ff2b107e293ba339df go1.22.10.windows-amd64.zip +454c45de32d325f175dc9ccd262944aec0d24b12c47a8f6d4000adad9f271adc go1.22.10.windows-amd64.msi +46af3f2506a8887ed1de0e38244730a2ba944cfed7804d6baa9773790d2a294d go1.22.10.aix-ppc64.tar.gz +1684ae4c10c4d30e6f4950fbb71d9cc096d0541e5cf769b3195e91f475249d9a go1.22.10.dragonfly-amd64.tar.gz +f82f5d194114963693e0f51fd56d55d8417ca556438062f2b0df608473b62837 go1.22.10.freebsd-386.tar.gz +cce9da240870a4430c5cf1227bcf29d37575043ff16f7982a69f1139c6f564b5 go1.22.10.freebsd-amd64.tar.gz +abae388d0d42563a242db0d405172cb73e09236f68000ff90c2a327ec8c5764c go1.22.10.freebsd-arm64.tar.gz +7c9c8fe30cbabbb4fb597f0f0ad1279fd2b320bc70831eba4c207b55ad46931d go1.22.10.freebsd-arm.tar.gz +d6f25fd79e17b84d1b61bec3e2fdffc47377b28b51a04b6bdbeac0199313e059 go1.22.10.freebsd-riscv64.tar.gz +4a1121d8331208cb614c6f0474b0e4fa3c3023c5e8a88fb8d37f7e3454589aa2 go1.22.10.illumos-amd64.tar.gz +0be34dbc69726b52414e0283736f997fee477379ebff66cebd7d8c35f4f64f9d go1.22.10.linux-loong64.tar.gz +bb7d7e99db7ee70063cb57bb7395c392b8b5ed87f37d733a1c91de935c70bb91 go1.22.10.linux-mips.tar.gz +c7f0571410297cb29e52d10fed7a2a21aeaeabb9539d0c04a6d778adf0fe7f1b go1.22.10.linux-mips64.tar.gz +e66c440c03dd19bf8423034cbde7f6813321beb18d3fcf2ef234c13a25467952 go1.22.10.linux-mips64le.tar.gz +b4e0061f62a9c1f874893aa4951a4883c19762a9dd64c5710554ec5a7aaf311a go1.22.10.linux-mipsle.tar.gz +4192158cdedc6a124aa32a099cc6bebebabf1f4d380c46c5e36ea52c30a3888b go1.22.10.linux-ppc64.tar.gz +db05b9838f69d741fb9a5301220b1a62014aee025b0baf341aba3d280087b981 go1.22.10.linux-ppc64le.tar.gz +aef9b186c1b9b58c0472dbf54978f97682852a91b2e8d6bf354e59ba9c24438a go1.22.10.linux-riscv64.tar.gz +4ab2286adb096576771801b5099760b1d625fd7b44080449151a4d9b21303672 go1.22.10.linux-s390x.tar.gz +32e66f6ae2082cce98ccb557f54965ae5452e1b705470ae403446062938db1d5 go1.22.10.netbsd-386.tar.gz +e876962e6032175d049259559978c10af578dce506ffb064ce61e60a5b5308cb go1.22.10.netbsd-amd64.tar.gz +b95696f92afe5062d4e17c48cf0756699a7522fbfd1b034bfb1eb2b636d34163 go1.22.10.netbsd-arm64.tar.gz +9d5e08939b95dca7d102eae7a832813ee12337187786f548848b10503ddc80cc go1.22.10.netbsd-arm.tar.gz +5c4294fed0bf981f81b8be979e955516d0a78019990f2f7462246ef4bb3960e5 go1.22.10.openbsd-386.tar.gz +c72b4d4f4cedce007e4d52a0e496169b0739b3bbe7fa13bc1322fe3b79d55221 go1.22.10.openbsd-amd64.tar.gz +1a90e0fb2e6ca881b78692594f0e29834f738c593ea627a631f8e81cdddfdc32 go1.22.10.openbsd-arm64.tar.gz +f6153ebd844ccc21ec8420fecccf9214dc0a7a572b28234ec1e00e04b0f438bb go1.22.10.openbsd-arm.tar.gz +5fe1abee2805334404da9c4e2aedb93764b31d6de3fe9d3cb49a2fd844992f68 go1.22.10.openbsd-ppc64.tar.gz +834fe42edf63a67b7b6c57fcfd1e8b159842f3615bfbc975b5ceed994db7e834 go1.22.10.plan9-386.tar.gz +9fa2282fccb668ef9e3cdb1fa3f0128994224f95267f54640779049df3bb3a6c go1.22.10.plan9-amd64.tar.gz +d66acc86e00ead41966bb599c26fda983a686232040996a307262e71b3576c48 go1.22.10.plan9-arm.tar.gz +40779a36f3f78b2ac1f3da5e6336f4fa24996d2412d5ca5685077103c8d3bbe2 go1.22.10.solaris-amd64.tar.gz +974656452fd7d104f34ee6e8ac92bb7431af84a1ce55226d9af485cb9ec23dd5 go1.22.10.windows-arm64.zip +f62491c8bbc811ddbdd25ee34af5bbd200f3d6086c1a3ebb64e435ce3b346a97 go1.22.10.windows-arm64.msi +de1fb78d98ebd054a6fce5b71d1dcd1d49a68db75e0b6fd3d98ae5818d81fdba go1.22.10.windows-arm.zip +5523272bb157db06311a907289c92caf59347d4b6721d407486256e61c593dc9 go1.22.10.windows-arm.msi + +# version:golangci 1.63.4 +# https://github.com/golangci/golangci-lint/releases/ +# https://github.com/golangci/golangci-lint/releases/download/v1.63.4/ +878d017cc360e4fb19510d39852c8189852e3c48e7ce0337577df73507c97d68 golangci-lint-1.63.4-darwin-amd64.tar.gz +a2b630c2ac8466393f0ccbbede4462387b6c190697a70bc2298c6d2123f21bbf golangci-lint-1.63.4-darwin-arm64.tar.gz +8938b74aa92888e561a1c5a4c175110b92f84e7d24733703e6d9ebc39e9cd5f8 golangci-lint-1.63.4-freebsd-386.tar.gz +054903339d620df2e760b978920100986e3b03bcb058f669d520a71dac9c34ed golangci-lint-1.63.4-freebsd-amd64.tar.gz +a19d499f961a02608348e8b626537a88edfaab6e1b6534f1eff742b5d6d750e4 golangci-lint-1.63.4-freebsd-armv6.tar.gz +00d616f0fb275b780ce4d26604bdd7fdbfe6bc9c63acd5a0b31498e1f7511108 golangci-lint-1.63.4-freebsd-armv7.tar.gz +d453688e0eabded3c1a97ff5a2777bb0df5a18851efdaaaf6b472e3e5713c33e golangci-lint-1.63.4-illumos-amd64.tar.gz +6b1bec847fc9f347d53712d05606a49d55d0e3b5c1bacadfed2393f3503de0e9 golangci-lint-1.63.4-linux-386.tar.gz +01abb14a4df47b5ca585eff3c34b105023cba92ec34ff17212dbb83855581690 golangci-lint-1.63.4-linux-amd64.tar.gz +51f0c79d19a92353e0465fb30a4901a0644a975d34e6f399ad2eebc0160bbb24 golangci-lint-1.63.4-linux-arm64.tar.gz +8d0a43f41e8424fbae10f7aa2dc29999f98112817c6dba63d7dc76832940a673 golangci-lint-1.63.4-linux-armv6.tar.gz +1045a047b31e9302c9160c7b0f199f4ac1bd02a1b221a2d9521bd3507f0cf671 golangci-lint-1.63.4-linux-armv7.tar.gz +933fe10ab50ce3bb0806e15a4ae69fe20f0549abf91dea0161236000ca706e67 golangci-lint-1.63.4-linux-loong64.tar.gz +45798630cbad5642862766051199fa862ef3c33d569cab12f01cac4f68e2ddd5 golangci-lint-1.63.4-linux-mips64.tar.gz +86ae25335ddb24975d2c915c1af0c7fad70dce99d0b4614fa4bee392de714aa2 golangci-lint-1.63.4-linux-mips64le.tar.gz +33dabd11aaba4b602938da98bcf49aabab55019557e0115cdc3dbcc3009768fa golangci-lint-1.63.4-linux-ppc64le.tar.gz +4e7a81230a663bcdf30bba5689ce96040abc76994dbc2003dce32c8dca8c06f3 golangci-lint-1.63.4-linux-riscv64.tar.gz +21370b49c7c47f4d9b8f982c952f940b01e65710174c3b4dad7b6452d58f92ec golangci-lint-1.63.4-linux-s390x.tar.gz +255866a6464c7e11bb7edd8e6e6ad54f11e1f01b82ba9ca229698ac788cd9724 golangci-lint-1.63.4-netbsd-386.tar.gz +2798c040ac658bda97224f204795199c81ac97bb207b21c02b664aaed380d5d2 golangci-lint-1.63.4-netbsd-amd64.tar.gz +b910eecffd0064103837e7e1abe870deb8ade22331e6dffe319f430d49399c8e golangci-lint-1.63.4-netbsd-arm64.tar.gz +df2693ef37147b457c3e2089614537dd2ae2e18e53641e756a5b404f4c72d3fa golangci-lint-1.63.4-netbsd-armv6.tar.gz +a28a533366974bd7834c4516cd6075bff3419a508d1ed7aa63ae8182768b352e golangci-lint-1.63.4-netbsd-armv7.tar.gz +368932775fb5c620b324dabf018155f3365f5e33c5af5b26e9321db373f96eea golangci-lint-1.63.4-windows-386.zip +184d13c2b8f5441576bec2a0d8ba7b2d45445595cf796b879a73bcc98c39f8c1 golangci-lint-1.63.4-windows-amd64.zip +4fabf175d5b05ef0858ded49527948eebac50e9093814979fd84555a75fb80a6 golangci-lint-1.63.4-windows-arm64.zip +e92be3f3ff30d4a849fb4b9a4c8d56837dee45269cb405a3ecad52fa034c781b golangci-lint-1.63.4-windows-armv6.zip +c71d348653b8f7fbb109bb10c1a481722bc6b0b2b6e731b897f99ac869f7653e golangci-lint-1.63.4-windows-armv7.zip + +# This is the builder on PPA that will build Go itself (inception-y), don't modify! +# +# This version is fine to be old and full of security holes, we just use it +# to build the latest Go. Don't change it. +# +# version:ppa-builder-1 1.19.6 +# https://go.dev/dl/ +d7f0013f82e6d7f862cc6cb5c8cdb48eef5f2e239b35baa97e2f1a7466043767 go1.19.6.src.tar.gz + +# version:ppa-builder-2 1.21.9 +# https://go.dev/dl/ +58f0c5ced45a0012bce2ff7a9df03e128abcc8818ebabe5027bb92bafe20e421 go1.21.9.src.tar.gz + +# version:protoc 27.1 +# https://github.com/protocolbuffers/protobuf/releases/ +# https://github.com/protocolbuffers/protobuf/releases/download/v27.1/ +8809c2ec85368c6b6e9af161b6771a153aa92670a24adbe46dd34fa02a04df2f protoc-27.1-linux-aarch_64.zip +5d21979a6d27475e810b76b88863d1e784fa01ffb15e511a3ec5bd1924d89426 protoc-27.1-linux-ppcle_64.zip +84d8852750ed186dc4a057a1a86bcac409be5362d6af04770f42367fee6b7bc1 protoc-27.1-linux-s390_64.zip +2f028796ff5741691650e0eea290e61ff2f1c0d87f8d31fe45ef47fd967cef0c protoc-27.1-linux-x86_32.zip +8970e3d8bbd67d53768fe8c2e3971bdd71e51cfe2001ca06dacad17258a7dae3 protoc-27.1-linux-x86_64.zip +03b7af1bf469e7285dc51976ee5fa99412704dbd1c017105114852a37b165c12 protoc-27.1-osx-aarch_64.zip +f14d3973cf13283d07c520ed6f4c12405ad41b9efd18089a1c74897037d742b5 protoc-27.1-osx-universal_binary.zip +8520d944f3a3890fa296a3b3b0d4bb18337337e2526bbbf1b507eeea3c2a1ec4 protoc-27.1-osx-x86_64.zip +6263718ff96547b8392a079f6fdf02a4156f2e8d13cd51649a0d03fb7afa2de8 protoc-27.1-win32.zip +da531c51ccd1290d8d34821f0ce4e219c7fbaa6f9825f5a3fb092a9d03fe6206 protoc-27.1-win64.zip + +# version:protoc-gen-go 1.34.2 +# https://github.com/protocolbuffers/protobuf-go/releases/ +# https://github.com/protocolbuffers/protobuf-go/releases/download/v1.34.2/ +9b48d8f90add02e8e94e14962fed74e7ce2b2d6bda4dd42f1f4fbccf0f766f1a protoc-gen-go.v1.34.2.darwin.amd64.tar.gz +17aca7f948dbb624049030cf841e35895cf34183ba006e721247fdeb95ff2780 protoc-gen-go.v1.34.2.darwin.arm64.tar.gz +a191849433fd489f1d44f37788d762658f3f5fb225f3a85d4ce6ba32666703ed protoc-gen-go.v1.34.2.linux.386.tar.gz +b87bc134dee55576a842141bf0ed27761c635d746780fce5dee038c6dd16554f protoc-gen-go.v1.34.2.linux.amd64.tar.gz +63d400167e75ab9f6690688f6fdc6a9455aa20bc1faa71e32149dbd322f7f198 protoc-gen-go.v1.34.2.linux.arm64.tar.gz +56e7675816db6e62be4f833a51544d5716b8420c462515579e05ca8444ab06ed protoc-gen-go.v1.34.2.windows.386.zip +abafd39612177dd4e9a65207cadd5374a9352d8611e8e040f8462fcfa3010daf protoc-gen-go.v1.34.2.windows.amd64.zip diff --git a/build/ci.go b/build/ci.go index ff3ea89d10f6..3bdb52a7a32e 100644 --- a/build/ci.go +++ b/build/ci.go @@ -246,37 +246,52 @@ func doTest(cmdline []string) { build.MustRun(gotest) } +// doLint runs golangci-lint on requested packages. func doLint(cmdline []string) { + var ( + cachedir = flag.String("cachedir", "./build/cache", "directory for caching golangci-lint binary.") + ) flag.CommandLine.Parse(cmdline) - packages := []string{"./..."} if len(flag.CommandLine.Args()) > 0 { packages = flag.CommandLine.Args() } - // Get golangci-lint and install all supported linters - build.MustRun(goTool("get", "github.com/golangci/golangci-lint/cmd/golangci-lint@v1.18.0")) - - // Run fast linters batched together - configs := []string{ - "run", - "--disable-all", - "--enable=vet", - "--enable=gofmt", - "--enable=misspell", - "--enable=goconst", - "--min-occurrences=6", // for goconst + + linter := downloadLinter(*cachedir) + lflags := []string{"run", "--config", ".golangci.yml"} + build.MustRunCommandWithOutput(linter, append(lflags, packages...)...) + fmt.Println("You have achieved perfection.") +} + +// downloadLinter downloads and unpacks golangci-lint. +func downloadLinter(cachedir string) string { + csdb := build.MustLoadChecksums("build/checksums.txt") + version, err := build.Version(csdb, "golangci") + if err != nil { + log.Fatal(err) } - build.MustRunCommand(filepath.Join(GOBIN, "golangci-lint"), append(configs, packages...)...) + arch := runtime.GOARCH + ext := ".tar.gz" - // Run slow linters one by one - for _, linter := range []string{"unconvert", "gosimple"} { - configs = []string{"--vendor", "--deadline=10m", "--disable-all", "--enable=" + linter} - build.MustRunCommand(filepath.Join(GOBIN, "golangci-lint"), append(configs, packages...)...) + if runtime.GOOS == "windows" { + ext = ".zip" + } + if arch == "arm" { + arch += "v" + os.Getenv("GOARM") + } + base := fmt.Sprintf("golangci-lint-%s-%s-%s", version, runtime.GOOS, arch) + url := fmt.Sprintf("https://github.com/golangci/golangci-lint/releases/download/v%s/%s%s", version, base, ext) + archivePath := filepath.Join(cachedir, base+ext) + if err := csdb.DownloadFile(url, archivePath); err != nil { + log.Fatal(err) } + if err := build.ExtractArchive(archivePath, cachedir); err != nil { + log.Fatal(err) + } + return filepath.Join(cachedir, base, "golangci-lint") } // Cross compilation - func doXgo(cmdline []string) { var ( alltools = flag.Bool("alltools", false, `Flag whether we're building all known tools, or only on in particular`) diff --git a/go.mod b/go.mod index 3b58b4c90cdc..9b6faf749c1b 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/XinFinOrg/XDPoSChain go 1.22 +toolchain go1.22.0 + require ( github.com/VictoriaMetrics/fastcache v1.12.2 github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 diff --git a/internal/build/archive.go b/internal/build/archive.go new file mode 100644 index 000000000000..645921c690a7 --- /dev/null +++ b/internal/build/archive.go @@ -0,0 +1,296 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package build + +import ( + "archive/tar" + "archive/zip" + "compress/gzip" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "time" +) + +type Archive interface { + // Directory adds a new directory entry to the archive and sets the + // directory for subsequent calls to Header. + Directory(name string) error + + // Header adds a new file to the archive. The file is added to the directory + // set by Directory. The content of the file must be written to the returned + // writer. + Header(os.FileInfo) (io.Writer, error) + + // Close flushes the archive and closes the underlying file. + Close() error +} + +func NewArchive(file *os.File) (Archive, string) { + switch { + case strings.HasSuffix(file.Name(), ".zip"): + return NewZipArchive(file), strings.TrimSuffix(file.Name(), ".zip") + case strings.HasSuffix(file.Name(), ".tar.gz"): + return NewTarballArchive(file), strings.TrimSuffix(file.Name(), ".tar.gz") + default: + return nil, "" + } +} + +// AddFile appends an existing file to an archive. +func AddFile(a Archive, file string) error { + fd, err := os.Open(file) + if err != nil { + return err + } + defer fd.Close() + fi, err := fd.Stat() + if err != nil { + return err + } + w, err := a.Header(fi) + if err != nil { + return err + } + if _, err := io.Copy(w, fd); err != nil { + return err + } + return nil +} + +// WriteArchive creates an archive containing the given files. +func WriteArchive(name string, files []string) (err error) { + archfd, err := os.Create(name) + if err != nil { + return err + } + + defer func() { + archfd.Close() + // Remove the half-written archive on failure. + if err != nil { + os.Remove(name) + } + }() + archive, basename := NewArchive(archfd) + if archive == nil { + return errors.New("unknown archive extension") + } + fmt.Println(name) + if err := archive.Directory(basename); err != nil { + return err + } + for _, file := range files { + fmt.Println(" +", filepath.Base(file)) + if err := AddFile(archive, file); err != nil { + return err + } + } + return archive.Close() +} + +type ZipArchive struct { + dir string + zipw *zip.Writer + file io.Closer +} + +func NewZipArchive(w io.WriteCloser) Archive { + return &ZipArchive{"", zip.NewWriter(w), w} +} + +func (a *ZipArchive) Directory(name string) error { + a.dir = name + "/" + return nil +} + +func (a *ZipArchive) Header(fi os.FileInfo) (io.Writer, error) { + head, err := zip.FileInfoHeader(fi) + if err != nil { + return nil, fmt.Errorf("can't make zip header: %v", err) + } + head.Name = a.dir + head.Name + head.Method = zip.Deflate + w, err := a.zipw.CreateHeader(head) + if err != nil { + return nil, fmt.Errorf("can't add zip header: %v", err) + } + return w, nil +} + +func (a *ZipArchive) Close() error { + if err := a.zipw.Close(); err != nil { + return err + } + return a.file.Close() +} + +type TarballArchive struct { + dir string + tarw *tar.Writer + gzw *gzip.Writer + file io.Closer +} + +func NewTarballArchive(w io.WriteCloser) Archive { + gzw := gzip.NewWriter(w) + tarw := tar.NewWriter(gzw) + return &TarballArchive{"", tarw, gzw, w} +} + +func (a *TarballArchive) Directory(name string) error { + a.dir = name + "/" + return a.tarw.WriteHeader(&tar.Header{ + Name: a.dir, + Mode: 0755, + Typeflag: tar.TypeDir, + ModTime: time.Now(), + }) +} + +func (a *TarballArchive) Header(fi os.FileInfo) (io.Writer, error) { + head, err := tar.FileInfoHeader(fi, "") + if err != nil { + return nil, fmt.Errorf("can't make tar header: %v", err) + } + head.Name = a.dir + head.Name + if err := a.tarw.WriteHeader(head); err != nil { + return nil, fmt.Errorf("can't add tar header: %v", err) + } + return a.tarw, nil +} + +func (a *TarballArchive) Close() error { + if err := a.tarw.Close(); err != nil { + return err + } + if err := a.gzw.Close(); err != nil { + return err + } + return a.file.Close() +} + +// ExtractArchive unpacks a .zip or .tar.gz archive to the destination directory. +func ExtractArchive(archive string, dest string) error { + ar, err := os.Open(archive) + if err != nil { + return err + } + defer ar.Close() + + switch { + case strings.HasSuffix(archive, ".tar.gz"): + return extractTarball(ar, dest) + case strings.HasSuffix(archive, ".zip"): + return extractZip(ar, dest) + default: + return fmt.Errorf("unhandled archive type %s", archive) + } +} + +// extractTarball unpacks a .tar.gz file. +func extractTarball(ar io.Reader, dest string) error { + gzr, err := gzip.NewReader(ar) + if err != nil { + return err + } + defer gzr.Close() + + tr := tar.NewReader(gzr) + for { + // Move to the next file header. + header, err := tr.Next() + if err != nil { + if err == io.EOF { + return nil + } + return err + } + // We only care about regular files, directory modes + // and special file types are not supported. + if header.Typeflag == tar.TypeReg { + armode := header.FileInfo().Mode() + err := extractFile(header.Name, armode, tr, dest) + if err != nil { + return fmt.Errorf("extract %s: %v", header.Name, err) + } + } + } +} + +// extractZip unpacks the given .zip file. +func extractZip(ar *os.File, dest string) error { + info, err := ar.Stat() + if err != nil { + return err + } + zr, err := zip.NewReader(ar, info.Size()) + if err != nil { + return err + } + + for _, zf := range zr.File { + if !zf.Mode().IsRegular() { + continue + } + + data, err := zf.Open() + if err != nil { + return err + } + err = extractFile(zf.Name, zf.Mode(), data, dest) + data.Close() + if err != nil { + return fmt.Errorf("extract %s: %v", zf.Name, err) + } + } + return nil +} + +// extractFile extracts a single file from an archive. +func extractFile(arpath string, armode os.FileMode, data io.Reader, dest string) error { + // Check that path is inside destination directory. + target := filepath.Join(dest, filepath.FromSlash(arpath)) + if !strings.HasPrefix(target, filepath.Clean(dest)+string(os.PathSeparator)) { + return fmt.Errorf("path %q escapes archive destination", target) + } + + // Remove the preivously-extracted file if it exists + if err := os.RemoveAll(target); err != nil { + return err + } + + // Recreate the destination directory + if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { + return err + } + + // Copy file data. + file, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY, armode) + if err != nil { + return err + } + if _, err = io.Copy(file, data); err != nil { + file.Close() + os.Remove(target) + return err + } + return file.Close() +} diff --git a/internal/build/download.go b/internal/build/download.go new file mode 100644 index 000000000000..50268227a501 --- /dev/null +++ b/internal/build/download.go @@ -0,0 +1,151 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package build + +import ( + "bufio" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" + "strings" +) + +// ChecksumDB keeps file checksums. +type ChecksumDB struct { + allChecksums []string +} + +// MustLoadChecksums loads a file containing checksums. +func MustLoadChecksums(file string) *ChecksumDB { + content, err := os.ReadFile(file) + if err != nil { + log.Fatal("can't load checksum file: " + err.Error()) + } + return &ChecksumDB{strings.Split(strings.ReplaceAll(string(content), "\r\n", "\n"), "\n")} +} + +// Verify checks whether the given file is valid according to the checksum database. +func (db *ChecksumDB) Verify(path string) error { + fd, err := os.Open(path) + if err != nil { + return err + } + defer fd.Close() + + h := sha256.New() + if _, err := io.Copy(h, bufio.NewReader(fd)); err != nil { + return err + } + fileHash := hex.EncodeToString(h.Sum(nil)) + if !db.findHash(filepath.Base(path), fileHash) { + return fmt.Errorf("invalid file hash: %s %s", fileHash, filepath.Base(path)) + } + return nil +} + +func (db *ChecksumDB) findHash(basename, hash string) bool { + want := hash + " " + basename + for _, line := range db.allChecksums { + if strings.TrimSpace(line) == want { + return true + } + } + return false +} + +// DownloadFile downloads a file and verifies its checksum. +func (db *ChecksumDB) DownloadFile(url, dstPath string) error { + if err := db.Verify(dstPath); err == nil { + fmt.Printf("%s is up-to-date\n", dstPath) + return nil + } + fmt.Printf("%s is stale\n", dstPath) + fmt.Printf("downloading from %s\n", url) + + resp, err := http.Get(url) + if err != nil { + return fmt.Errorf("download error: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("download error: status %d", resp.StatusCode) + } + if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil { + return err + } + fd, err := os.OpenFile(dstPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) + if err != nil { + return err + } + dst := newDownloadWriter(fd, resp.ContentLength) + _, err = io.Copy(dst, resp.Body) + dst.Close() + if err != nil { + return err + } + return db.Verify(dstPath) +} + +type downloadWriter struct { + file *os.File + dstBuf *bufio.Writer + size int64 + written int64 + lastpct int64 +} + +func newDownloadWriter(dst *os.File, size int64) *downloadWriter { + return &downloadWriter{ + file: dst, + dstBuf: bufio.NewWriter(dst), + size: size, + } +} + +func (w *downloadWriter) Write(buf []byte) (int, error) { + n, err := w.dstBuf.Write(buf) + + // Report progress. + w.written += int64(n) + pct := w.written * 10 / w.size * 10 + if pct != w.lastpct { + if w.lastpct != 0 { + fmt.Print("...") + } + fmt.Print(pct, "%") + w.lastpct = pct + } + return n, err +} + +func (w *downloadWriter) Close() error { + if w.lastpct > 0 { + fmt.Println() // Finish the progress line. + } + flushErr := w.dstBuf.Flush() + closeErr := w.file.Close() + if flushErr != nil { + return flushErr + } + return closeErr +} diff --git a/internal/build/gotool.go b/internal/build/gotool.go new file mode 100644 index 000000000000..2a474604183f --- /dev/null +++ b/internal/build/gotool.go @@ -0,0 +1,180 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package build + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" +) + +type GoToolchain struct { + Root string // GOROOT + + // Cross-compilation variables. These are set when running the go tool. + GOARCH string + GOOS string + CC string +} + +// Go creates an invocation of the go command. +func (g *GoToolchain) Go(command string, args ...string) *exec.Cmd { + tool := g.goTool(command, args...) + + // Configure environment for cross build. + if g.GOARCH != "" && g.GOARCH != runtime.GOARCH { + tool.Env = append(tool.Env, "CGO_ENABLED=1") + tool.Env = append(tool.Env, "GOARCH="+g.GOARCH) + } + if g.GOOS != "" && g.GOOS != runtime.GOOS { + tool.Env = append(tool.Env, "GOOS="+g.GOOS) + } + // Configure C compiler. + if g.CC != "" { + tool.Env = append(tool.Env, "CC="+g.CC) + } else if os.Getenv("CC") != "" { + tool.Env = append(tool.Env, "CC="+os.Getenv("CC")) + } + // CKZG by default is not portable, append the necessary build flags to make + // it not rely on modern CPU instructions and enable linking against. + tool.Env = append(tool.Env, "CGO_CFLAGS=-O2 -g -D__BLST_PORTABLE__") + + return tool +} + +func (g *GoToolchain) goTool(command string, args ...string) *exec.Cmd { + if g.Root == "" { + g.Root = runtime.GOROOT() + } + tool := exec.Command(filepath.Join(g.Root, "bin", "go"), command) // nolint: gosec + tool.Args = append(tool.Args, args...) + tool.Env = append(tool.Env, "GOROOT="+g.Root) + + // Forward environment variables to the tool, but skip compiler target settings. + // TODO: what about GOARM? + skip := map[string]struct{}{"GOROOT": {}, "GOARCH": {}, "GOOS": {}, "GOBIN": {}, "CC": {}} + for _, e := range os.Environ() { + if i := strings.IndexByte(e, '='); i >= 0 { + if _, ok := skip[e[:i]]; ok { + continue + } + } + tool.Env = append(tool.Env, e) + } + return tool +} + +// DownloadGo downloads the Go binary distribution and unpacks it into a temporary +// directory. It returns the GOROOT of the unpacked toolchain. +func DownloadGo(csdb *ChecksumDB) string { + version, err := Version(csdb, "golang") + if err != nil { + log.Fatal(err) + } + // Shortcut: if the Go version that runs this script matches the + // requested version exactly, there is no need to download anything. + activeGo := strings.TrimPrefix(runtime.Version(), "go") + if activeGo == version { + log.Printf("-dlgo version matches active Go version %s, skipping download.", activeGo) + return runtime.GOROOT() + } + + ucache, err := os.UserCacheDir() + if err != nil { + log.Fatal(err) + } + + // For Arm architecture, GOARCH includes ISA version. + os := runtime.GOOS + arch := runtime.GOARCH + if arch == "arm" { + arch = "armv6l" + } + file := fmt.Sprintf("go%s.%s-%s", version, os, arch) + if os == "windows" { + file += ".zip" + } else { + file += ".tar.gz" + } + url := "https://golang.org/dl/" + file + dst := filepath.Join(ucache, file) + if err := csdb.DownloadFile(url, dst); err != nil { + log.Fatal(err) + } + + godir := filepath.Join(ucache, fmt.Sprintf("geth-go-%s-%s-%s", version, os, arch)) + if err := ExtractArchive(dst, godir); err != nil { + log.Fatal(err) + } + goroot, err := filepath.Abs(filepath.Join(godir, "go")) + if err != nil { + log.Fatal(err) + } + return goroot +} + +// Version returns the versions defined in the checksumdb. +func Version(csdb *ChecksumDB, version string) (string, error) { + for _, l := range csdb.allChecksums { + if !strings.HasPrefix(l, "# version:") { + continue + } + v := strings.Split(l, ":")[1] + parts := strings.Split(v, " ") + if len(parts) != 2 { + log.Print("Erroneous version-string", "v", l) + continue + } + if parts[0] == version { + return parts[1], nil + } + } + return "", fmt.Errorf("no version found for '%v'", version) +} + +// DownloadAndVerifyChecksums downloads all files and checks that they match +// the checksum given in checksums.txt. +// This task can be used to sanity-check new checksums. +func DownloadAndVerifyChecksums(csdb *ChecksumDB) { + var ( + base = "" + ucache = os.TempDir() + ) + for _, l := range csdb.allChecksums { + if strings.HasPrefix(l, "# https://") { + base = l[2:] + continue + } + if strings.HasPrefix(l, "#") { + continue + } + hashFile := strings.Split(l, " ") + if len(hashFile) != 2 { + continue + } + file := hashFile[1] + url := base + file + dst := filepath.Join(ucache, file) + if err := csdb.DownloadFile(url, dst); err != nil { + log.Print(err) + } + } +} diff --git a/internal/build/util.go b/internal/build/util.go index 3fcb411c70de..42f57a468181 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -26,7 +26,9 @@ import ( "path" "path/filepath" "runtime" + "strconv" "strings" + "time" ) var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands") @@ -34,7 +36,7 @@ var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands") // MustRun executes the given command and exits the host process for // any error. func MustRun(cmd *exec.Cmd) { - fmt.Println(">>>", strings.Join(cmd.Args, " ")) + fmt.Println(">>>", printArgs(cmd.Args)) if !*DryRunFlag { cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout @@ -44,10 +46,45 @@ func MustRun(cmd *exec.Cmd) { } } +func printArgs(args []string) string { + var s strings.Builder + for i, arg := range args { + if i > 0 { + s.WriteByte(' ') + } + if strings.IndexByte(arg, ' ') >= 0 { + arg = strconv.QuoteToASCII(arg) + } + s.WriteString(arg) + } + return s.String() +} + func MustRunCommand(cmd string, args ...string) { MustRun(exec.Command(cmd, args...)) } +// MustRunCommandWithOutput runs the given command, and ensures that some output will be +// printed while it runs. This is useful for CI builds where the process will be stopped +// when there is no output. +func MustRunCommandWithOutput(cmd string, args ...string) { + interval := time.NewTicker(time.Minute) + done := make(chan struct{}) + defer interval.Stop() + defer close(done) + go func() { + for { + select { + case <-interval.C: + fmt.Printf("Waiting for command %q\n", cmd) + case <-done: + return + } + } + }() + MustRun(exec.Command(cmd, args...)) +} + // GOPATH returns the value that the GOPATH environment // variable should be set to. func GOPATH() string { From 47a67158e525dc12c7eccae433e30fa25d8dfdfd Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 11:50:20 +0800 Subject: [PATCH 115/121] core/types: remove generate directive for gen_tx_json.go --- core/types/lending_transaction.go | 2 -- core/types/order_transaction.go | 2 -- core/types/transaction.go | 1 - 3 files changed, 5 deletions(-) diff --git a/core/types/lending_transaction.go b/core/types/lending_transaction.go index 21544043deb2..ff79f2bf39af 100644 --- a/core/types/lending_transaction.go +++ b/core/types/lending_transaction.go @@ -27,8 +27,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/rlp" ) -//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go - var ( // ErrInvalidLengdingSig invalidate signer ErrInvalidLengdingSig = errors.New("invalid transaction v, r, s values") diff --git a/core/types/order_transaction.go b/core/types/order_transaction.go index 6ec5c8c6c1a7..cfabfb3f43d7 100644 --- a/core/types/order_transaction.go +++ b/core/types/order_transaction.go @@ -27,8 +27,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/rlp" ) -//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go - var ( // ErrInvalidOrderSig invalidate signer ErrInvalidOrderSig = errors.New("invalid transaction v, r, s values") diff --git a/core/types/transaction.go b/core/types/transaction.go index 3054534e558d..104abcd53b5a 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -32,7 +32,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/rlp" ) -//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go var ( ErrInvalidSig = errors.New("invalid transaction v, r, s values") ErrUnexpectedProtection = errors.New("transaction type does not supported EIP-155 protected signatures") From 00797dda0c2a9899d5bea6bfd32867ef546850a2 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 09:46:27 +0800 Subject: [PATCH 116/121] build: add 'go mod tidy' checker --- Makefile | 4 ++ build/ci.go | 26 ++++++++++- internal/build/file.go | 102 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 internal/build/file.go diff --git a/Makefile b/Makefile index e92835b952a0..3b748a0a0b2f 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,10 @@ test: all lint: ## Run linters. $(GORUN) build/ci.go lint +#? check_tidy: Verify go.mod and go.sum by 'go mod tidy' +check_tidy: ## Run 'go mod tidy'. + $(GORUN) build/ci.go check_tidy + #? clean: Clean go cache, built executables, and the auto generated folder. clean: rm -fr build/_workspace/pkg/ $(GOBIN)/* diff --git a/build/ci.go b/build/ci.go index 3bdb52a7a32e..3c0660a71a30 100644 --- a/build/ci.go +++ b/build/ci.go @@ -24,9 +24,11 @@ Usage: go run build/ci.go Available commands are: + lint -- runs certain pre-selected linters + check_tidy -- verifies that everything is 'go mod tidy'-ed + install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables test [ -coverage ] [ packages... ] -- runs the tests - lint -- runs certain pre-selected linters importkeys -- imports signing keys from env xgo [ -alltools ] [ options ] -- cross builds according to options @@ -89,6 +91,8 @@ func main() { doTest(os.Args[2:]) case "lint": doLint(os.Args[2:]) + case "check_tidy": + doCheckTidy() case "xgo": doXgo(os.Args[2:]) default: @@ -246,6 +250,26 @@ func doTest(cmdline []string) { build.MustRun(gotest) } +// doCheckTidy assets that the Go modules files are tidied already. +func doCheckTidy() { + targets := []string{"go.mod", "go.sum"} + + hashes, err := build.HashFiles(targets) + if err != nil { + log.Fatalf("failed to hash go.mod/go.sum: %v", err) + } + build.MustRun(new(build.GoToolchain).Go("mod", "tidy")) + + tidied, err := build.HashFiles(targets) + if err != nil { + log.Fatalf("failed to rehash go.mod/go.sum: %v", err) + } + if updates := build.DiffHashes(hashes, tidied); len(updates) > 0 { + log.Fatalf("files changed on running 'go mod tidy': %v", updates) + } + fmt.Println("No untidy module files detected.") +} + // doLint runs golangci-lint on requested packages. func doLint(cmdline []string) { var ( diff --git a/internal/build/file.go b/internal/build/file.go new file mode 100644 index 000000000000..2d8c993f3608 --- /dev/null +++ b/internal/build/file.go @@ -0,0 +1,102 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package build + +import ( + "crypto/sha256" + "io" + "os" + "path/filepath" + "sort" + "strings" +) + +// FileExist checks if a file exists at path. +func FileExist(path string) bool { + _, err := os.Stat(path) + if err != nil && os.IsNotExist(err) { + return false + } + return true +} + +// HashFiles iterates the provided set of files, computing the hash of each. +func HashFiles(files []string) (map[string][32]byte, error) { + res := make(map[string][32]byte) + for _, filePath := range files { + f, err := os.OpenFile(filePath, os.O_RDONLY, 0666) + if err != nil { + return nil, err + } + hasher := sha256.New() + if _, err := io.Copy(hasher, f); err != nil { + return nil, err + } + res[filePath] = [32]byte(hasher.Sum(nil)) + } + return res, nil +} + +// HashFolder iterates all files under the given directory, computing the hash +// of each. +func HashFolder(folder string, exlude []string) (map[string][32]byte, error) { + res := make(map[string][32]byte) + err := filepath.WalkDir(folder, func(path string, d os.DirEntry, _ error) error { + // Skip anything that's exluded or not a regular file + for _, skip := range exlude { + if strings.HasPrefix(path, filepath.FromSlash(skip)) { + return filepath.SkipDir + } + } + if !d.Type().IsRegular() { + return nil + } + // Regular file found, hash it + f, err := os.OpenFile(path, os.O_RDONLY, 0666) + if err != nil { + return err + } + hasher := sha256.New() + if _, err := io.Copy(hasher, f); err != nil { + return err + } + res[path] = [32]byte(hasher.Sum(nil)) + return nil + }) + if err != nil { + return nil, err + } + return res, nil +} + +// DiffHashes compares two maps of file hashes and returns the changed files. +func DiffHashes(a map[string][32]byte, b map[string][32]byte) []string { + var updates []string + + for file := range a { + if _, ok := b[file]; !ok || a[file] != b[file] { + updates = append(updates, file) + } + } + for file := range b { + if _, ok := a[file]; !ok { + updates = append(updates, file) + } + } + sort.Strings(updates) + return updates +} From 3b6ece40d71eebc1eb15d192dc7e89b465814044 Mon Sep 17 00:00:00 2001 From: "liam.lai" Date: Tue, 14 Jan 2025 18:04:07 -0800 Subject: [PATCH 117/121] update mainnet bootnode list --- cicd/mainnet/bootnodes.list | 157 +++++++++++++++++++++++++++--------- 1 file changed, 120 insertions(+), 37 deletions(-) diff --git a/cicd/mainnet/bootnodes.list b/cicd/mainnet/bootnodes.list index 4527bbbf5db1..60bada8fbbfc 100644 --- a/cicd/mainnet/bootnodes.list +++ b/cicd/mainnet/bootnodes.list @@ -1,37 +1,120 @@ -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@154.53.42.5:30303 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@194.146.12.183:30303 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@194.146.12.181:30303 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@154.53.56.28:30303 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@144.126.150.58:30303 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@194.146.12.182:30303 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@78.129.229.96:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@5.152.223.199:30301 -enode://560113969268e30a430991e36fcb1a6ea8a2bc16f23bc1dabffd6f8c17649237d58d8cf554e9ce882184abdc9b3a607230123e2bcf819d4ed01ec02acee1c4c2@78.159.100.155:30303 -enode://a86d3268c060323572bfeb6df76081e4668ec44cc60ff028c1685a9a683c5d6497c987b5dfade81323d08875066218a1877484396e11f400ce1c2c9bd343c935@78.159.100.155:30304 -enode://b69648bc931e60ab59057af72f411567444725a165c8798ffdb420de3be2636c5823f69f8ea76895422d5797af439c97221daa153785ad4bc2e7a6719a6116ae@78.159.100.155:30305 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@107.191.46.179:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@107.191.63.81:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@108.61.208.82:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@137.220.52.242:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@137.220.53.156:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@139.180.167.226:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@139.180.188.238:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@139.180.207.188:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@149.248.57.56:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@149.248.7.129:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@155.138.129.23:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@155.138.132.39:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@155.138.135.5:30301 -enode://1c20e6b46ce608c1fe739e78611225b94e663535b74a1545b1667eac8ff75ed43216306d123306c10e043f228e42cc53cb2728655019292380313393eaaf6e23@155.138.136.247:30301 -enode://07257a47f5609c284e43b6c08d54fa2bd1ef524e39d552da928938b9e86c1944aec5d4c7e46919b6953fe4ecd8b4847c6aa0e2303fdc417cb3439abd03706311@209.126.9.230:30303 -enode://3dc8823dba75781aad99534ff7ff0460d95120644421c3874d3759a25eb4c84ad1e7aa3129110901f1dd42d6c19cc02a7757c152c5d433ceb8e47c621d02e15e@144.126.146.184:30303 -enode://fc7d703932a2f53e203c6263462af69bfca3520c5130748f54f3ce85196f895f6be43e618544e66b511f78e926dcfe7e842e0b94937cdadb9d6e9f328a34796f@66.94.122.169:30303 -enode://8d6ecd0fcc842a3553847b7f66cdee2c008e295ba657ed63da4b8e6da303c6bb308b6e9a8d9c0d0cc357c690033696e5c8222f726a3f39338101ef9b1f4026f1@66.94.122.172:30303 -enode://f1bb123968485d1acb3d3b19230742e7018c91419d2acd5fb391d5150310c6b6a686de287394dd28087ba5e6019a8ccc494a4d8eddf21e8324e794173d7d9f35@66.94.100.116:30303 -enode://25bd979e84e09401b3dcbf506f859fb979ca5dd1d1687d500a5fa5798308119f4cbe49cd26136d6a480f855b5b3f99a26f696c01fff45630aba5aea24b958469@66.94.100.115:30303 -enode://a49ba70cb4991fc3dbb15f0133684c3501a46004a0d4f3abfa1137c5a1c50f5942b2b8bc9c9fa6649621275df3532681f1167c06ea2e1ab0cd6f71e33cf97d9b@86.48.31.135:30303 -enode://5de7e18451f56ae6506d28a85b0d274b03dec7028bdfaf9407816765d38352c654a35b4b260c710de0f2e33bd9df63420ec448d4b87d46b81a05729c9d1df350@66.94.122.40:30303 -enode://4515870a9dd133c3cbbcb194e0f73853fae510217dd35bb0ffe6793f9b21945e0a280708273e7f5b30330b6737858bedabbc6eebcf68d38089eb11e4fb6930d8@161.97.156.58:30303 -enode://1686e2536b5c27a443575e0e94daee0736d6a043e806bfe889b979003c43a6017f00aa2b4e5b820afbd02822f1918e07ce15b050ae55202355c1d803ed372b0c@161.97.175.15:30303 -enode://ad187cfa297ccd540b6afc1fbc4e5d552c27eadd788084b5667cd57b558109f338b9403f880d96d6efed65fbd741521ec81c77c01b0b7bce5dbafe30043369fd@194.233.74.229:30303 -enode://3dc8823dba75781aad99534ff7ff0460d95120644421c3874d3759a25eb4c84ad1e7aa3129110901f1dd42d6c19cc02a7757c152c5d433ceb8e47c621d02e15e@144.126.146.184:30303 \ No newline at end of file +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@81.0.220.137:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@5.189.144.192:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@154.53.42.5:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@85.239.236.17:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@85.239.236.16:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.121.140:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.1.25:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.11.52:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.11.108:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.9.230:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@109.123.242.198:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.2.33:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.131.145:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.172.27:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@109.123.242.118:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@66.94.97.241:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@86.48.31.133:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@173.212.216.152:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@66.94.96.252:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@185.252.234.115:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@173.249.25.180:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@89.117.49.57:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@86.48.31.135:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@173.212.213.154:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@85.239.242.168:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@85.239.242.167:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@149.102.140.198:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.142.140:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@85.190.246.191:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@194.233.78.84:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@154.26.154.58:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@154.12.243.174:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@135.181.182.73:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@86.48.31.130:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@81.0.220.143:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.156.37:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@62.171.130.0:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.130.13:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.131.6:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.164.153:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.0.250:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.4.150:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.7.127:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@185.194.216.142:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@62.171.132.144:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.1.10:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.128.201:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@85.239.236.19:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@194.163.148.93:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@194.163.148.88:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.145.58.106:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@66.94.108.109:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@66.94.108.110:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@154.12.234.133:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.80.128:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@45.130.104.21:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@45.130.104.20:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.157.22:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.143.126:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@178.18.243.215:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@75.119.139.126:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@167.86.76.86:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@164.68.99.215:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@31.220.77.198:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@62.171.129.243:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@109.199.104.176:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@149.102.139.253:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@149.102.140.32:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@149.102.140.32:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.148.246:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.126.1.25:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@109.199.104.167:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.136.27:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@194.163.138.98:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.150.58:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@185.252.233.29:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@75.119.155.142:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@86.48.31.134:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@185.211.5.57:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@89.117.49.48:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@81.0.220.139:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@85.239.242.166:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@109.123.232.200:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@45.10.162.64:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@62.171.129.255:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@209.145.54.70:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@38.242.205.107:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@161.97.128.208:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@109.123.232.201:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@89.117.49.59:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@66.151.42.217:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@158.255.5.87:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@158.255.5.100:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@141.105.70.96:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@141.105.70.103:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@162.250.190.246:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@162.250.191.5:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@162.250.191.14:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@162.250.189.149:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@162.250.189.152:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@104.152.209.119:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@104.152.209.131:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@104.152.209.134:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@104.152.209.135:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@38.102.87.214:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@104.152.211.94:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@78.129.222.91:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@212.38.189.116:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@212.38.189.120:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@212.38.189.121:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@212.38.189.122:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@37.48.110.241:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@23.106.120.231:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@23.106.120.233:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@23.111.13.174:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@23.111.13.177:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@173.234.105.193:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@103.101.129.198:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@103.101.129.240:30304 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@103.101.131.35:30304 \ No newline at end of file From 9bfec339422ca3fcc45bcd6033ec0814f3775a65 Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Mon, 13 Jan 2025 09:42:37 +0400 Subject: [PATCH 118/121] remove old config update bootnodes and cicd --- .github/workflows/ci.yml | 42 ++++++++++++------------ .github/workflows/deploy_rpc_image.yml | 40 ---------------------- cicd/ansible/inventory.yaml | 17 ---------- cicd/ansible/playbooks/update-image.yaml | 16 --------- cicd/devnet/bootnodes.list | 4 +-- params/config.go | 24 -------------- 6 files changed, 23 insertions(+), 120 deletions(-) delete mode 100644 .github/workflows/deploy_rpc_image.yml delete mode 100644 cicd/ansible/inventory.yaml delete mode 100644 cicd/ansible/playbooks/update-image.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 19d914017d70..a2e7daecfeef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,24 +116,24 @@ jobs: echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config chmod 600 $HOME/.kube/config git_hash=$(git rev-parse --short "$GITHUB_SHA") - kubectl set image deployment/devnet1 devnet1=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet2 devnet2=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet3 devnet3=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet4 devnet4=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet5 devnet5=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet6 devnet6=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet7 devnet7=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet8 devnet8=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet9 devnet9=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet10 devnet10=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet11 devnet11=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet12 devnet12=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet13 devnet13=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet14 devnet14=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet15 devnet15=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet16 devnet16=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet17 devnet17=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/devnet18 devnet18=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnet1 devnet1=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet2 devnet2=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet3 devnet3=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet4 devnet4=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet5 devnet5=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet6 devnet6=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet7 devnet7=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet8 devnet8=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet9 devnet9=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet10 devnet10=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet11 devnet11=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet12 devnet12=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet13 devnet13=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet14 devnet14=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet15 devnet15=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet16 devnet16=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet17 devnet17=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/devnet18 devnet18=xinfinorg/devnet:dev-upgrade-${git_hash} ; echo done rpc_k8_apply: @@ -152,9 +152,9 @@ jobs: echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config chmod 600 $HOME/.kube/config git_hash=$(git rev-parse --short "$GITHUB_SHA") - kubectl set image deployment/devnetrpc devnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/testnetrpc testnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} || - kubectl set image deployment/mainnetrpc mainnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} || + kubectl set image deployment/devnetrpc devnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/testnetrpc testnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} ; + kubectl set image deployment/mainnetrpc mainnetrpc=xinfinorg/devnet:dev-upgrade-${git_hash} ; echo done devnet_send_notification: diff --git a/.github/workflows/deploy_rpc_image.yml b/.github/workflows/deploy_rpc_image.yml deleted file mode 100644 index 088d809aeee8..000000000000 --- a/.github/workflows/deploy_rpc_image.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Deploy RPC Image -on: - #need to make sure only authorized people can use this function - workflow_dispatch: - inputs: - network: - type: choice - description: 'devnet, testnet, or mainnet' - options: - - devnet - - testnet - - mainnet - rpc_image: - description: 'full image name' - -jobs: - ansible: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Update RPC nodes image - uses: dawidd6/action-ansible-playbook@v2 - with: - playbook: playbooks/update-image.yaml - directory: ./cicd/ansible - key: ${{secrets.SSH_PRIVATE_KEY_DEVNET}} - options: | - --inventory inventory.yaml - --extra-vars network=${{inputs.network}} - --extra-vars rpc_image=${{inputs.rpc_image}} - - devnet_send_notification: - runs-on: ubuntu-latest - needs: ansible - steps: - - uses: actions/checkout@v4 - - name: Send deployment notification - run: | - curl --location --request POST "66.94.98.186:8080/deploy?environment=${{inputs.network}}&service=xdc_rpc&version=${{inputs.rpc_image}}" diff --git a/cicd/ansible/inventory.yaml b/cicd/ansible/inventory.yaml deleted file mode 100644 index 141604ff7c7d..000000000000 --- a/cicd/ansible/inventory.yaml +++ /dev/null @@ -1,17 +0,0 @@ -ec2_rpcs: - hosts: - devnet: - ansible_host: devnet.hashlabs.apothem.network - ansible_port: 22 - ansible_user: ec2-user - deploy_path: /work/XinFin-Node/devnet - testnet: - ansible_host: testnet.hashlabs.apothem.network - ansible_port: 22 - ansible_user: ec2-user - deploy_path: /work/XinFin-Node/testnet - mainnet: - ansible_host: mainnet.hashlabs.apothem.network - ansible_port: 22 - ansible_user: ec2-user - deploy_path: /work/XinFin-Node/mainnet \ No newline at end of file diff --git a/cicd/ansible/playbooks/update-image.yaml b/cicd/ansible/playbooks/update-image.yaml deleted file mode 100644 index a55ac6a7ece9..000000000000 --- a/cicd/ansible/playbooks/update-image.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- name: Run Bash Script on Host - hosts: "{{ network }}" - become: true #sudo/root - - tasks: - - name: Update RPC image version - shell: | - export RPC_IMAGE={{ rpc_image }} - cd {{ deploy_path }} - git pull - ./docker-down.sh - ./docker-up-hash.sh - docker ps - register: output - - debug: var=output.stdout_lines \ No newline at end of file diff --git a/cicd/devnet/bootnodes.list b/cicd/devnet/bootnodes.list index d3b1228edd76..03a7f014e51b 100644 --- a/cicd/devnet/bootnodes.list +++ b/cicd/devnet/bootnodes.list @@ -1,4 +1,4 @@ enode://00d49d72a48164681906ad61924568da0d3049937efdbaed0b7533e34a99f55814f1839d909cdc82f78e04a36ac04737d80b41b22905c7d6cac3c80bb5cdbbc4@66.94.98.186:30301 enode://d6793b02a478f13ed6d01c30778935f6f8f7461a75aebedcb310def4ed9b066f995a0dca046d0c7ea7f5ffdd8e3f1f53c6b6dce909d1693650504921aad62f1a@194.163.167.177:30301 -enode://c7a38ecc7fd5849eaefb3e928f882ab2f1260d5591bd1fef1db39c8ae0d9fe21d86e2d4efee6def0f4f16d0b6103f86f92f7e910295b849266fef83f05768596@10.244.1.77:30301 -enode://9160713d41656154ce3fdaa9d0f9799dd8546652b1784edecf82ce7a5b54a977f897ea617a9b3b4db513dc6b0dc98c1c3ad8a1914075ab87ded4e367c89dcd3b@10.244.2.53:30301 +enode://64e1b1969f9102977691a40431b0b672055dcf31163897d996434420e6c95dc9c16f60c7c11fc3c9eb27fa26a9035b669bfb77d21cef371ddce94e329222550c@100.42.189.174:30301 +enode://5a95a9ce5aa070ee8ae158988a0b9e34e98e6371f05f4318f88c1b7e2c8123877c95583b1f530858b7b580a9d906a38a8bffbc3c095fc9ef5eb7b339a112da67@209.126.80.43:30302 diff --git a/params/config.go b/params/config.go index 6630f9b197b6..cb67859d9076 100644 --- a/params/config.go +++ b/params/config.go @@ -110,30 +110,6 @@ var ( TimeoutPeriod: 30, MinePeriod: 2, }, - 7956000: { // 2024.01.17 Devnet Deplyment Issue - MaxMasternodes: 108, - SwitchRound: 7956000, - CertThreshold: 0.4, - TimeoutSyncThreshold: 3, - TimeoutPeriod: 30, - MinePeriod: 2, - }, - 7974000: { - MaxMasternodes: 108, - SwitchRound: 7974000, - CertThreshold: 0.667, - TimeoutSyncThreshold: 3, - TimeoutPeriod: 30, - MinePeriod: 2, - }, - 13625855: { // 2024.07.29 RPC call and reorg sync issue - MaxMasternodes: 108, - SwitchRound: 13625855, - CertThreshold: 0.4, - TimeoutSyncThreshold: 3, - TimeoutPeriod: 60, - MinePeriod: 2, - }, } UnitTestV2Configs = map[uint64]*V2Config{ From 1d5d2f134979fd8fef736cd5d493b64b74b8469e Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:01:01 +0800 Subject: [PATCH 119/121] build: add 'go generate' checker --- Makefile | 4 ++ build/ci.go | 133 +++++++++++++++++++++++++++++++++++++++++++ build/tools/tools.go | 27 +++++++++ go.mod | 4 +- go.sum | 4 ++ 5 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 build/tools/tools.go diff --git a/Makefile b/Makefile index 3b748a0a0b2f..cf6493922c29 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,10 @@ lint: ## Run linters. check_tidy: ## Run 'go mod tidy'. $(GORUN) build/ci.go check_tidy +#? check_generate: Verify everything is 'go generate'-ed +check_generate: ## Run 'go generate ./...'. + $(GORUN) build/ci.go check_generate + #? clean: Clean go cache, built executables, and the auto generated folder. clean: rm -fr build/_workspace/pkg/ $(GOBIN)/* diff --git a/build/ci.go b/build/ci.go index 3c0660a71a30..9b13d4bff564 100644 --- a/build/ci.go +++ b/build/ci.go @@ -26,6 +26,7 @@ Available commands are: lint -- runs certain pre-selected linters check_tidy -- verifies that everything is 'go mod tidy'-ed + check_generate -- verifies that everything is 'go generate'-ed install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables test [ -coverage ] [ packages... ] -- runs the tests @@ -44,6 +45,7 @@ import ( "log" "os" "os/exec" + "path" "path/filepath" "runtime" "strings" @@ -93,6 +95,8 @@ func main() { doLint(os.Args[2:]) case "check_tidy": doCheckTidy() + case "check_generate": + doCheckGenerate() case "xgo": doXgo(os.Args[2:]) default: @@ -270,6 +274,45 @@ func doCheckTidy() { fmt.Println("No untidy module files detected.") } +// doCheckGenerate ensures that re-generating generated files does not cause +// any mutations in the source file tree. +func doCheckGenerate() { + var ( + cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.") + ) + // Compute the origin hashes of all the files + var hashes map[string][32]byte + + var err error + hashes, err = build.HashFolder(".", []string{"tests/testdata", "build/cache"}) + if err != nil { + log.Fatal("Error computing hashes", "err", err) + } + // Run any go generate steps we might be missing + var ( + protocPath = downloadProtoc(*cachedir) + protocGenGoPath = downloadProtocGenGo(*cachedir) + ) + c := new(build.GoToolchain).Go("generate", "./...") + pathList := []string{filepath.Join(protocPath, "bin"), protocGenGoPath, os.Getenv("PATH")} + c.Env = append(c.Env, "PATH="+strings.Join(pathList, string(os.PathListSeparator))) + build.MustRun(c) + + // Check if generate file hashes have changed + generated, err := build.HashFolder(".", []string{"tests/testdata", "build/cache"}) + if err != nil { + log.Fatalf("Error re-computing hashes: %v", err) + } + updates := build.DiffHashes(hashes, generated) + for _, file := range updates { + log.Printf("File changed: %s", file) + } + if len(updates) != 0 { + log.Fatal("One or more generated files were updated by running 'go generate ./...'") + } + fmt.Println("No stale files detected.") +} + // doLint runs golangci-lint on requested packages. func doLint(cmdline []string) { var ( @@ -315,6 +358,96 @@ func downloadLinter(cachedir string) string { return filepath.Join(cachedir, base, "golangci-lint") } +// downloadProtocGenGo downloads protoc-gen-go, which is used by protoc +// in the generate command. It returns the full path of the directory +// containing the 'protoc-gen-go' executable. +func downloadProtocGenGo(cachedir string) string { + csdb := build.MustLoadChecksums("build/checksums.txt") + version, err := build.Version(csdb, "protoc-gen-go") + if err != nil { + log.Fatal(err) + } + baseName := fmt.Sprintf("protoc-gen-go.v%s.%s.%s", version, runtime.GOOS, runtime.GOARCH) + archiveName := baseName + if runtime.GOOS == "windows" { + archiveName += ".zip" + } else { + archiveName += ".tar.gz" + } + + url := fmt.Sprintf("https://github.com/protocolbuffers/protobuf-go/releases/download/v%s/%s", version, archiveName) + + archivePath := path.Join(cachedir, archiveName) + if err := csdb.DownloadFile(url, archivePath); err != nil { + log.Fatal(err) + } + extractDest := filepath.Join(cachedir, baseName) + if err := build.ExtractArchive(archivePath, extractDest); err != nil { + log.Fatal(err) + } + extractDest, err = filepath.Abs(extractDest) + if err != nil { + log.Fatal("error resolving absolute path for protoc", "err", err) + } + return extractDest +} + +// protocArchiveBaseName returns the name of the protoc archive file for +// the current system, stripped of version and file suffix. +func protocArchiveBaseName() (string, error) { + switch runtime.GOOS + "-" + runtime.GOARCH { + case "windows-amd64": + return "win64", nil + case "windows-386": + return "win32", nil + case "linux-arm64": + return "linux-aarch_64", nil + case "linux-386": + return "linux-x86_32", nil + case "linux-amd64": + return "linux-x86_64", nil + case "darwin-arm64": + return "osx-aarch_64", nil + case "darwin-amd64": + return "osx-x86_64", nil + default: + return "", fmt.Errorf("no prebuilt release of protoc available for this system (os: %s, arch: %s)", runtime.GOOS, runtime.GOARCH) + } +} + +// downloadProtoc downloads the prebuilt protoc binary used to lint generated +// files as a CI step. It returns the full path to the directory containing +// the protoc executable. +func downloadProtoc(cachedir string) string { + csdb := build.MustLoadChecksums("build/checksums.txt") + version, err := build.Version(csdb, "protoc") + if err != nil { + log.Fatal(err) + } + baseName, err := protocArchiveBaseName() + if err != nil { + log.Fatal(err) + } + + fileName := fmt.Sprintf("protoc-%s-%s", version, baseName) + archiveFileName := fileName + ".zip" + url := fmt.Sprintf("https://github.com/protocolbuffers/protobuf/releases/download/v%s/%s", version, archiveFileName) + archivePath := filepath.Join(cachedir, archiveFileName) + + if err := csdb.DownloadFile(url, archivePath); err != nil { + log.Fatal(err) + } + extractDest := filepath.Join(cachedir, fileName) + if err := build.ExtractArchive(archivePath, extractDest); err != nil { + log.Fatal(err) + } + extractDest, err = filepath.Abs(extractDest) + if err != nil { + log.Fatal("error resolving absolute path for protoc", "err", err) + } + return extractDest +} + // Cross compilation func doXgo(cmdline []string) { var ( diff --git a/build/tools/tools.go b/build/tools/tools.go new file mode 100644 index 000000000000..e9e2241d2fe8 --- /dev/null +++ b/build/tools/tools.go @@ -0,0 +1,27 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +//go:build tools +// +build tools + +package tools + +import ( + // Tool imports for go:generate. + _ "github.com/fjl/gencodec" + _ "golang.org/x/tools/cmd/stringer" + _ "google.golang.org/protobuf/cmd/protoc-gen-go" +) diff --git a/go.mod b/go.mod index 9b6faf749c1b..a4a458bbebc1 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/ethereum/c-kzg-4844 v0.4.0 + github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e github.com/go-yaml/yaml v2.1.0+incompatible github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c @@ -57,6 +58,7 @@ require ( github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/urfave/cli/v2 v2.27.5 + google.golang.org/protobuf v1.31.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -68,6 +70,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect + github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/google/uuid v1.3.0 // indirect @@ -91,7 +94,6 @@ require ( golang.org/x/net v0.25.0 // indirect golang.org/x/term v0.26.0 // indirect golang.org/x/text v0.20.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools v2.2.0+incompatible // indirect diff --git a/go.sum b/go.sum index baa6733abe5e..8e3cc32731b7 100644 --- a/go.sum +++ b/go.sum @@ -47,9 +47,13 @@ github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY= +github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= From 7bbb05d672dd6291dfe3170e94f9af4ec68747af Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 15 Jan 2025 23:02:06 +0800 Subject: [PATCH 120/121] contracts: remove ens --- contracts/ens/README.md | 20 - contracts/ens/contract/AbstractENS.sol | 23 - contracts/ens/contract/ENS.sol | 94 -- contracts/ens/contract/FIFSRegistrar.sol | 39 - contracts/ens/contract/PublicResolver.sol | 212 ---- contracts/ens/contract/ens.go | 879 -------------- contracts/ens/contract/fifsregistrar.go | 195 --- contracts/ens/contract/publicresolver.go | 1321 --------------------- contracts/ens/ens.go | 178 --- contracts/ens/ens_test.go | 78 -- 10 files changed, 3039 deletions(-) delete mode 100644 contracts/ens/README.md delete mode 100644 contracts/ens/contract/AbstractENS.sol delete mode 100644 contracts/ens/contract/ENS.sol delete mode 100644 contracts/ens/contract/FIFSRegistrar.sol delete mode 100644 contracts/ens/contract/PublicResolver.sol delete mode 100644 contracts/ens/contract/ens.go delete mode 100644 contracts/ens/contract/fifsregistrar.go delete mode 100644 contracts/ens/contract/publicresolver.go delete mode 100644 contracts/ens/ens.go delete mode 100644 contracts/ens/ens_test.go diff --git a/contracts/ens/README.md b/contracts/ens/README.md deleted file mode 100644 index c09b47e39d81..000000000000 --- a/contracts/ens/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Swarm ENS interface - -## Usage - -Full documentation for the Ethereum Name Service [can be found as EIP 137](https://github.com/ethereum/EIPs/issues/137). -This package offers a simple binding that streamlines the registration of arbitrary UTF8 domain names to swarm content hashes. - -## Development - -The SOL file in contract subdirectory implements the ENS root registry, a simple -first-in, first-served registrar for the root namespace, and a simple resolver contract; -they're used in tests, and can be used to deploy these contracts for your own purposes. - -The solidity source code can be found at [github.com/arachnid/ens/](https://github.com/arachnid/ens/). - -The go bindings for ENS contracts are generated using `abigen` via the go generator: - -```shell -go generate ./contracts/ens -``` diff --git a/contracts/ens/contract/AbstractENS.sol b/contracts/ens/contract/AbstractENS.sol deleted file mode 100644 index b80a1b0e6b50..000000000000 --- a/contracts/ens/contract/AbstractENS.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity ^0.4.0; - -contract AbstractENS { - function owner(bytes32 node) constant returns(address); - function resolver(bytes32 node) constant returns(address); - function ttl(bytes32 node) constant returns(uint64); - function setOwner(bytes32 node, address owner); - function setSubnodeOwner(bytes32 node, bytes32 label, address owner); - function setResolver(bytes32 node, address resolver); - function setTTL(bytes32 node, uint64 ttl); - - // Logged when the owner of a node assigns a new owner to a subnode. - event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); - - // Logged when the owner of a node transfers ownership to a new account. - event Transfer(bytes32 indexed node, address owner); - - // Logged when the resolver for a node changes. - event NewResolver(bytes32 indexed node, address resolver); - - // Logged when the TTL of a node changes - event NewTTL(bytes32 indexed node, uint64 ttl); -} diff --git a/contracts/ens/contract/ENS.sol b/contracts/ens/contract/ENS.sol deleted file mode 100644 index 47050c19dabb..000000000000 --- a/contracts/ens/contract/ENS.sol +++ /dev/null @@ -1,94 +0,0 @@ -pragma solidity ^0.4.0; - -import './AbstractENS.sol'; - -/** - * The ENS registry contract. - */ -contract ENS is AbstractENS { - struct Record { - address owner; - address resolver; - uint64 ttl; - } - - mapping(bytes32=>Record) records; - - // Permits modifications only by the owner of the specified node. - modifier only_owner(bytes32 node) { - if (records[node].owner != msg.sender) throw; - _; - } - - /** - * Constructs a new ENS registrar. - */ - function ENS() { - records[0].owner = msg.sender; - } - - /** - * Returns the address that owns the specified node. - */ - function owner(bytes32 node) constant returns (address) { - return records[node].owner; - } - - /** - * Returns the address of the resolver for the specified node. - */ - function resolver(bytes32 node) constant returns (address) { - return records[node].resolver; - } - - /** - * Returns the TTL of a node, and any records associated with it. - */ - function ttl(bytes32 node) constant returns (uint64) { - return records[node].ttl; - } - - /** - * Transfers ownership of a node to a new address. May only be called by the current - * owner of the node. - * @param node The node to transfer ownership of. - * @param owner The address of the new owner. - */ - function setOwner(bytes32 node, address owner) only_owner(node) { - Transfer(node, owner); - records[node].owner = owner; - } - - /** - * Transfers ownership of a subnode sha3(node, label) to a new address. May only be - * called by the owner of the parent node. - * @param node The parent node. - * @param label The hash of the label specifying the subnode. - * @param owner The address of the new owner. - */ - function setSubnodeOwner(bytes32 node, bytes32 label, address owner) only_owner(node) { - var subnode = sha3(node, label); - NewOwner(node, label, owner); - records[subnode].owner = owner; - } - - /** - * Sets the resolver address for the specified node. - * @param node The node to update. - * @param resolver The address of the resolver. - */ - function setResolver(bytes32 node, address resolver) only_owner(node) { - NewResolver(node, resolver); - records[node].resolver = resolver; - } - - /** - * Sets the TTL for the specified node. - * @param node The node to update. - * @param ttl The TTL in seconds. - */ - function setTTL(bytes32 node, uint64 ttl) only_owner(node) { - NewTTL(node, ttl); - records[node].ttl = ttl; - } -} diff --git a/contracts/ens/contract/FIFSRegistrar.sol b/contracts/ens/contract/FIFSRegistrar.sol deleted file mode 100644 index 51629c2b65e0..000000000000 --- a/contracts/ens/contract/FIFSRegistrar.sol +++ /dev/null @@ -1,39 +0,0 @@ -pragma solidity ^0.4.0; - -import './AbstractENS.sol'; - -/** - * A registrar that allocates subdomains to the first person to claim them. - */ -contract FIFSRegistrar { - AbstractENS ens; - bytes32 rootNode; - - modifier only_owner(bytes32 subnode) { - var node = sha3(rootNode, subnode); - var currentOwner = ens.owner(node); - - if (currentOwner != 0 && currentOwner != msg.sender) throw; - - _; - } - - /** - * Constructor. - * @param ensAddr The address of the ENS registry. - * @param node The node that this registrar administers. - */ - function FIFSRegistrar(AbstractENS ensAddr, bytes32 node) { - ens = ensAddr; - rootNode = node; - } - - /** - * Register a name, or change the owner of an existing registration. - * @param subnode The hash of the label to register. - * @param owner The address of the new owner. - */ - function register(bytes32 subnode, address owner) only_owner(subnode) { - ens.setSubnodeOwner(rootNode, subnode, owner); - } -} diff --git a/contracts/ens/contract/PublicResolver.sol b/contracts/ens/contract/PublicResolver.sol deleted file mode 100644 index 9dcc95689ecc..000000000000 --- a/contracts/ens/contract/PublicResolver.sol +++ /dev/null @@ -1,212 +0,0 @@ -pragma solidity ^0.4.0; - -import './AbstractENS.sol'; - -/** - * A simple resolver anyone can use; only allows the owner of a node to set its - * address. - */ -contract PublicResolver { - bytes4 constant INTERFACE_META_ID = 0x01ffc9a7; - bytes4 constant ADDR_INTERFACE_ID = 0x3b3b57de; - bytes4 constant CONTENT_INTERFACE_ID = 0xd8389dc5; - bytes4 constant NAME_INTERFACE_ID = 0x691f3431; - bytes4 constant ABI_INTERFACE_ID = 0x2203ab56; - bytes4 constant PUBKEY_INTERFACE_ID = 0xc8690233; - bytes4 constant TEXT_INTERFACE_ID = 0x59d1d43c; - - event AddrChanged(bytes32 indexed node, address a); - event ContentChanged(bytes32 indexed node, bytes32 hash); - event NameChanged(bytes32 indexed node, string name); - event ABIChanged(bytes32 indexed node, uint256 indexed contentType); - event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y); - event TextChanged(bytes32 indexed node, string indexed indexedKey, string key); - - struct PublicKey { - bytes32 x; - bytes32 y; - } - - struct Record { - address addr; - bytes32 content; - string name; - PublicKey pubkey; - mapping(string=>string) text; - mapping(uint256=>bytes) abis; - } - - AbstractENS ens; - mapping(bytes32=>Record) records; - - modifier only_owner(bytes32 node) { - if (ens.owner(node) != msg.sender) throw; - _; - } - - /** - * Constructor. - * @param ensAddr The ENS registrar contract. - */ - function PublicResolver(AbstractENS ensAddr) { - ens = ensAddr; - } - - /** - * Returns true if the resolver implements the interface specified by the provided hash. - * @param interfaceID The ID of the interface to check for. - * @return True if the contract implements the requested interface. - */ - function supportsInterface(bytes4 interfaceID) constant returns (bool) { - return interfaceID == ADDR_INTERFACE_ID || - interfaceID == CONTENT_INTERFACE_ID || - interfaceID == NAME_INTERFACE_ID || - interfaceID == ABI_INTERFACE_ID || - interfaceID == PUBKEY_INTERFACE_ID || - interfaceID == TEXT_INTERFACE_ID || - interfaceID == INTERFACE_META_ID; - } - - /** - * Returns the address associated with an ENS node. - * @param node The ENS node to query. - * @return The associated address. - */ - function addr(bytes32 node) constant returns (address ret) { - ret = records[node].addr; - } - - /** - * Sets the address associated with an ENS node. - * May only be called by the owner of that node in the ENS registry. - * @param node The node to update. - * @param addr The address to set. - */ - function setAddr(bytes32 node, address addr) only_owner(node) { - records[node].addr = addr; - AddrChanged(node, addr); - } - - /** - * Returns the content hash associated with an ENS node. - * Note that this resource type is not standardized, and will likely change - * in future to a resource type based on multihash. - * @param node The ENS node to query. - * @return The associated content hash. - */ - function content(bytes32 node) constant returns (bytes32 ret) { - ret = records[node].content; - } - - /** - * Sets the content hash associated with an ENS node. - * May only be called by the owner of that node in the ENS registry. - * Note that this resource type is not standardized, and will likely change - * in future to a resource type based on multihash. - * @param node The node to update. - * @param hash The content hash to set - */ - function setContent(bytes32 node, bytes32 hash) only_owner(node) { - records[node].content = hash; - ContentChanged(node, hash); - } - - /** - * Returns the name associated with an ENS node, for reverse records. - * Defined in EIP181. - * @param node The ENS node to query. - * @return The associated name. - */ - function name(bytes32 node) constant returns (string ret) { - ret = records[node].name; - } - - /** - * Sets the name associated with an ENS node, for reverse records. - * May only be called by the owner of that node in the ENS registry. - * @param node The node to update. - * @param name The name to set. - */ - function setName(bytes32 node, string name) only_owner(node) { - records[node].name = name; - NameChanged(node, name); - } - - /** - * Returns the ABI associated with an ENS node. - * Defined in EIP205. - * @param node The ENS node to query - * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. - * @return contentType The content type of the return value - * @return data The ABI data - */ - function ABI(bytes32 node, uint256 contentTypes) constant returns (uint256 contentType, bytes data) { - var record = records[node]; - for(contentType = 1; contentType <= contentTypes; contentType <<= 1) { - if ((contentType & contentTypes) != 0 && record.abis[contentType].length > 0) { - data = record.abis[contentType]; - return; - } - } - contentType = 0; - } - - /** - * Sets the ABI associated with an ENS node. - * Nodes may have one ABI of each content type. To remove an ABI, set it to - * the empty string. - * @param node The node to update. - * @param contentType The content type of the ABI - * @param data The ABI data. - */ - function setABI(bytes32 node, uint256 contentType, bytes data) only_owner(node) { - // Content types must be powers of 2 - if (((contentType - 1) & contentType) != 0) throw; - - records[node].abis[contentType] = data; - ABIChanged(node, contentType); - } - - /** - * Returns the SECP256k1 public key associated with an ENS node. - * Defined in EIP 619. - * @param node The ENS node to query - * @return x, y the X and Y coordinates of the curve point for the public key. - */ - function pubkey(bytes32 node) constant returns (bytes32 x, bytes32 y) { - return (records[node].pubkey.x, records[node].pubkey.y); - } - - /** - * Sets the SECP256k1 public key associated with an ENS node. - * @param node The ENS node to query - * @param x the X coordinate of the curve point for the public key. - * @param y the Y coordinate of the curve point for the public key. - */ - function setPubkey(bytes32 node, bytes32 x, bytes32 y) only_owner(node) { - records[node].pubkey = PublicKey(x, y); - PubkeyChanged(node, x, y); - } - - /** - * Returns the text data associated with an ENS node and key. - * @param node The ENS node to query. - * @param key The text data key to query. - * @return The associated text data. - */ - function text(bytes32 node, string key) constant returns (string ret) { - ret = records[node].text[key]; - } - - /** - * Sets the text data associated with an ENS node and key. - * May only be called by the owner of that node in the ENS registry. - * @param node The node to update. - * @param key The key to set. - * @param value The text data value to set. - */ - function setText(bytes32 node, string key, string value) only_owner(node) { - records[node].text[key] = value; - TextChanged(node, key, key); - } -} diff --git a/contracts/ens/contract/ens.go b/contracts/ens/contract/ens.go deleted file mode 100644 index 68418c45a14f..000000000000 --- a/contracts/ens/contract/ens.go +++ /dev/null @@ -1,879 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contract - -import ( - "strings" - - ethereum "github.com/XinFinOrg/XDPoSChain" - "github.com/XinFinOrg/XDPoSChain/accounts/abi" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/event" -) - -// ENSABI is the input ABI used to generate the binding from. -const ENSABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"resolver\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"label\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setSubnodeOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"setTTL\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"ttl\",\"outputs\":[{\"name\":\"\",\"type\":\"uint64\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"setResolver\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"label\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NewOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"NewResolver\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"NewTTL\",\"type\":\"event\"}]" - -// ENSBin is the compiled bytecode used for deploying new contracts. -const ENSBin = `0x6060604052341561000f57600080fd5b60008080526020527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb58054600160a060020a033316600160a060020a0319909116179055610503806100626000396000f3006060604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630178b8bf811461008757806302571be3146100b957806306ab5923146100cf57806314ab9038146100f657806316a25cbd146101195780631896f70a1461014c5780635b0fc9c31461016e575b600080fd5b341561009257600080fd5b61009d600435610190565b604051600160a060020a03909116815260200160405180910390f35b34156100c457600080fd5b61009d6004356101ae565b34156100da57600080fd5b6100f4600435602435600160a060020a03604435166101c9565b005b341561010157600080fd5b6100f460043567ffffffffffffffff6024351661028b565b341561012457600080fd5b61012f600435610357565b60405167ffffffffffffffff909116815260200160405180910390f35b341561015757600080fd5b6100f4600435600160a060020a036024351661038e565b341561017957600080fd5b6100f4600435600160a060020a0360243516610434565b600090815260208190526040902060010154600160a060020a031690565b600090815260208190526040902054600160a060020a031690565b600083815260208190526040812054849033600160a060020a039081169116146101f257600080fd5b8484604051918252602082015260409081019051908190039020915083857fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8285604051600160a060020a03909116815260200160405180910390a3506000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555050565b600082815260208190526040902054829033600160a060020a039081169116146102b457600080fd5b827f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa688360405167ffffffffffffffff909116815260200160405180910390a250600091825260208290526040909120600101805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60009081526020819052604090206001015474010000000000000000000000000000000000000000900467ffffffffffffffff1690565b600082815260208190526040902054829033600160a060020a039081169116146103b757600080fd5b827f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a083604051600160a060020a03909116815260200160405180910390a250600091825260208290526040909120600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909216919091179055565b600082815260208190526040902054829033600160a060020a0390811691161461045d57600080fd5b827fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d26683604051600160a060020a03909116815260200160405180910390a250600091825260208290526040909120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039092169190911790555600a165627a7a72305820f4c798d4c84c9912f389f64631e85e8d16c3e6644f8c2e1579936015c7d5f6660029` - -// DeployENS deploys a new Ethereum contract, binding an instance of ENS to it. -func DeployENS(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ENS, error) { - parsed, err := abi.JSON(strings.NewReader(ENSABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ENSBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}, ENSFilterer: ENSFilterer{contract: contract}}, nil -} - -// ENS is an auto generated Go binding around an Ethereum contract. -type ENS struct { - ENSCaller // Read-only binding to the contract - ENSTransactor // Write-only binding to the contract - ENSFilterer // Log filterer for contract events -} - -// ENSCaller is an auto generated read-only Go binding around an Ethereum contract. -type ENSCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ENSTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ENSTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ENSFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ENSFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ENSSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ENSSession struct { - Contract *ENS // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ENSCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ENSCallerSession struct { - Contract *ENSCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ENSTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ENSTransactorSession struct { - Contract *ENSTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ENSRaw is an auto generated low-level Go binding around an Ethereum contract. -type ENSRaw struct { - Contract *ENS // Generic contract binding to access the raw methods on -} - -// ENSCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ENSCallerRaw struct { - Contract *ENSCaller // Generic read-only contract binding to access the raw methods on -} - -// ENSTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ENSTransactorRaw struct { - Contract *ENSTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewENS creates a new instance of ENS, bound to a specific deployed contract. -func NewENS(address common.Address, backend bind.ContractBackend) (*ENS, error) { - contract, err := bindENS(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}, ENSFilterer: ENSFilterer{contract: contract}}, nil -} - -// NewENSCaller creates a new read-only instance of ENS, bound to a specific deployed contract. -func NewENSCaller(address common.Address, caller bind.ContractCaller) (*ENSCaller, error) { - contract, err := bindENS(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ENSCaller{contract: contract}, nil -} - -// NewENSTransactor creates a new write-only instance of ENS, bound to a specific deployed contract. -func NewENSTransactor(address common.Address, transactor bind.ContractTransactor) (*ENSTransactor, error) { - contract, err := bindENS(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ENSTransactor{contract: contract}, nil -} - -// NewENSFilterer creates a new log filterer instance of ENS, bound to a specific deployed contract. -func NewENSFilterer(address common.Address, filterer bind.ContractFilterer) (*ENSFilterer, error) { - contract, err := bindENS(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ENSFilterer{contract: contract}, nil -} - -// bindENS binds a generic wrapper to an already deployed contract. -func bindENS(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ENSABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ENS *ENSRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _ENS.Contract.ENSCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ENS *ENSRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ENS.Contract.ENSTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ENS *ENSRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ENS.Contract.ENSTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ENS *ENSCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _ENS.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ENS *ENSTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ENS.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ENS *ENSTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ENS.Contract.contract.Transact(opts, method, params...) -} - -// Owner is a free data retrieval call binding the contract method 0x02571be3. -// -// Solidity: function owner(node bytes32) constant returns(address) -func (_ENS *ENSCaller) Owner(opts *bind.CallOpts, node [32]byte) (common.Address, error) { - var ( - ret0 = new(common.Address) - ) - out := ret0 - err := _ENS.contract.Call(opts, out, "owner", node) - return *ret0, err -} - -// Owner is a free data retrieval call binding the contract method 0x02571be3. -// -// Solidity: function owner(node bytes32) constant returns(address) -func (_ENS *ENSSession) Owner(node [32]byte) (common.Address, error) { - return _ENS.Contract.Owner(&_ENS.CallOpts, node) -} - -// Owner is a free data retrieval call binding the contract method 0x02571be3. -// -// Solidity: function owner(node bytes32) constant returns(address) -func (_ENS *ENSCallerSession) Owner(node [32]byte) (common.Address, error) { - return _ENS.Contract.Owner(&_ENS.CallOpts, node) -} - -// Resolver is a free data retrieval call binding the contract method 0x0178b8bf. -// -// Solidity: function resolver(node bytes32) constant returns(address) -func (_ENS *ENSCaller) Resolver(opts *bind.CallOpts, node [32]byte) (common.Address, error) { - var ( - ret0 = new(common.Address) - ) - out := ret0 - err := _ENS.contract.Call(opts, out, "resolver", node) - return *ret0, err -} - -// Resolver is a free data retrieval call binding the contract method 0x0178b8bf. -// -// Solidity: function resolver(node bytes32) constant returns(address) -func (_ENS *ENSSession) Resolver(node [32]byte) (common.Address, error) { - return _ENS.Contract.Resolver(&_ENS.CallOpts, node) -} - -// Resolver is a free data retrieval call binding the contract method 0x0178b8bf. -// -// Solidity: function resolver(node bytes32) constant returns(address) -func (_ENS *ENSCallerSession) Resolver(node [32]byte) (common.Address, error) { - return _ENS.Contract.Resolver(&_ENS.CallOpts, node) -} - -// Ttl is a free data retrieval call binding the contract method 0x16a25cbd. -// -// Solidity: function ttl(node bytes32) constant returns(uint64) -func (_ENS *ENSCaller) Ttl(opts *bind.CallOpts, node [32]byte) (uint64, error) { - var ( - ret0 = new(uint64) - ) - out := ret0 - err := _ENS.contract.Call(opts, out, "ttl", node) - return *ret0, err -} - -// Ttl is a free data retrieval call binding the contract method 0x16a25cbd. -// -// Solidity: function ttl(node bytes32) constant returns(uint64) -func (_ENS *ENSSession) Ttl(node [32]byte) (uint64, error) { - return _ENS.Contract.Ttl(&_ENS.CallOpts, node) -} - -// Ttl is a free data retrieval call binding the contract method 0x16a25cbd. -// -// Solidity: function ttl(node bytes32) constant returns(uint64) -func (_ENS *ENSCallerSession) Ttl(node [32]byte) (uint64, error) { - return _ENS.Contract.Ttl(&_ENS.CallOpts, node) -} - -// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3. -// -// Solidity: function setOwner(node bytes32, owner address) returns() -func (_ENS *ENSTransactor) SetOwner(opts *bind.TransactOpts, node [32]byte, owner common.Address) (*types.Transaction, error) { - return _ENS.contract.Transact(opts, "setOwner", node, owner) -} - -// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3. -// -// Solidity: function setOwner(node bytes32, owner address) returns() -func (_ENS *ENSSession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) { - return _ENS.Contract.SetOwner(&_ENS.TransactOpts, node, owner) -} - -// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3. -// -// Solidity: function setOwner(node bytes32, owner address) returns() -func (_ENS *ENSTransactorSession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) { - return _ENS.Contract.SetOwner(&_ENS.TransactOpts, node, owner) -} - -// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a. -// -// Solidity: function setResolver(node bytes32, resolver address) returns() -func (_ENS *ENSTransactor) SetResolver(opts *bind.TransactOpts, node [32]byte, resolver common.Address) (*types.Transaction, error) { - return _ENS.contract.Transact(opts, "setResolver", node, resolver) -} - -// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a. -// -// Solidity: function setResolver(node bytes32, resolver address) returns() -func (_ENS *ENSSession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) { - return _ENS.Contract.SetResolver(&_ENS.TransactOpts, node, resolver) -} - -// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a. -// -// Solidity: function setResolver(node bytes32, resolver address) returns() -func (_ENS *ENSTransactorSession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) { - return _ENS.Contract.SetResolver(&_ENS.TransactOpts, node, resolver) -} - -// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923. -// -// Solidity: function setSubnodeOwner(node bytes32, label bytes32, owner address) returns() -func (_ENS *ENSTransactor) SetSubnodeOwner(opts *bind.TransactOpts, node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) { - return _ENS.contract.Transact(opts, "setSubnodeOwner", node, label, owner) -} - -// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923. -// -// Solidity: function setSubnodeOwner(node bytes32, label bytes32, owner address) returns() -func (_ENS *ENSSession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) { - return _ENS.Contract.SetSubnodeOwner(&_ENS.TransactOpts, node, label, owner) -} - -// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923. -// -// Solidity: function setSubnodeOwner(node bytes32, label bytes32, owner address) returns() -func (_ENS *ENSTransactorSession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) { - return _ENS.Contract.SetSubnodeOwner(&_ENS.TransactOpts, node, label, owner) -} - -// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038. -// -// Solidity: function setTTL(node bytes32, ttl uint64) returns() -func (_ENS *ENSTransactor) SetTTL(opts *bind.TransactOpts, node [32]byte, ttl uint64) (*types.Transaction, error) { - return _ENS.contract.Transact(opts, "setTTL", node, ttl) -} - -// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038. -// -// Solidity: function setTTL(node bytes32, ttl uint64) returns() -func (_ENS *ENSSession) SetTTL(node [32]byte, ttl uint64) (*types.Transaction, error) { - return _ENS.Contract.SetTTL(&_ENS.TransactOpts, node, ttl) -} - -// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038. -// -// Solidity: function setTTL(node bytes32, ttl uint64) returns() -func (_ENS *ENSTransactorSession) SetTTL(node [32]byte, ttl uint64) (*types.Transaction, error) { - return _ENS.Contract.SetTTL(&_ENS.TransactOpts, node, ttl) -} - -// ENSNewOwnerIterator is returned from FilterNewOwner and is used to iterate over the raw logs and unpacked data for NewOwner events raised by the ENS contract. -type ENSNewOwnerIterator struct { - Event *ENSNewOwner // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ENSNewOwnerIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ENSNewOwner) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ENSNewOwner) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *ENSNewOwnerIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ENSNewOwnerIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ENSNewOwner represents a NewOwner event raised by the ENS contract. -type ENSNewOwner struct { - Node [32]byte - Label [32]byte - Owner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterNewOwner is a free log retrieval operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82. -// -// Solidity: event NewOwner(node indexed bytes32, label indexed bytes32, owner address) -func (_ENS *ENSFilterer) FilterNewOwner(opts *bind.FilterOpts, node [][32]byte, label [][32]byte) (*ENSNewOwnerIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - var labelRule []interface{} - for _, labelItem := range label { - labelRule = append(labelRule, labelItem) - } - - logs, sub, err := _ENS.contract.FilterLogs(opts, "NewOwner", nodeRule, labelRule) - if err != nil { - return nil, err - } - return &ENSNewOwnerIterator{contract: _ENS.contract, event: "NewOwner", logs: logs, sub: sub}, nil -} - -// WatchNewOwner is a free log subscription operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82. -// -// Solidity: event NewOwner(node indexed bytes32, label indexed bytes32, owner address) -func (_ENS *ENSFilterer) WatchNewOwner(opts *bind.WatchOpts, sink chan<- *ENSNewOwner, node [][32]byte, label [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - var labelRule []interface{} - for _, labelItem := range label { - labelRule = append(labelRule, labelItem) - } - - logs, sub, err := _ENS.contract.WatchLogs(opts, "NewOwner", nodeRule, labelRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ENSNewOwner) - if err := _ENS.contract.UnpackLog(event, "NewOwner", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ENSNewResolverIterator is returned from FilterNewResolver and is used to iterate over the raw logs and unpacked data for NewResolver events raised by the ENS contract. -type ENSNewResolverIterator struct { - Event *ENSNewResolver // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ENSNewResolverIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ENSNewResolver) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ENSNewResolver) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *ENSNewResolverIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ENSNewResolverIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ENSNewResolver represents a NewResolver event raised by the ENS contract. -type ENSNewResolver struct { - Node [32]byte - Resolver common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterNewResolver is a free log retrieval operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0. -// -// Solidity: event NewResolver(node indexed bytes32, resolver address) -func (_ENS *ENSFilterer) FilterNewResolver(opts *bind.FilterOpts, node [][32]byte) (*ENSNewResolverIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _ENS.contract.FilterLogs(opts, "NewResolver", nodeRule) - if err != nil { - return nil, err - } - return &ENSNewResolverIterator{contract: _ENS.contract, event: "NewResolver", logs: logs, sub: sub}, nil -} - -// WatchNewResolver is a free log subscription operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0. -// -// Solidity: event NewResolver(node indexed bytes32, resolver address) -func (_ENS *ENSFilterer) WatchNewResolver(opts *bind.WatchOpts, sink chan<- *ENSNewResolver, node [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _ENS.contract.WatchLogs(opts, "NewResolver", nodeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ENSNewResolver) - if err := _ENS.contract.UnpackLog(event, "NewResolver", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ENSNewTTLIterator is returned from FilterNewTTL and is used to iterate over the raw logs and unpacked data for NewTTL events raised by the ENS contract. -type ENSNewTTLIterator struct { - Event *ENSNewTTL // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ENSNewTTLIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ENSNewTTL) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ENSNewTTL) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *ENSNewTTLIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ENSNewTTLIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ENSNewTTL represents a NewTTL event raised by the ENS contract. -type ENSNewTTL struct { - Node [32]byte - Ttl uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterNewTTL is a free log retrieval operation binding the contract event 0x1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa68. -// -// Solidity: event NewTTL(node indexed bytes32, ttl uint64) -func (_ENS *ENSFilterer) FilterNewTTL(opts *bind.FilterOpts, node [][32]byte) (*ENSNewTTLIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _ENS.contract.FilterLogs(opts, "NewTTL", nodeRule) - if err != nil { - return nil, err - } - return &ENSNewTTLIterator{contract: _ENS.contract, event: "NewTTL", logs: logs, sub: sub}, nil -} - -// WatchNewTTL is a free log subscription operation binding the contract event 0x1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa68. -// -// Solidity: event NewTTL(node indexed bytes32, ttl uint64) -func (_ENS *ENSFilterer) WatchNewTTL(opts *bind.WatchOpts, sink chan<- *ENSNewTTL, node [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _ENS.contract.WatchLogs(opts, "NewTTL", nodeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ENSNewTTL) - if err := _ENS.contract.UnpackLog(event, "NewTTL", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ENSTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ENS contract. -type ENSTransferIterator struct { - Event *ENSTransfer // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ENSTransferIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ENSTransfer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ENSTransfer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *ENSTransferIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ENSTransferIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ENSTransfer represents a Transfer event raised by the ENS contract. -type ENSTransfer struct { - Node [32]byte - Owner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterTransfer is a free log retrieval operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266. -// -// Solidity: event Transfer(node indexed bytes32, owner address) -func (_ENS *ENSFilterer) FilterTransfer(opts *bind.FilterOpts, node [][32]byte) (*ENSTransferIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _ENS.contract.FilterLogs(opts, "Transfer", nodeRule) - if err != nil { - return nil, err - } - return &ENSTransferIterator{contract: _ENS.contract, event: "Transfer", logs: logs, sub: sub}, nil -} - -// WatchTransfer is a free log subscription operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266. -// -// Solidity: event Transfer(node indexed bytes32, owner address) -func (_ENS *ENSFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ENSTransfer, node [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _ENS.contract.WatchLogs(opts, "Transfer", nodeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ENSTransfer) - if err := _ENS.contract.UnpackLog(event, "Transfer", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} diff --git a/contracts/ens/contract/fifsregistrar.go b/contracts/ens/contract/fifsregistrar.go deleted file mode 100644 index ad431b467ea9..000000000000 --- a/contracts/ens/contract/fifsregistrar.go +++ /dev/null @@ -1,195 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contract - -import ( - "strings" - - "github.com/XinFinOrg/XDPoSChain/accounts/abi" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core/types" -) - -// FIFSRegistrarABI is the input ABI used to generate the binding from. -const FIFSRegistrarABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"subnode\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"},{\"name\":\"node\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" - -// FIFSRegistrarBin is the compiled bytecode used for deploying new contracts. -const FIFSRegistrarBin = `0x6060604052341561000f57600080fd5b604051604080610224833981016040528080519190602001805160008054600160a060020a03909516600160a060020a03199095169490941790935550506001556101c58061005f6000396000f3006060604052600436106100275763ffffffff60e060020a600035041663d22057a9811461002c575b600080fd5b341561003757600080fd5b61004e600435600160a060020a0360243516610050565b005b816000806001548360405191825260208201526040908101905190819003902060008054919350600160a060020a03909116906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156100c857600080fd5b6102c65a03f115156100d957600080fd5b5050506040518051915050600160a060020a0381161580159061010e575033600160a060020a031681600160a060020a031614155b1561011857600080fd5b600054600154600160a060020a03909116906306ab592390878760405160e060020a63ffffffff861602815260048101939093526024830191909152600160a060020a03166044820152606401600060405180830381600087803b151561017e57600080fd5b6102c65a03f1151561018f57600080fd5b50505050505050505600a165627a7a723058206fb963cb168d5e3a51af12cd6bb23e324dbd32dd4954f43653ba27e66b68ea650029` - -// DeployFIFSRegistrar deploys a new Ethereum contract, binding an instance of FIFSRegistrar to it. -func DeployFIFSRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address, node [32]byte) (common.Address, *types.Transaction, *FIFSRegistrar, error) { - parsed, err := abi.JSON(strings.NewReader(FIFSRegistrarABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(FIFSRegistrarBin), backend, ensAddr, node) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}, FIFSRegistrarFilterer: FIFSRegistrarFilterer{contract: contract}}, nil -} - -// FIFSRegistrar is an auto generated Go binding around an Ethereum contract. -type FIFSRegistrar struct { - FIFSRegistrarCaller // Read-only binding to the contract - FIFSRegistrarTransactor // Write-only binding to the contract - FIFSRegistrarFilterer // Log filterer for contract events -} - -// FIFSRegistrarCaller is an auto generated read-only Go binding around an Ethereum contract. -type FIFSRegistrarCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// FIFSRegistrarTransactor is an auto generated write-only Go binding around an Ethereum contract. -type FIFSRegistrarTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// FIFSRegistrarFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type FIFSRegistrarFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// FIFSRegistrarSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type FIFSRegistrarSession struct { - Contract *FIFSRegistrar // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// FIFSRegistrarCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type FIFSRegistrarCallerSession struct { - Contract *FIFSRegistrarCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// FIFSRegistrarTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type FIFSRegistrarTransactorSession struct { - Contract *FIFSRegistrarTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// FIFSRegistrarRaw is an auto generated low-level Go binding around an Ethereum contract. -type FIFSRegistrarRaw struct { - Contract *FIFSRegistrar // Generic contract binding to access the raw methods on -} - -// FIFSRegistrarCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type FIFSRegistrarCallerRaw struct { - Contract *FIFSRegistrarCaller // Generic read-only contract binding to access the raw methods on -} - -// FIFSRegistrarTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type FIFSRegistrarTransactorRaw struct { - Contract *FIFSRegistrarTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewFIFSRegistrar creates a new instance of FIFSRegistrar, bound to a specific deployed contract. -func NewFIFSRegistrar(address common.Address, backend bind.ContractBackend) (*FIFSRegistrar, error) { - contract, err := bindFIFSRegistrar(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}, FIFSRegistrarFilterer: FIFSRegistrarFilterer{contract: contract}}, nil -} - -// NewFIFSRegistrarCaller creates a new read-only instance of FIFSRegistrar, bound to a specific deployed contract. -func NewFIFSRegistrarCaller(address common.Address, caller bind.ContractCaller) (*FIFSRegistrarCaller, error) { - contract, err := bindFIFSRegistrar(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &FIFSRegistrarCaller{contract: contract}, nil -} - -// NewFIFSRegistrarTransactor creates a new write-only instance of FIFSRegistrar, bound to a specific deployed contract. -func NewFIFSRegistrarTransactor(address common.Address, transactor bind.ContractTransactor) (*FIFSRegistrarTransactor, error) { - contract, err := bindFIFSRegistrar(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &FIFSRegistrarTransactor{contract: contract}, nil -} - -// NewFIFSRegistrarFilterer creates a new log filterer instance of FIFSRegistrar, bound to a specific deployed contract. -func NewFIFSRegistrarFilterer(address common.Address, filterer bind.ContractFilterer) (*FIFSRegistrarFilterer, error) { - contract, err := bindFIFSRegistrar(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &FIFSRegistrarFilterer{contract: contract}, nil -} - -// bindFIFSRegistrar binds a generic wrapper to an already deployed contract. -func bindFIFSRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(FIFSRegistrarABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_FIFSRegistrar *FIFSRegistrarRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _FIFSRegistrar.Contract.FIFSRegistrarCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_FIFSRegistrar *FIFSRegistrarRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FIFSRegistrar.Contract.FIFSRegistrarTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_FIFSRegistrar *FIFSRegistrarRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FIFSRegistrar.Contract.FIFSRegistrarTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_FIFSRegistrar *FIFSRegistrarCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _FIFSRegistrar.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_FIFSRegistrar *FIFSRegistrarTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FIFSRegistrar.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_FIFSRegistrar *FIFSRegistrarTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _FIFSRegistrar.Contract.contract.Transact(opts, method, params...) -} - -// Register is a paid mutator transaction binding the contract method 0xd22057a9. -// -// Solidity: function register(subnode bytes32, owner address) returns() -func (_FIFSRegistrar *FIFSRegistrarTransactor) Register(opts *bind.TransactOpts, subnode [32]byte, owner common.Address) (*types.Transaction, error) { - return _FIFSRegistrar.contract.Transact(opts, "register", subnode, owner) -} - -// Register is a paid mutator transaction binding the contract method 0xd22057a9. -// -// Solidity: function register(subnode bytes32, owner address) returns() -func (_FIFSRegistrar *FIFSRegistrarSession) Register(subnode [32]byte, owner common.Address) (*types.Transaction, error) { - return _FIFSRegistrar.Contract.Register(&_FIFSRegistrar.TransactOpts, subnode, owner) -} - -// Register is a paid mutator transaction binding the contract method 0xd22057a9. -// -// Solidity: function register(subnode bytes32, owner address) returns() -func (_FIFSRegistrar *FIFSRegistrarTransactorSession) Register(subnode [32]byte, owner common.Address) (*types.Transaction, error) { - return _FIFSRegistrar.Contract.Register(&_FIFSRegistrar.TransactOpts, subnode, owner) -} diff --git a/contracts/ens/contract/publicresolver.go b/contracts/ens/contract/publicresolver.go deleted file mode 100644 index a7ac9ab0ef7b..000000000000 --- a/contracts/ens/contract/publicresolver.go +++ /dev/null @@ -1,1321 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contract - -import ( - "math/big" - "strings" - - ethereum "github.com/XinFinOrg/XDPoSChain" - "github.com/XinFinOrg/XDPoSChain/accounts/abi" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/event" -) - -// PublicResolverABI is the input ABI used to generate the binding from. -const PublicResolverABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setText\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentTypes\",\"type\":\"uint256\"}],\"name\":\"ABI\",\"outputs\":[{\"name\":\"contentType\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"setPubkey\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"content\",\"outputs\":[{\"name\":\"ret\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"name\":\"ret\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"key\",\"type\":\"string\"}],\"name\":\"text\",\"outputs\":[{\"name\":\"ret\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentType\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"setABI\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"name\",\"outputs\":[{\"name\":\"ret\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"setContent\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"pubkey\",\"outputs\":[{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setAddr\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"ContentChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"contentType\",\"type\":\"uint256\"}],\"name\":\"ABIChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"x\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"PubkeyChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"indexedKey\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"key\",\"type\":\"string\"}],\"name\":\"TextChanged\",\"type\":\"event\"}]" - -// PublicResolverBin is the compiled bytecode used for deploying new contracts. -const PublicResolverBin = `0x6060604052341561000f57600080fd5b6040516020806111b28339810160405280805160008054600160a060020a03909216600160a060020a0319909216919091179055505061115e806100546000396000f3006060604052600436106100ab5763ffffffff60e060020a60003504166301ffc9a781146100b057806310f13a8c146100e45780632203ab561461017e57806329cd62ea146102155780632dff6941146102315780633b3b57de1461025957806359d1d43c1461028b578063623195b014610358578063691f3431146103b457806377372213146103ca578063c3d014d614610420578063c869023314610439578063d5fa2b0014610467575b600080fd5b34156100bb57600080fd5b6100d0600160e060020a031960043516610489565b604051901515815260200160405180910390f35b34156100ef57600080fd5b61017c600480359060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405281815292919060208401838380828437509496506105f695505050505050565b005b341561018957600080fd5b610197600435602435610807565b60405182815260406020820181815290820183818151815260200191508051906020019080838360005b838110156101d95780820151838201526020016101c1565b50505050905090810190601f1680156102065780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561022057600080fd5b61017c600435602435604435610931565b341561023c57600080fd5b610247600435610a30565b60405190815260200160405180910390f35b341561026457600080fd5b61026f600435610a46565b604051600160a060020a03909116815260200160405180910390f35b341561029657600080fd5b6102e1600480359060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610a6195505050505050565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561031d578082015183820152602001610305565b50505050905090810190601f16801561034a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561036357600080fd5b61017c600480359060248035919060649060443590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610b8095505050505050565b34156103bf57600080fd5b6102e1600435610c7c565b34156103d557600080fd5b61017c600480359060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610d4295505050505050565b341561042b57600080fd5b61017c600435602435610e8c565b341561044457600080fd5b61044f600435610f65565b60405191825260208201526040908101905180910390f35b341561047257600080fd5b61017c600435600160a060020a0360243516610f82565b6000600160e060020a031982167f3b3b57de0000000000000000000000000000000000000000000000000000000014806104ec5750600160e060020a031982167fd8389dc500000000000000000000000000000000000000000000000000000000145b806105205750600160e060020a031982167f691f343100000000000000000000000000000000000000000000000000000000145b806105545750600160e060020a031982167f2203ab5600000000000000000000000000000000000000000000000000000000145b806105885750600160e060020a031982167fc869023300000000000000000000000000000000000000000000000000000000145b806105bc5750600160e060020a031982167f59d1d43c00000000000000000000000000000000000000000000000000000000145b806105f05750600160e060020a031982167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b600080548491600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561064f57600080fd5b6102c65a03f1151561066057600080fd5b50505060405180519050600160a060020a031614151561067f57600080fd5b6000848152600160205260409081902083916005909101908590518082805190602001908083835b602083106106c65780518252601f1990920191602091820191016106a7565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902090805161070a929160200190611085565b50826040518082805190602001908083835b6020831061073b5780518252601f19909201916020918201910161071c565b6001836020036101000a0380198251168184511617909252505050919091019250604091505051908190039020847fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a75508560405160208082528190810183818151815260200191508051906020019080838360005b838110156107c75780820151838201526020016107af565b50505050905090810190601f1680156107f45780820380516001836020036101000a031916815260200191505b509250505060405180910390a350505050565b6000610811611103565b60008481526001602081905260409091209092505b838311610924578284161580159061085f5750600083815260068201602052604081205460026000196101006001841615020190911604115b15610919578060060160008481526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561090d5780601f106108e25761010080835404028352916020019161090d565b820191906000526020600020905b8154815290600101906020018083116108f057829003601f168201915b50505050509150610929565b600290920291610826565b600092505b509250929050565b600080548491600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561098a57600080fd5b6102c65a03f1151561099b57600080fd5b50505060405180519050600160a060020a03161415156109ba57600080fd5b6040805190810160409081528482526020808301859052600087815260019091522060030181518155602082015160019091015550837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46848460405191825260208201526040908101905180910390a250505050565b6000908152600160208190526040909120015490565b600090815260016020526040902054600160a060020a031690565b610a69611103565b60008381526001602052604090819020600501908390518082805190602001908083835b60208310610aac5780518252601f199092019160209182019101610a8d565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b735780601f10610b4857610100808354040283529160200191610b73565b820191906000526020600020905b815481529060010190602001808311610b5657829003601f168201915b5050505050905092915050565b600080548491600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610bd957600080fd5b6102c65a03f11515610bea57600080fd5b50505060405180519050600160a060020a0316141515610c0957600080fd5b6000198301831615610c1a57600080fd5b60008481526001602090815260408083208684526006019091529020828051610c47929160200190611085565b5082847faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe360405160405180910390a350505050565b610c84611103565b6001600083600019166000191681526020019081526020016000206002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610d365780601f10610d0b57610100808354040283529160200191610d36565b820191906000526020600020905b815481529060010190602001808311610d1957829003601f168201915b50505050509050919050565b600080548391600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610d9b57600080fd5b6102c65a03f11515610dac57600080fd5b50505060405180519050600160a060020a0316141515610dcb57600080fd5b6000838152600160205260409020600201828051610ded929160200190611085565b50827fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78360405160208082528190810183818151815260200191508051906020019080838360005b83811015610e4d578082015183820152602001610e35565b50505050905090810190601f168015610e7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505050565b600080548391600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610ee557600080fd5b6102c65a03f11515610ef657600080fd5b50505060405180519050600160a060020a0316141515610f1557600080fd5b6000838152600160208190526040918290200183905583907f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc9084905190815260200160405180910390a2505050565b600090815260016020526040902060038101546004909101549091565b600080548391600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610fdb57600080fd5b6102c65a03f11515610fec57600080fd5b50505060405180519050600160a060020a031614151561100b57600080fd5b60008381526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03851617905583907f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd290849051600160a060020a03909116815260200160405180910390a2505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106110c657805160ff19168380011785556110f3565b828001600101855582156110f3579182015b828111156110f35782518255916020019190600101906110d8565b506110ff929150611115565b5090565b60206040519081016040526000815290565b61112f91905b808211156110ff576000815560010161111b565b905600a165627a7a723058201ecacbc445b9fbcd91b0ab164389f69d7283b856883bc7437eeed1008345a4920029` - -// DeployPublicResolver deploys a new Ethereum contract, binding an instance of PublicResolver to it. -func DeployPublicResolver(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address) (common.Address, *types.Transaction, *PublicResolver, error) { - parsed, err := abi.JSON(strings.NewReader(PublicResolverABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PublicResolverBin), backend, ensAddr) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil -} - -// PublicResolver is an auto generated Go binding around an Ethereum contract. -type PublicResolver struct { - PublicResolverCaller // Read-only binding to the contract - PublicResolverTransactor // Write-only binding to the contract - PublicResolverFilterer // Log filterer for contract events -} - -// PublicResolverCaller is an auto generated read-only Go binding around an Ethereum contract. -type PublicResolverCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// PublicResolverTransactor is an auto generated write-only Go binding around an Ethereum contract. -type PublicResolverTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// PublicResolverFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type PublicResolverFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// PublicResolverSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type PublicResolverSession struct { - Contract *PublicResolver // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// PublicResolverCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type PublicResolverCallerSession struct { - Contract *PublicResolverCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// PublicResolverTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type PublicResolverTransactorSession struct { - Contract *PublicResolverTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// PublicResolverRaw is an auto generated low-level Go binding around an Ethereum contract. -type PublicResolverRaw struct { - Contract *PublicResolver // Generic contract binding to access the raw methods on -} - -// PublicResolverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type PublicResolverCallerRaw struct { - Contract *PublicResolverCaller // Generic read-only contract binding to access the raw methods on -} - -// PublicResolverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type PublicResolverTransactorRaw struct { - Contract *PublicResolverTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewPublicResolver creates a new instance of PublicResolver, bound to a specific deployed contract. -func NewPublicResolver(address common.Address, backend bind.ContractBackend) (*PublicResolver, error) { - contract, err := bindPublicResolver(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil -} - -// NewPublicResolverCaller creates a new read-only instance of PublicResolver, bound to a specific deployed contract. -func NewPublicResolverCaller(address common.Address, caller bind.ContractCaller) (*PublicResolverCaller, error) { - contract, err := bindPublicResolver(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &PublicResolverCaller{contract: contract}, nil -} - -// NewPublicResolverTransactor creates a new write-only instance of PublicResolver, bound to a specific deployed contract. -func NewPublicResolverTransactor(address common.Address, transactor bind.ContractTransactor) (*PublicResolverTransactor, error) { - contract, err := bindPublicResolver(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &PublicResolverTransactor{contract: contract}, nil -} - -// NewPublicResolverFilterer creates a new log filterer instance of PublicResolver, bound to a specific deployed contract. -func NewPublicResolverFilterer(address common.Address, filterer bind.ContractFilterer) (*PublicResolverFilterer, error) { - contract, err := bindPublicResolver(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &PublicResolverFilterer{contract: contract}, nil -} - -// bindPublicResolver binds a generic wrapper to an already deployed contract. -func bindPublicResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(PublicResolverABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_PublicResolver *PublicResolverRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _PublicResolver.Contract.PublicResolverCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_PublicResolver *PublicResolverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _PublicResolver.Contract.PublicResolverTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_PublicResolver *PublicResolverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _PublicResolver.Contract.PublicResolverTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_PublicResolver *PublicResolverCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { - return _PublicResolver.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_PublicResolver *PublicResolverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _PublicResolver.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_PublicResolver *PublicResolverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _PublicResolver.Contract.contract.Transact(opts, method, params...) -} - -// ABI is a free data retrieval call binding the contract method 0x2203ab56. -// -// Solidity: function ABI(node bytes32, contentTypes uint256) constant returns(contentType uint256, data bytes) -func (_PublicResolver *PublicResolverCaller) ABI(opts *bind.CallOpts, node [32]byte, contentTypes *big.Int) (struct { - ContentType *big.Int - Data []byte -}, error) { - ret := new(struct { - ContentType *big.Int - Data []byte - }) - out := ret - err := _PublicResolver.contract.Call(opts, out, "ABI", node, contentTypes) - return *ret, err -} - -// ABI is a free data retrieval call binding the contract method 0x2203ab56. -// -// Solidity: function ABI(node bytes32, contentTypes uint256) constant returns(contentType uint256, data bytes) -func (_PublicResolver *PublicResolverSession) ABI(node [32]byte, contentTypes *big.Int) (struct { - ContentType *big.Int - Data []byte -}, error) { - return _PublicResolver.Contract.ABI(&_PublicResolver.CallOpts, node, contentTypes) -} - -// ABI is a free data retrieval call binding the contract method 0x2203ab56. -// -// Solidity: function ABI(node bytes32, contentTypes uint256) constant returns(contentType uint256, data bytes) -func (_PublicResolver *PublicResolverCallerSession) ABI(node [32]byte, contentTypes *big.Int) (struct { - ContentType *big.Int - Data []byte -}, error) { - return _PublicResolver.Contract.ABI(&_PublicResolver.CallOpts, node, contentTypes) -} - -// Addr is a free data retrieval call binding the contract method 0x3b3b57de. -// -// Solidity: function addr(node bytes32) constant returns(ret address) -func (_PublicResolver *PublicResolverCaller) Addr(opts *bind.CallOpts, node [32]byte) (common.Address, error) { - var ( - ret0 = new(common.Address) - ) - out := ret0 - err := _PublicResolver.contract.Call(opts, out, "addr", node) - return *ret0, err -} - -// Addr is a free data retrieval call binding the contract method 0x3b3b57de. -// -// Solidity: function addr(node bytes32) constant returns(ret address) -func (_PublicResolver *PublicResolverSession) Addr(node [32]byte) (common.Address, error) { - return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node) -} - -// Addr is a free data retrieval call binding the contract method 0x3b3b57de. -// -// Solidity: function addr(node bytes32) constant returns(ret address) -func (_PublicResolver *PublicResolverCallerSession) Addr(node [32]byte) (common.Address, error) { - return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node) -} - -// Content is a free data retrieval call binding the contract method 0x2dff6941. -// -// Solidity: function content(node bytes32) constant returns(ret bytes32) -func (_PublicResolver *PublicResolverCaller) Content(opts *bind.CallOpts, node [32]byte) ([32]byte, error) { - var ( - ret0 = new([32]byte) - ) - out := ret0 - err := _PublicResolver.contract.Call(opts, out, "content", node) - return *ret0, err -} - -// Content is a free data retrieval call binding the contract method 0x2dff6941. -// -// Solidity: function content(node bytes32) constant returns(ret bytes32) -func (_PublicResolver *PublicResolverSession) Content(node [32]byte) ([32]byte, error) { - return _PublicResolver.Contract.Content(&_PublicResolver.CallOpts, node) -} - -// Content is a free data retrieval call binding the contract method 0x2dff6941. -// -// Solidity: function content(node bytes32) constant returns(ret bytes32) -func (_PublicResolver *PublicResolverCallerSession) Content(node [32]byte) ([32]byte, error) { - return _PublicResolver.Contract.Content(&_PublicResolver.CallOpts, node) -} - -// Name is a free data retrieval call binding the contract method 0x691f3431. -// -// Solidity: function name(node bytes32) constant returns(ret string) -func (_PublicResolver *PublicResolverCaller) Name(opts *bind.CallOpts, node [32]byte) (string, error) { - var ( - ret0 = new(string) - ) - out := ret0 - err := _PublicResolver.contract.Call(opts, out, "name", node) - return *ret0, err -} - -// Name is a free data retrieval call binding the contract method 0x691f3431. -// -// Solidity: function name(node bytes32) constant returns(ret string) -func (_PublicResolver *PublicResolverSession) Name(node [32]byte) (string, error) { - return _PublicResolver.Contract.Name(&_PublicResolver.CallOpts, node) -} - -// Name is a free data retrieval call binding the contract method 0x691f3431. -// -// Solidity: function name(node bytes32) constant returns(ret string) -func (_PublicResolver *PublicResolverCallerSession) Name(node [32]byte) (string, error) { - return _PublicResolver.Contract.Name(&_PublicResolver.CallOpts, node) -} - -// Pubkey is a free data retrieval call binding the contract method 0xc8690233. -// -// Solidity: function pubkey(node bytes32) constant returns(x bytes32, y bytes32) -func (_PublicResolver *PublicResolverCaller) Pubkey(opts *bind.CallOpts, node [32]byte) (struct { - X [32]byte - Y [32]byte -}, error) { - ret := new(struct { - X [32]byte - Y [32]byte - }) - out := ret - err := _PublicResolver.contract.Call(opts, out, "pubkey", node) - return *ret, err -} - -// Pubkey is a free data retrieval call binding the contract method 0xc8690233. -// -// Solidity: function pubkey(node bytes32) constant returns(x bytes32, y bytes32) -func (_PublicResolver *PublicResolverSession) Pubkey(node [32]byte) (struct { - X [32]byte - Y [32]byte -}, error) { - return _PublicResolver.Contract.Pubkey(&_PublicResolver.CallOpts, node) -} - -// Pubkey is a free data retrieval call binding the contract method 0xc8690233. -// -// Solidity: function pubkey(node bytes32) constant returns(x bytes32, y bytes32) -func (_PublicResolver *PublicResolverCallerSession) Pubkey(node [32]byte) (struct { - X [32]byte - Y [32]byte -}, error) { - return _PublicResolver.Contract.Pubkey(&_PublicResolver.CallOpts, node) -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(interfaceID bytes4) constant returns(bool) -func (_PublicResolver *PublicResolverCaller) SupportsInterface(opts *bind.CallOpts, interfaceID [4]byte) (bool, error) { - var ( - ret0 = new(bool) - ) - out := ret0 - err := _PublicResolver.contract.Call(opts, out, "supportsInterface", interfaceID) - return *ret0, err -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(interfaceID bytes4) constant returns(bool) -func (_PublicResolver *PublicResolverSession) SupportsInterface(interfaceID [4]byte) (bool, error) { - return _PublicResolver.Contract.SupportsInterface(&_PublicResolver.CallOpts, interfaceID) -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(interfaceID bytes4) constant returns(bool) -func (_PublicResolver *PublicResolverCallerSession) SupportsInterface(interfaceID [4]byte) (bool, error) { - return _PublicResolver.Contract.SupportsInterface(&_PublicResolver.CallOpts, interfaceID) -} - -// Text is a free data retrieval call binding the contract method 0x59d1d43c. -// -// Solidity: function text(node bytes32, key string) constant returns(ret string) -func (_PublicResolver *PublicResolverCaller) Text(opts *bind.CallOpts, node [32]byte, key string) (string, error) { - var ( - ret0 = new(string) - ) - out := ret0 - err := _PublicResolver.contract.Call(opts, out, "text", node, key) - return *ret0, err -} - -// Text is a free data retrieval call binding the contract method 0x59d1d43c. -// -// Solidity: function text(node bytes32, key string) constant returns(ret string) -func (_PublicResolver *PublicResolverSession) Text(node [32]byte, key string) (string, error) { - return _PublicResolver.Contract.Text(&_PublicResolver.CallOpts, node, key) -} - -// Text is a free data retrieval call binding the contract method 0x59d1d43c. -// -// Solidity: function text(node bytes32, key string) constant returns(ret string) -func (_PublicResolver *PublicResolverCallerSession) Text(node [32]byte, key string) (string, error) { - return _PublicResolver.Contract.Text(&_PublicResolver.CallOpts, node, key) -} - -// SetABI is a paid mutator transaction binding the contract method 0x623195b0. -// -// Solidity: function setABI(node bytes32, contentType uint256, data bytes) returns() -func (_PublicResolver *PublicResolverTransactor) SetABI(opts *bind.TransactOpts, node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) { - return _PublicResolver.contract.Transact(opts, "setABI", node, contentType, data) -} - -// SetABI is a paid mutator transaction binding the contract method 0x623195b0. -// -// Solidity: function setABI(node bytes32, contentType uint256, data bytes) returns() -func (_PublicResolver *PublicResolverSession) SetABI(node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) { - return _PublicResolver.Contract.SetABI(&_PublicResolver.TransactOpts, node, contentType, data) -} - -// SetABI is a paid mutator transaction binding the contract method 0x623195b0. -// -// Solidity: function setABI(node bytes32, contentType uint256, data bytes) returns() -func (_PublicResolver *PublicResolverTransactorSession) SetABI(node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) { - return _PublicResolver.Contract.SetABI(&_PublicResolver.TransactOpts, node, contentType, data) -} - -// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00. -// -// Solidity: function setAddr(node bytes32, addr address) returns() -func (_PublicResolver *PublicResolverTransactor) SetAddr(opts *bind.TransactOpts, node [32]byte, addr common.Address) (*types.Transaction, error) { - return _PublicResolver.contract.Transact(opts, "setAddr", node, addr) -} - -// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00. -// -// Solidity: function setAddr(node bytes32, addr address) returns() -func (_PublicResolver *PublicResolverSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) { - return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr) -} - -// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00. -// -// Solidity: function setAddr(node bytes32, addr address) returns() -func (_PublicResolver *PublicResolverTransactorSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) { - return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr) -} - -// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6. -// -// Solidity: function setContent(node bytes32, hash bytes32) returns() -func (_PublicResolver *PublicResolverTransactor) SetContent(opts *bind.TransactOpts, node [32]byte, hash [32]byte) (*types.Transaction, error) { - return _PublicResolver.contract.Transact(opts, "setContent", node, hash) -} - -// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6. -// -// Solidity: function setContent(node bytes32, hash bytes32) returns() -func (_PublicResolver *PublicResolverSession) SetContent(node [32]byte, hash [32]byte) (*types.Transaction, error) { - return _PublicResolver.Contract.SetContent(&_PublicResolver.TransactOpts, node, hash) -} - -// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6. -// -// Solidity: function setContent(node bytes32, hash bytes32) returns() -func (_PublicResolver *PublicResolverTransactorSession) SetContent(node [32]byte, hash [32]byte) (*types.Transaction, error) { - return _PublicResolver.Contract.SetContent(&_PublicResolver.TransactOpts, node, hash) -} - -// SetName is a paid mutator transaction binding the contract method 0x77372213. -// -// Solidity: function setName(node bytes32, name string) returns() -func (_PublicResolver *PublicResolverTransactor) SetName(opts *bind.TransactOpts, node [32]byte, name string) (*types.Transaction, error) { - return _PublicResolver.contract.Transact(opts, "setName", node, name) -} - -// SetName is a paid mutator transaction binding the contract method 0x77372213. -// -// Solidity: function setName(node bytes32, name string) returns() -func (_PublicResolver *PublicResolverSession) SetName(node [32]byte, name string) (*types.Transaction, error) { - return _PublicResolver.Contract.SetName(&_PublicResolver.TransactOpts, node, name) -} - -// SetName is a paid mutator transaction binding the contract method 0x77372213. -// -// Solidity: function setName(node bytes32, name string) returns() -func (_PublicResolver *PublicResolverTransactorSession) SetName(node [32]byte, name string) (*types.Transaction, error) { - return _PublicResolver.Contract.SetName(&_PublicResolver.TransactOpts, node, name) -} - -// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea. -// -// Solidity: function setPubkey(node bytes32, x bytes32, y bytes32) returns() -func (_PublicResolver *PublicResolverTransactor) SetPubkey(opts *bind.TransactOpts, node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) { - return _PublicResolver.contract.Transact(opts, "setPubkey", node, x, y) -} - -// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea. -// -// Solidity: function setPubkey(node bytes32, x bytes32, y bytes32) returns() -func (_PublicResolver *PublicResolverSession) SetPubkey(node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) { - return _PublicResolver.Contract.SetPubkey(&_PublicResolver.TransactOpts, node, x, y) -} - -// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea. -// -// Solidity: function setPubkey(node bytes32, x bytes32, y bytes32) returns() -func (_PublicResolver *PublicResolverTransactorSession) SetPubkey(node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) { - return _PublicResolver.Contract.SetPubkey(&_PublicResolver.TransactOpts, node, x, y) -} - -// SetText is a paid mutator transaction binding the contract method 0x10f13a8c. -// -// Solidity: function setText(node bytes32, key string, value string) returns() -func (_PublicResolver *PublicResolverTransactor) SetText(opts *bind.TransactOpts, node [32]byte, key string, value string) (*types.Transaction, error) { - return _PublicResolver.contract.Transact(opts, "setText", node, key, value) -} - -// SetText is a paid mutator transaction binding the contract method 0x10f13a8c. -// -// Solidity: function setText(node bytes32, key string, value string) returns() -func (_PublicResolver *PublicResolverSession) SetText(node [32]byte, key string, value string) (*types.Transaction, error) { - return _PublicResolver.Contract.SetText(&_PublicResolver.TransactOpts, node, key, value) -} - -// SetText is a paid mutator transaction binding the contract method 0x10f13a8c. -// -// Solidity: function setText(node bytes32, key string, value string) returns() -func (_PublicResolver *PublicResolverTransactorSession) SetText(node [32]byte, key string, value string) (*types.Transaction, error) { - return _PublicResolver.Contract.SetText(&_PublicResolver.TransactOpts, node, key, value) -} - -// PublicResolverABIChangedIterator is returned from FilterABIChanged and is used to iterate over the raw logs and unpacked data for ABIChanged events raised by the PublicResolver contract. -type PublicResolverABIChangedIterator struct { - Event *PublicResolverABIChanged // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *PublicResolverABIChangedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(PublicResolverABIChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(PublicResolverABIChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *PublicResolverABIChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *PublicResolverABIChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// PublicResolverABIChanged represents a ABIChanged event raised by the PublicResolver contract. -type PublicResolverABIChanged struct { - Node [32]byte - ContentType *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterABIChanged is a free log retrieval operation binding the contract event 0xaa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe3. -// -// Solidity: event ABIChanged(node indexed bytes32, contentType indexed uint256) -func (_PublicResolver *PublicResolverFilterer) FilterABIChanged(opts *bind.FilterOpts, node [][32]byte, contentType []*big.Int) (*PublicResolverABIChangedIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - var contentTypeRule []interface{} - for _, contentTypeItem := range contentType { - contentTypeRule = append(contentTypeRule, contentTypeItem) - } - - logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "ABIChanged", nodeRule, contentTypeRule) - if err != nil { - return nil, err - } - return &PublicResolverABIChangedIterator{contract: _PublicResolver.contract, event: "ABIChanged", logs: logs, sub: sub}, nil -} - -// WatchABIChanged is a free log subscription operation binding the contract event 0xaa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe3. -// -// Solidity: event ABIChanged(node indexed bytes32, contentType indexed uint256) -func (_PublicResolver *PublicResolverFilterer) WatchABIChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverABIChanged, node [][32]byte, contentType []*big.Int) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - var contentTypeRule []interface{} - for _, contentTypeItem := range contentType { - contentTypeRule = append(contentTypeRule, contentTypeItem) - } - - logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "ABIChanged", nodeRule, contentTypeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(PublicResolverABIChanged) - if err := _PublicResolver.contract.UnpackLog(event, "ABIChanged", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// PublicResolverAddrChangedIterator is returned from FilterAddrChanged and is used to iterate over the raw logs and unpacked data for AddrChanged events raised by the PublicResolver contract. -type PublicResolverAddrChangedIterator struct { - Event *PublicResolverAddrChanged // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *PublicResolverAddrChangedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(PublicResolverAddrChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(PublicResolverAddrChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *PublicResolverAddrChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *PublicResolverAddrChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// PublicResolverAddrChanged represents a AddrChanged event raised by the PublicResolver contract. -type PublicResolverAddrChanged struct { - Node [32]byte - A common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterAddrChanged is a free log retrieval operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2. -// -// Solidity: event AddrChanged(node indexed bytes32, a address) -func (_PublicResolver *PublicResolverFilterer) FilterAddrChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverAddrChangedIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "AddrChanged", nodeRule) - if err != nil { - return nil, err - } - return &PublicResolverAddrChangedIterator{contract: _PublicResolver.contract, event: "AddrChanged", logs: logs, sub: sub}, nil -} - -// WatchAddrChanged is a free log subscription operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2. -// -// Solidity: event AddrChanged(node indexed bytes32, a address) -func (_PublicResolver *PublicResolverFilterer) WatchAddrChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverAddrChanged, node [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "AddrChanged", nodeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(PublicResolverAddrChanged) - if err := _PublicResolver.contract.UnpackLog(event, "AddrChanged", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// PublicResolverContentChangedIterator is returned from FilterContentChanged and is used to iterate over the raw logs and unpacked data for ContentChanged events raised by the PublicResolver contract. -type PublicResolverContentChangedIterator struct { - Event *PublicResolverContentChanged // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *PublicResolverContentChangedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(PublicResolverContentChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(PublicResolverContentChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *PublicResolverContentChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *PublicResolverContentChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// PublicResolverContentChanged represents a ContentChanged event raised by the PublicResolver contract. -type PublicResolverContentChanged struct { - Node [32]byte - Hash [32]byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterContentChanged is a free log retrieval operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc. -// -// Solidity: event ContentChanged(node indexed bytes32, hash bytes32) -func (_PublicResolver *PublicResolverFilterer) FilterContentChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverContentChangedIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "ContentChanged", nodeRule) - if err != nil { - return nil, err - } - return &PublicResolverContentChangedIterator{contract: _PublicResolver.contract, event: "ContentChanged", logs: logs, sub: sub}, nil -} - -// WatchContentChanged is a free log subscription operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc. -// -// Solidity: event ContentChanged(node indexed bytes32, hash bytes32) -func (_PublicResolver *PublicResolverFilterer) WatchContentChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverContentChanged, node [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "ContentChanged", nodeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(PublicResolverContentChanged) - if err := _PublicResolver.contract.UnpackLog(event, "ContentChanged", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// PublicResolverNameChangedIterator is returned from FilterNameChanged and is used to iterate over the raw logs and unpacked data for NameChanged events raised by the PublicResolver contract. -type PublicResolverNameChangedIterator struct { - Event *PublicResolverNameChanged // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *PublicResolverNameChangedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(PublicResolverNameChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(PublicResolverNameChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *PublicResolverNameChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *PublicResolverNameChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// PublicResolverNameChanged represents a NameChanged event raised by the PublicResolver contract. -type PublicResolverNameChanged struct { - Node [32]byte - Name string - Raw types.Log // Blockchain specific contextual infos -} - -// FilterNameChanged is a free log retrieval operation binding the contract event 0xb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7. -// -// Solidity: event NameChanged(node indexed bytes32, name string) -func (_PublicResolver *PublicResolverFilterer) FilterNameChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverNameChangedIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "NameChanged", nodeRule) - if err != nil { - return nil, err - } - return &PublicResolverNameChangedIterator{contract: _PublicResolver.contract, event: "NameChanged", logs: logs, sub: sub}, nil -} - -// WatchNameChanged is a free log subscription operation binding the contract event 0xb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7. -// -// Solidity: event NameChanged(node indexed bytes32, name string) -func (_PublicResolver *PublicResolverFilterer) WatchNameChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverNameChanged, node [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "NameChanged", nodeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(PublicResolverNameChanged) - if err := _PublicResolver.contract.UnpackLog(event, "NameChanged", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// PublicResolverPubkeyChangedIterator is returned from FilterPubkeyChanged and is used to iterate over the raw logs and unpacked data for PubkeyChanged events raised by the PublicResolver contract. -type PublicResolverPubkeyChangedIterator struct { - Event *PublicResolverPubkeyChanged // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *PublicResolverPubkeyChangedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(PublicResolverPubkeyChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(PublicResolverPubkeyChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *PublicResolverPubkeyChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *PublicResolverPubkeyChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// PublicResolverPubkeyChanged represents a PubkeyChanged event raised by the PublicResolver contract. -type PublicResolverPubkeyChanged struct { - Node [32]byte - X [32]byte - Y [32]byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterPubkeyChanged is a free log retrieval operation binding the contract event 0x1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46. -// -// Solidity: event PubkeyChanged(node indexed bytes32, x bytes32, y bytes32) -func (_PublicResolver *PublicResolverFilterer) FilterPubkeyChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverPubkeyChangedIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "PubkeyChanged", nodeRule) - if err != nil { - return nil, err - } - return &PublicResolverPubkeyChangedIterator{contract: _PublicResolver.contract, event: "PubkeyChanged", logs: logs, sub: sub}, nil -} - -// WatchPubkeyChanged is a free log subscription operation binding the contract event 0x1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46. -// -// Solidity: event PubkeyChanged(node indexed bytes32, x bytes32, y bytes32) -func (_PublicResolver *PublicResolverFilterer) WatchPubkeyChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverPubkeyChanged, node [][32]byte) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - - logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "PubkeyChanged", nodeRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(PublicResolverPubkeyChanged) - if err := _PublicResolver.contract.UnpackLog(event, "PubkeyChanged", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// PublicResolverTextChangedIterator is returned from FilterTextChanged and is used to iterate over the raw logs and unpacked data for TextChanged events raised by the PublicResolver contract. -type PublicResolverTextChangedIterator struct { - Event *PublicResolverTextChanged // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *PublicResolverTextChangedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(PublicResolverTextChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(PublicResolverTextChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error retruned any retrieval or parsing error occurred during filtering. -func (it *PublicResolverTextChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *PublicResolverTextChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// PublicResolverTextChanged represents a TextChanged event raised by the PublicResolver contract. -type PublicResolverTextChanged struct { - Node [32]byte - IndexedKey common.Hash - Key string - Raw types.Log // Blockchain specific contextual infos -} - -// FilterTextChanged is a free log retrieval operation binding the contract event 0xd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550. -// -// Solidity: event TextChanged(node indexed bytes32, indexedKey indexed string, key string) -func (_PublicResolver *PublicResolverFilterer) FilterTextChanged(opts *bind.FilterOpts, node [][32]byte, indexedKey []string) (*PublicResolverTextChangedIterator, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - var indexedKeyRule []interface{} - for _, indexedKeyItem := range indexedKey { - indexedKeyRule = append(indexedKeyRule, indexedKeyItem) - } - - logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "TextChanged", nodeRule, indexedKeyRule) - if err != nil { - return nil, err - } - return &PublicResolverTextChangedIterator{contract: _PublicResolver.contract, event: "TextChanged", logs: logs, sub: sub}, nil -} - -// WatchTextChanged is a free log subscription operation binding the contract event 0xd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550. -// -// Solidity: event TextChanged(node indexed bytes32, indexedKey indexed string, key string) -func (_PublicResolver *PublicResolverFilterer) WatchTextChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverTextChanged, node [][32]byte, indexedKey []string) (event.Subscription, error) { - - var nodeRule []interface{} - for _, nodeItem := range node { - nodeRule = append(nodeRule, nodeItem) - } - var indexedKeyRule []interface{} - for _, indexedKeyItem := range indexedKey { - indexedKeyRule = append(indexedKeyRule, indexedKeyItem) - } - - logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "TextChanged", nodeRule, indexedKeyRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(PublicResolverTextChanged) - if err := _PublicResolver.contract.UnpackLog(event, "TextChanged", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} diff --git a/contracts/ens/ens.go b/contracts/ens/ens.go deleted file mode 100644 index 7c47865097b8..000000000000 --- a/contracts/ens/ens.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package ens - -//go:generate abigen --sol contract/ENS.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/ens.go -//go:generate abigen --sol contract/FIFSRegistrar.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/fifsregistrar.go -//go:generate abigen --sol contract/PublicResolver.sol --exc contract/AbstractENS.sol:AbstractENS --pkg contract --out contract/publicresolver.go - -import ( - "strings" - - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/contracts/ens/contract" - "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/crypto" -) - -var ( - MainNetAddress = common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b") - TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010") -) - -// swarm domain name registry and resolver -type ENS struct { - *contract.ENSSession - contractBackend bind.ContractBackend -} - -// NewENS creates a struct exposing convenient high-level operations for interacting with -// the Ethereum Name Service. -func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) { - ens, err := contract.NewENS(contractAddr, contractBackend) - if err != nil { - return nil, err - } - - return &ENS{ - &contract.ENSSession{ - Contract: ens, - TransactOpts: *transactOpts, - }, - contractBackend, - }, nil -} - -// DeployENS deploys an instance of the ENS nameservice, with a 'first-in, first-served' root registrar. -func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *ENS, error) { - // Deploy the ENS registry. - ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend) - if err != nil { - return ensAddr, nil, err - } - - ens, err := NewENS(transactOpts, ensAddr, contractBackend) - if err != nil { - return ensAddr, nil, err - } - - // Deploy the registrar. - regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{}) - if err != nil { - return ensAddr, nil, err - } - // Set the registrar as owner of the ENS root. - if _, err = ens.SetOwner([32]byte{}, regAddr); err != nil { - return ensAddr, nil, err - } - - return ensAddr, ens, nil -} - -func ensParentNode(name string) (common.Hash, common.Hash) { - parts := strings.SplitN(name, ".", 2) - label := crypto.Keccak256Hash([]byte(parts[0])) - if len(parts) == 1 { - return [32]byte{}, label - } else { - parentNode, parentLabel := ensParentNode(parts[1]) - return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label - } -} - -func ensNode(name string) common.Hash { - parentNode, parentLabel := ensParentNode(name) - return crypto.Keccak256Hash(parentNode[:], parentLabel[:]) -} - -func (e *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) { - resolverAddr, err := e.Resolver(node) - if err != nil { - return nil, err - } - - resolver, err := contract.NewPublicResolver(resolverAddr, e.contractBackend) - if err != nil { - return nil, err - } - - return &contract.PublicResolverSession{ - Contract: resolver, - TransactOpts: e.TransactOpts, - }, nil -} - -func (e *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) { - registrarAddr, err := e.Owner(node) - if err != nil { - return nil, err - } - - registrar, err := contract.NewFIFSRegistrar(registrarAddr, e.contractBackend) - if err != nil { - return nil, err - } - - return &contract.FIFSRegistrarSession{ - Contract: registrar, - TransactOpts: e.TransactOpts, - }, nil -} - -// Resolve is a non-transactional call that returns the content hash associated with a name. -func (e *ENS) Resolve(name string) (common.Hash, error) { - node := ensNode(name) - - resolver, err := e.getResolver(node) - if err != nil { - return common.Hash{}, err - } - - ret, err := resolver.Content(node) - if err != nil { - return common.Hash{}, err - } - - return common.BytesToHash(ret[:]), nil -} - -// Register registers a new domain name for the caller, making them the owner of the new name. -// Only works if the registrar for the parent domain implements the FIFS registrar protocol. -func (e *ENS) Register(name string) (*types.Transaction, error) { - parentNode, label := ensParentNode(name) - registrar, err := e.getRegistrar(parentNode) - if err != nil { - return nil, err - } - return registrar.Contract.Register(&e.TransactOpts, label, e.TransactOpts.From) -} - -// SetContentHash sets the content hash associated with a name. Only works if the caller -// owns the name, and the associated resolver implements a `setContent` function. -func (e *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) { - node := ensNode(name) - - resolver, err := e.getResolver(node) - if err != nil { - return nil, err - } - - opts := e.TransactOpts - opts.GasLimit = 200000 - return resolver.Contract.SetContent(&opts, node, hash) -} diff --git a/contracts/ens/ens_test.go b/contracts/ens/ens_test.go deleted file mode 100644 index 410b5acdadf1..000000000000 --- a/contracts/ens/ens_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package ens - -import ( - "math/big" - "testing" - - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/contracts/ens/contract" - "github.com/XinFinOrg/XDPoSChain/core" - "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/params" -) - -var ( - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - name = "my name on ENS" - hash = crypto.Keccak256Hash([]byte("my content")) - addr = crypto.PubkeyToAddress(key.PublicKey) -) - -func TestENS(t *testing.T) { - contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig) - transactOpts := bind.NewKeyedTransactor(key) - - ensAddr, ens, err := DeployENS(transactOpts, contractBackend) - if err != nil { - t.Fatalf("can't deploy root registry: %v", err) - } - contractBackend.Commit() - - // Set ourself as the owner of the name. - if _, err := ens.Register(name); err != nil { - t.Fatalf("can't register: %v", err) - } - contractBackend.Commit() - - // Deploy a resolver and make it responsible for the name. - resolverAddr, _, _, err := contract.DeployPublicResolver(transactOpts, contractBackend, ensAddr) - if err != nil { - t.Fatalf("can't deploy resolver: %v", err) - } - if _, err := ens.SetResolver(ensNode(name), resolverAddr); err != nil { - t.Fatalf("can't set resolver: %v", err) - } - contractBackend.Commit() - - // Set the content hash for the name. - if _, err = ens.SetContentHash(name, hash); err != nil { - t.Fatalf("can't set content hash: %v", err) - } - contractBackend.Commit() - - // Try to resolve the name. - vhost, err := ens.Resolve(name) - if err != nil { - t.Fatalf("expected no error, got %v", err) - } - if vhost != hash { - t.Fatalf("resolve error, expected %v, got %v", hash.Hex(), vhost.Hex()) - } -} From 38f4c98740655be12ed62a082391b39e12bcd616 Mon Sep 17 00:00:00 2001 From: benjamin202410 Date: Wed, 15 Jan 2025 19:47:58 -0800 Subject: [PATCH 121/121] remove-ec2-rpcs (#793) Co-authored-by: liam.lai --- cicd/terraform/.env | 1 - cicd/terraform/iam.tf | 28 ----- cicd/terraform/main.tf | 66 ----------- cicd/terraform/module/ec2_rpc/main.tf | 109 ------------------ .../module/region/container-definition.tpl | 44 ------- cicd/terraform/module/region/ecs.tf | 96 --------------- cicd/terraform/module/region/efs.tf | 67 ----------- cicd/terraform/module/region/main.tf | 103 ----------------- cicd/terraform/module/region/rpc.tf | 104 ----------------- cicd/terraform/module/region/variables.tf | 50 -------- cicd/terraform/s3.tf | 14 --- cicd/terraform/variables.tf | 17 --- 12 files changed, 699 deletions(-) delete mode 100644 cicd/terraform/.env delete mode 100644 cicd/terraform/iam.tf delete mode 100644 cicd/terraform/main.tf delete mode 100644 cicd/terraform/module/ec2_rpc/main.tf delete mode 100644 cicd/terraform/module/region/container-definition.tpl delete mode 100644 cicd/terraform/module/region/ecs.tf delete mode 100644 cicd/terraform/module/region/efs.tf delete mode 100644 cicd/terraform/module/region/main.tf delete mode 100644 cicd/terraform/module/region/rpc.tf delete mode 100644 cicd/terraform/module/region/variables.tf delete mode 100644 cicd/terraform/s3.tf delete mode 100644 cicd/terraform/variables.tf diff --git a/cicd/terraform/.env b/cicd/terraform/.env deleted file mode 100644 index bffc1dd977b8..000000000000 --- a/cicd/terraform/.env +++ /dev/null @@ -1 +0,0 @@ -log_level=3 diff --git a/cicd/terraform/iam.tf b/cicd/terraform/iam.tf deleted file mode 100644 index f5c5ee2fe08c..000000000000 --- a/cicd/terraform/iam.tf +++ /dev/null @@ -1,28 +0,0 @@ -# IAM policies -data "aws_iam_policy_document" "xdc_ecs_tasks_execution_role" { - statement { - actions = ["sts:AssumeRole"] - - principals { - type = "Service" - identifiers = ["ecs-tasks.amazonaws.com"] - } - } -} - -# Create the role -resource "aws_iam_role" "xdc_ecs_tasks_execution_role" { - name = "xdc-ecs-task-execution-role" - assume_role_policy = "${data.aws_iam_policy_document.xdc_ecs_tasks_execution_role.json}" -} - -# Attached the AWS managed policies to the new role -resource "aws_iam_role_policy_attachment" "xdc_ecs_tasks_execution_role" { - for_each = toset([ - "arn:aws:iam::aws:policy/AmazonElasticFileSystemClientFullAccess", - "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", - "arn:aws:iam::aws:policy/AmazonElasticFileSystemsUtils" - ]) - role = aws_iam_role.xdc_ecs_tasks_execution_role.name - policy_arn = each.value -} diff --git a/cicd/terraform/main.tf b/cicd/terraform/main.tf deleted file mode 100644 index 7fc541fb7f1d..000000000000 --- a/cicd/terraform/main.tf +++ /dev/null @@ -1,66 +0,0 @@ -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.13.1" - } - } -} - -# Default -provider "aws" { - region = "us-east-1" -} - -provider "aws" { - alias = "ap-southeast-1" - region = "ap-southeast-1" -} - -module "devnet_rpc" { - source = "./module/ec2_rpc" - network = "devnet" - vpc_id = local.vpc_id - aws_subnet_id = local.aws_subnet_id - ami_id = local.ami_id - instance_type = "t3.large" - ssh_key_name = local.ssh_key_name - rpc_image = local.rpc_image - volume_size = 1500 - - providers = { - aws = aws.ap-southeast-1 - } -} - -module "testnet_rpc" { - source = "./module/ec2_rpc" - network = "testnet" - vpc_id = local.vpc_id - aws_subnet_id = local.aws_subnet_id - ami_id = local.ami_id - instance_type = "t3.large" - ssh_key_name = local.ssh_key_name - rpc_image = local.rpc_image - volume_size = 1500 - - providers = { - aws = aws.ap-southeast-1 - } -} - -module "mainnet_rpc" { - source = "./module/ec2_rpc" - network = "mainnet" - vpc_id = local.vpc_id - aws_subnet_id = local.aws_subnet_id - ami_id = local.ami_id - instance_type = "t3.large" - ssh_key_name = local.ssh_key_name - rpc_image = local.rpc_image - volume_size = 3000 - - providers = { - aws = aws.ap-southeast-1 - } -} \ No newline at end of file diff --git a/cicd/terraform/module/ec2_rpc/main.tf b/cicd/terraform/module/ec2_rpc/main.tf deleted file mode 100644 index 00594517acea..000000000000 --- a/cicd/terraform/module/ec2_rpc/main.tf +++ /dev/null @@ -1,109 +0,0 @@ -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.13.1" - } - } -} -variable network { - type = string -} -variable vpc_id { - type = string -} -variable aws_subnet_id { - type = string -} -variable ami_id { - type = string -} -variable instance_type { - type = string -} -variable ssh_key_name { - type = string -} -variable rpc_image { - type = string -} -variable volume_size{ - type = number -} - -resource "aws_security_group" "rpc_sg" { - name_prefix = "${var.network}_rpc_sg" - - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 30303 - to_port = 30303 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 8545 - to_port = 8545 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 8555 - to_port = 8555 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } -} - -resource "aws_instance" "rpc_instance" { - instance_type = var.instance_type - ami = var.ami_id - tags = { - Name = var.network - } - key_name = var.ssh_key_name - vpc_security_group_ids = [aws_security_group.rpc_sg.id] - - root_block_device { - volume_size = var.volume_size - } - - - #below still need to remove git checkout {{branch}} after files merged to master - user_data = <<-EOF - #!/bin/bash - sudo yum update -y - sudo yum upgrade -y - sudo yum install git -y - sudo yum install docker -y - mkdir -p /root/.docker/cli-plugins - curl -SL https://github.com/docker/compose/releases/download/v2.25.0/docker-compose-linux-x86_64 -o /root/.docker/cli-plugins/docker-compose - sudo chmod +x /root/.docker/cli-plugins/docker-compose - echo checking compose version - docker compose version - sudo systemctl enable docker - sudo systemctl start docker - mkdir -p /work - cd /work - git clone https://github.com/XinFinOrg/XinFin-Node - cd /work/XinFin-Node/${var.network} - export RPC_IMAGE="${var.rpc_image}" - echo RPC_IMAGE=$RPC_IMAGE - ./docker-up-hash.sh - EOF -} \ No newline at end of file diff --git a/cicd/terraform/module/region/container-definition.tpl b/cicd/terraform/module/region/container-definition.tpl deleted file mode 100644 index 008e98522ac1..000000000000 --- a/cicd/terraform/module/region/container-definition.tpl +++ /dev/null @@ -1,44 +0,0 @@ -[ - { - "name": "tfXdcNode", - "image": "xinfinorg/${image_environment}:${image_tag}", - "environment": [ - {"name": "PRIVATE_KEY", "value": "${private_key}"}, - {"name": "LOG_LEVEL", "value": "${log_level}"}, - {"name": "NODE_NAME", "value": "${node_name}"}, - {"name": "NETWORK", "value": "${chain_network}"} - ], - "essential": true, - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-group": "${cloudwatch_group}", - "awslogs-region": "${cloudwatch_region}", - "awslogs-stream-prefix": "ecs" - } - }, - "portMappings": [ - { - "hostPort": 8555, - "protocol": "tcp", - "containerPort": 8555 - }, - { - "hostPort": 8545, - "protocol": "tcp", - "containerPort": 8545 - }, - { - "hostPort": 30303, - "protocol": "tcp", - "containerPort": 30303 - } - ], - "mountPoints": [ - { - "containerPath": "/work/xdcchain", - "sourceVolume": "efs" - } - ] - } -] \ No newline at end of file diff --git a/cicd/terraform/module/region/ecs.tf b/cicd/terraform/module/region/ecs.tf deleted file mode 100644 index d529cafb4702..000000000000 --- a/cicd/terraform/module/region/ecs.tf +++ /dev/null @@ -1,96 +0,0 @@ -data template_file container_definition { - for_each = var.nodeKeys - template = "${file("${path.module}/container-definition.tpl")}" - - vars = { - image_environment = "${lookup(each.value, "imageEnvironment", "devnet")}" - image_tag = "${lookup(each.value, "imageTag", "latest")}" - node_name = "${each.key}" - private_key = "${each.value.pk}" - cloudwatch_group = "tf-${each.key}" - cloudwatch_region = "${var.region}" - log_level = "${lookup(each.value, "logLevel", "${var.logLevel}")}" - chain_network = var.network - } -} - -resource "aws_ecs_task_definition" "task_definition_group" { - for_each = var.nodeKeys - - family = "${var.network}-${each.key}" - requires_compatibilities = ["FARGATE"] - network_mode = "awsvpc" - container_definitions = data.template_file.container_definition[each.key].rendered - execution_role_arn = var.xdc_ecs_tasks_execution_role_arn - task_role_arn = var.xdc_ecs_tasks_execution_role_arn - - # New nodes will consume a lot more CPU usage than existing nodes. - # This is due to sync is resource heavy. Recommending set to below if doing sync: - # CPU = 2048, Memory = 4096 - # Please set it back to cpu 256 and memory of 2048 after sync is done to save the cost - # cpu = 256 - # memory = 2048 - cpu = var.cpu - memory = var.memory - volume { - name = "efs" - - efs_volume_configuration { - file_system_id = aws_efs_file_system.efs[each.key].id - root_directory = "/" - transit_encryption = "ENABLED" - authorization_config { - access_point_id = aws_efs_access_point.efs_access_point[each.key].id - iam = "DISABLED" - } - } - } - - tags = { - Name = "Tf${var.network}Ecs-${each.key}" - } -} - -data "aws_ecs_task_definition" "ecs_task_definition" { - for_each = var.nodeKeys - task_definition = aws_ecs_task_definition.task_definition_group[each.key].family -} - -# ECS cluster -resource "aws_ecs_cluster" "ecs_cluster" { - name = "${var.network}-xdcnode-cluster" - tags = { - Name = "Tf${var.network}EcsCluster" - } -} - - -resource "aws_ecs_service" "ecs_service" { - for_each = var.enableFixedIp ? {} : var.nodeKeys - name = "ecs-service-${each.key}" - cluster = aws_ecs_cluster.ecs_cluster.id - task_definition = "${aws_ecs_task_definition.task_definition_group[each.key].family}:${max(aws_ecs_task_definition.task_definition_group[each.key].revision, data.aws_ecs_task_definition.ecs_task_definition[each.key].revision)}" - launch_type = "FARGATE" - scheduling_strategy = "REPLICA" - desired_count = 1 - force_new_deployment = true - deployment_minimum_healthy_percent = 0 - deployment_maximum_percent = 100 - - network_configuration { - subnets = [aws_subnet.subnet.id] - assign_public_ip = true - security_groups = [ - aws_default_security_group.xdcnode_security_group.id - ] - } - - deployment_circuit_breaker { - enable = true - rollback = false - } - - tags = { - Name = "Tf${var.network}EcsService-${each.key}" - } -} \ No newline at end of file diff --git a/cicd/terraform/module/region/efs.tf b/cicd/terraform/module/region/efs.tf deleted file mode 100644 index 11b426ff3754..000000000000 --- a/cicd/terraform/module/region/efs.tf +++ /dev/null @@ -1,67 +0,0 @@ - -# EFS -resource "aws_security_group" "efs_security_group" { - name = "Tf${var.network}EfsSecurityGroup" - description = "Allow HTTP in and out of ${var.network} EFS" - vpc_id = aws_vpc.vpc.id - - ingress { - from_port = 2049 - to_port = 2049 - protocol = "TCP" - security_groups = [aws_default_security_group.xdcnode_security_group.id] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - tags = { - Name = "Tf${var.network}Efs" - } -} - -resource "aws_efs_file_system" "efs" { - for_each = var.nodeKeys - creation_token = "efs-${each.key}" - performance_mode = "generalPurpose" - throughput_mode = "bursting" - encrypted = "true" - lifecycle_policy { - transition_to_ia = "AFTER_30_DAYS" - } - tags = { - Name = "Tf${var.network}Efs${each.key}" - } - } - -resource "aws_efs_mount_target" "efs_efs_mount_target" { - for_each = var.nodeKeys - file_system_id = aws_efs_file_system.efs[each.key].id - subnet_id = aws_subnet.subnet.id - security_groups = [aws_security_group.efs_security_group.id] -} - -resource "aws_efs_access_point" "efs_access_point" { - for_each = var.nodeKeys - file_system_id = aws_efs_file_system.efs[each.key].id - root_directory { - path = "/${each.key}/database" - creation_info { - owner_gid = 1001 - owner_uid = 1001 - permissions = 777 - } - } - posix_user { - gid = 1001 - uid = 1001 - secondary_gids = [0] - } - - tags = { - Name = "Tf${var.network}EfsAccessPoint${each.key}" - } -} \ No newline at end of file diff --git a/cicd/terraform/module/region/main.tf b/cicd/terraform/module/region/main.tf deleted file mode 100644 index 5c6e0a47cd16..000000000000 --- a/cicd/terraform/module/region/main.tf +++ /dev/null @@ -1,103 +0,0 @@ -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.13.1" - } - } -} - -resource "aws_vpc" "vpc" { - cidr_block = var.vpc_cidr - instance_tenancy = "default" - enable_dns_hostnames = true - - tags = { - Name = "Tf${var.network}Vpc" - } -} - -resource "aws_subnet" "subnet" { - vpc_id = aws_vpc.vpc.id - cidr_block = var.subnet_cidr - map_public_ip_on_launch = true - - tags = { - Name = "Tf${var.network}VpcSubnet" - } -} - -resource "aws_internet_gateway" "gatewat" { - vpc_id = aws_vpc.vpc.id - - tags = { - Name = "Tf${var.network}Gateway" - } -} - -resource "aws_route_table" "route_table" { - vpc_id = aws_vpc.vpc.id - - route { - cidr_block = "0.0.0.0/0" - gateway_id = aws_internet_gateway.gatewat.id - } - - tags = { - Name = "Tf${var.network}VpcRoutingTable" - } -} - -resource "aws_route_table_association" "route_table_association" { - subnet_id = aws_subnet.subnet.id - route_table_id = aws_route_table.route_table.id -} - -resource "aws_default_security_group" "xdcnode_security_group" { - vpc_id = aws_vpc.vpc.id - - ingress { - description = "listener port" - from_port = 30303 - to_port = 30303 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - description = "discovery port" - from_port = 30303 - to_port = 30303 - protocol = "udp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - description = "rpc port" - from_port = 8545 - to_port = 8545 - protocol = "tcp" - cidr_blocks = [var.vpc_cidr] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - tags = { - Name = "Tf${var.network}Node" - } -} - -# Logs -resource "aws_cloudwatch_log_group" "cloud_watch_group" { - for_each = var.nodeKeys - - name = "tf-${each.key}" - retention_in_days = 14 # Logs are only kept for 14 days - tags = { - Name = "Tf${var.network}CloudWatchGroup${each.key}" - } -} \ No newline at end of file diff --git a/cicd/terraform/module/region/rpc.tf b/cicd/terraform/module/region/rpc.tf deleted file mode 100644 index 901b3b9c0bca..000000000000 --- a/cicd/terraform/module/region/rpc.tf +++ /dev/null @@ -1,104 +0,0 @@ -# Allocate an Elastic IP for the NLB -resource "aws_eip" "nlb_eip" { - domain = "vpc" -} - - -# Create a Network Load Balancer -resource "aws_lb" "rpc_node_nlb" { - count = var.enableFixedIp ? 1 : 0 - name = "${var.network}-rpc-node-nlb" - load_balancer_type = "network" - - enable_deletion_protection = false - - subnet_mapping { - subnet_id = aws_subnet.subnet.id - allocation_id = aws_eip.nlb_eip.id - } -} - -# Listener and Target Group for the rpc node container -resource "aws_lb_target_group" "rpc_node_tg_8545" { - count = var.enableFixedIp ? 1 : 0 - name = "${var.network}-rpc-node-tg" - port = 8545 - protocol = "TCP" - vpc_id = aws_vpc.vpc.id - target_type = "ip" -} - -resource "aws_lb_listener" "rpc_node_listener_8545" { - count = var.enableFixedIp ? 1 : 0 - load_balancer_arn = aws_lb.rpc_node_nlb[0].arn - port = 8545 - protocol = "TCP" - - default_action { - type = "forward" - target_group_arn = aws_lb_target_group.rpc_node_tg_8545[0].arn - } -} - -resource "aws_ecs_service" "rpc_node_ecs_service" { - for_each = var.enableFixedIp ? var.nodeKeys : {} - name = "ecs-service-${each.key}" - cluster = aws_ecs_cluster.ecs_cluster.id - task_definition = "${aws_ecs_task_definition.task_definition_group[each.key].family}:${max(aws_ecs_task_definition.task_definition_group[each.key].revision, data.aws_ecs_task_definition.ecs_task_definition[each.key].revision)}" - launch_type = "FARGATE" - scheduling_strategy = "REPLICA" - desired_count = 1 - force_new_deployment = true - deployment_minimum_healthy_percent = 0 - deployment_maximum_percent = 100 - - network_configuration { - subnets = [aws_subnet.subnet.id] - assign_public_ip = true - security_groups = [ - aws_default_security_group.xdcnode_security_group.id - ] - } - - deployment_circuit_breaker { - enable = true - rollback = false - } - - load_balancer { - target_group_arn = aws_lb_target_group.rpc_node_tg_8545[0].arn - container_name = "tfXdcNode" - container_port = 8545 - } - - depends_on = [ - aws_lb_listener.rpc_node_listener_8545 - ] - - tags = { - Name = "TfRpcNodeEcsService-${each.key}" - } -} - -# Target Group for port 30303 -resource "aws_lb_target_group" "rpc_node_tg_30303" { - count = var.enableFixedIp ? 1 : 0 - name = "${var.network}-rpc-node-tg-30303" - port = 30303 - protocol = "TCP" - vpc_id = aws_vpc.vpc.id - target_type = "ip" -} - -# Listener for port 30303 -resource "aws_lb_listener" "rpc_node_listener_30303" { - count = var.enableFixedIp ? 1 : 0 - load_balancer_arn = aws_lb.rpc_node_nlb[0].arn - port = 30303 - protocol = "TCP" - - default_action { - type = "forward" - target_group_arn = aws_lb_target_group.rpc_node_tg_30303[0].arn - } -} \ No newline at end of file diff --git a/cicd/terraform/module/region/variables.tf b/cicd/terraform/module/region/variables.tf deleted file mode 100644 index 3f09785b8142..000000000000 --- a/cicd/terraform/module/region/variables.tf +++ /dev/null @@ -1,50 +0,0 @@ -variable "region" { - description = "AWS region" - type = string -} - -variable "nodeKeys" { - description = "each miner's key" - type = map -} - -variable "logLevel" { - description = "containers log level" - type = string -} - -variable "xdc_ecs_tasks_execution_role_arn" { - description = "aws iam role resource arn" - type = string -} - -variable "enableFixedIp" { - description = "a flag to indicate whether fixed ip should be associated to the nodes. This is used for RPC node" - type = bool - default = false -} - -variable "network" { - description = "blockchain network" - type = string -} - -variable "cpu" { - description = "container cpu" - type = number -} - -variable "memory" { - description = "container memory" - type = number -} - -variable "vpc_cidr" { - description = "vpc cidr" - type = string -} - -variable "subnet_cidr" { - description = "subnet cidr" - type = string -} \ No newline at end of file diff --git a/cicd/terraform/s3.tf b/cicd/terraform/s3.tf deleted file mode 100644 index 5c1fc4911508..000000000000 --- a/cicd/terraform/s3.tf +++ /dev/null @@ -1,14 +0,0 @@ -# Bucket need to be created first. If first time run terraform init, need to comment out the below section -terraform { - backend "s3" { - bucket = "tf-xinfin-bucket" - key = "tf/terraform_rpc.tfstate" - region = "us-east-1" - encrypt = true - } -} - -data "aws_s3_object" "xdc_node_config" { - bucket = "tf-xinfin-bucket" - key = "node-config.json" -} diff --git a/cicd/terraform/variables.tf b/cicd/terraform/variables.tf deleted file mode 100644 index 02bf5bdcf46c..000000000000 --- a/cicd/terraform/variables.tf +++ /dev/null @@ -1,17 +0,0 @@ -locals { - predefinedNodesConfig = jsondecode(data.aws_s3_object.xdc_node_config.body) - envs = { for tuple in regexall("(.*)=(.*)", file(".env")) : tuple[0] => tuple[1] } - logLevel = local.envs["log_level"] - - rpcDevnetNodeKeys = { "devnet-rpc1": local.predefinedNodesConfig["devnet-rpc1"]} // we hardcode the rpc to a single node for now - rpcTestnetNodeKeys = { "testnet-rpc1": local.predefinedNodesConfig["testnet-rpc1"]} // we hardcode the rpc to a single node for now - rpcMainnetNodeKeys = { "mainnet-rpc1": local.predefinedNodesConfig["mainnet-rpc1"]} // we hardcode the rpc to a single node for now -} - -locals { - ami_id = "ami-097c4e1feeea169e5" - rpc_image = "xinfinorg/xdposchain:v2.2.0-beta1" - vpc_id = "vpc-20a06846" - aws_subnet_id = "subnet-4653ee20" - ssh_key_name = "devnetkey" -} \ No newline at end of file