5353210814
* Read a subset of filecoin state over the full node API * wip * import export wip * extract actors from message * generate car for any state * library for providing a pruned statetree * test vector schema draft + example 'message' class test vector. * message => messages test vector class. * fixup * wip * use lb.NewBlockstore with ID * fixup lotus-soup, and generate * fix deals * magic params * work on schema / export of test vector * fixup * wip deserialise state tree * pass at building a test case from a message * progress loading / serializing * recreation of ipld nodes * generation of vector creates json * kick off tvx tool. * wip * wip * retain init actor state. * initial test with printed out state * remove testing.T, but keep require and assert libraries * wip refactor state tree plucking. * simplified * removed factories * remove builder.Build ; remove interface - use concrete iface * comment out validateState * remove Validator * remove TestDriverBuilder * remove client * remove box * remove gen * remove factories * remove KeyManager interfafce * moved stuff around * remove ValidationConfig * extract randomness * extract config and key_manager * extract statewrapper * extract applier * rename factories to various * flatten chain-validation package * initial marshal of test vector * do not require schema package * fixup * run all messages tests * better names * run all messages tests * remove Indent setting from JSON encoder for now * refactor, and actually running successfully ;-) * remove irrelevant files; rename extract-msg command. * remove root CID from state_tree object in schema. * add tvx/lotus package; adjust .gitignore. * tidy up command flag management. * add comment. * remove validateState and trackState * remove xerrors * remove NewVM * remove commented out RootCID sets * enable more tests * add all `message_application` tests * delete all.json * update Message struct * fix message serialization * support multiple messages * gofmt * remove custom Message and SignedMessage types * update tests with gzip and adhere to new schema for compressed CAR * improved iface for Marshal * update Validation * remove test-suites and utils * better names for chain. methods * go mod tidy * remove top-level dummyT Co-authored-by: Will Scott <will@cypherpunk.email> Co-authored-by: Raúl Kripalani <raul@protocol.ai>
202 lines
5.3 KiB
Go
202 lines
5.3 KiB
Go
package drivers
|
|
|
|
import (
|
|
"github.com/filecoin-project/go-address"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
vtypes "github.com/filecoin-project/oni/tvx/chain/types"
|
|
)
|
|
|
|
type TipSetMessageBuilder struct {
|
|
driver *TestDriver
|
|
|
|
bbs []*BlockBuilder
|
|
}
|
|
|
|
func NewTipSetMessageBuilder(testDriver *TestDriver) *TipSetMessageBuilder {
|
|
return &TipSetMessageBuilder{
|
|
driver: testDriver,
|
|
bbs: nil,
|
|
}
|
|
}
|
|
|
|
func (t *TipSetMessageBuilder) WithBlockBuilder(bb *BlockBuilder) *TipSetMessageBuilder {
|
|
t.bbs = append(t.bbs, bb)
|
|
return t
|
|
}
|
|
|
|
func (t *TipSetMessageBuilder) Apply() vtypes.ApplyTipSetResult {
|
|
result := t.apply()
|
|
|
|
t.Clear()
|
|
return result
|
|
}
|
|
|
|
func (t *TipSetMessageBuilder) ApplyAndValidate() vtypes.ApplyTipSetResult {
|
|
result := t.apply()
|
|
|
|
t.validateResult(result)
|
|
|
|
t.Clear()
|
|
return result
|
|
}
|
|
|
|
func (tb *TipSetMessageBuilder) apply() vtypes.ApplyTipSetResult {
|
|
var blks []vtypes.BlockMessagesInfo
|
|
for _, b := range tb.bbs {
|
|
blks = append(blks, b.build())
|
|
}
|
|
result, err := tb.driver.applier.ApplyTipSetMessages(tb.driver.ExeCtx.Epoch, blks, tb.driver.Randomness())
|
|
require.NoError(t, err)
|
|
|
|
//t.driver.StateTracker.TrackResult(result)
|
|
return result
|
|
}
|
|
|
|
func (tb *TipSetMessageBuilder) validateResult(result vtypes.ApplyTipSetResult) {
|
|
expected := []ExpectedResult{}
|
|
for _, b := range tb.bbs {
|
|
expected = append(expected, b.expectedResults...)
|
|
}
|
|
|
|
if len(result.Receipts) > len(expected) {
|
|
t.Fatalf("ApplyTipSetMessages returned more result than expected. Expected: %d, Actual: %d", len(expected), len(result.Receipts))
|
|
return
|
|
}
|
|
|
|
for i := range result.Receipts {
|
|
if tb.driver.Config.ValidateExitCode() {
|
|
assert.Equal(t, expected[i].ExitCode, result.Receipts[i].ExitCode, "Message Number: %d Expected ExitCode: %s Actual ExitCode: %s", i, expected[i].ExitCode.Error(), result.Receipts[i].ExitCode.Error())
|
|
}
|
|
if tb.driver.Config.ValidateReturnValue() {
|
|
assert.Equal(t, expected[i].ReturnVal, result.Receipts[i].ReturnValue, "Message Number: %d Expected ReturnValue: %v Actual ReturnValue: %v", i, expected[i].ReturnVal, result.Receipts[i].ReturnValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (t *TipSetMessageBuilder) Clear() {
|
|
t.bbs = nil
|
|
}
|
|
|
|
type BlockBuilder struct {
|
|
TD *TestDriver
|
|
|
|
miner address.Address
|
|
ticketCount int64
|
|
|
|
secpMsgs []*types.SignedMessage
|
|
blsMsgs []*types.Message
|
|
|
|
expectedResults []ExpectedResult
|
|
}
|
|
|
|
type ExpectedResult struct {
|
|
ExitCode exitcode.ExitCode
|
|
ReturnVal []byte
|
|
}
|
|
|
|
func NewBlockBuilder(td *TestDriver, miner address.Address) *BlockBuilder {
|
|
return &BlockBuilder{
|
|
TD: td,
|
|
miner: miner,
|
|
ticketCount: 1,
|
|
secpMsgs: nil,
|
|
blsMsgs: nil,
|
|
expectedResults: nil,
|
|
}
|
|
}
|
|
|
|
func (bb *BlockBuilder) addResult(code exitcode.ExitCode, retval []byte) {
|
|
bb.expectedResults = append(bb.expectedResults, ExpectedResult{
|
|
ExitCode: code,
|
|
ReturnVal: retval,
|
|
})
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageOk(blsMsg *types.Message) *BlockBuilder {
|
|
bb.blsMsgs = append(bb.blsMsgs, blsMsg)
|
|
bb.addResult(exitcode.Ok, EmptyReturnValue)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageDropped(blsMsg *types.Message) *BlockBuilder {
|
|
bb.blsMsgs = append(bb.blsMsgs, blsMsg)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageAndCode(bm *types.Message, code exitcode.ExitCode) *BlockBuilder {
|
|
bb.blsMsgs = append(bb.blsMsgs, bm)
|
|
bb.addResult(code, EmptyReturnValue)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithBLSMessageAndRet(bm *types.Message, retval []byte) *BlockBuilder {
|
|
bb.blsMsgs = append(bb.blsMsgs, bm)
|
|
bb.addResult(exitcode.Ok, retval)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageAndCode(bm *types.Message, code exitcode.ExitCode) *BlockBuilder {
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
bb.addResult(code, EmptyReturnValue)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageAndRet(bm *types.Message, retval []byte) *BlockBuilder {
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
bb.addResult(exitcode.Ok, retval)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageOk(bm *types.Message) *BlockBuilder {
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
bb.addResult(exitcode.Ok, EmptyReturnValue)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithSECPMessageDropped(bm *types.Message) *BlockBuilder {
|
|
secpMsg := bb.toSignedMessage(bm)
|
|
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) WithTicketCount(count int64) *BlockBuilder {
|
|
bb.ticketCount = count
|
|
return bb
|
|
}
|
|
|
|
func (bb *BlockBuilder) toSignedMessage(m *types.Message) *types.SignedMessage {
|
|
from := m.From
|
|
if from.Protocol() == address.ID {
|
|
from = bb.TD.ActorPubKey(from)
|
|
}
|
|
if from.Protocol() != address.SECP256K1 {
|
|
t.Fatalf("Invalid address for SECP signature, address protocol: %v", from.Protocol())
|
|
}
|
|
raw, err := m.Serialize()
|
|
require.NoError(t, err)
|
|
|
|
sig, err := bb.TD.Wallet().Sign(from, raw)
|
|
require.NoError(t, err)
|
|
|
|
return &types.SignedMessage{
|
|
Message: *m,
|
|
Signature: sig,
|
|
}
|
|
}
|
|
|
|
func (bb *BlockBuilder) build() vtypes.BlockMessagesInfo {
|
|
return vtypes.BlockMessagesInfo{
|
|
BLSMessages: bb.blsMsgs,
|
|
SECPMessages: bb.secpMsgs,
|
|
Miner: bb.miner,
|
|
TicketCount: bb.ticketCount,
|
|
}
|
|
}
|