Skip to content

Commit

Permalink
Merge branch 'master' into fix-dasstore-errorlog
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuacolvin0 authored Dec 10, 2024
2 parents 42bb3e1 + 955f058 commit 4ad7568
Show file tree
Hide file tree
Showing 98 changed files with 5,051 additions and 991 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
redis:
image: redis
ports:
- 6379:6379
- 6379:6379

strategy:
fail-fast: false
Expand Down Expand Up @@ -192,7 +192,7 @@ jobs:
- name: run challenge tests
if: matrix.test-mode == 'challenge'
run: ${{ github.workspace }}/.github/workflows/gotestsum.sh --tags challengetest --run TestChallenge --cover
run: ${{ github.workspace }}/.github/workflows/gotestsum.sh --tags challengetest --run TestChallenge --timeout 60m --cover

- name: run stylus tests
if: matrix.test-mode == 'stylus'
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
[submodule "nitro-testnode"]
path = nitro-testnode
url = https://github.com/OffchainLabs/nitro-testnode.git
[submodule "bold"]
path = bold
url = https://github.com/OffchainLabs/bold.git
[submodule "arbitrator/langs/rust"]
path = arbitrator/langs/rust
url = https://github.com/OffchainLabs/stylus-sdk-rs.git
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
COPY go.mod go.sum ./
COPY go-ethereum/go.mod go-ethereum/go.sum go-ethereum/
COPY fastcache/go.mod fastcache/go.sum fastcache/
COPY bold/go.mod bold/go.sum bold/
RUN go mod download
COPY . ./
COPY --from=contracts-builder workspace/contracts/build/ contracts/build/
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Additional Use Grant: You may use the Licensed Work in a production environment
validating the correctness of the posted chain state, or to deploy
and operate (x) a blockchain that settles to a Covered Arbitrum Chain
or (y) a blockchain in accordance with, and subject to, the [Arbitrum
Expansion Program Term of Use](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf). For purposes of this
Expansion Program Term of Use](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf). For purposes of this
Additional Use Grant, the "Covered Arbitrum Chains" are
(a) Arbitrum One (chainid:42161), Arbitrum Nova (chainid:42170),
Arbitrum Rinkeby testnet/Rinkarby (chainid:421611),Arbitrum Nitro
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Nitro is currently licensed under a [Business Source License](./LICENSE.md), sim

The Additional Use Grant also permits the deployment of the Nitro software, in a permissionless fashion and without cost, as a new blockchain provided that the chain settles to either Arbitrum One or Arbitrum Nova.

For those that prefer to deploy the Nitro software either directly on Ethereum (i.e. an L2) or have it settle to another Layer-2 on top of Ethereum, the [Arbitrum Expansion Program (the "AEP")](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf) was recently established. The AEP allows for the permissionless deployment in the aforementioned fashion provided that 10% of net revenue (as more fully described in the AEP) is contributed back to the Arbitrum community in accordance with the requirements of the AEP.
For those that prefer to deploy the Nitro software either directly on Ethereum (i.e. an L2) or have it settle to another Layer-2 on top of Ethereum, the [Arbitrum Expansion Program (the "AEP")](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf) was recently established. The AEP allows for the permissionless deployment in the aforementioned fashion provided that 10% of net revenue (as more fully described in the AEP) is contributed back to the Arbitrum community in accordance with the requirements of the AEP.

## Contact

Expand Down
6 changes: 6 additions & 0 deletions arbitrator/prover/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char)
}
}

#[no_mangle]
#[cfg(feature = "native")]
pub unsafe extern "C" fn arbitrator_new_finished(gs: GlobalState) -> *mut Machine {
Box::into_raw(Box::new(Machine::new_finished(gs)))
}

unsafe fn cstr_to_string(c_str: *const c_char) -> String {
CStr::from_ptr(c_str).to_string_lossy().into_owned()
}
Expand Down
39 changes: 39 additions & 0 deletions arbitrator/prover/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,36 @@ impl Machine {
Ok(mach)
}

