Jump to content
SBC-Daniel

Understanding Flag Integer Values when Mutiple flags are set

Recommended Posts

Posted (edited)

Ive become stuck attempting to decipher the integer value of the flag field when retrieving account info. It’s fairly simple if only one flag is set. But they seem to do some weird combining of the flag code’s integer value when multiple flags are present.

Has anyone been able to successfully determine which flags are set on a specific account using JS?

Edited by SBC-Daniel

Share this post


Link to post
Share on other sites
Posted (edited)

These are bit flags.  They look weird as decimal values, but as binary values they make a lot more sense, eg, a few are "on", and the rest are "off".  So 194 might appear to contain little immediately useful information, but its binary equivalent %11000010 shows which three flags would be considered to be switched on.

So, in JS you need to do this kind of thing:

var containsFlag = function(number, flag) {
  return (number & flag) === flag;
};

containsFlag(129, 128);  // true
containsFlag(81, 128);   // false

(Source: This Stack Overflow question.)

The difference in the case of Ripple Account flags is they are all presently higher order bits, but the principle is the same, you just need to shift the bits to the right (note that if they enabled more flags in the lower order this would change and you'd have to adjust your code accordingly).

Thus, if you saw an account with the flags set as 17891328, you'd just need to:

(17891328 >>> 16).toString(2) // '100010001'

To reveal the flags.  In this case, lsfDepositAuth, lsfDisableMaster and lsfPasswordSpent, as per this list.

(If you order the available flags in such a list by their descendent decimal value, they will correspond to the bits resulting from the above piece of code when read from left to right.)

Edited by Professor Hantzen

Share this post


Link to post
Share on other sites

Sukrim, they do appear to be bitmasks. Something I haven’t personally encountered before.

Prof Hantzen, thanks for the lesson. I’ll see what I can apply to my code and take note that this must be updated as ripple updates anything about the flag codes. 

Any idea why this methodology was used to communicate flag values instead of listing possible flags and their states in an object? (like they do with a lot of other info)

Share this post


Link to post
Share on other sites
10 minutes ago, SBC-Daniel said:

Sukrim, they do appear to be bitmasks. Something I haven’t personally encountered before.

Prof Hantzen, thanks for the lesson. I’ll see what I can apply to my code and take note that this must be updated as ripple updates anything about the flag codes. 

Any idea why this methodology was used to communicate flag values instead of listing possible flags and their states in an object? (like they do with a lot of other info)

No problem.  The reason its done this way is presumably for speed within rippled when processing account information.  In C++ - the langage rippled is primarily written in, and what is generally regarded as a language used for projects requiring fast run-time - this is a very typical construct to store this kind of information.  If you come across code that reduces things to bits, and requires bitwise operators, it is almost always done this way as a speed optimisation.  (By taking something a human readily understands and storing it in a manner a computer readily "understands".)

Share this post


Link to post
Share on other sites

Probably because historically it used to be THE way to efficiently encode flags, if you look at any network protocol or similar you'll see them being used. (https://en.wikipedia.org/wiki/Bit_field)

I also would rather see a list of bools in the interface instead of a single bitmask field, but since in the end it is going to end up in a field like that anyways and it is more or less an industry standard that most lower level programmers will have encountered, they maybe just went ahead with encoding that implementation detail in their API.

Share this post


Link to post
Share on other sites

Thanks for the responses. I can see how it’s more efficient and somewhat similar as how web developers minify css and JS code before a production launch.

I’m a web developer that has primarily handled front-end development of websites in my career.  (Read 0% experience with C++) I’m actively attempting to learn more about RCL so I can expand my contributions to SBC’s development team beyond making the interfaces of our products. Thanks for making that process a bit easier. 

Share this post


Link to post
Share on other sites

BTW, even if they look weird it's actually a sum of the values of the flag.

Imagine you have flags:

  • A --> 1 decimal (1 binary)
  • B --> 2 decimal (10 binary)
  • C --> 4 decimal (100 binary)
  • D --> 8 decimal (1000 binary)
  • E --> 16 decimal (10000 binary)

If you have D+B, it's 1010 binary which is 10 decimal (8+2).

If you have C+D+E, it's 11100 binary which is 28 decimal (16+8+4).

The JS code pointed by @Professor Hantzen is the most correct to "decode" flags.

To compose flags just use the OR operator. For example:

const flagA = 1; //you can use also const flagA = 0b1 in ES6
const flagB = 2; //you can use also const flagB = 0b10 in ES6

var flagAB = flagA | flagB;

 

Share this post


Link to post
Share on other sites

Continuing from what tulo said, to check whether flags are set, use the AND operator (&). For example:

tfSetfAuth = 0x00010000
tfSetNoRipple = 0x00020000
tfSetFreeze = 0x00100000

Flags = 2147680256 // tfFullyCanonicalSig, tfSetfAuth, and tfSetNoRipple are enabled

if (Flags & tfSetNoRipple) { // True
	console.log("Flags include tfSetNoRipple")
} else {
	console.log("Flags don't include tfSetNoRipple")
}

if (Flags & tfSetFreeze) { // False
	console.log("Flags include tfSetFreeze")
} else {
	console.log("Flags don't include tfSetFreeze")
}

 

Share this post


Link to post
Share on other sites

×