From 89c51c5e6911d814b7370b10a2c6a1cb7d79e560 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 18 Dec 2024 17:50:26 +0800 Subject: [PATCH 01/63] 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 02/63] 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 03/63] 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 04/63] 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 05/63] 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 06/63] 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 07/63] 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 08/63] 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 09/63] 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 10/63] 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 11/63] 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 12/63] 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 13/63] 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 14/63] 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 15/63] 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 16/63] 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 17/63] 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 18/63] 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 19/63] 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 20/63] 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 21/63] 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 22/63] 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 23/63] 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 24/63] 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 25/63] 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 26/63] 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 27/63] 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 28/63] 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 29/63] 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 30/63] 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 31/63] 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 32/63] 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 33/63] 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 34/63] 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 35/63] 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 36/63] 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 37/63] 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 38/63] 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 39/63] 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 40/63] 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 41/63] 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 42/63] 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 43/63] 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 44/63] 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 45/63] 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 46/63] 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 47/63] 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 48/63] 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 49/63] 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 50/63] 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 51/63] 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 52/63] 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 53/63] 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 54/63] 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 55/63] 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 56/63] 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 57/63] 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 58/63] 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 59/63] 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 60/63] 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 61/63] 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 62/63] 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 63/63] 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")