// new_finished returns a Machine in the Finished state at step 0.
//
// This allows the Mahine to be set up to model the final state of the
// machine at the end of the execution of a block.
pub fn new_finished(gs: GlobalState) -> Machine {
Machine {
steps: 0,
status: MachineStatus::Finished,
global_state: gs,
// The machine is in the Finished state, so nothing else really matters.
// values_stacks and frame_stacks cannot be empty for proof serialization,
// but everything else can just be entirely blank.
thread_state: ThreadState::Main,
value_stacks: vec![Vec::new()],
frame_stacks: vec![Vec::new()],
internal_stack: Default::default(),
modules: Default::default(),
modules_merkle: Default::default(),
pc: Default::default(),
stdio_output: Default::default(),
inbox_contents: Default::default(),
first_too_far: Default::default(),
preimage_resolver: PreimageResolverWrapper::new(Arc::new(|_, _, _| None)),
stylus_modules: Default::default(),
initial_hash: Default::default(),
context: Default::default(),
debug_info: Default::default(),
}
}

pub fn new_from_wavm(wavm_binary: &Path) -> Result<Machine> {
let mut modules: Vec<Module> = {
let compressed = std::fs::read(wavm_binary)?;
Expand Down Expand Up @@ -2867,6 +2897,15 @@ impl Machine {
let mod_merkle = self.get_modules_merkle();
out!(mod_merkle.root());

if self.is_halted() {
// If the machine is halted, instead of serializing the module,
// serialize the global state and return.
// This is for the "kickstart" BoLD proof, but it's backwards compatible
// with the old OSP behavior which reads no further.
out!(self.global_state.serialize());
return data;
}

// End machine serialization, serialize module

let module = &self.modules[self.pc.module()];
Expand Down
33 changes: 33 additions & 0 deletions arbitrator/stylus/tests/hostio-test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,37 @@ impl HostioTest {
fn tx_origin() -> Result<Address> {
Ok(tx::origin())
}

fn storage_cache_bytes32() {
let key = B256::ZERO;
let val = B256::ZERO;
unsafe {
hostio::storage_cache_bytes32(key.as_ptr(), val.as_ptr());
}
}

fn pay_for_memory_grow(pages: U256) {
let pages: u16 = pages.try_into().unwrap();
unsafe {
hostio::pay_for_memory_grow(pages);
}
}

fn write_result_empty() {
}

fn write_result(size: U256) -> Result<Vec<u32>> {
let size: usize = size.try_into().unwrap();
let data = vec![0; size];
Ok(data)
}

fn read_args_no_args() {
}

fn read_args_one_arg(_arg1: U256) {
}

fn read_args_three_args(_arg1: U256, _arg2: U256, _arg3: U256) {
}
}
2 changes: 1 addition & 1 deletion arbitrator/wasm-libraries/user-host-trait/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ pub trait UserHost<DR: DataReader>: GasMeteredMachine {
fn pay_for_memory_grow(&mut self, pages: u16) -> Result<(), Self::Err> {
if pages == 0 {
self.buy_ink(HOSTIO_INK)?;
return Ok(());
return trace!("pay_for_memory_grow", self, be!(pages), &[]);
}
let gas_cost = self.evm_api().add_pages(pages); // no sentry needed since the work happens after the hostio
self.buy_gas(gas_cost)?;
Expand Down
14 changes: 12 additions & 2 deletions arbnode/dataposter/data_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -712,13 +712,23 @@ func (p *DataPoster) feeAndTipCaps(ctx context.Context, nonce uint64, gasLimit u
return newBaseFeeCap, newTipCap, newBlobFeeCap, nil
}

func (p *DataPoster) PostSimpleTransaction(ctx context.Context, nonce uint64, to common.Address, calldata []byte, gasLimit uint64, value *big.Int) (*types.Transaction, error) {
return p.PostTransaction(ctx, time.Now(), nonce, nil, to, calldata, gasLimit, value, nil, nil)
func (p *DataPoster) PostSimpleTransaction(ctx context.Context, to common.Address, calldata []byte, gasLimit uint64, value *big.Int) (*types.Transaction, error) {
p.mutex.Lock()
defer p.mutex.Unlock()
nonce, _, _, _, err := p.getNextNonceAndMaybeMeta(ctx, 1)
if err != nil {
return nil, err
}
return p.postTransactionWithMutex(ctx, time.Now(), nonce, nil, to, calldata, gasLimit, value, nil, nil)
}

func (p *DataPoster) PostTransaction(ctx context.Context, dataCreatedAt time.Time, nonce uint64, meta []byte, to common.Address, calldata []byte, gasLimit uint64, value *big.Int, kzgBlobs []kzg4844.Blob, accessList types.AccessList) (*types.Transaction, error) {
p.mutex.Lock()
defer p.mutex.Unlock()
return p.postTransactionWithMutex(ctx, dataCreatedAt, nonce, meta, to, calldata, gasLimit, value, kzgBlobs, accessList)
}

func (p *DataPoster) postTransactionWithMutex(ctx context.Context, dataCreatedAt time.Time, nonce uint64, meta []byte, to common.Address, calldata []byte, gasLimit uint64, value *big.Int, kzgBlobs []kzg4844.Blob, accessList types.AccessList) (*types.Transaction, error) {

if p.config().DisableNewTx {
return nil, fmt.Errorf("posting new transaction is disabled")
Expand Down
3 changes: 2 additions & 1 deletion arbnode/inbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/offchainlabs/nitro/arbos/arbostypes"
"github.com/offchainlabs/nitro/arbos/l2pricing"
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/cmd/chaininfo"
"github.com/offchainlabs/nitro/execution/gethexec"
"github.com/offchainlabs/nitro/statetransfer"
"github.com/offchainlabs/nitro/util/arbmath"
Expand All @@ -44,7 +45,7 @@ func (w *execClientWrapper) FullSyncProgressMap() map[string]interface{} {
}

func NewTransactionStreamerForTest(t *testing.T, ownerAddress common.Address) (*gethexec.ExecutionEngine, *TransactionStreamer, ethdb.Database, *core.BlockChain) {
chainConfig := params.ArbitrumDevTestChainConfig()
chainConfig := chaininfo.ArbitrumDevTestChainConfig()

initData := statetransfer.ArbosInitializationInfo{
Accounts: []statetransfer.AccountInitializationInfo{
Expand Down
61 changes: 31 additions & 30 deletions arbnode/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ import (
"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
"github.com/offchainlabs/nitro/solgen/go/rollupgen"
"github.com/offchainlabs/nitro/staker"
boldstaker "github.com/offchainlabs/nitro/staker/bold"
legacystaker "github.com/offchainlabs/nitro/staker/legacy"
multiprotocolstaker "github.com/offchainlabs/nitro/staker/multi_protocol"
"github.com/offchainlabs/nitro/staker/validatorwallet"
"github.com/offchainlabs/nitro/util/contracts"
"github.com/offchainlabs/nitro/util/headerreader"
Expand Down Expand Up @@ -79,22 +82,23 @@ func GenerateRollupConfig(prod bool, wasmModuleRoot common.Hash, rollupOwner com
}

type Config struct {
Sequencer bool `koanf:"sequencer"`
ParentChainReader headerreader.Config `koanf:"parent-chain-reader" reload:"hot"`
InboxReader InboxReaderConfig `koanf:"inbox-reader" reload:"hot"`
DelayedSequencer DelayedSequencerConfig `koanf:"delayed-sequencer" reload:"hot"`
BatchPoster BatchPosterConfig `koanf:"batch-poster" reload:"hot"`
MessagePruner MessagePrunerConfig `koanf:"message-pruner" reload:"hot"`
BlockValidator staker.BlockValidatorConfig `koanf:"block-validator" reload:"hot"`
Feed broadcastclient.FeedConfig `koanf:"feed" reload:"hot"`
Staker staker.L1ValidatorConfig `koanf:"staker" reload:"hot"`
SeqCoordinator SeqCoordinatorConfig `koanf:"seq-coordinator"`
DataAvailability das.DataAvailabilityConfig `koanf:"data-availability"`
SyncMonitor SyncMonitorConfig `koanf:"sync-monitor"`
Dangerous DangerousConfig `koanf:"dangerous"`
TransactionStreamer TransactionStreamerConfig `koanf:"transaction-streamer" reload:"hot"`
Maintenance MaintenanceConfig `koanf:"maintenance" reload:"hot"`
ResourceMgmt resourcemanager.Config `koanf:"resource-mgmt" reload:"hot"`
Sequencer bool `koanf:"sequencer"`
ParentChainReader headerreader.Config `koanf:"parent-chain-reader" reload:"hot"`
InboxReader InboxReaderConfig `koanf:"inbox-reader" reload:"hot"`
DelayedSequencer DelayedSequencerConfig `koanf:"delayed-sequencer" reload:"hot"`
BatchPoster BatchPosterConfig `koanf:"batch-poster" reload:"hot"`
MessagePruner MessagePrunerConfig `koanf:"message-pruner" reload:"hot"`
BlockValidator staker.BlockValidatorConfig `koanf:"block-validator" reload:"hot"`
Feed broadcastclient.FeedConfig `koanf:"feed" reload:"hot"`
Staker legacystaker.L1ValidatorConfig `koanf:"staker" reload:"hot"`
Bold boldstaker.BoldConfig `koanf:"bold"`
SeqCoordinator SeqCoordinatorConfig `koanf:"seq-coordinator"`
DataAvailability das.DataAvailabilityConfig `koanf:"data-availability"`
SyncMonitor SyncMonitorConfig `koanf:"sync-monitor"`
Dangerous DangerousConfig `koanf:"dangerous"`
TransactionStreamer TransactionStreamerConfig `koanf:"transaction-streamer" reload:"hot"`
Maintenance MaintenanceConfig `koanf:"maintenance" reload:"hot"`
ResourceMgmt resourcemanager.Config `koanf:"resource-mgmt" reload:"hot"`
// SnapSyncConfig is only used for testing purposes, these should not be configured in production.
SnapSyncTest SnapSyncConfig
}
Expand Down Expand Up @@ -153,7 +157,8 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet, feedInputEnable bool, feed
MessagePrunerConfigAddOptions(prefix+".message-pruner", f)
staker.BlockValidatorConfigAddOptions(prefix+".block-validator", f)
broadcastclient.FeedConfigAddOptions(prefix+".feed", f, feedInputEnable, feedOutputEnable)
staker.L1ValidatorConfigAddOptions(prefix+".staker", f)
legacystaker.L1ValidatorConfigAddOptions(prefix+".staker", f)
boldstaker.BoldConfigAddOptions(prefix+".bold", f)
SeqCoordinatorConfigAddOptions(prefix+".seq-coordinator", f)
das.DataAvailabilityConfigAddNodeOptions(prefix+".data-availability", f)
SyncMonitorConfigAddOptions(prefix+".sync-monitor", f)
Expand All @@ -171,7 +176,8 @@ var ConfigDefault = Config{
MessagePruner: DefaultMessagePrunerConfig,
BlockValidator: staker.DefaultBlockValidatorConfig,
Feed: broadcastclient.FeedConfigDefault,
Staker: staker.DefaultL1ValidatorConfig,
Staker: legacystaker.DefaultL1ValidatorConfig,
Bold: boldstaker.DefaultBoldConfig,
SeqCoordinator: DefaultSeqCoordinatorConfig,
DataAvailability: das.DefaultDataAvailabilityConfig,
SyncMonitor: DefaultSyncMonitorConfig,
Expand Down Expand Up @@ -203,7 +209,7 @@ func ConfigDefaultL1NonSequencerTest() *Config {
config.SeqCoordinator.Enable = false
config.BlockValidator = staker.TestBlockValidatorConfig
config.SyncMonitor = TestSyncMonitorConfig
config.Staker = staker.TestL1ValidatorConfig
config.Staker = legacystaker.TestL1ValidatorConfig
config.Staker.Enable = false
config.BlockValidator.ValidationServerConfigs = []rpcclient.ClientConfig{{URL: ""}}

Expand All @@ -219,7 +225,7 @@ func ConfigDefaultL2Test() *Config {
config.Feed.Output.Signed = false
config.SeqCoordinator.Signer.ECDSA.AcceptSequencer = false
config.SeqCoordinator.Signer.ECDSA.Dangerous.AcceptMissing = true
config.Staker = staker.TestL1ValidatorConfig
config.Staker = legacystaker.TestL1ValidatorConfig
config.SyncMonitor = TestSyncMonitorConfig
config.Staker.Enable = false
config.BlockValidator.ValidationServerConfigs = []rpcclient.ClientConfig{{URL: ""}}
Expand Down Expand Up @@ -267,7 +273,7 @@ type Node struct {
MessagePruner *MessagePruner
BlockValidator *staker.BlockValidator
StatelessBlockValidator *staker.StatelessBlockValidator
Staker *staker.Staker
Staker *multiprotocolstaker.MultiProtocolStaker
BroadcastServer *broadcaster.Broadcaster
BroadcastClients *broadcastclients.BroadcastClients
SeqCoordinator *SeqCoordinator
Expand Down Expand Up @@ -633,7 +639,7 @@ func createNodeImpl(
}
}

var stakerObj *staker.Staker
var stakerObj *multiprotocolstaker.MultiProtocolStaker
var messagePruner *MessagePruner
var stakerAddr common.Address

Expand All @@ -653,7 +659,7 @@ func createNodeImpl(
getExtraGas := func() uint64 { return configFetcher.Get().Staker.ExtraGas }
// TODO: factor this out into separate helper, and split rest of node
// creation into multiple helpers.
var wallet staker.ValidatorWalletInterface = validatorwallet.NewNoOp(l1client, deployInfo.Rollup)
var wallet legacystaker.ValidatorWalletInterface = validatorwallet.NewNoOp(l1client, deployInfo.Rollup)
if !strings.EqualFold(config.Staker.Strategy, "watchtower") {
if config.Staker.UseSmartContractWallet || (txOptsValidator == nil && config.Staker.DataPoster.ExternalSigner.URL == "") {
var existingWalletAddress *common.Address
Expand Down Expand Up @@ -681,13 +687,13 @@ func createNodeImpl(
}
}

var confirmedNotifiers []staker.LatestConfirmedNotifier
var confirmedNotifiers []legacystaker.LatestConfirmedNotifier
if config.MessagePruner.Enable {
messagePruner = NewMessagePruner(txStreamer, inboxTracker, func() *MessagePrunerConfig { return &configFetcher.Get().MessagePruner })
confirmedNotifiers = append(confirmedNotifiers, messagePruner)
}

stakerObj, err = staker.NewStaker(l1Reader, wallet, bind.CallOpts{}, func() *staker.L1ValidatorConfig { return &configFetcher.Get().Staker }, blockValidator, statelessBlockValidator, nil, confirmedNotifiers, deployInfo.ValidatorUtils, fatalErrChan)
stakerObj, err = multiprotocolstaker.NewMultiProtocolStaker(stack, l1Reader, wallet, bind.CallOpts{}, func() *legacystaker.L1ValidatorConfig { return &configFetcher.Get().Staker }, &configFetcher.Get().Bold, blockValidator, statelessBlockValidator, nil, deployInfo.StakeToken, confirmedNotifiers, deployInfo.ValidatorUtils, deployInfo.Bridge, fatalErrChan)
if err != nil {
return nil, err
}
Expand All @@ -697,11 +703,6 @@ func createNodeImpl(
if dp != nil {
stakerAddr = dp.Sender()
}
whitelisted, err := stakerObj.IsWhitelisted(ctx)
if err != nil {
return nil, err
}
log.Info("running as validator", "txSender", stakerAddr, "actingAsWallet", wallet.Address(), "whitelisted", whitelisted, "strategy", config.Staker.Strategy)
}

var batchPoster *BatchPoster
Expand Down
2 changes: 1 addition & 1 deletion arbnode/seq_coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ func (c *SeqCoordinator) update(ctx context.Context) time.Duration {
for msgToRead < readUntil && localMsgCount >= remoteFinalizedMsgCount {
var resString string
resString, msgReadErr = client.Get(ctx, redisutil.MessageKeyFor(msgToRead)).Result()
if msgReadErr != nil {
if msgReadErr != nil && c.sequencer.Synced() {
log.Warn("coordinator failed reading message", "pos", msgToRead, "err", msgReadErr)
break
}
Expand Down
12 changes: 7 additions & 5 deletions arbnode/sync_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,13 @@ func (s *SyncMonitor) FullSyncProgressMap() map[string]interface{} {
batchProcessed := s.inboxReader.GetLastReadBatchCount()
res["batchProcessed"] = batchProcessed

processedBatchMsgs, err := s.inboxReader.Tracker().GetBatchMessageCount(batchProcessed - 1)
if err != nil {
res["batchMetadataError"] = err.Error()
} else {
res["messageOfProcessedBatch"] = processedBatchMsgs
if batchProcessed > 0 {
processedBatchMsgs, err := s.inboxReader.Tracker().GetBatchMessageCount(batchProcessed - 1)
if err != nil {
res["batchMetadataError"] = err.Error()
} else {
res["messageOfProcessedBatch"] = processedBatchMsgs
}
}

l1reader := s.inboxReader.l1Reader
Expand Down
Loading

0 comments on commit 4ad7568

Please sign in to comment.