Skip to content

Add more functionality to the sim #5

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

Merged
merged 33 commits into from
Oct 26, 2019
Merged

Conversation

gitteri
Copy link

@gitteri gitteri commented Oct 21, 2019

Adds many new functions for the eth sim and tests.

PD added TransactionByHashWithBlockNum. I'll look to see if we need this and if we should keep it in this pr. Goal is to upstream this to go-etherem. Note: this is up to date with go-ethereum's current master

bmperrea and others added 30 commits October 18, 2018 18:54
Fixing the Simulated and Adding a new Fn TransactionByHashWithBlockNum
Fixing the Simulated and Adding a new Fn TransactionByHashWithBlockNum
Fixing the Simulated and Adding a new Fn TransactionByHashWithBlockNum
// TransactionByHash returns the transaction with the given hash.
// The code is exactly copied from the function TransactionByHash
// but this returns the blockHexString instead of json.BlockNumber == nil
func (ec *Client) TransactionByHashWithBlockNum(ctx context.Context, hash common.Hash) (tx *types.Transaction, blockHexString string, err error) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we need this. I'll look through for usage and also update the comment to reflect what it actually does if we do

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. ya if this was in a public PR I think it might open a separate can of worms. For Receipts we added block info to the Receipt struct and made changes throughout geth to populate it. For a Transaction there is already an RPC transaction, which may be worth migration to or returning here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I would anticipate resistance to the TransactionReader interface change - adding interface methods is a breaking change for other implementors.

Potentially-silly question, not knowing the contents of the return structs: A transaction won't be assigned a block num unless it has been mined, right? So we ought to be able to use a combination of the newTransactionReceipt (with block info) and TransactionByHashto accomplish whatever we were doing with this method?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I pushed back pretty hard when he was trying to add this but I guess he just did it anyway

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

axed!

@@ -419,10 +541,38 @@ func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethere
}), nil
}

// SubscribeNewHead returns an event subscription for a new header
func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed this functionality implement the ChainReader interface


tx, _, blockNumber, _ := rawdb.ReadTransaction(b.database, txHash)
if tx != nil {
return tx, hexutil.EncodeUint64(blockNumber), nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not return uint64 here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully we can just remove this function

return nil, errBlockDoesNotExist
}

return block.Transactions()[index], nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a scenario where block.Transactions returns nil?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't look like it returns nil but it could return a nil slice. adding a check

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still want to add a check here? I see another case of block.Transactions()[index] a few lines above.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

improved this function a bit and added some of the error cases to the test

