Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Transaction Restriction Service (TRS) implementation and Fixed bugs #42

Merged
merged 7 commits into from
Jun 20, 2024
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,10 @@ gmet-linux:
docker build -t meta/builder:local \
-f Dockerfile.metadium . && \
docker run -e HOME=/tmp --rm -v $(shell pwd):/data \
-u $(shell id -u):$(shell id -g) \
-u $(shell id -u):$(shell id -g) \
-w /data meta/builder:local \
"make USE_ROCKSDB=$(USE_ROCKSDB)"; \
"git config --global --add safe.directory /data;\
make USE_ROCKSDB=$(USE_ROCKSDB)"; \
fi

ifneq ($(USE_ROCKSDB), YES)
Expand Down Expand Up @@ -154,6 +155,11 @@ BEGIN { print "package metadium\n"; } \
sub("^var[^(]*\\(","",$$0); sub("\\);$$","",$$0); \
n = "Gov"; \
print "var " n "Abi = `{ \"contractName\": \"" n "\", \"abi\": " $$0 "}`"; \
} \
/^var TRSListImp_contract/ { \
sub("^var[^(]*\\(","",$$0); sub("\\);$$","",$$0); \
n = "TRSList"; \
print "var " n "Abi = `{ \"contractName\": \"" n "\", \"abi\": " $$0 "}`"; \
}'

metadium/governance_abi.go: metadium/contracts/MetadiumGovernance.js
Expand Down
4 changes: 4 additions & 0 deletions core/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,8 @@ var (
// ErrSenderInsufficientFunds is returned if the value cost of executing a transaction
// is higher than the balance of the sender's account.
ErrSenderInsufficientFunds = errors.New("fee delegation: insufficient sender's funds for value")

// Add TRS
// ErrIncludedTRSList is returned if the address included in the TRSList.
ErrIncludedTRSList = errors.New("included in the TRSList")
)
3 changes: 1 addition & 2 deletions core/state/snapshot/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
// If the iterated account is the contract, create a further loop to
// verify or regenerate the contract storage.
if acc.Root == emptyRoot {
log.Debug("removeStorageAt skip for rocksdb")
// ctx.removeStorageAt(account)
ctx.removeStorageAt(account)
} else {
var storeMarker []byte
if accMarker != nil && bytes.Equal(account[:], accMarker) && len(dl.genMarker) > common.HashLength {
Expand Down
94 changes: 82 additions & 12 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
metaminer "github.com/ethereum/go-ethereum/metadium/miner"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
)
Expand Down Expand Up @@ -95,6 +96,8 @@ var (
var (
evictionInterval = time.Minute // Time interval to check for evictable transactions
statsReportInterval = 8 * time.Second // Time interval to report transaction pool stats
// Add TRS
trsTickerInterval = 3 * time.Hour // Time interval to check for TRS transactions
)

var (
Expand Down Expand Up @@ -250,6 +253,9 @@ type TxPool struct {
eip1559 bool // Fork indicator whether we are using EIP-1559 type transactions.
// fee delegation
feedelegation bool // Fork indicator whether we are using fee delegation type transactions.
// Add TRS
trsListMap map[common.Address]bool
trsSubscribe bool

currentState *state.StateDB // Current state in the blockchain head
pendingNonces *txNoncer // Pending state tracking virtual nonces
Expand Down Expand Up @@ -356,12 +362,16 @@ func (pool *TxPool) loop() {
report = time.NewTicker(statsReportInterval)
evict = time.NewTicker(evictionInterval)
journal = time.NewTicker(pool.config.Rejournal)
// Add TRS
trsTicker = time.NewTicker(trsTickerInterval)
// Track the previous head headers for transaction reorgs
head = pool.chain.CurrentBlock()
)
defer report.Stop()
defer evict.Stop()
defer journal.Stop()
// Add TRS
defer trsTicker.Stop()

// Notify tests that the init phase is done
close(pool.initDoneCh)
Expand Down Expand Up @@ -433,6 +443,25 @@ func (pool *TxPool) loop() {
}
pool.mu.Unlock()
}
// Add TRS
case <-trsTicker.C:
// Removes the transaction included in trsList regardless of TRS subscription.
if !metaminer.IsPoW() {
if len(pool.trsListMap) > 0 {
pool.mu.Lock()
for addr := range pool.pending {
list := pool.pending[addr].Flatten()
for _, tx := range list {
if pool.trsListMap[addr] || (tx.To() != nil && pool.trsListMap[*tx.To()]) {
log.Debug("Discard pending transaction included in trsList", "hash", tx.Hash(), "addr", addr)
pool.removeTx(tx.Hash(), true)
pendingDiscardMeter.Mark(int64(1))
}
}
}
pool.mu.Unlock()
}
}
}
}
}
Expand Down Expand Up @@ -701,6 +730,16 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
if pool.currentState.GetNonce(from) > tx.Nonce() {
return ErrNonceTooLow
}
// Add TRS
// Only nodes that subscribe to TRS removes transactions included in trsList.
if !metaminer.IsPoW() {
if len(pool.trsListMap) > 0 && pool.trsSubscribe {
if pool.trsListMap[from] || (tx.To() != nil && pool.trsListMap[*tx.To()]) {
return ErrIncludedTRSList
}
}
}

// Transactor should have enough funds to cover the costs
// cost == V + GP * GL

Expand Down Expand Up @@ -1400,6 +1439,13 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
pool.eip1559 = pool.chainconfig.IsLondon(next)
// fee delegation
pool.feedelegation = pool.chainconfig.IsApplepie(next)
// Add TRS
if !metaminer.IsPoW() {
pool.trsListMap, pool.trsSubscribe, _ = metaminer.GetTRSListMap(newHead.Number)
} else {
pool.trsListMap = nil
pool.trsSubscribe = false
}
}

