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

add unit test for find_secondary host functions #1024

Merged
merged 5 commits into from
Nov 13, 2024
Merged

Conversation

spoonincode
Copy link
Member

Which key should the find_secondary host function return when there are duplicate keys? cdt avoids this question entirely by never using these host functions and instead always doing a lowerbound (it's possible the find_secondary host function has never once been used on EOS! Unless a rare contract built with something other then cdt used it of course)

The host function ultimately performs a "partial key lookup" on the table (this then goes through to chainbase's find())

int find_secondary( uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_const_type secondary, uint64_t& primary ) {
auto tab = context.find_table( name(code), name(scope), name(table) );
if( !tab ) return -1;
auto table_end_itr = itr_cache.cache_table( *tab );
const auto* obj = context.db.find<ObjectType, by_secondary>( secondary_key_helper_t::create_tuple( *tab, secondary ) );

In leap 3.1+ & spring, the underlying data structure (boost intrusive avltree) does specify that find() is treated like lowerbound(). And even looking through the code makes it clear that find() simply calls lowerbound().

EOSIO 2.0 and earlier it is not so clear: the documentation for the data structure in use (boost multindex directly) simply says it finds "a" matching key. But eyeballing the code suggests it does effectively behave like lowerbound. And empirically the test code still passes on 2.0.

This test confirms that the find_secondary host functions behave like lowerbound: lowest primary key is returned.

Closes #1019

(data (i32.const 16) "\00\00\00\00\01\02\03\04AbcdefghABCDEFGH01234567")
(data (i32.const 48) "\00\00\00\00\01\02\03\05abcdefghABCDEFGH99999999")
(data (i32.const 80) "\00\00\00\00\01\02\03\06aBcdefghABCDEFGH00000000")
)
Copy link
Member Author

Choose a reason for hiding this comment

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

hm maybe I should have just done this in a .cpp contract, but I would have had to use the internal_use_do_not_use functions which I wanted to avoid.

@spoonincode spoonincode merged commit a7a0f11 into main Nov 13, 2024
36 checks passed
@spoonincode spoonincode deleted the find_secondary_test branch November 13, 2024 17:07
@ericpassmore
Copy link
Contributor

Note:start
category: Tests
component: Host Functions
summary: Add unit test for find_secondary host functions.
Note:end

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.

unit test exercising secondary key find
4 participants