Skip to content

Commit

Permalink
Add fuse support (#8)
Browse files Browse the repository at this point in the history
* Add fuse support
Why?
Previously, transactions under 10 gwei could lower the average gas price over the last 50 blocks, potentially causing a backlog of stuck transactions. 
Solution:
This PR allow nodes to set a minimum gas price limit. As a result, eth_gasPrice calls will return either the average gas price from the last 50 blocks or this newly set minimum limit, whichever is higher.
Flag: `UseMinGasPriceInEstimates`
  • Loading branch information
Andrew-Pohl authored Jan 29, 2024
1 parent e64bee7 commit 7a24e3b
Show file tree
Hide file tree
Showing 13 changed files with 563 additions and 2 deletions.
1 change: 1 addition & 0 deletions VERSION.FUSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4.0.5
79 changes: 79 additions & 0 deletions src/Nethermind/Chains/fuse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"name": "FuseNetwork",
"engine": {
"authorityRound": {
"params": {
"stepDuration": "5",
"blockReward": "0x0",
"blockRewardContractAddress": "0x63D4efeD2e3dA070247bea3073BCaB896dFF6C9B",
"blockRewardContractTransition": 100,
"validators": {
"multi": {
"0": {
"list": ["0xd9176e84898a0054680aec3f7c056b200c3d96c3"]
},
"100": {
"safeContract": "0x3014ca10b91cb3D0AD85fEf7A3Cb95BCAc9c0f79"
}
}
}
}
}
},
"params": {
"gasLimitBoundDivisor": "0x400",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x07a",
"eip155Transition": 0,
"validateChainIdTransition": 0,
"eip140Transition": 0,
"eip211Transition": 0,
"eip214Transition": 0,
"eip658Transition": 0,
"eip150Transition": "0x0",
"eip160Transition": "0x0",
"eip161abcTransition": "0x0",
"eip161dTransition": "0x0",
"eip98Transition": "0x7fffffffffffff",
"eip145Transition": "0x38ada7",
"eip1014Transition": "0x38ada7",
"eip1052Transition": "0x38ada7",
"eip1283Transition": "0xd29240",
"eip1344Transition": "0xd29240",
"eip1706Transition": "0xd29240",
"eip1884Transition": "0xd29240",
"eip2028Transition": "0xd29240",
"eip2929Transition": "0xd29240",
"eip2930Transition": "0xd29240",
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0"
},
"genesis": {
"seal": {
"authorityRound": {
"step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"gasLimit": "0x989680"
},
"nodes": [
"enode://c78e7cce5e84a3a6c723d10dc40a033ad50dbc835b3a1f1d85b1a4f299afe8e3a8112fe26b045e23370bbf22c179d0d9f6e4f8302bf72dea67fa3b684232d6eb@3.125.148.125:30303",
"enode://0690b49d2de17516e8776df4cd171da148769e43e9ac0c9b1ef6e9f6f6a983f5d508ce44bbb6e974c663611c3c03492cdf3d6838907e0ce392c125741912d8a5@3.121.55.130:30303",
"enode://7bc2e851cad345437984d6550b1b98d7029b694f2793e2c592637a793b243760060a5a3e00d6212b75f1c534a97b41d532221071242d01116e9ff3c8dcc95672@95.217.1.4:30303"
],
"accounts": {
"0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "pricing": { "0": { "price": { "modexp": { "divisor": 20 } } }, "0xd29240": { "info": "EIP-2565: ModExp Gas Cost.", "price": { "modexp2565": {} } } } } },
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "pricing": { "0": { "price": { "alt_bn128_const_operations": { "price": 500 } } }, "0xd29240": { "info": "EIP-1108 Istanbul HF", "price": { "alt_bn128_const_operations": { "price": 150 } } } } } },
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "pricing": { "0": { "price": { "alt_bn128_const_operations": { "price": 4000 } } }, "0xd29240": { "info": "EIP-1108 Istanbul HF", "price": { "alt_bn128_const_operations": { "price": 6000 } } } } } },
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "pricing": { "0": { "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } }, "0xd29240": { "info": "EIP-1108 Istanbul HF", "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 } } } } } },
"0x0000000000000000000000000000000000000009": { "builtin": { "name": "blake2_f", "pricing": { "0xd29240": { "info": "EIP-152 Istanbul HF", "price": { "blake2_f": { "gas_per_round": 1 } } } } } },
"0xd9176e84898a0054680aec3f7c056b200c3d96c3": { "balance": "300000000000000000000000000" }
}
}
155 changes: 155 additions & 0 deletions src/Nethermind/Chains/spark.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
"name": "FuseNetwork",
"engine": {
"authorityRound": {
"params": {
"stepDuration": "5",
"blockReward": "0x0",
"blockRewardContractAddress": "0x52B9b9585e1b50DA5600f7dbD94E9fE68943162c",
"blockRewardContractTransition": 1000,
"validators": {
"multi": {
"0": {
"list": ["0xba7829b381f07cca0d186bdf619fdc6c7f756d0a"]
},
"1000": {
"safeContract": "0xC8c3a332f9e4CE6bfFFcf967026cB006Db2311c7"
},
"6905799": {
"list": [
"0x379e81df609e8235c9026f25a379d49a27b10d30",
"0xba7829b381f07cca0d186bdf619fdc6c7f756d0a",
"0xe4cc9b2836ba373c3ccf473cbb15ed07007963ee",
"0xbc048d3064fd912b40a9aadcf67a14fd4601db77"
]
},
"6910120": {
"safeContract": "0xC8c3a332f9e4CE6bfFFcf967026cB006Db2311c7"
},
"6925000": {
"list": [
"0x379e81df609e8235c9026f25a379d49a27b10d30",
"0xba7829b381f07cca0d186bdf619fdc6c7f756d0a",
"0xe4cc9b2836ba373c3ccf473cbb15ed07007963ee",
"0xbc048d3064fd912b40a9aadcf67a14fd4601db77"
]
},
"13608000": {
"list": [
"0xba7829b381f07cca0d186bdf619fdc6c7f756d0a",
"0xe4cc9b2836ba373c3ccf473cbb15ed07007963ee",
"0xbc048d3064fd912b40a9aadcf67a14fd4601db77"
]
},
"13639200": {
"safeContract": "0x8C682051D70301A0ca913Ce0A0e71539702E1122"
}
}
},
"blockRewardContractTransitions": {
"13639200": "0xEa2151b6095CB76ECc57A57DE166728dd9b53Ed9"
}
}
}
},
"params": {
"gasLimitBoundDivisor": "0x400",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID": "0x07b",
"eip155Transition": 0,
"validateChainIdTransition": 0,
"eip140Transition": 0,
"eip211Transition": 0,
"eip214Transition": 0,
"eip658Transition": 0,
"eip150Transition": "0x0",
"eip160Transition": "0x0",
"eip161abcTransition": "0x0",
"eip161dTransition": "0x0",
"eip98Transition": "0x7fffffffffffff",
"eip145Transition": "0x6bf64",
"eip1014Transition": "0x6bf64",
"eip1052Transition": "0x6bf64",
"eip1283Transition": "0x13d620",
"eip1344Transition": "0x13d620",
"eip1706Transition": "0x13d620",
"eip1884Transition": "0x13d620",
"eip2028Transition": "0x13d620",
"eip2929Transition": "0x13d620",
"eip2930Transition": "0x13d620",
"maxCodeSize": 24576,
"maxCodeSizeTransition": "0x0"
},
"genesis": {
"seal": {
"authorityRound": {
"step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"gasLimit": "0x5F5E100"
},
"accounts": {
"0x0000000000000000000000000000000000000001": {
"balance": "1",
"builtin": {
"name": "ecrecover",
"pricing": { "linear": { "base": 3000, "word": 0 } }
}
},
"0x0000000000000000000000000000000000000002": {
"balance": "1",
"builtin": {
"name": "sha256",
"pricing": { "linear": { "base": 60, "word": 12 } }
}
},
"0x0000000000000000000000000000000000000003": {
"balance": "1",
"builtin": {
"name": "ripemd160",
"pricing": { "linear": { "base": 600, "word": 120 } }
}
},
"0x0000000000000000000000000000000000000004": {
"balance": "1",
"builtin": {
"name": "identity",
"pricing": { "linear": { "base": 15, "word": 3 } }
}
},
"0x0000000000000000000000000000000000000005": {
"builtin": {
"name": "modexp",
"activate_at": 0,
"pricing": { "modexp": { "divisor": 20 } }
}
},
"0x0000000000000000000000000000000000000006": {
"builtin": {
"name": "alt_bn128_add",
"activate_at": 0,
"pricing": { "linear": { "base": 500, "word": 0 } }
}
},
"0x0000000000000000000000000000000000000007": {
"builtin": {
"name": "alt_bn128_mul",
"activate_at": 0,
"pricing": { "linear": { "base": 40000, "word": 0 } }
}
},
"0x0000000000000000000000000000000000000008": {
"builtin": {
"name": "alt_bn128_pairing",
"activate_at": 0,
"pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } }
}
},
"0xba7829b381f07cca0d186bdf619fdc6c7f756d0a": {
"balance": "300000000000000000000000000"
}
}
}
4 changes: 3 additions & 1 deletion src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using Nethermind.Db.FullPruning;
using Nethermind.Evm;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.JsonRpc;
using Nethermind.JsonRpc.Converters;
using Nethermind.JsonRpc.Modules.DebugModule;
using Nethermind.JsonRpc.Modules.Eth.GasPrice;
Expand Down Expand Up @@ -69,6 +70,7 @@ protected virtual Task InitBlockchain()

IInitConfig initConfig = getApi.Config<IInitConfig>();
IBlocksConfig blocksConfig = getApi.Config<IBlocksConfig>();
IJsonRpcConfig jsonRpcConfig = getApi.Config<IJsonRpcConfig>();

IStateReader stateReader = setApi.StateReader!;
ITxPool txPool = _api.TxPool = CreateTxPool();
Expand Down Expand Up @@ -101,7 +103,7 @@ protected virtual Task InitBlockchain()
setApi.TxSender = new TxPoolSender(txPool, nonceReservingTxSealer, nonceManager, getApi.EthereumEcdsa!);

setApi.TxPoolInfoProvider = new TxPoolInfoProvider(chainHeadInfoProvider.AccountStateProvider, txPool);
setApi.GasPriceOracle = new GasPriceOracle(getApi.BlockTree!, getApi.SpecProvider, _api.LogManager, blocksConfig.MinGasPrice);
setApi.GasPriceOracle = new GasPriceOracle(getApi.BlockTree!, getApi.SpecProvider, _api.LogManager, blocksConfig.MinGasPrice, jsonRpcConfig.UseMinGasPriceInEstimates);
IBlockProcessor mainBlockProcessor = setApi.MainBlockProcessor = CreateBlockProcessor();

BlockchainProcessor blockchainProcessor = new(
Expand Down
5 changes: 5 additions & 0 deletions src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ public interface IJsonRpcConfig : IConfig
[ConfigItem(Description = "The max length of HTTP request body, in bytes.", DefaultValue = "30000000")]
long? MaxRequestBodySize { get; set; }

[ConfigItem(
Description = "Set a lower limit for GetGasPriceEstimate. This ensure rpc calls to eth_gasPrice are never below the limit set by MiningConfig.MinGasPrice",
DefaultValue = "false")]
bool UseMinGasPriceInEstimates { get; set; }

[ConfigItem(
Description = """
The number of concurrent instances for non-sharable calls:
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public int WebSocketsPort
public string[] EngineEnabledModules { get; set; } = ModuleType.DefaultEngineModules.ToArray();
public int MaxBatchSize { get; set; } = 1024;
public long? MaxBatchResponseBodySize { get; set; } = 30.MB();
public bool UseMinGasPriceInEstimates { get; set; } = false;
};
};

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class GasPriceOracle : IGasPriceOracle
private readonly IBlockFinder _blockFinder;
private readonly ILogger _logger;
private readonly UInt256 _minGasPrice;
private readonly bool _UseMinGasPrice;
internal PriceCache _gasPriceEstimation;
internal PriceCache _maxPriorityFeePerGasEstimation;
private UInt256 FallbackGasPrice(in UInt256? baseFeePerGas = null) => _gasPriceEstimation.LastPrice ?? GetMinimumGasPrice(baseFeePerGas ?? UInt256.Zero);
Expand All @@ -32,11 +33,13 @@ public GasPriceOracle(
IBlockFinder blockFinder,
ISpecProvider specProvider,
ILogManager logManager,
UInt256? minGasPrice = null)
UInt256? minGasPrice = null,
bool useMinGasPrice = false)
{
_blockFinder = blockFinder;
_logger = logManager.GetClassLogger();
_minGasPrice = minGasPrice ?? new BlocksConfig().MinGasPrice;
_UseMinGasPrice = useMinGasPrice;
SpecProvider = specProvider;
}

Expand All @@ -56,6 +59,10 @@ public UInt256 GetGasPriceEstimate()

IEnumerable<UInt256> txGasPrices = GetSortedGasPricesFromRecentBlocks(headBlock.Number);
UInt256 gasPriceEstimate = GetGasPriceAtPercentile(txGasPrices.ToList()) ?? GetMinimumGasPrice(headBlock.BaseFeePerGas);
if (_UseMinGasPrice == true)
{
gasPriceEstimate = UInt256.Max(gasPriceEstimate, GetMinimumGasPrice(headBlock.BaseFeePerGas));
}
gasPriceEstimate = UInt256.Min(gasPriceEstimate!, EthGasPriceConstants.MaxGasPrice);
_gasPriceEstimation.Set(headBlockHash, gasPriceEstimate);
return gasPriceEstimate!;
Expand Down
54 changes: 54 additions & 0 deletions src/Nethermind/Nethermind.Runner/configs/fuse.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"Init": {
"DiscoveryEnabled": true,
"WebSocketsEnabled": false,
"StoreReceipts" : true,
"ChainSpecPath": "chainspec/fuse.json",
"BaseDbPath": "nethermind_db/fuse",
"LogFileName": "fuse.logs.txt"
},
"Sync": {
"FastSync": true,
"PivotNumber": 27600000,
"PivotHash": "0x7181ad9fa9b8317c886668a1fa7738de280cf8fcf09bc45d99fbd6e92b0744aa",
"PivotTotalDifficulty": "9391793327017901591589139165116802635816949662",
"FastBlocks": true,
"UseGethLimitsInFastBlocks": false,
"FastSyncCatchUpHeightDelta": 10000000000
},
"Network": {
"DiscoveryPort": 30303,
"P2PPort": 30303,
"LocalIp": "0.0.0.0",
"ExternalIp": "0.0.0.0"
},
"JsonRpc": {
"Enabled": true,
"Timeout": 20000,
"Host": "0.0.0.0",
"Port": 8545,
"WebSocketsPort": 8546,
"UseMinGasPriceInEstimates": true
},
"Metrics": {
"NodeName": "Fuse"
},
"Bloom": {
"IndexLevelBucketSizes": [
16,
16,
16
]
},
"Pruning": {
"Enabled": true,
"CacheMb": 1024,
"PersistenceInterval": 16384
},
"Mining": {
"MinGasPrice": "10000000000"
},
"Merge": {
"Enabled": false
}
}
Loading

0 comments on commit 7a24e3b

Please sign in to comment.