// promoteExecutables moves transactions that have become processable from the
Expand All @@ -1425,13 +1471,25 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Trans
// Drop all transactions that are too costly (low balance or out of gas)
drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas)

// fee delegation
if pool.feedelegation {
// Add TRS
// Only nodes that subscribe to TRS removes transactions included in trsList.
doTrs := !metaminer.IsPoW() && len(pool.trsListMap) > 0 && pool.trsSubscribe
if pool.feedelegation || doTrs {
for _, tx := range list.Flatten() {
if tx.Type() == types.FeeDelegateDynamicFeeTxType && tx.FeePayer() != nil {
feePayer := *tx.FeePayer()
if pool.currentState.GetBalance(feePayer).Cmp(tx.FeePayerCost()) < 0 {
log.Trace("promoteExecutables", "hash", tx.Hash().String())
if pool.feedelegation {
if tx.Type() == types.FeeDelegateDynamicFeeTxType && tx.FeePayer() != nil {
feePayer := *tx.FeePayer()
if pool.currentState.GetBalance(feePayer).Cmp(tx.FeePayerCost()) < 0 {
log.Trace("Removed queued fee delegation transaction", "hash", tx.Hash().String())
list.Remove(tx)
drops = append(drops, tx)
continue
}
}
}
if doTrs {
if pool.trsListMap[addr] || (tx.To() != nil && pool.trsListMap[*tx.To()]) {
log.Trace("Removed queued transaction included in trsList", "hash", tx.Hash(), "addr", addr)
list.Remove(tx)
drops = append(drops, tx)
}
Expand Down Expand Up @@ -1637,13 +1695,25 @@ func (pool *TxPool) demoteUnexecutables() {
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas)

// fee delegation
if pool.feedelegation {
// Add TRS
// Only nodes that subscribe to TRS removes transactions included in trsList.
doTrs := !metaminer.IsPoW() && len(pool.trsListMap) > 0 && pool.trsSubscribe
if pool.feedelegation || doTrs {
for _, tx := range list.Flatten() {
if tx.Type() == types.FeeDelegateDynamicFeeTxType && tx.FeePayer() != nil {
feePayer := *tx.FeePayer()
if pool.currentState.GetBalance(feePayer).Cmp(tx.FeePayerCost()) < 0 {
log.Trace("demoteUnexecutables", "hash", tx.Hash().String())
if pool.feedelegation {
if tx.Type() == types.FeeDelegateDynamicFeeTxType && tx.FeePayer() != nil {
feePayer := *tx.FeePayer()
if pool.currentState.GetBalance(feePayer).Cmp(tx.FeePayerCost()) < 0 {
log.Trace("Removed pending fee delegation transaction", "hash", tx.Hash().String())
list.Remove(tx)
drops = append(drops, tx)
continue
}
}
}
if doTrs {
if pool.trsListMap[addr] || (tx.To() != nil && pool.trsListMap[*tx.To()]) {
log.Trace("Removed pending transaction included in trsList", "hash", tx.Hash(), "addr", addr)
list.Remove(tx)
drops = append(drops, tx)
}
Expand Down
5 changes: 5 additions & 0 deletions ethdb/rocksdb/rocksdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ func (it *RDBIterator) Next() bool {
if it.first {
it.first = false
} else {
// Added conditions to prevent Rocksdb Iterator error.
// Valid() call is a RocksDB requirement.
if C.rocksdb_iter_valid(it.it) == 0 {
return false
}
C.rocksdb_iter_next(it.it)
}
return C.rocksdb_iter_valid(it.it) != 0
Expand Down
6 changes: 6 additions & 0 deletions internal/web3ext/web3ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ web3._extend({
call: 'admin_etcdDeleteWork',
params: 0
}),
new web3._extend.Method({
name: 'trsInfo',
call: 'admin_trsInfo',
params: 1,
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter]
}),
],
properties: [
new web3._extend.Property({
Expand Down
21 changes: 21 additions & 0 deletions light/txpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
metaminer "github.com/ethereum/go-ethereum/metadium/miner"
"github.com/ethereum/go-ethereum/params"
)

Expand Down Expand Up @@ -71,6 +72,9 @@ type TxPool struct {
eip2718 bool // Fork indicator whether we are in the eip2718 stage.
// fee delegation
feedelegation bool // Fork indicator whether we are in the fee delegation stage.
// Add TRS
trsListMap map[common.Address]bool
trsSubscribe bool
}

// TxRelayBackend provides an interface to the mechanism that forwards transacions
Expand Down Expand Up @@ -322,6 +326,13 @@ func (pool *TxPool) setNewHead(head *types.Header) {
pool.eip2718 = pool.config.IsBerlin(next)
// fee delegation
pool.feedelegation = pool.config.IsApplepie(next)
// Add TRS
if !metaminer.IsPoW() {
pool.trsListMap, pool.trsSubscribe, _ = metaminer.GetTRSListMap(head.Number)
} else {
pool.trsListMap = nil
pool.trsSubscribe = false
}
}

// Stop stops the light transaction pool
Expand Down Expand Up @@ -382,6 +393,16 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
return core.ErrNegativeValue
}

// Add TRS
// Only nodes that subscribe to TRS reject transactions included in trsList.
if !metaminer.IsPoW() {
if len(pool.trsListMap) > 0 && pool.trsSubscribe {
if pool.trsListMap[from] || (tx.To() != nil && pool.trsListMap[*tx.To()]) {
return core.ErrIncludedTRSList
}
}
}

// Transactor should have enough funds to cover the costs
// cost == V + GP * GL

Expand Down
Loading
Loading