// TransactionByHash returns the transaction with the given hash.
// The code is exactly copied from the function TransactionByHash
// but this returns the blockHexString instead of json.BlockNumber == nil
func (ec *Client) TransactionByHashWithBlockNum(ctx context.Context, hash common.Hash) (tx *types.Transaction, blockHexString string, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. ya if this was in a public PR I think it might open a separate can of worms. For Receipts we added block info to the Receipt struct and made changes throughout geth to populate it. For a Transaction there is already an RPC transaction, which may be worth migration to or returning here.

// SubscribeNewHead returns an event subscription for a new header
func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) {
// subscribe to a new head
sink := make(chan *types.Header)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unless this is an established naming convention in this kind of method, maybe upstream ? It's a little weird to call it "sink" in the context of this function because we do not write to the it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I found sink elsewhere when dealing with subscriptions:
Subscribe(sink chan<- WalletEvent) event.Subscription

select {
case head := <-sink:
select {
case ch <- head:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a nested select because the send to ch might block, and we want to be able to handle the error or quit messages while it's blocked?

It's probably simpler to avoid the nesting:

waitWrite := make(chan *types.Header)
defer close(curr)
var source <-chan *types.Header = upstream
for {
  var curr *types.Header
  select {
  case head := <-upstream:
    curr = head
  case err ...
  case quit...
 }
 select {
  case ch <- curr:
    continue
  case err...
  case quit...
  }
}

(unless the nesting is an established pattern in go-ethereum)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I see nested selects everywhere:

node/api.go line 128
contract/oracle line 379
eth/enr_entry.go line 45
miner/miner.go line 89
p2p/simulations/network.go line 977

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and many more

t.Errorf("could not estimate gas: %v", err)
}

if gas != uint64(21000) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just use params.TxGas rather than hard code

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true throughout these tests

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

if len(res) == 0 {
t.Errorf("result of contract call was empty: %v", res)
}
// use strings contains since actual response is padded with many \x00 bytes and a space

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The padding shouldn't change though right? If so we could look for the exact bytes to tighten up this test

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

@gitteri gitteri changed the base branch from master to igitter-sim-improved October 26, 2019 14:23
@gitteri gitteri merged commit ed6b7de into igitter-sim-improved Oct 26, 2019
connorwstein pushed a commit that referenced this pull request Nov 25, 2019
* backends: implement more of ethclient in sim

* backends: add BlockByNumber to simulated backend

* backends: make simulated progress function agree with syncprogress interface for client

* backends: add more tests

* backends: add more comments

* backends: fix sim for index in tx and add tests
gitteri pushed a commit that referenced this pull request Jul 20, 2021
* eth/protocols: persist received state segments

* core: initial implementation

* core/state/snapshot: add tests

* core, eth: updates

* eth/protocols/snapshot: count flat state size

* core/state: add metrics

* core/state/snapshot: skip unnecessary deletion

* core/state/snapshot: rename

* core/state/snapshot: use the global batch

* core/state/snapshot: add logs and fix wiping

* core/state/snapshot: fix

* core/state/snapshot: save generation progress even if the batch is empty

* core/state/snapshot: fixes

* core/state/snapshot: fix initial account range length

* core/state/snapshot: fix initial account range

* eth/protocols/snap: store flat states during the healing

* eth/protocols/snap: print logs

* core/state/snapshot: refactor (#4)

* core/state/snapshot: refactor

* core/state/snapshot: tiny fix and polish

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>

* core, eth: fixes

* core, eth: fix healing writer

* core, trie, eth: fix paths

* eth/protocols/snap: fix encoding

* eth, core: add debug log

* core/state/generate: release iterator asap (#5)

core/state/snapshot: less copy

core/state/snapshot: revert split loop

core/state/snapshot: handle storage becoming empty, improve test robustness

core/state: test modified codehash

core/state/snapshot: polish

* core/state/snapshot: optimize stats counter

* core, eth: add metric

* core/state/snapshot: update comments

* core/state/snapshot: improve tests

* core/state/snapshot: replace secure trie with standard trie

* core/state/snapshot: wrap return as the struct

* core/state/snapshot: skip wiping correct states

* core/state/snapshot: updates

* core/state/snapshot: fixes

* core/state/snapshot: fix panic due to reference flaw in closure

* core/state/snapshot: fix errors in state generation logic + fix log output

* core/state/snapshot: remove an error case

* core/state/snapshot: fix condition-check for exhausted snap state

* core/state/snapshot: use stackTrie for small tries

* core/state/snapshot: don't resolve small storage tries in vain

* core/state/snapshot: properly clean up storage of deleted accounts

* core/state/snapshot: avoid RLP-encoding in some cases + minor nitpicks

* core/state/snapshot: fix error (+testcase)

* core/state/snapshot: clean up tests a bit

* core/state/snapshot: work in progress on better tests

* core/state/snapshot: polish code

* core/state/snapshot: fix trie iteration abortion trigger

* core/state/snapshot: fixes flaws

* core/state/snapshot: remove panic

* core/state/snapshot: fix abort

* core/state/snapshot: more tests (plus failing testcase)

* core/state/snapshot: more testcases + fix for failing test

* core/state/snapshot: testcase for malformed data

* core/state/snapshot: some test nitpicks

* core/state/snapshot: improvements to logging

* core/state/snapshot: testcase to demo error in abortion

* core/state/snapshot: fix abortion

* cmd/geth: make verify-state report the root

* trie: fix failing test

* core/state/snapshot: add timer metrics

* core/state/snapshot: fix metrics

* core/state/snapshot: udpate tests

* eth/protocols/snap: write snapshot account even if code or state is needed

* core/state/snapshot: fix diskmore check

* core/state/snapshot: review fixes

* core/state/snapshot: improve error message

* cmd/geth: rename 'error' to 'err' in logs

* core/state/snapshot: fix some review concerns

* core/state/snapshot, eth/protocols/snap: clear snapshot marker when starting/resuming snap sync

* core: add error log

* core/state/snapshot: use proper timers for metrics collection

* core/state/snapshot: address some review concerns

* eth/protocols/snap: improved log message

* eth/protocols/snap: fix heal logs to condense infos

* core/state/snapshot: wait for generator termination before restarting

* core/state/snapshot: revert timers to counters to track total time

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants